From 123a44dbe08fee96148cf82494039adb7b3b869c Mon Sep 17 00:00:00 2001 From: emrgnt-cmplxty <68796651+emrgnt-cmplxty@users.noreply.github.com> Date: Fri, 16 Aug 2024 13:19:43 -0700 Subject: [PATCH 01/74] Feature/merge graphrag group mgmt (#876) * add group ids to document abstraction, first steps * extend group permissions * up * add tests for new group features * up * fixup auth * onboard extensive regression tests * adding regression tests * finish tests * rm selenium * test observability * uncomment tests * checkin first set of group tests * modify search, passing vector tests * checkin work * full delete logic * update search to use new filters * check in * Clean up * Check in * add search * tests/test_end_to_end.py::test_ingest_txt_document passing * cleanup logging * make schemas explicit * move to run logger abstraction * cleanup some test workflows * revive tests * tweak to pass tests * tweak rrf * finish hybrid search cleanup * fixup on regr tests, regen payloads * refresh payloads * refactor api model * Feature/refactor api model (#868) * cleanup imports * flake and cleanup * coherent global import / export structure * add ingestion response models * add management response models * cleanups * checkin work on routes * remove request models * last fixes * merge * add user / group gating * working test groups * updating client --------- Co-authored-by: NolanTrem <34580718+NolanTrem@users.noreply.github.com> --- poetry.lock | 1537 ++++++++++++++--- pyproject.toml | 3 + r2r/__init__.py | 286 ++- r2r/{agents => agent}/__init__.py | 2 + r2r/{agents => agent}/base.py | 13 +- r2r/{agents => agent}/rag.py | 12 +- r2r/base/__init__.py | 298 ++-- r2r/base/abstractions/__init__.py | 94 + r2r/base/abstractions/document.py | 172 +- r2r/base/abstractions/graph.py | 452 +++++ r2r/base/abstractions/llama_abstractions.py | 439 ----- r2r/base/abstractions/search.py | 95 +- r2r/base/abstractions/user.py | 41 +- r2r/base/abstractions/vector.py | 45 +- r2r/base/agent/__init__.py | 11 + r2r/base/{abstractions => agent}/agent.py | 47 +- r2r/base/agent/base.py | 31 + r2r/base/api/models/__init__.py | 93 + r2r/base/api/models/auth/__init__.py | 0 r2r/base/api/models/auth/responses.py | 41 + r2r/base/api/models/base.py | 9 + r2r/base/api/models/ingestion/__init__.py | 0 r2r/base/api/models/ingestion/responses.py | 77 + r2r/base/api/models/management/__init__.py | 0 r2r/base/api/models/management/responses.py | 126 ++ r2r/base/api/models/retrieval/__init__.py | 0 r2r/base/api/models/retrieval/responses.py | 149 ++ r2r/base/logging/__init__.py | 39 + r2r/base/logging/base.py | 11 + r2r/base/logging/log_processor.py | 2 +- .../logging/{kv_logger.py => run_logger.py} | 563 +++--- r2r/base/logging/run_manager.py | 45 +- r2r/base/pipeline/__init__.py | 5 + r2r/base/pipeline/base_pipeline.py | 74 +- r2r/base/pipes/__init__.py | 3 + r2r/base/pipes/base_pipe.py | 7 +- r2r/base/providers/__init__.py | 54 + r2r/base/providers/auth.py | 20 +- r2r/base/providers/chunking.py | 9 +- r2r/base/providers/database.py | 97 +- r2r/base/providers/embedding.py | 5 +- r2r/base/providers/eval.py | 46 - r2r/base/providers/kg.py | 110 +- r2r/base/utils/__init__.py | 19 +- r2r/base/utils/base_utils.py | 14 +- r2r/base/utils/splitter/text.py | 65 +- r2r/cli/__init__.py | 23 + r2r/cli/cli.py | 3 + r2r/cli/commands/document_operations.py | 31 +- r2r/cli/commands/kg_operations.py | 16 + .../commands/oberservability_operations.py | 13 +- r2r/cli/commands/rag_operations.py | 40 +- r2r/examples/configs/graphrag.toml | 61 + r2r/examples/configs/neo4j_kg.toml | 40 +- r2r/examples/scripts/advanced_kg_cookbook.py | 34 +- r2r/examples/scripts/sample_data_ingestor.py | 4 +- r2r/examples/scripts/test_e2e.py | 321 ---- r2r/main/__init__.py | 88 +- r2r/main/abstractions.py | 17 +- r2r/main/api/__init__.py | 17 + r2r/main/api/client.py | 620 ------- r2r/main/api/client/__init__.py | 1 + r2r/main/api/client/auth.py | 93 + r2r/main/api/client/client.py | 198 +++ r2r/main/api/client/ingestion.py | 230 +++ r2r/main/api/client/management.py | 267 +++ r2r/main/api/client/restructure.py | 51 + r2r/main/api/client/retrieval.py | 146 ++ r2r/main/api/routes/auth/base.py | 209 ++- r2r/main/api/routes/auth/requests.py | 14 - r2r/main/api/routes/base_router.py | 33 +- r2r/main/api/routes/ingestion/base.py | 464 ++++- r2r/main/api/routes/ingestion/requests.py | 17 - r2r/main/api/routes/kg/__init__.py | 0 r2r/main/api/routes/kg/base.py | 23 + r2r/main/api/routes/kg/requests.py | 10 + r2r/main/api/routes/management/base.py | 396 +++-- r2r/main/api/routes/management/requests.py | 49 - r2r/main/api/routes/retrieval/base.py | 688 ++++++-- r2r/main/api/routes/retrieval/requests.py | 35 - r2r/main/app.py | 11 +- r2r/main/app_entry.py | 4 +- r2r/main/assembly/__init__.py | 23 + r2r/main/assembly/builder.py | 66 +- r2r/main/assembly/config.py | 18 +- r2r/main/assembly/factory.py | 122 +- r2r/main/assembly/factory_extensions.py | 3 +- r2r/main/engine.py | 77 +- r2r/main/execution.py | 61 +- r2r/main/services/__init__.py | 2 + r2r/main/services/auth_service.py | 61 +- r2r/main/services/base.py | 4 +- r2r/main/services/ingestion_service.py | 302 +--- r2r/main/services/management_service.py | 204 ++- r2r/main/services/restructure_service.py | 94 + r2r/main/services/retrieval_service.py | 93 +- r2r/parsers/__init__.py | 24 +- r2r/parsers/media/__init__.py | 17 + r2r/parsers/media/openai_helpers.py | 2 +- r2r/parsers/media/pdf_parser.py | 11 +- r2r/parsers/structured/__init__.py | 11 + r2r/parsers/structured/xlsx_parser.py | 4 +- r2r/parsers/text/__init__.py | 9 + r2r/pipelines/__init__.py | 4 +- r2r/pipelines/eval_pipeline.py | 37 - r2r/pipelines/graph_enrichment.py | 33 + r2r/pipelines/ingestion_pipeline.py | 22 +- r2r/pipelines/rag_pipeline.py | 23 +- r2r/pipelines/search_pipeline.py | 23 +- r2r/pipes/__init__.py | 11 +- r2r/pipes/abstractions/generator_pipe.py | 4 +- r2r/pipes/abstractions/search_pipe.py | 6 +- r2r/pipes/ingestion/chunking_pipe.py | 39 +- r2r/pipes/ingestion/embedding_pipe.py | 23 +- r2r/pipes/ingestion/kg_extraction_pipe.py | 15 +- r2r/pipes/ingestion/parsing_pipe.py | 20 +- r2r/pipes/ingestion/vector_storage_pipe.py | 24 +- r2r/pipes/kg/clustering.py | 282 +++ r2r/pipes/kg/extraction.py | 227 +++ r2r/pipes/kg/node_extraction.py | 234 +++ .../kg_storage_pipe.py => kg/storage.py} | 39 +- r2r/pipes/other/eval_pipe.py | 54 - r2r/pipes/other/web_search_pipe.py | 11 +- r2r/pipes/retrieval/kg_search_search_pipe.py | 190 +- r2r/pipes/retrieval/search_rag_pipe.py | 2 +- r2r/pipes/retrieval/streaming_rag_pipe.py | 4 +- r2r/pipes/retrieval/vector_search_pipe.py | 12 +- r2r/providers/__init__.py | 17 +- r2r/providers/auth/r2r_auth.py | 22 +- r2r/providers/chunking/r2r_chunking.py | 46 +- .../chunking/unstructured_chunking.py | 2 +- r2r/providers/database/base.py | 87 + r2r/providers/database/document.py | 111 ++ r2r/providers/database/group.py | 392 +++++ r2r/providers/database/postgres.py | 1052 +---------- r2r/providers/database/relational.py | 47 + r2r/providers/database/tokens.py | 59 + r2r/providers/database/user.py | 432 +++++ .../database/vecs/adapter/__init__.py | 3 +- r2r/providers/database/vecs/adapter/base.py | 18 +- r2r/providers/database/vecs/adapter/noop.py | 39 +- r2r/providers/database/vecs/collection.py | 568 +++--- r2r/providers/database/vector.py | 430 +++++ r2r/providers/eval/__init__.py | 3 - r2r/providers/eval/r2r_llm_eval.py | 84 - r2r/providers/kg/neo4j.py | 989 ----------- r2r/providers/kg/neo4j/__init__.py | 1 + r2r/providers/kg/neo4j/graph_queries.py | 168 ++ r2r/providers/kg/neo4j/provider.py | 405 +++++ r2r/providers/parsing/r2r_parsing.py | 20 +- r2r/providers/parsing/unstructured_parsing.py | 21 +- r2r/providers/prompts/defaults.yaml | 0 .../defaults/graphrag_community_reports.yaml | 150 ++ .../defaults/graphrag_map_system_prompt.yaml | 55 + .../graphrag_reduce_system_prompt.yaml | 43 + .../graphrag_triplet_extraction_few_shot.yaml | 36 + ...graphrag_triplet_extraction_zero_shot.yaml | 28 + .../prompts/defaults/rag_answer.yaml | 52 - .../prompts/defaults/rag_context.yaml | 2 +- r2r/providers/prompts/r2r_prompts.py | 6 +- tests/__init__.py | 0 .../test_document_management.json | 1183 +++++++++++++ .../test_group_management.json | 168 ++ .../expected_outputs/test_observability.json | 381 ++++ .../expected_outputs/test_retrieval.json | 554 ++++++ .../test_user_management.json | 116 ++ tests/regression/runner.py | 138 ++ tests/regression/test_cases/base.py | 273 +++ .../test_cases/test_document_management.py | 115 ++ .../test_cases/test_group_management.py | 169 ++ .../test_cases/test_observability.py | 26 + tests/regression/test_cases/test_retrieval.py | 87 + .../test_cases/test_user_management.py | 156 ++ .../test_data/admin_document_group1.txt | 1 + .../test_data/admin_document_user1.txt | 1 + tests/regression/test_data/test_document.txt | 1 + tests/regression/test_data/user1_document.txt | 1 + .../test_data/user1_document_group.txt | 1 + tests/regression/test_data/user2_document.txt | 1 + tests/test_abstractions.py | 76 +- tests/test_auth.py | 280 ++- tests/test_cli.py | 29 +- tests/test_client.py | 120 +- tests/test_database.py | 48 +- tests/test_end_to_end.py | 478 ++--- tests/test_groups.py | 415 +++++ tests/test_groups_client.py | 376 ++++ tests/test_ingestion_service.py | 159 +- tests/test_kg.py | 139 ++ tests/test_logging.py | 352 ++-- tests/test_vector_db.py | 282 +++ 191 files changed, 15996 insertions(+), 7593 deletions(-) rename r2r/{agents => agent}/__init__.py (87%) rename r2r/{agents => agent}/base.py (96%) rename r2r/{agents => agent}/rag.py (93%) create mode 100644 r2r/base/abstractions/graph.py delete mode 100644 r2r/base/abstractions/llama_abstractions.py create mode 100644 r2r/base/agent/__init__.py rename r2r/base/{abstractions => agent}/agent.py (88%) create mode 100644 r2r/base/agent/base.py create mode 100644 r2r/base/api/models/__init__.py create mode 100644 r2r/base/api/models/auth/__init__.py create mode 100644 r2r/base/api/models/auth/responses.py create mode 100644 r2r/base/api/models/base.py create mode 100644 r2r/base/api/models/ingestion/__init__.py create mode 100644 r2r/base/api/models/ingestion/responses.py create mode 100644 r2r/base/api/models/management/__init__.py create mode 100644 r2r/base/api/models/management/responses.py create mode 100644 r2r/base/api/models/retrieval/__init__.py create mode 100644 r2r/base/api/models/retrieval/responses.py create mode 100644 r2r/base/logging/base.py rename r2r/base/logging/{kv_logger.py => run_logger.py} (55%) delete mode 100644 r2r/base/providers/eval.py create mode 100644 r2r/cli/commands/kg_operations.py create mode 100644 r2r/examples/configs/graphrag.toml delete mode 100644 r2r/examples/scripts/test_e2e.py delete mode 100644 r2r/main/api/client.py create mode 100644 r2r/main/api/client/__init__.py create mode 100644 r2r/main/api/client/auth.py create mode 100644 r2r/main/api/client/client.py create mode 100644 r2r/main/api/client/ingestion.py create mode 100644 r2r/main/api/client/management.py create mode 100644 r2r/main/api/client/restructure.py create mode 100644 r2r/main/api/client/retrieval.py delete mode 100644 r2r/main/api/routes/auth/requests.py delete mode 100644 r2r/main/api/routes/ingestion/requests.py create mode 100644 r2r/main/api/routes/kg/__init__.py create mode 100644 r2r/main/api/routes/kg/base.py create mode 100644 r2r/main/api/routes/kg/requests.py delete mode 100644 r2r/main/api/routes/management/requests.py delete mode 100644 r2r/main/api/routes/retrieval/requests.py create mode 100644 r2r/main/services/restructure_service.py delete mode 100644 r2r/pipelines/eval_pipeline.py create mode 100644 r2r/pipelines/graph_enrichment.py create mode 100644 r2r/pipes/kg/clustering.py create mode 100644 r2r/pipes/kg/extraction.py create mode 100644 r2r/pipes/kg/node_extraction.py rename r2r/pipes/{ingestion/kg_storage_pipe.py => kg/storage.py} (65%) delete mode 100644 r2r/pipes/other/eval_pipe.py create mode 100644 r2r/providers/database/base.py create mode 100644 r2r/providers/database/document.py create mode 100644 r2r/providers/database/group.py create mode 100644 r2r/providers/database/relational.py create mode 100644 r2r/providers/database/tokens.py create mode 100644 r2r/providers/database/user.py create mode 100644 r2r/providers/database/vector.py delete mode 100644 r2r/providers/eval/__init__.py delete mode 100644 r2r/providers/eval/r2r_llm_eval.py delete mode 100644 r2r/providers/kg/neo4j.py create mode 100644 r2r/providers/kg/neo4j/__init__.py create mode 100644 r2r/providers/kg/neo4j/graph_queries.py create mode 100644 r2r/providers/kg/neo4j/provider.py create mode 100644 r2r/providers/prompts/defaults.yaml create mode 100644 r2r/providers/prompts/defaults/graphrag_community_reports.yaml create mode 100644 r2r/providers/prompts/defaults/graphrag_map_system_prompt.yaml create mode 100644 r2r/providers/prompts/defaults/graphrag_reduce_system_prompt.yaml create mode 100644 r2r/providers/prompts/defaults/graphrag_triplet_extraction_few_shot.yaml create mode 100644 r2r/providers/prompts/defaults/graphrag_triplet_extraction_zero_shot.yaml delete mode 100644 r2r/providers/prompts/defaults/rag_answer.yaml create mode 100644 tests/__init__.py create mode 100644 tests/regression/expected_outputs/test_document_management.json create mode 100644 tests/regression/expected_outputs/test_group_management.json create mode 100644 tests/regression/expected_outputs/test_observability.json create mode 100644 tests/regression/expected_outputs/test_retrieval.json create mode 100644 tests/regression/expected_outputs/test_user_management.json create mode 100644 tests/regression/runner.py create mode 100644 tests/regression/test_cases/base.py create mode 100644 tests/regression/test_cases/test_document_management.py create mode 100644 tests/regression/test_cases/test_group_management.py create mode 100644 tests/regression/test_cases/test_observability.py create mode 100644 tests/regression/test_cases/test_retrieval.py create mode 100644 tests/regression/test_cases/test_user_management.py create mode 100644 tests/regression/test_data/admin_document_group1.txt create mode 100644 tests/regression/test_data/admin_document_user1.txt create mode 100644 tests/regression/test_data/test_document.txt create mode 100644 tests/regression/test_data/user1_document.txt create mode 100644 tests/regression/test_data/user1_document_group.txt create mode 100644 tests/regression/test_data/user2_document.txt create mode 100644 tests/test_groups.py create mode 100644 tests/test_groups_client.py create mode 100644 tests/test_kg.py create mode 100644 tests/test_vector_db.py diff --git a/poetry.lock b/poetry.lock index 67a55a596..82c4a01ba 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2,13 +2,13 @@ [[package]] name = "aiohappyeyeballs" -version = "2.3.4" +version = "2.3.5" description = "Happy Eyeballs for asyncio" optional = false -python-versions = "<4.0,>=3.8" +python-versions = ">=3.8" files = [ - {file = "aiohappyeyeballs-2.3.4-py3-none-any.whl", hash = "sha256:40a16ceffcf1fc9e142fd488123b2e218abc4188cf12ac20c67200e1579baa42"}, - {file = "aiohappyeyeballs-2.3.4.tar.gz", hash = "sha256:7e1ae8399c320a8adec76f6c919ed5ceae6edd4c3672f4d9eae2b27e37c80ff6"}, + {file = "aiohappyeyeballs-2.3.5-py3-none-any.whl", hash = "sha256:4d6dea59215537dbc746e93e779caea8178c866856a721c9c660d7a5a7b8be03"}, + {file = "aiohappyeyeballs-2.3.5.tar.gz", hash = "sha256:6fa48b9f1317254f122a07a131a86b71ca6946ca989ce6326fff54a99a920105"}, ] [[package]] @@ -192,6 +192,20 @@ doc = ["Sphinx (>=7)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphin test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] trio = ["trio (>=0.23)"] +[[package]] +name = "anytree" +version = "2.12.1" +description = "Powerful and Lightweight Python Tree Data Structure with various plugins" +optional = false +python-versions = ">=3.7.2,<4" +files = [ + {file = "anytree-2.12.1-py3-none-any.whl", hash = "sha256:5ea9e61caf96db1e5b3d0a914378d2cd83c269dfce1fb8242ce96589fa3382f0"}, + {file = "anytree-2.12.1.tar.gz", hash = "sha256:244def434ccf31b668ed282954e5d315b4e066c4940b94aff4a7962d85947830"}, +] + +[package.dependencies] +six = "*" + [[package]] name = "async-timeout" version = "4.0.3" @@ -262,13 +276,13 @@ test = ["flake8 (>=6.1,<7.0)", "uvloop (>=0.15.3)"] [[package]] name = "attrs" -version = "24.1.0" +version = "24.2.0" description = "Classes Without Boilerplate" optional = false python-versions = ">=3.7" files = [ - {file = "attrs-24.1.0-py3-none-any.whl", hash = "sha256:377b47448cb61fea38533f671fba0d0f8a96fd58facd4dc518e3dac9dbea0905"}, - {file = "attrs-24.1.0.tar.gz", hash = "sha256:adbdec84af72d38be7628e353a09b6a6790d15cd71819f6e9d7b0faa8a125745"}, + {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, + {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, ] [package.extras] @@ -279,6 +293,21 @@ docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphi tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] +[[package]] +name = "autograd" +version = "1.6.2" +description = "Efficiently computes derivatives of numpy code." +optional = false +python-versions = "*" +files = [ + {file = "autograd-1.6.2-py3-none-any.whl", hash = "sha256:208dde2a938e63b4f8f5049b1985505139e529068b0d26f8cd7771fd3eb145d5"}, + {file = "autograd-1.6.2.tar.gz", hash = "sha256:8731e08a0c4e389d8695a40072ada4512641c113b6cace8f4cfbe8eb7e9aedeb"}, +] + +[package.dependencies] +future = ">=0.15.2" +numpy = ">=1.12" + [[package]] name = "backoff" version = "2.2.1" @@ -330,6 +359,24 @@ files = [ tests = ["pytest (>=3.2.1,!=3.3.0)"] typecheck = ["mypy"] +[[package]] +name = "beartype" +version = "0.18.5" +description = "Unbearably fast runtime type checking in pure Python." +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "beartype-0.18.5-py3-none-any.whl", hash = "sha256:5301a14f2a9a5540fe47ec6d34d758e9cd8331d36c4760fc7a5499ab86310089"}, + {file = "beartype-0.18.5.tar.gz", hash = "sha256:264ddc2f1da9ec94ff639141fbe33d22e12a9f75aa863b83b7046ffff1381927"}, +] + +[package.extras] +all = ["typing-extensions (>=3.10.0.0)"] +dev = ["autoapi (>=0.9.0)", "coverage (>=5.5)", "equinox", "mypy (>=0.800)", "numpy", "pandera", "pydata-sphinx-theme (<=0.7.2)", "pytest (>=4.0.0)", "sphinx", "sphinx (>=4.2.0,<6.0.0)", "sphinxext-opengraph (>=0.7.5)", "tox (>=3.20.1)", "typing-extensions (>=3.10.0.0)"] +doc-rtd = ["autoapi (>=0.9.0)", "pydata-sphinx-theme (<=0.7.2)", "sphinx (>=4.2.0,<6.0.0)", "sphinxext-opengraph (>=0.7.5)"] +test-tox = ["equinox", "mypy (>=0.800)", "numpy", "pandera", "pytest (>=4.0.0)", "sphinx", "typing-extensions (>=3.10.0.0)"] +test-tox-coverage = ["coverage (>=5.5)"] + [[package]] name = "beautifulsoup4" version = "4.12.3" @@ -558,6 +605,69 @@ files = [ {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] +[[package]] +name = "contourpy" +version = "1.2.1" +description = "Python library for calculating contours of 2D quadrilateral grids" +optional = false +python-versions = ">=3.9" +files = [ + {file = "contourpy-1.2.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bd7c23df857d488f418439686d3b10ae2fbf9bc256cd045b37a8c16575ea1040"}, + {file = "contourpy-1.2.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5b9eb0ca724a241683c9685a484da9d35c872fd42756574a7cfbf58af26677fd"}, + {file = "contourpy-1.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c75507d0a55378240f781599c30e7776674dbaf883a46d1c90f37e563453480"}, + {file = "contourpy-1.2.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:11959f0ce4a6f7b76ec578576a0b61a28bdc0696194b6347ba3f1c53827178b9"}, + {file = "contourpy-1.2.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eb3315a8a236ee19b6df481fc5f997436e8ade24a9f03dfdc6bd490fea20c6da"}, + {file = "contourpy-1.2.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:39f3ecaf76cd98e802f094e0d4fbc6dc9c45a8d0c4d185f0f6c2234e14e5f75b"}, + {file = "contourpy-1.2.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:94b34f32646ca0414237168d68a9157cb3889f06b096612afdd296003fdd32fd"}, + {file = "contourpy-1.2.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:457499c79fa84593f22454bbd27670227874cd2ff5d6c84e60575c8b50a69619"}, + {file = "contourpy-1.2.1-cp310-cp310-win32.whl", hash = "sha256:ac58bdee53cbeba2ecad824fa8159493f0bf3b8ea4e93feb06c9a465d6c87da8"}, + {file = "contourpy-1.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:9cffe0f850e89d7c0012a1fb8730f75edd4320a0a731ed0c183904fe6ecfc3a9"}, + {file = "contourpy-1.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6022cecf8f44e36af10bd9118ca71f371078b4c168b6e0fab43d4a889985dbb5"}, + {file = "contourpy-1.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef5adb9a3b1d0c645ff694f9bca7702ec2c70f4d734f9922ea34de02294fdf72"}, + {file = "contourpy-1.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6150ffa5c767bc6332df27157d95442c379b7dce3a38dff89c0f39b63275696f"}, + {file = "contourpy-1.2.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c863140fafc615c14a4bf4efd0f4425c02230eb8ef02784c9a156461e62c965"}, + {file = "contourpy-1.2.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:00e5388f71c1a0610e6fe56b5c44ab7ba14165cdd6d695429c5cd94021e390b2"}, + {file = "contourpy-1.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d4492d82b3bc7fbb7e3610747b159869468079fe149ec5c4d771fa1f614a14df"}, + {file = "contourpy-1.2.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:49e70d111fee47284d9dd867c9bb9a7058a3c617274900780c43e38d90fe1205"}, + {file = "contourpy-1.2.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b59c0ffceff8d4d3996a45f2bb6f4c207f94684a96bf3d9728dbb77428dd8cb8"}, + {file = "contourpy-1.2.1-cp311-cp311-win32.whl", hash = "sha256:7b4182299f251060996af5249c286bae9361fa8c6a9cda5efc29fe8bfd6062ec"}, + {file = "contourpy-1.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2855c8b0b55958265e8b5888d6a615ba02883b225f2227461aa9127c578a4922"}, + {file = "contourpy-1.2.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:62828cada4a2b850dbef89c81f5a33741898b305db244904de418cc957ff05dc"}, + {file = "contourpy-1.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:309be79c0a354afff9ff7da4aaed7c3257e77edf6c1b448a779329431ee79d7e"}, + {file = "contourpy-1.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e785e0f2ef0d567099b9ff92cbfb958d71c2d5b9259981cd9bee81bd194c9a4"}, + {file = "contourpy-1.2.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1cac0a8f71a041aa587410424ad46dfa6a11f6149ceb219ce7dd48f6b02b87a7"}, + {file = "contourpy-1.2.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:af3f4485884750dddd9c25cb7e3915d83c2db92488b38ccb77dd594eac84c4a0"}, + {file = "contourpy-1.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ce6889abac9a42afd07a562c2d6d4b2b7134f83f18571d859b25624a331c90b"}, + {file = "contourpy-1.2.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:a1eea9aecf761c661d096d39ed9026574de8adb2ae1c5bd7b33558af884fb2ce"}, + {file = "contourpy-1.2.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:187fa1d4c6acc06adb0fae5544c59898ad781409e61a926ac7e84b8f276dcef4"}, + {file = "contourpy-1.2.1-cp312-cp312-win32.whl", hash = "sha256:c2528d60e398c7c4c799d56f907664673a807635b857df18f7ae64d3e6ce2d9f"}, + {file = "contourpy-1.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:1a07fc092a4088ee952ddae19a2b2a85757b923217b7eed584fdf25f53a6e7ce"}, + {file = "contourpy-1.2.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bb6834cbd983b19f06908b45bfc2dad6ac9479ae04abe923a275b5f48f1a186b"}, + {file = "contourpy-1.2.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1d59e739ab0e3520e62a26c60707cc3ab0365d2f8fecea74bfe4de72dc56388f"}, + {file = "contourpy-1.2.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd3db01f59fdcbce5b22afad19e390260d6d0222f35a1023d9adc5690a889364"}, + {file = "contourpy-1.2.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a12a813949e5066148712a0626895c26b2578874e4cc63160bb007e6df3436fe"}, + {file = "contourpy-1.2.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe0ccca550bb8e5abc22f530ec0466136379c01321fd94f30a22231e8a48d985"}, + {file = "contourpy-1.2.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1d59258c3c67c865435d8fbeb35f8c59b8bef3d6f46c1f29f6123556af28445"}, + {file = "contourpy-1.2.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f32c38afb74bd98ce26de7cc74a67b40afb7b05aae7b42924ea990d51e4dac02"}, + {file = "contourpy-1.2.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d31a63bc6e6d87f77d71e1abbd7387ab817a66733734883d1fc0021ed9bfa083"}, + {file = "contourpy-1.2.1-cp39-cp39-win32.whl", hash = "sha256:ddcb8581510311e13421b1f544403c16e901c4e8f09083c881fab2be80ee31ba"}, + {file = "contourpy-1.2.1-cp39-cp39-win_amd64.whl", hash = "sha256:10a37ae557aabf2509c79715cd20b62e4c7c28b8cd62dd7d99e5ed3ce28c3fd9"}, + {file = "contourpy-1.2.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a31f94983fecbac95e58388210427d68cd30fe8a36927980fab9c20062645609"}, + {file = "contourpy-1.2.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef2b055471c0eb466033760a521efb9d8a32b99ab907fc8358481a1dd29e3bd3"}, + {file = "contourpy-1.2.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:b33d2bc4f69caedcd0a275329eb2198f560b325605810895627be5d4b876bf7f"}, + {file = "contourpy-1.2.1.tar.gz", hash = "sha256:4d8908b3bee1c889e547867ca4cdc54e5ab6be6d3e078556814a22457f49423c"}, +] + +[package.dependencies] +numpy = ">=1.20" + +[package.extras] +bokeh = ["bokeh", "selenium"] +docs = ["furo", "sphinx (>=7.2)", "sphinx-copybutton"] +mypy = ["contourpy[bokeh,docs]", "docutils-stubs", "mypy (==1.8.0)", "types-Pillow"] +test = ["Pillow", "contourpy[test-no-images]", "matplotlib"] +test-no-images = ["pytest", "pytest-cov", "pytest-xdist", "wurlitzer"] + [[package]] name = "coverage" version = "7.6.1" @@ -645,6 +755,21 @@ tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.1 [package.extras] toml = ["tomli"] +[[package]] +name = "cycler" +version = "0.12.1" +description = "Composable style cycles" +optional = false +python-versions = ">=3.8" +files = [ + {file = "cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30"}, + {file = "cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c"}, +] + +[package.extras] +docs = ["ipython", "matplotlib", "numpydoc", "sphinx"] +tests = ["pytest", "pytest-cov", "pytest-xdist"] + [[package]] name = "decorator" version = "4.4.2" @@ -656,6 +781,24 @@ files = [ {file = "decorator-4.4.2.tar.gz", hash = "sha256:e3a62f0520172440ca0dcc823749319382e377f37f140a0b99ef45fecb84bfe7"}, ] +[[package]] +name = "deepdiff" +version = "7.0.1" +description = "Deep Difference and Search of any Python object/data. Recreate objects by adding adding deltas to each other." +optional = false +python-versions = ">=3.8" +files = [ + {file = "deepdiff-7.0.1-py3-none-any.whl", hash = "sha256:447760081918216aa4fd4ca78a4b6a848b81307b2ea94c810255334b759e1dc3"}, + {file = "deepdiff-7.0.1.tar.gz", hash = "sha256:260c16f052d4badbf60351b4f77e8390bee03a0b516246f6839bc813fb429ddf"}, +] + +[package.dependencies] +ordered-set = ">=4.1.0,<4.2.0" + +[package.extras] +cli = ["click (==8.1.7)", "pyyaml (==6.0.1)"] +optimize = ["orjson"] + [[package]] name = "deprecated" version = "1.2.14" @@ -836,6 +979,71 @@ typing_extensions = "*" [package.extras] dev = ["black", "mypy", "pre-commit", "pylint", "pytest", "pytest-benchmark", "pytest-cov"] +[[package]] +name = "fonttools" +version = "4.53.1" +description = "Tools to manipulate font files" +optional = false +python-versions = ">=3.8" +files = [ + {file = "fonttools-4.53.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0679a30b59d74b6242909945429dbddb08496935b82f91ea9bf6ad240ec23397"}, + {file = "fonttools-4.53.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e8bf06b94694251861ba7fdeea15c8ec0967f84c3d4143ae9daf42bbc7717fe3"}, + {file = "fonttools-4.53.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b96cd370a61f4d083c9c0053bf634279b094308d52fdc2dd9a22d8372fdd590d"}, + {file = "fonttools-4.53.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1c7c5aa18dd3b17995898b4a9b5929d69ef6ae2af5b96d585ff4005033d82f0"}, + {file = "fonttools-4.53.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e013aae589c1c12505da64a7d8d023e584987e51e62006e1bb30d72f26522c41"}, + {file = "fonttools-4.53.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9efd176f874cb6402e607e4cc9b4a9cd584d82fc34a4b0c811970b32ba62501f"}, + {file = "fonttools-4.53.1-cp310-cp310-win32.whl", hash = "sha256:c8696544c964500aa9439efb6761947393b70b17ef4e82d73277413f291260a4"}, + {file = "fonttools-4.53.1-cp310-cp310-win_amd64.whl", hash = "sha256:8959a59de5af6d2bec27489e98ef25a397cfa1774b375d5787509c06659b3671"}, + {file = "fonttools-4.53.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:da33440b1413bad53a8674393c5d29ce64d8c1a15ef8a77c642ffd900d07bfe1"}, + {file = "fonttools-4.53.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5ff7e5e9bad94e3a70c5cd2fa27f20b9bb9385e10cddab567b85ce5d306ea923"}, + {file = "fonttools-4.53.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c6e7170d675d12eac12ad1a981d90f118c06cf680b42a2d74c6c931e54b50719"}, + {file = "fonttools-4.53.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bee32ea8765e859670c4447b0817514ca79054463b6b79784b08a8df3a4d78e3"}, + {file = "fonttools-4.53.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6e08f572625a1ee682115223eabebc4c6a2035a6917eac6f60350aba297ccadb"}, + {file = "fonttools-4.53.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b21952c092ffd827504de7e66b62aba26fdb5f9d1e435c52477e6486e9d128b2"}, + {file = "fonttools-4.53.1-cp311-cp311-win32.whl", hash = "sha256:9dfdae43b7996af46ff9da520998a32b105c7f098aeea06b2226b30e74fbba88"}, + {file = "fonttools-4.53.1-cp311-cp311-win_amd64.whl", hash = "sha256:d4d0096cb1ac7a77b3b41cd78c9b6bc4a400550e21dc7a92f2b5ab53ed74eb02"}, + {file = "fonttools-4.53.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:d92d3c2a1b39631a6131c2fa25b5406855f97969b068e7e08413325bc0afba58"}, + {file = "fonttools-4.53.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3b3c8ebafbee8d9002bd8f1195d09ed2bd9ff134ddec37ee8f6a6375e6a4f0e8"}, + {file = "fonttools-4.53.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32f029c095ad66c425b0ee85553d0dc326d45d7059dbc227330fc29b43e8ba60"}, + {file = "fonttools-4.53.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10f5e6c3510b79ea27bb1ebfcc67048cde9ec67afa87c7dd7efa5c700491ac7f"}, + {file = "fonttools-4.53.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f677ce218976496a587ab17140da141557beb91d2a5c1a14212c994093f2eae2"}, + {file = "fonttools-4.53.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9e6ceba2a01b448e36754983d376064730690401da1dd104ddb543519470a15f"}, + {file = "fonttools-4.53.1-cp312-cp312-win32.whl", hash = "sha256:791b31ebbc05197d7aa096bbc7bd76d591f05905d2fd908bf103af4488e60670"}, + {file = "fonttools-4.53.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ed170b5e17da0264b9f6fae86073be3db15fa1bd74061c8331022bca6d09bab"}, + {file = "fonttools-4.53.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:c818c058404eb2bba05e728d38049438afd649e3c409796723dfc17cd3f08749"}, + {file = "fonttools-4.53.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:651390c3b26b0c7d1f4407cad281ee7a5a85a31a110cbac5269de72a51551ba2"}, + {file = "fonttools-4.53.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e54f1bba2f655924c1138bbc7fa91abd61f45c68bd65ab5ed985942712864bbb"}, + {file = "fonttools-4.53.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9cd19cf4fe0595ebdd1d4915882b9440c3a6d30b008f3cc7587c1da7b95be5f"}, + {file = "fonttools-4.53.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:2af40ae9cdcb204fc1d8f26b190aa16534fcd4f0df756268df674a270eab575d"}, + {file = "fonttools-4.53.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:35250099b0cfb32d799fb5d6c651220a642fe2e3c7d2560490e6f1d3f9ae9169"}, + {file = "fonttools-4.53.1-cp38-cp38-win32.whl", hash = "sha256:f08df60fbd8d289152079a65da4e66a447efc1d5d5a4d3f299cdd39e3b2e4a7d"}, + {file = "fonttools-4.53.1-cp38-cp38-win_amd64.whl", hash = "sha256:7b6b35e52ddc8fb0db562133894e6ef5b4e54e1283dff606fda3eed938c36fc8"}, + {file = "fonttools-4.53.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:75a157d8d26c06e64ace9df037ee93a4938a4606a38cb7ffaf6635e60e253b7a"}, + {file = "fonttools-4.53.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4824c198f714ab5559c5be10fd1adf876712aa7989882a4ec887bf1ef3e00e31"}, + {file = "fonttools-4.53.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:becc5d7cb89c7b7afa8321b6bb3dbee0eec2b57855c90b3e9bf5fb816671fa7c"}, + {file = "fonttools-4.53.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84ec3fb43befb54be490147b4a922b5314e16372a643004f182babee9f9c3407"}, + {file = "fonttools-4.53.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:73379d3ffdeecb376640cd8ed03e9d2d0e568c9d1a4e9b16504a834ebadc2dfb"}, + {file = "fonttools-4.53.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:02569e9a810f9d11f4ae82c391ebc6fb5730d95a0657d24d754ed7763fb2d122"}, + {file = "fonttools-4.53.1-cp39-cp39-win32.whl", hash = "sha256:aae7bd54187e8bf7fd69f8ab87b2885253d3575163ad4d669a262fe97f0136cb"}, + {file = "fonttools-4.53.1-cp39-cp39-win_amd64.whl", hash = "sha256:e5b708073ea3d684235648786f5f6153a48dc8762cdfe5563c57e80787c29fbb"}, + {file = "fonttools-4.53.1-py3-none-any.whl", hash = "sha256:f1f8758a2ad110bd6432203a344269f445a2907dc24ef6bccfd0ac4e14e0d71d"}, + {file = "fonttools-4.53.1.tar.gz", hash = "sha256:e128778a8e9bc11159ce5447f76766cefbd876f44bd79aff030287254e4752c4"}, +] + +[package.extras] +all = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "fs (>=2.2.0,<3)", "lxml (>=4.0)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres", "pycairo", "scipy", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.23.0)", "unicodedata2 (>=15.1.0)", "xattr", "zopfli (>=0.1.4)"] +graphite = ["lz4 (>=1.7.4.2)"] +interpolatable = ["munkres", "pycairo", "scipy"] +lxml = ["lxml (>=4.0)"] +pathops = ["skia-pathops (>=0.5.0)"] +plot = ["matplotlib"] +repacker = ["uharfbuzz (>=0.23.0)"] +symfont = ["sympy"] +type1 = ["xattr"] +ufo = ["fs (>=2.2.0,<3)"] +unicode = ["unicodedata2 (>=15.1.0)"] +woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] + [[package]] name = "frozenlist" version = "1.4.1" @@ -961,6 +1169,105 @@ test-downstream = ["aiobotocore (>=2.5.4,<3.0.0)", "dask-expr", "dask[dataframe, test-full = ["adlfs", "aiohttp (!=4.0.0a0,!=4.0.0a1)", "cloudpickle", "dask", "distributed", "dropbox", "dropboxdrivefs", "fastparquet", "fusepy", "gcsfs", "jinja2", "kerchunk", "libarchive-c", "lz4", "notebook", "numpy", "ocifs", "pandas", "panel", "paramiko", "pyarrow", "pyarrow (>=1)", "pyftpdlib", "pygit2", "pytest", "pytest-asyncio (!=0.22.0)", "pytest-benchmark", "pytest-cov", "pytest-mock", "pytest-recording", "pytest-rerunfailures", "python-snappy", "requests", "smbprotocol", "tqdm", "urllib3", "zarr", "zstandard"] tqdm = ["tqdm"] +[[package]] +name = "future" +version = "1.0.0" +description = "Clean single-source support for Python 3 and 2" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "future-1.0.0-py3-none-any.whl", hash = "sha256:929292d34f5872e70396626ef385ec22355a1fae8ad29e1a734c3e43f9fbc216"}, + {file = "future-1.0.0.tar.gz", hash = "sha256:bd2968309307861edae1458a4f8a4f3598c03be43b97521076aebf5d94c07b05"}, +] + +[[package]] +name = "gensim" +version = "4.3.3" +description = "Python framework for fast Vector Space Modelling" +optional = false +python-versions = ">=3.8" +files = [ + {file = "gensim-4.3.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4e72840adfbea35c5804fd559bc0cb6bc9f439926220a37d852b7ce76eb325c1"}, + {file = "gensim-4.3.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4019263c9d9afae7c669f880c17e09461e77a71afce04ed4d79cf71a4cad2848"}, + {file = "gensim-4.3.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dea62d3e2ada547687bde6cbba37efa50b534db77e9d44fd5802676bb072c9d9"}, + {file = "gensim-4.3.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fac93ef5e44982defef9d3c1e4cd00245506b8a29cec19ec5e00f0221b8144c"}, + {file = "gensim-4.3.3-cp310-cp310-win_amd64.whl", hash = "sha256:7c3409f755fb8d62da99cea65e7a40a99d21f8fd86443a3aaf2d90eb68995021"}, + {file = "gensim-4.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:99e7b70352aecc6c1674dde82b75f453e7a5d1cc71ac1cfbc460bf1fe20501b7"}, + {file = "gensim-4.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:32a4cac3f3c38af2069eab9524609fc92ebaeb2692b7280cfda365a3517a280a"}, + {file = "gensim-4.3.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c071b4329ed1be02446eb7ef637b94c68cf0080c15c57fbcde667fce2e49c3fe"}, + {file = "gensim-4.3.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d662bf96e3d741b6ab61a54be842a7cbf5e45193008b2f4225c758cafd7f9cdc"}, + {file = "gensim-4.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:a54bd53a0e6f991abb837f126663353657270e75be53287e8a568ada0b35b1b0"}, + {file = "gensim-4.3.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9a65ed1a8c1fc83890b4eb2a45ae2b32e82a0209c970c8c74694d0374c2415cb"}, + {file = "gensim-4.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4db485e08a0287e0fd6a029d89b90913d1df38f1dcd34cd2ab758873ba9255f3"}, + {file = "gensim-4.3.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7198987116373ab99f034b292a04ac841531d12b56345851c98b40a3fcd93a85"}, + {file = "gensim-4.3.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6237a50de4da7a037b19b2b6c430b6537243dcdedebf94afeb089e951953e601"}, + {file = "gensim-4.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:c910c2d5a71f532273166a3a82762959973f0513b221a495fa5a2a07652ee66d"}, + {file = "gensim-4.3.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d7efa5e35d3f0ec02e6e8343b623c2c863be99e8c26866cf0bebd24fb10198c"}, + {file = "gensim-4.3.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2e8eaf5ef576f4d45e98cf87e7edda9afb469dff954a923402dc1ffc35195901"}, + {file = "gensim-4.3.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9161e52a6ec2a0580df66e9fac4ff7fc43efdc40674fbd4dd9e914796cc68bc3"}, + {file = "gensim-4.3.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a200d6ac522cdf91e6048e1a368318c6b1b6e0c79009dfd408345ea2b9d3c096"}, + {file = "gensim-4.3.3-cp38-cp38-win_amd64.whl", hash = "sha256:065547124a93948926b88cb854e1c09750e9a4c7be92f55858159aa8a23359c3"}, + {file = "gensim-4.3.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688a13b9bba839fedc7f3da6806d5701a756ed940839702ba6d7f494e917baef"}, + {file = "gensim-4.3.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c560d28133cca58078221d60fce346f98f2c5e93d2ad42942f32c0d60903f65b"}, + {file = "gensim-4.3.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:832311f0c420c0841c98b9e6cc4d83ea362add6db917bf2d646de4bed48a29f7"}, + {file = "gensim-4.3.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1049f5bc2a84b21a1cb9976741826c0ebf25cfdff4a888361db4b4a697d99f0d"}, + {file = "gensim-4.3.3-cp39-cp39-win_amd64.whl", hash = "sha256:e99b236b6638a30d7f878e2e21a94dab2f6d4b4fd3c242f44dca1341940cb0cb"}, + {file = "gensim-4.3.3.tar.gz", hash = "sha256:84852076a6a3d88d7dac5be245e24c21c3b819b565e14c1b61fa3e5ee76dcf57"}, +] + +[package.dependencies] +numpy = ">=1.18.5,<2.0" +scipy = ">=1.7.0,<1.14.0" +smart-open = ">=1.8.1" + +[package.extras] +distributed = ["Pyro4 (>=4.27)"] +docs = ["POT", "Pyro4", "Pyro4 (>=4.27)", "annoy", "matplotlib", "memory-profiler", "nltk", "pandas", "pytest", "pytest-cov", "scikit-learn", "sphinx (==5.1.1)", "sphinx-gallery (==0.11.1)", "sphinxcontrib-napoleon (==0.7)", "sphinxcontrib.programoutput (==0.17)", "statsmodels", "testfixtures", "visdom (>=0.1.8,!=0.1.8.7)"] +test = ["POT", "pytest", "pytest-cov", "testfixtures", "visdom (>=0.1.8,!=0.1.8.7)"] +test-win = ["POT", "pytest", "pytest-cov", "testfixtures"] + +[[package]] +name = "graspologic" +version = "3.4.1" +description = "A set of Python modules for graph statistics" +optional = false +python-versions = "<3.13,>=3.9" +files = [ + {file = "graspologic-3.4.1-py3-none-any.whl", hash = "sha256:c6563e087eda599bad1de831d4b7321c0daa7a82f4e85a7d7737ff67e07cdda2"}, + {file = "graspologic-3.4.1.tar.gz", hash = "sha256:7561f0b852a2bccd351bff77e8db07d9892f9dfa35a420fdec01690e4fdc8075"}, +] + +[package.dependencies] +anytree = ">=2.12.1,<3.0.0" +beartype = ">=0.18.5,<0.19.0" +gensim = ">=4.3.2,<5.0.0" +graspologic-native = ">=1.2.1,<2.0.0" +hyppo = ">=0.4.0,<0.5.0" +joblib = ">=1.4.2,<2.0.0" +matplotlib = ">=3.8.4,<4.0.0" +networkx = ">=3,<4" +numpy = ">=1.26.4,<2.0.0" +POT = ">=0.9,<0.10" +scikit-learn = ">=1.4.2,<2.0.0" +scipy = "1.12.0" +seaborn = ">=0.13.2,<0.14.0" +statsmodels = ">=0.14.2,<0.15.0" +typing-extensions = ">=4.4.0,<5.0.0" +umap-learn = ">=0.5.6,<0.6.0" + +[[package]] +name = "graspologic-native" +version = "1.2.1" +description = "Python native companion module to the graspologic library" +optional = false +python-versions = ">=3.6, <3.13" +files = [ + {file = "graspologic_native-1.2.1-cp36-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:eccb2fa475b604375e34b4ae1d5497a428c34ed65f27888495239f8e120acea1"}, + {file = "graspologic_native-1.2.1-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a44cfdee11718c01c0f6c544750b3ae64e28cc03432a620fe0295704bd0d618d"}, + {file = "graspologic_native-1.2.1-cp36-abi3-win_amd64.whl", hash = "sha256:56b5e66ba003fd38efc0919ce90fa22d379456e177dca65e26626498d2b9b96b"}, + {file = "graspologic_native-1.2.1.tar.gz", hash = "sha256:72b7586028a91e9fef9af0ef314d368f0240c18dca99e6e6c546334359a8610a"}, +] + [[package]] name = "greenlet" version = "3.0.3" @@ -1142,6 +1449,23 @@ testing = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "fastapi", "gr torch = ["safetensors[torch]", "torch"] typing = ["types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)"] +[[package]] +name = "hyppo" +version = "0.4.0" +description = "A comprehensive independence testing package" +optional = false +python-versions = "*" +files = [ + {file = "hyppo-0.4.0-py3-none-any.whl", hash = "sha256:4e75565b8deb601485cd7bc1b5c3f44e6ddf329136fc81e65d011f9b4e95132f"}, +] + +[package.dependencies] +autograd = ">=1.3" +numba = ">=0.46" +numpy = ">=1.17" +scikit-learn = ">=0.19.1" +scipy = ">=1.4.0" + [[package]] name = "identify" version = "2.6.0" @@ -1236,6 +1560,24 @@ doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linke perf = ["ipython"] test = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-perf (>=0.9.2)", "pytest-ruff (>=0.2.1)"] +[[package]] +name = "importlib-resources" +version = "6.4.2" +description = "Read resources from Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "importlib_resources-6.4.2-py3-none-any.whl", hash = "sha256:8bba8c54a8a3afaa1419910845fa26ebd706dc716dd208d9b158b4b6966f5c5c"}, + {file = "importlib_resources-6.4.2.tar.gz", hash = "sha256:6cbfbefc449cc6e2095dd184691b7a12a04f40bc75dd4c55d31c34f174cdf57a"}, +] + +[package.dependencies] +zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} + +[package.extras] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +test = ["jaraco.test (>=5.4)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-ruff (>=0.2.1)", "zipp (>=3.17)"] + [[package]] name = "iniconfig" version = "2.0.0" @@ -1281,6 +1623,87 @@ MarkupSafe = ">=2.0" [package.extras] i18n = ["Babel (>=2.7)"] +[[package]] +name = "jiter" +version = "0.5.0" +description = "Fast iterable JSON parser." +optional = false +python-versions = ">=3.8" +files = [ + {file = "jiter-0.5.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b599f4e89b3def9a94091e6ee52e1d7ad7bc33e238ebb9c4c63f211d74822c3f"}, + {file = "jiter-0.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a063f71c4b06225543dddadbe09d203dc0c95ba352d8b85f1221173480a71d5"}, + {file = "jiter-0.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:acc0d5b8b3dd12e91dd184b87273f864b363dfabc90ef29a1092d269f18c7e28"}, + {file = "jiter-0.5.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c22541f0b672f4d741382a97c65609332a783501551445ab2df137ada01e019e"}, + {file = "jiter-0.5.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:63314832e302cc10d8dfbda0333a384bf4bcfce80d65fe99b0f3c0da8945a91a"}, + {file = "jiter-0.5.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a25fbd8a5a58061e433d6fae6d5298777c0814a8bcefa1e5ecfff20c594bd749"}, + {file = "jiter-0.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:503b2c27d87dfff5ab717a8200fbbcf4714516c9d85558048b1fc14d2de7d8dc"}, + {file = "jiter-0.5.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6d1f3d27cce923713933a844872d213d244e09b53ec99b7a7fdf73d543529d6d"}, + {file = "jiter-0.5.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:c95980207b3998f2c3b3098f357994d3fd7661121f30669ca7cb945f09510a87"}, + {file = "jiter-0.5.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:afa66939d834b0ce063f57d9895e8036ffc41c4bd90e4a99631e5f261d9b518e"}, + {file = "jiter-0.5.0-cp310-none-win32.whl", hash = "sha256:f16ca8f10e62f25fd81d5310e852df6649af17824146ca74647a018424ddeccf"}, + {file = "jiter-0.5.0-cp310-none-win_amd64.whl", hash = "sha256:b2950e4798e82dd9176935ef6a55cf6a448b5c71515a556da3f6b811a7844f1e"}, + {file = "jiter-0.5.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d4c8e1ed0ef31ad29cae5ea16b9e41529eb50a7fba70600008e9f8de6376d553"}, + {file = "jiter-0.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c6f16e21276074a12d8421692515b3fd6d2ea9c94fd0734c39a12960a20e85f3"}, + {file = "jiter-0.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5280e68e7740c8c128d3ae5ab63335ce6d1fb6603d3b809637b11713487af9e6"}, + {file = "jiter-0.5.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:583c57fc30cc1fec360e66323aadd7fc3edeec01289bfafc35d3b9dcb29495e4"}, + {file = "jiter-0.5.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:26351cc14507bdf466b5f99aba3df3143a59da75799bf64a53a3ad3155ecded9"}, + {file = "jiter-0.5.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4829df14d656b3fb87e50ae8b48253a8851c707da9f30d45aacab2aa2ba2d614"}, + {file = "jiter-0.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a42a4bdcf7307b86cb863b2fb9bb55029b422d8f86276a50487982d99eed7c6e"}, + {file = "jiter-0.5.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:04d461ad0aebf696f8da13c99bc1b3e06f66ecf6cfd56254cc402f6385231c06"}, + {file = "jiter-0.5.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e6375923c5f19888c9226582a124b77b622f8fd0018b843c45eeb19d9701c403"}, + {file = "jiter-0.5.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:2cec323a853c24fd0472517113768c92ae0be8f8c384ef4441d3632da8baa646"}, + {file = "jiter-0.5.0-cp311-none-win32.whl", hash = "sha256:aa1db0967130b5cab63dfe4d6ff547c88b2a394c3410db64744d491df7f069bb"}, + {file = "jiter-0.5.0-cp311-none-win_amd64.whl", hash = "sha256:aa9d2b85b2ed7dc7697597dcfaac66e63c1b3028652f751c81c65a9f220899ae"}, + {file = "jiter-0.5.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9f664e7351604f91dcdd557603c57fc0d551bc65cc0a732fdacbf73ad335049a"}, + {file = "jiter-0.5.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:044f2f1148b5248ad2c8c3afb43430dccf676c5a5834d2f5089a4e6c5bbd64df"}, + {file = "jiter-0.5.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:702e3520384c88b6e270c55c772d4bd6d7b150608dcc94dea87ceba1b6391248"}, + {file = "jiter-0.5.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:528d742dcde73fad9d63e8242c036ab4a84389a56e04efd854062b660f559544"}, + {file = "jiter-0.5.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8cf80e5fe6ab582c82f0c3331df27a7e1565e2dcf06265afd5173d809cdbf9ba"}, + {file = "jiter-0.5.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:44dfc9ddfb9b51a5626568ef4e55ada462b7328996294fe4d36de02fce42721f"}, + {file = "jiter-0.5.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c451f7922992751a936b96c5f5b9bb9312243d9b754c34b33d0cb72c84669f4e"}, + {file = "jiter-0.5.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:308fce789a2f093dca1ff91ac391f11a9f99c35369117ad5a5c6c4903e1b3e3a"}, + {file = "jiter-0.5.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7f5ad4a7c6b0d90776fdefa294f662e8a86871e601309643de30bf94bb93a64e"}, + {file = "jiter-0.5.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ea189db75f8eca08807d02ae27929e890c7d47599ce3d0a6a5d41f2419ecf338"}, + {file = "jiter-0.5.0-cp312-none-win32.whl", hash = "sha256:e3bbe3910c724b877846186c25fe3c802e105a2c1fc2b57d6688b9f8772026e4"}, + {file = "jiter-0.5.0-cp312-none-win_amd64.whl", hash = "sha256:a586832f70c3f1481732919215f36d41c59ca080fa27a65cf23d9490e75b2ef5"}, + {file = "jiter-0.5.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:f04bc2fc50dc77be9d10f73fcc4e39346402ffe21726ff41028f36e179b587e6"}, + {file = "jiter-0.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6f433a4169ad22fcb550b11179bb2b4fd405de9b982601914ef448390b2954f3"}, + {file = "jiter-0.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad4a6398c85d3a20067e6c69890ca01f68659da94d74c800298581724e426c7e"}, + {file = "jiter-0.5.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6baa88334e7af3f4d7a5c66c3a63808e5efbc3698a1c57626541ddd22f8e4fbf"}, + {file = "jiter-0.5.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ece0a115c05efca597c6d938f88c9357c843f8c245dbbb53361a1c01afd7148"}, + {file = "jiter-0.5.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:335942557162ad372cc367ffaf93217117401bf930483b4b3ebdb1223dbddfa7"}, + {file = "jiter-0.5.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:649b0ee97a6e6da174bffcb3c8c051a5935d7d4f2f52ea1583b5b3e7822fbf14"}, + {file = "jiter-0.5.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f4be354c5de82157886ca7f5925dbda369b77344b4b4adf2723079715f823989"}, + {file = "jiter-0.5.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5206144578831a6de278a38896864ded4ed96af66e1e63ec5dd7f4a1fce38a3a"}, + {file = "jiter-0.5.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8120c60f8121ac3d6f072b97ef0e71770cc72b3c23084c72c4189428b1b1d3b6"}, + {file = "jiter-0.5.0-cp38-none-win32.whl", hash = "sha256:6f1223f88b6d76b519cb033a4d3687ca157c272ec5d6015c322fc5b3074d8a5e"}, + {file = "jiter-0.5.0-cp38-none-win_amd64.whl", hash = "sha256:c59614b225d9f434ea8fc0d0bec51ef5fa8c83679afedc0433905994fb36d631"}, + {file = "jiter-0.5.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:0af3838cfb7e6afee3f00dc66fa24695199e20ba87df26e942820345b0afc566"}, + {file = "jiter-0.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:550b11d669600dbc342364fd4adbe987f14d0bbedaf06feb1b983383dcc4b961"}, + {file = "jiter-0.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:489875bf1a0ffb3cb38a727b01e6673f0f2e395b2aad3c9387f94187cb214bbf"}, + {file = "jiter-0.5.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b250ca2594f5599ca82ba7e68785a669b352156260c5362ea1b4e04a0f3e2389"}, + {file = "jiter-0.5.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ea18e01f785c6667ca15407cd6dabbe029d77474d53595a189bdc813347218e"}, + {file = "jiter-0.5.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:462a52be85b53cd9bffd94e2d788a09984274fe6cebb893d6287e1c296d50653"}, + {file = "jiter-0.5.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:92cc68b48d50fa472c79c93965e19bd48f40f207cb557a8346daa020d6ba973b"}, + {file = "jiter-0.5.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1c834133e59a8521bc87ebcad773608c6fa6ab5c7a022df24a45030826cf10bc"}, + {file = "jiter-0.5.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab3a71ff31cf2d45cb216dc37af522d335211f3a972d2fe14ea99073de6cb104"}, + {file = "jiter-0.5.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:cccd3af9c48ac500c95e1bcbc498020c87e1781ff0345dd371462d67b76643eb"}, + {file = "jiter-0.5.0-cp39-none-win32.whl", hash = "sha256:368084d8d5c4fc40ff7c3cc513c4f73e02c85f6009217922d0823a48ee7adf61"}, + {file = "jiter-0.5.0-cp39-none-win_amd64.whl", hash = "sha256:ce03f7b4129eb72f1687fa11300fbf677b02990618428934662406d2a76742a1"}, + {file = "jiter-0.5.0.tar.gz", hash = "sha256:1d916ba875bcab5c5f7d927df998c4cb694d27dceddf3392e58beaf10563368a"}, +] + +[[package]] +name = "joblib" +version = "1.4.2" +description = "Lightweight pipelining with Python functions" +optional = false +python-versions = ">=3.8" +files = [ + {file = "joblib-1.4.2-py3-none-any.whl", hash = "sha256:06d478d5674cbc267e7496a410ee875abd68e4340feff4490bcb7afb88060ae6"}, + {file = "joblib-1.4.2.tar.gz", hash = "sha256:2382c5816b2636fbd20a09e0f4e9dad4736765fdfb7dca582943b9c1366b3f0e"}, +] + [[package]] name = "jsonschema" version = "4.23.0" @@ -1316,15 +1739,128 @@ files = [ [package.dependencies] referencing = ">=0.31.0" +[[package]] +name = "kiwisolver" +version = "1.4.5" +description = "A fast implementation of the Cassowary constraint solver" +optional = false +python-versions = ">=3.7" +files = [ + {file = "kiwisolver-1.4.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:05703cf211d585109fcd72207a31bb170a0f22144d68298dc5e61b3c946518af"}, + {file = "kiwisolver-1.4.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:146d14bebb7f1dc4d5fbf74f8a6cb15ac42baadee8912eb84ac0b3b2a3dc6ac3"}, + {file = "kiwisolver-1.4.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6ef7afcd2d281494c0a9101d5c571970708ad911d028137cd558f02b851c08b4"}, + {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9eaa8b117dc8337728e834b9c6e2611f10c79e38f65157c4c38e9400286f5cb1"}, + {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ec20916e7b4cbfb1f12380e46486ec4bcbaa91a9c448b97023fde0d5bbf9e4ff"}, + {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39b42c68602539407884cf70d6a480a469b93b81b7701378ba5e2328660c847a"}, + {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa12042de0171fad672b6c59df69106d20d5596e4f87b5e8f76df757a7c399aa"}, + {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2a40773c71d7ccdd3798f6489aaac9eee213d566850a9533f8d26332d626b82c"}, + {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:19df6e621f6d8b4b9c4d45f40a66839294ff2bb235e64d2178f7522d9170ac5b"}, + {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:83d78376d0d4fd884e2c114d0621624b73d2aba4e2788182d286309ebdeed770"}, + {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e391b1f0a8a5a10ab3b9bb6afcfd74f2175f24f8975fb87ecae700d1503cdee0"}, + {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:852542f9481f4a62dbb5dd99e8ab7aedfeb8fb6342349a181d4036877410f525"}, + {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59edc41b24031bc25108e210c0def6f6c2191210492a972d585a06ff246bb79b"}, + {file = "kiwisolver-1.4.5-cp310-cp310-win32.whl", hash = "sha256:a6aa6315319a052b4ee378aa171959c898a6183f15c1e541821c5c59beaa0238"}, + {file = "kiwisolver-1.4.5-cp310-cp310-win_amd64.whl", hash = "sha256:d0ef46024e6a3d79c01ff13801cb19d0cad7fd859b15037aec74315540acc276"}, + {file = "kiwisolver-1.4.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:11863aa14a51fd6ec28688d76f1735f8f69ab1fabf388851a595d0721af042f5"}, + {file = "kiwisolver-1.4.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8ab3919a9997ab7ef2fbbed0cc99bb28d3c13e6d4b1ad36e97e482558a91be90"}, + {file = "kiwisolver-1.4.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fcc700eadbbccbf6bc1bcb9dbe0786b4b1cb91ca0dcda336eef5c2beed37b797"}, + {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dfdd7c0b105af050eb3d64997809dc21da247cf44e63dc73ff0fd20b96be55a9"}, + {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76c6a5964640638cdeaa0c359382e5703e9293030fe730018ca06bc2010c4437"}, + {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bbea0db94288e29afcc4c28afbf3a7ccaf2d7e027489c449cf7e8f83c6346eb9"}, + {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ceec1a6bc6cab1d6ff5d06592a91a692f90ec7505d6463a88a52cc0eb58545da"}, + {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:040c1aebeda72197ef477a906782b5ab0d387642e93bda547336b8957c61022e"}, + {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f91de7223d4c7b793867797bacd1ee53bfe7359bd70d27b7b58a04efbb9436c8"}, + {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:faae4860798c31530dd184046a900e652c95513796ef51a12bc086710c2eec4d"}, + {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:b0157420efcb803e71d1b28e2c287518b8808b7cf1ab8af36718fd0a2c453eb0"}, + {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:06f54715b7737c2fecdbf140d1afb11a33d59508a47bf11bb38ecf21dc9ab79f"}, + {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fdb7adb641a0d13bdcd4ef48e062363d8a9ad4a182ac7647ec88f695e719ae9f"}, + {file = "kiwisolver-1.4.5-cp311-cp311-win32.whl", hash = "sha256:bb86433b1cfe686da83ce32a9d3a8dd308e85c76b60896d58f082136f10bffac"}, + {file = "kiwisolver-1.4.5-cp311-cp311-win_amd64.whl", hash = "sha256:6c08e1312a9cf1074d17b17728d3dfce2a5125b2d791527f33ffbe805200a355"}, + {file = "kiwisolver-1.4.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:32d5cf40c4f7c7b3ca500f8985eb3fb3a7dfc023215e876f207956b5ea26632a"}, + {file = "kiwisolver-1.4.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f846c260f483d1fd217fe5ed7c173fb109efa6b1fc8381c8b7552c5781756192"}, + {file = "kiwisolver-1.4.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5ff5cf3571589b6d13bfbfd6bcd7a3f659e42f96b5fd1c4830c4cf21d4f5ef45"}, + {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7269d9e5f1084a653d575c7ec012ff57f0c042258bf5db0954bf551c158466e7"}, + {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da802a19d6e15dffe4b0c24b38b3af68e6c1a68e6e1d8f30148c83864f3881db"}, + {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3aba7311af82e335dd1e36ffff68aaca609ca6290c2cb6d821a39aa075d8e3ff"}, + {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:763773d53f07244148ccac5b084da5adb90bfaee39c197554f01b286cf869228"}, + {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2270953c0d8cdab5d422bee7d2007f043473f9d2999631c86a223c9db56cbd16"}, + {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d099e745a512f7e3bbe7249ca835f4d357c586d78d79ae8f1dcd4d8adeb9bda9"}, + {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:74db36e14a7d1ce0986fa104f7d5637aea5c82ca6326ed0ec5694280942d1162"}, + {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:7e5bab140c309cb3a6ce373a9e71eb7e4873c70c2dda01df6820474f9889d6d4"}, + {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:0f114aa76dc1b8f636d077979c0ac22e7cd8f3493abbab152f20eb8d3cda71f3"}, + {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:88a2df29d4724b9237fc0c6eaf2a1adae0cdc0b3e9f4d8e7dc54b16812d2d81a"}, + {file = "kiwisolver-1.4.5-cp312-cp312-win32.whl", hash = "sha256:72d40b33e834371fd330fb1472ca19d9b8327acb79a5821d4008391db8e29f20"}, + {file = "kiwisolver-1.4.5-cp312-cp312-win_amd64.whl", hash = "sha256:2c5674c4e74d939b9d91dda0fae10597ac7521768fec9e399c70a1f27e2ea2d9"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3a2b053a0ab7a3960c98725cfb0bf5b48ba82f64ec95fe06f1d06c99b552e130"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cd32d6c13807e5c66a7cbb79f90b553642f296ae4518a60d8d76243b0ad2898"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59ec7b7c7e1a61061850d53aaf8e93db63dce0c936db1fda2658b70e4a1be709"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:da4cfb373035def307905d05041c1d06d8936452fe89d464743ae7fb8371078b"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2400873bccc260b6ae184b2b8a4fec0e4082d30648eadb7c3d9a13405d861e89"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1b04139c4236a0f3aff534479b58f6f849a8b351e1314826c2d230849ed48985"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:4e66e81a5779b65ac21764c295087de82235597a2293d18d943f8e9e32746265"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:7931d8f1f67c4be9ba1dd9c451fb0eeca1a25b89e4d3f89e828fe12a519b782a"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:b3f7e75f3015df442238cca659f8baa5f42ce2a8582727981cbfa15fee0ee205"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:bbf1d63eef84b2e8c89011b7f2235b1e0bf7dacc11cac9431fc6468e99ac77fb"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:4c380469bd3f970ef677bf2bcba2b6b0b4d5c75e7a020fb863ef75084efad66f"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-win32.whl", hash = "sha256:9408acf3270c4b6baad483865191e3e582b638b1654a007c62e3efe96f09a9a3"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-win_amd64.whl", hash = "sha256:5b94529f9b2591b7af5f3e0e730a4e0a41ea174af35a4fd067775f9bdfeee01a"}, + {file = "kiwisolver-1.4.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:11c7de8f692fc99816e8ac50d1d1aef4f75126eefc33ac79aac02c099fd3db71"}, + {file = "kiwisolver-1.4.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:53abb58632235cd154176ced1ae8f0d29a6657aa1aa9decf50b899b755bc2b93"}, + {file = "kiwisolver-1.4.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:88b9f257ca61b838b6f8094a62418421f87ac2a1069f7e896c36a7d86b5d4c29"}, + {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3195782b26fc03aa9c6913d5bad5aeb864bdc372924c093b0f1cebad603dd712"}, + {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fc579bf0f502e54926519451b920e875f433aceb4624a3646b3252b5caa9e0b6"}, + {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a580c91d686376f0f7c295357595c5a026e6cbc3d77b7c36e290201e7c11ecb"}, + {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cfe6ab8da05c01ba6fbea630377b5da2cd9bcbc6338510116b01c1bc939a2c18"}, + {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:d2e5a98f0ec99beb3c10e13b387f8db39106d53993f498b295f0c914328b1333"}, + {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a51a263952b1429e429ff236d2f5a21c5125437861baeed77f5e1cc2d2c7c6da"}, + {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:3edd2fa14e68c9be82c5b16689e8d63d89fe927e56debd6e1dbce7a26a17f81b"}, + {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:74d1b44c6cfc897df648cc9fdaa09bc3e7679926e6f96df05775d4fb3946571c"}, + {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:76d9289ed3f7501012e05abb8358bbb129149dbd173f1f57a1bf1c22d19ab7cc"}, + {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:92dea1ffe3714fa8eb6a314d2b3c773208d865a0e0d35e713ec54eea08a66250"}, + {file = "kiwisolver-1.4.5-cp38-cp38-win32.whl", hash = "sha256:5c90ae8c8d32e472be041e76f9d2f2dbff4d0b0be8bd4041770eddb18cf49a4e"}, + {file = "kiwisolver-1.4.5-cp38-cp38-win_amd64.whl", hash = "sha256:c7940c1dc63eb37a67721b10d703247552416f719c4188c54e04334321351ced"}, + {file = "kiwisolver-1.4.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:9407b6a5f0d675e8a827ad8742e1d6b49d9c1a1da5d952a67d50ef5f4170b18d"}, + {file = "kiwisolver-1.4.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:15568384086b6df3c65353820a4473575dbad192e35010f622c6ce3eebd57af9"}, + {file = "kiwisolver-1.4.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0dc9db8e79f0036e8173c466d21ef18e1befc02de8bf8aa8dc0813a6dc8a7046"}, + {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:cdc8a402aaee9a798b50d8b827d7ecf75edc5fb35ea0f91f213ff927c15f4ff0"}, + {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6c3bd3cde54cafb87d74d8db50b909705c62b17c2099b8f2e25b461882e544ff"}, + {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:955e8513d07a283056b1396e9a57ceddbd272d9252c14f154d450d227606eb54"}, + {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:346f5343b9e3f00b8db8ba359350eb124b98c99efd0b408728ac6ebf38173958"}, + {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b9098e0049e88c6a24ff64545cdfc50807818ba6c1b739cae221bbbcbc58aad3"}, + {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:00bd361b903dc4bbf4eb165f24d1acbee754fce22ded24c3d56eec268658a5cf"}, + {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7b8b454bac16428b22560d0a1cf0a09875339cab69df61d7805bf48919415901"}, + {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:f1d072c2eb0ad60d4c183f3fb44ac6f73fb7a8f16a2694a91f988275cbf352f9"}, + {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:31a82d498054cac9f6d0b53d02bb85811185bcb477d4b60144f915f3b3126342"}, + {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6512cb89e334e4700febbffaaa52761b65b4f5a3cf33f960213d5656cea36a77"}, + {file = "kiwisolver-1.4.5-cp39-cp39-win32.whl", hash = "sha256:9db8ea4c388fdb0f780fe91346fd438657ea602d58348753d9fb265ce1bca67f"}, + {file = "kiwisolver-1.4.5-cp39-cp39-win_amd64.whl", hash = "sha256:59415f46a37f7f2efeec758353dd2eae1b07640d8ca0f0c42548ec4125492635"}, + {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5c7b3b3a728dc6faf3fc372ef24f21d1e3cee2ac3e9596691d746e5a536de920"}, + {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:620ced262a86244e2be10a676b646f29c34537d0d9cc8eb26c08f53d98013390"}, + {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:378a214a1e3bbf5ac4a8708304318b4f890da88c9e6a07699c4ae7174c09a68d"}, + {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaf7be1207676ac608a50cd08f102f6742dbfc70e8d60c4db1c6897f62f71523"}, + {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:ba55dce0a9b8ff59495ddd050a0225d58bd0983d09f87cfe2b6aec4f2c1234e4"}, + {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:fd32ea360bcbb92d28933fc05ed09bffcb1704ba3fc7942e81db0fd4f81a7892"}, + {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5e7139af55d1688f8b960ee9ad5adafc4ac17c1c473fe07133ac092310d76544"}, + {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:dced8146011d2bc2e883f9bd68618b8247387f4bbec46d7392b3c3b032640126"}, + {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9bf3325c47b11b2e51bca0824ea217c7cd84491d8ac4eefd1e409705ef092bd"}, + {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:5794cf59533bc3f1b1c821f7206a3617999db9fbefc345360aafe2e067514929"}, + {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e368f200bbc2e4f905b8e71eb38b3c04333bddaa6a2464a6355487b02bb7fb09"}, + {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5d706eba36b4c4d5bc6c6377bb6568098765e990cfc21ee16d13963fab7b3e7"}, + {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85267bd1aa8880a9c88a8cb71e18d3d64d2751a790e6ca6c27b8ccc724bcd5ad"}, + {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:210ef2c3a1f03272649aff1ef992df2e724748918c4bc2d5a90352849eb40bea"}, + {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:11d011a7574eb3b82bcc9c1a1d35c1d7075677fdd15de527d91b46bd35e935ee"}, + {file = "kiwisolver-1.4.5.tar.gz", hash = "sha256:e57e563a57fb22a142da34f38acc2fc1a5c864bc29ca1517a88abc963e60d6ec"}, +] + [[package]] name = "litellm" -version = "1.42.12" +version = "1.43.1" description = "Library to easily interface with LLM API providers" optional = false python-versions = "!=2.7.*,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,!=3.7.*,>=3.8" files = [ - {file = "litellm-1.42.12-py3-none-any.whl", hash = "sha256:63fa89457f70f21b522fc1be41e668c0492d1bc0949a50ec18542b3884517d40"}, - {file = "litellm-1.42.12.tar.gz", hash = "sha256:63a1db91647ec5208a9e3282dd640c3a9e76cee788f6526105b52d312141d090"}, + {file = "litellm-1.43.1-py3-none-any.whl", hash = "sha256:57a3ce38889782f014f371cd794a1cad4e7d9b97412d75ff8b051bc8fc4f4e4d"}, + {file = "litellm-1.43.1.tar.gz", hash = "sha256:f7132938b6e2120e40b01b2210087ca05c51f2f90cebf33495adb53e7f9aaaab"}, ] [package.dependencies] @@ -1344,6 +1880,36 @@ tokenizers = "*" extra-proxy = ["azure-identity (>=1.15.0,<2.0.0)", "azure-keyvault-secrets (>=4.8.0,<5.0.0)", "google-cloud-kms (>=2.21.3,<3.0.0)", "prisma (==0.11.0)", "pynacl (>=1.5.0,<2.0.0)", "resend (>=0.8.0,<0.9.0)"] proxy = ["PyJWT (>=2.8.0,<3.0.0)", "apscheduler (>=3.10.4,<4.0.0)", "backoff", "cryptography (>=42.0.5,<43.0.0)", "fastapi (>=0.111.0,<0.112.0)", "fastapi-sso (>=0.10.0,<0.11.0)", "gunicorn (>=22.0.0,<23.0.0)", "orjson (>=3.9.7,<4.0.0)", "python-multipart (>=0.0.9,<0.0.10)", "pyyaml (>=6.0.1,<7.0.0)", "rq", "uvicorn (>=0.22.0,<0.23.0)"] +[[package]] +name = "llvmlite" +version = "0.43.0" +description = "lightweight wrapper around basic LLVM functionality" +optional = false +python-versions = ">=3.9" +files = [ + {file = "llvmlite-0.43.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a289af9a1687c6cf463478f0fa8e8aa3b6fb813317b0d70bf1ed0759eab6f761"}, + {file = "llvmlite-0.43.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6d4fd101f571a31acb1559ae1af30f30b1dc4b3186669f92ad780e17c81e91bc"}, + {file = "llvmlite-0.43.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7d434ec7e2ce3cc8f452d1cd9a28591745de022f931d67be688a737320dfcead"}, + {file = "llvmlite-0.43.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6912a87782acdff6eb8bf01675ed01d60ca1f2551f8176a300a886f09e836a6a"}, + {file = "llvmlite-0.43.0-cp310-cp310-win_amd64.whl", hash = "sha256:14f0e4bf2fd2d9a75a3534111e8ebeb08eda2f33e9bdd6dfa13282afacdde0ed"}, + {file = "llvmlite-0.43.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3e8d0618cb9bfe40ac38a9633f2493d4d4e9fcc2f438d39a4e854f39cc0f5f98"}, + {file = "llvmlite-0.43.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e0a9a1a39d4bf3517f2af9d23d479b4175ead205c592ceeb8b89af48a327ea57"}, + {file = "llvmlite-0.43.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1da416ab53e4f7f3bc8d4eeba36d801cc1894b9fbfbf2022b29b6bad34a7df2"}, + {file = "llvmlite-0.43.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:977525a1e5f4059316b183fb4fd34fa858c9eade31f165427a3977c95e3ee749"}, + {file = "llvmlite-0.43.0-cp311-cp311-win_amd64.whl", hash = "sha256:d5bd550001d26450bd90777736c69d68c487d17bf371438f975229b2b8241a91"}, + {file = "llvmlite-0.43.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f99b600aa7f65235a5a05d0b9a9f31150c390f31261f2a0ba678e26823ec38f7"}, + {file = "llvmlite-0.43.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:35d80d61d0cda2d767f72de99450766250560399edc309da16937b93d3b676e7"}, + {file = "llvmlite-0.43.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eccce86bba940bae0d8d48ed925f21dbb813519169246e2ab292b5092aba121f"}, + {file = "llvmlite-0.43.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:df6509e1507ca0760787a199d19439cc887bfd82226f5af746d6977bd9f66844"}, + {file = "llvmlite-0.43.0-cp312-cp312-win_amd64.whl", hash = "sha256:7a2872ee80dcf6b5dbdc838763d26554c2a18aa833d31a2635bff16aafefb9c9"}, + {file = "llvmlite-0.43.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9cd2a7376f7b3367019b664c21f0c61766219faa3b03731113ead75107f3b66c"}, + {file = "llvmlite-0.43.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:18e9953c748b105668487b7c81a3e97b046d8abf95c4ddc0cd3c94f4e4651ae8"}, + {file = "llvmlite-0.43.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74937acd22dc11b33946b67dca7680e6d103d6e90eeaaaf932603bec6fe7b03a"}, + {file = "llvmlite-0.43.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc9efc739cc6ed760f795806f67889923f7274276f0eb45092a1473e40d9b867"}, + {file = "llvmlite-0.43.0-cp39-cp39-win_amd64.whl", hash = "sha256:47e147cdda9037f94b399bf03bfd8a6b6b1f2f90be94a454e3386f006455a9b4"}, + {file = "llvmlite-0.43.0.tar.gz", hash = "sha256:ae2b5b5c3ef67354824fb75517c8db5fbe93bc02cd9671f3c62271626bc041d5"}, +] + [[package]] name = "lxml" version = "5.2.2" @@ -1608,6 +2174,70 @@ files = [ {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, ] +[[package]] +name = "matplotlib" +version = "3.9.2" +description = "Python plotting package" +optional = false +python-versions = ">=3.9" +files = [ + {file = "matplotlib-3.9.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:9d78bbc0cbc891ad55b4f39a48c22182e9bdaea7fc0e5dbd364f49f729ca1bbb"}, + {file = "matplotlib-3.9.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c375cc72229614632c87355366bdf2570c2dac01ac66b8ad048d2dabadf2d0d4"}, + {file = "matplotlib-3.9.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d94ff717eb2bd0b58fe66380bd8b14ac35f48a98e7c6765117fe67fb7684e64"}, + {file = "matplotlib-3.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ab68d50c06938ef28681073327795c5db99bb4666214d2d5f880ed11aeaded66"}, + {file = "matplotlib-3.9.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:65aacf95b62272d568044531e41de26285d54aec8cb859031f511f84bd8b495a"}, + {file = "matplotlib-3.9.2-cp310-cp310-win_amd64.whl", hash = "sha256:3fd595f34aa8a55b7fc8bf9ebea8aa665a84c82d275190a61118d33fbc82ccae"}, + {file = "matplotlib-3.9.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d8dd059447824eec055e829258ab092b56bb0579fc3164fa09c64f3acd478772"}, + {file = "matplotlib-3.9.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c797dac8bb9c7a3fd3382b16fe8f215b4cf0f22adccea36f1545a6d7be310b41"}, + {file = "matplotlib-3.9.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d719465db13267bcef19ea8954a971db03b9f48b4647e3860e4bc8e6ed86610f"}, + {file = "matplotlib-3.9.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8912ef7c2362f7193b5819d17dae8629b34a95c58603d781329712ada83f9447"}, + {file = "matplotlib-3.9.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7741f26a58a240f43bee74965c4882b6c93df3e7eb3de160126d8c8f53a6ae6e"}, + {file = "matplotlib-3.9.2-cp311-cp311-win_amd64.whl", hash = "sha256:ae82a14dab96fbfad7965403c643cafe6515e386de723e498cf3eeb1e0b70cc7"}, + {file = "matplotlib-3.9.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:ac43031375a65c3196bee99f6001e7fa5bdfb00ddf43379d3c0609bdca042df9"}, + {file = "matplotlib-3.9.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:be0fc24a5e4531ae4d8e858a1a548c1fe33b176bb13eff7f9d0d38ce5112a27d"}, + {file = "matplotlib-3.9.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf81de2926c2db243c9b2cbc3917619a0fc85796c6ba4e58f541df814bbf83c7"}, + {file = "matplotlib-3.9.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6ee45bc4245533111ced13f1f2cace1e7f89d1c793390392a80c139d6cf0e6c"}, + {file = "matplotlib-3.9.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:306c8dfc73239f0e72ac50e5a9cf19cc4e8e331dd0c54f5e69ca8758550f1e1e"}, + {file = "matplotlib-3.9.2-cp312-cp312-win_amd64.whl", hash = "sha256:5413401594cfaff0052f9d8b1aafc6d305b4bd7c4331dccd18f561ff7e1d3bd3"}, + {file = "matplotlib-3.9.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:18128cc08f0d3cfff10b76baa2f296fc28c4607368a8402de61bb3f2eb33c7d9"}, + {file = "matplotlib-3.9.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4876d7d40219e8ae8bb70f9263bcbe5714415acfdf781086601211335e24f8aa"}, + {file = "matplotlib-3.9.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6d9f07a80deab4bb0b82858a9e9ad53d1382fd122be8cde11080f4e7dfedb38b"}, + {file = "matplotlib-3.9.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f7c0410f181a531ec4e93bbc27692f2c71a15c2da16766f5ba9761e7ae518413"}, + {file = "matplotlib-3.9.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:909645cce2dc28b735674ce0931a4ac94e12f5b13f6bb0b5a5e65e7cea2c192b"}, + {file = "matplotlib-3.9.2-cp313-cp313-win_amd64.whl", hash = "sha256:f32c7410c7f246838a77d6d1eff0c0f87f3cb0e7c4247aebea71a6d5a68cab49"}, + {file = "matplotlib-3.9.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:37e51dd1c2db16ede9cfd7b5cabdfc818b2c6397c83f8b10e0e797501c963a03"}, + {file = "matplotlib-3.9.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:b82c5045cebcecd8496a4d694d43f9cc84aeeb49fe2133e036b207abe73f4d30"}, + {file = "matplotlib-3.9.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f053c40f94bc51bc03832a41b4f153d83f2062d88c72b5e79997072594e97e51"}, + {file = "matplotlib-3.9.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbe196377a8248972f5cede786d4c5508ed5f5ca4a1e09b44bda889958b33f8c"}, + {file = "matplotlib-3.9.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:5816b1e1fe8c192cbc013f8f3e3368ac56fbecf02fb41b8f8559303f24c5015e"}, + {file = "matplotlib-3.9.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:cef2a73d06601437be399908cf13aee74e86932a5ccc6ccdf173408ebc5f6bb2"}, + {file = "matplotlib-3.9.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e0830e188029c14e891fadd99702fd90d317df294c3298aad682739c5533721a"}, + {file = "matplotlib-3.9.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:03ba9c1299c920964e8d3857ba27173b4dbb51ca4bab47ffc2c2ba0eb5e2cbc5"}, + {file = "matplotlib-3.9.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1cd93b91ab47a3616b4d3c42b52f8363b88ca021e340804c6ab2536344fad9ca"}, + {file = "matplotlib-3.9.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:6d1ce5ed2aefcdce11904fc5bbea7d9c21fff3d5f543841edf3dea84451a09ea"}, + {file = "matplotlib-3.9.2-cp39-cp39-win_amd64.whl", hash = "sha256:b2696efdc08648536efd4e1601b5fd491fd47f4db97a5fbfd175549a7365c1b2"}, + {file = "matplotlib-3.9.2-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:d52a3b618cb1cbb769ce2ee1dcdb333c3ab6e823944e9a2d36e37253815f9556"}, + {file = "matplotlib-3.9.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:039082812cacd6c6bec8e17a9c1e6baca230d4116d522e81e1f63a74d01d2e21"}, + {file = "matplotlib-3.9.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6758baae2ed64f2331d4fd19be38b7b4eae3ecec210049a26b6a4f3ae1c85dcc"}, + {file = "matplotlib-3.9.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:050598c2b29e0b9832cde72bcf97627bf00262adbc4a54e2b856426bb2ef0697"}, + {file = "matplotlib-3.9.2.tar.gz", hash = "sha256:96ab43906269ca64a6366934106fa01534454a69e471b7bf3d79083981aaab92"}, +] + +[package.dependencies] +contourpy = ">=1.0.1" +cycler = ">=0.10" +fonttools = ">=4.22.0" +importlib-resources = {version = ">=3.2.0", markers = "python_version < \"3.10\""} +kiwisolver = ">=1.3.1" +numpy = ">=1.23" +packaging = ">=20.0" +pillow = ">=8" +pyparsing = ">=2.3.1" +python-dateutil = ">=2.7" + +[package.extras] +dev = ["meson-python (>=0.13.1)", "numpy (>=1.25)", "pybind11 (>=2.6)", "setuptools (>=64)", "setuptools_scm (>=7)"] + [[package]] name = "mccabe" version = "0.7.0" @@ -1841,6 +2471,24 @@ files = [ {file = "nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe"}, ] +[[package]] +name = "networkx" +version = "3.2.1" +description = "Python package for creating and manipulating graphs and networks" +optional = false +python-versions = ">=3.9" +files = [ + {file = "networkx-3.2.1-py3-none-any.whl", hash = "sha256:f18c69adc97877c42332c170849c96cefa91881c99a7cb3e95b7c659ebdc1ec2"}, + {file = "networkx-3.2.1.tar.gz", hash = "sha256:9f1bb5cf3409bf324e0a722c20bdb4c20ee39bf1c30ce8ae499c8502b0b5e0c6"}, +] + +[package.extras] +default = ["matplotlib (>=3.5)", "numpy (>=1.22)", "pandas (>=1.4)", "scipy (>=1.9,!=1.11.0,!=1.11.1)"] +developer = ["changelist (==0.4)", "mypy (>=1.1)", "pre-commit (>=3.2)", "rtoml"] +doc = ["nb2plots (>=0.7)", "nbconvert (<7.9)", "numpydoc (>=1.6)", "pillow (>=9.4)", "pydata-sphinx-theme (>=0.14)", "sphinx (>=7)", "sphinx-gallery (>=0.14)", "texext (>=0.6.7)"] +extra = ["lxml (>=4.6)", "pydot (>=1.4.2)", "pygraphviz (>=1.11)", "sympy (>=1.10)"] +test = ["pytest (>=7.2)", "pytest-cov (>=4.0)"] + [[package]] name = "nodeenv" version = "1.9.1" @@ -1852,58 +2500,83 @@ files = [ {file = "nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f"}, ] +[[package]] +name = "numba" +version = "0.60.0" +description = "compiling Python code using LLVM" +optional = false +python-versions = ">=3.9" +files = [ + {file = "numba-0.60.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5d761de835cd38fb400d2c26bb103a2726f548dc30368853121d66201672e651"}, + {file = "numba-0.60.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:159e618ef213fba758837f9837fb402bbe65326e60ba0633dbe6c7f274d42c1b"}, + {file = "numba-0.60.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1527dc578b95c7c4ff248792ec33d097ba6bef9eda466c948b68dfc995c25781"}, + {file = "numba-0.60.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fe0b28abb8d70f8160798f4de9d486143200f34458d34c4a214114e445d7124e"}, + {file = "numba-0.60.0-cp310-cp310-win_amd64.whl", hash = "sha256:19407ced081d7e2e4b8d8c36aa57b7452e0283871c296e12d798852bc7d7f198"}, + {file = "numba-0.60.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a17b70fc9e380ee29c42717e8cc0bfaa5556c416d94f9aa96ba13acb41bdece8"}, + {file = "numba-0.60.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3fb02b344a2a80efa6f677aa5c40cd5dd452e1b35f8d1c2af0dfd9ada9978e4b"}, + {file = "numba-0.60.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5f4fde652ea604ea3c86508a3fb31556a6157b2c76c8b51b1d45eb40c8598703"}, + {file = "numba-0.60.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4142d7ac0210cc86432b818338a2bc368dc773a2f5cf1e32ff7c5b378bd63ee8"}, + {file = "numba-0.60.0-cp311-cp311-win_amd64.whl", hash = "sha256:cac02c041e9b5bc8cf8f2034ff6f0dbafccd1ae9590dc146b3a02a45e53af4e2"}, + {file = "numba-0.60.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d7da4098db31182fc5ffe4bc42c6f24cd7d1cb8a14b59fd755bfee32e34b8404"}, + {file = "numba-0.60.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:38d6ea4c1f56417076ecf8fc327c831ae793282e0ff51080c5094cb726507b1c"}, + {file = "numba-0.60.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:62908d29fb6a3229c242e981ca27e32a6e606cc253fc9e8faeb0e48760de241e"}, + {file = "numba-0.60.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0ebaa91538e996f708f1ab30ef4d3ddc344b64b5227b67a57aa74f401bb68b9d"}, + {file = "numba-0.60.0-cp312-cp312-win_amd64.whl", hash = "sha256:f75262e8fe7fa96db1dca93d53a194a38c46da28b112b8a4aca168f0df860347"}, + {file = "numba-0.60.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:01ef4cd7d83abe087d644eaa3d95831b777aa21d441a23703d649e06b8e06b74"}, + {file = "numba-0.60.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:819a3dfd4630d95fd574036f99e47212a1af41cbcb019bf8afac63ff56834449"}, + {file = "numba-0.60.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0b983bd6ad82fe868493012487f34eae8bf7dd94654951404114f23c3466d34b"}, + {file = "numba-0.60.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c151748cd269ddeab66334bd754817ffc0cabd9433acb0f551697e5151917d25"}, + {file = "numba-0.60.0-cp39-cp39-win_amd64.whl", hash = "sha256:3031547a015710140e8c87226b4cfe927cac199835e5bf7d4fe5cb64e814e3ab"}, + {file = "numba-0.60.0.tar.gz", hash = "sha256:5df6158e5584eece5fc83294b949fd30b9f1125df7708862205217e068aabf16"}, +] + +[package.dependencies] +llvmlite = "==0.43.*" +numpy = ">=1.22,<2.1" + [[package]] name = "numpy" -version = "2.0.1" +version = "1.26.4" description = "Fundamental package for array computing in Python" optional = false python-versions = ">=3.9" files = [ - {file = "numpy-2.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0fbb536eac80e27a2793ffd787895242b7f18ef792563d742c2d673bfcb75134"}, - {file = "numpy-2.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:69ff563d43c69b1baba77af455dd0a839df8d25e8590e79c90fcbe1499ebde42"}, - {file = "numpy-2.0.1-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:1b902ce0e0a5bb7704556a217c4f63a7974f8f43e090aff03fcf262e0b135e02"}, - {file = "numpy-2.0.1-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:f1659887361a7151f89e79b276ed8dff3d75877df906328f14d8bb40bb4f5101"}, - {file = "numpy-2.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4658c398d65d1b25e1760de3157011a80375da861709abd7cef3bad65d6543f9"}, - {file = "numpy-2.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4127d4303b9ac9f94ca0441138acead39928938660ca58329fe156f84b9f3015"}, - {file = "numpy-2.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e5eeca8067ad04bc8a2a8731183d51d7cbaac66d86085d5f4766ee6bf19c7f87"}, - {file = "numpy-2.0.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9adbd9bb520c866e1bfd7e10e1880a1f7749f1f6e5017686a5fbb9b72cf69f82"}, - {file = "numpy-2.0.1-cp310-cp310-win32.whl", hash = "sha256:7b9853803278db3bdcc6cd5beca37815b133e9e77ff3d4733c247414e78eb8d1"}, - {file = "numpy-2.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:81b0893a39bc5b865b8bf89e9ad7807e16717f19868e9d234bdaf9b1f1393868"}, - {file = "numpy-2.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:75b4e316c5902d8163ef9d423b1c3f2f6252226d1aa5cd8a0a03a7d01ffc6268"}, - {file = "numpy-2.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6e4eeb6eb2fced786e32e6d8df9e755ce5be920d17f7ce00bc38fcde8ccdbf9e"}, - {file = "numpy-2.0.1-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:a1e01dcaab205fbece13c1410253a9eea1b1c9b61d237b6fa59bcc46e8e89343"}, - {file = "numpy-2.0.1-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:a8fc2de81ad835d999113ddf87d1ea2b0f4704cbd947c948d2f5513deafe5a7b"}, - {file = "numpy-2.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a3d94942c331dd4e0e1147f7a8699a4aa47dffc11bf8a1523c12af8b2e91bbe"}, - {file = "numpy-2.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15eb4eca47d36ec3f78cde0a3a2ee24cf05ca7396ef808dda2c0ddad7c2bde67"}, - {file = "numpy-2.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b83e16a5511d1b1f8a88cbabb1a6f6a499f82c062a4251892d9ad5d609863fb7"}, - {file = "numpy-2.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1f87fec1f9bc1efd23f4227becff04bd0e979e23ca50cc92ec88b38489db3b55"}, - {file = "numpy-2.0.1-cp311-cp311-win32.whl", hash = "sha256:36d3a9405fd7c511804dc56fc32974fa5533bdeb3cd1604d6b8ff1d292b819c4"}, - {file = "numpy-2.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:08458fbf403bff5e2b45f08eda195d4b0c9b35682311da5a5a0a0925b11b9bd8"}, - {file = "numpy-2.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:6bf4e6f4a2a2e26655717a1983ef6324f2664d7011f6ef7482e8c0b3d51e82ac"}, - {file = "numpy-2.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7d6fddc5fe258d3328cd8e3d7d3e02234c5d70e01ebe377a6ab92adb14039cb4"}, - {file = "numpy-2.0.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:5daab361be6ddeb299a918a7c0864fa8618af66019138263247af405018b04e1"}, - {file = "numpy-2.0.1-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:ea2326a4dca88e4a274ba3a4405eb6c6467d3ffbd8c7d38632502eaae3820587"}, - {file = "numpy-2.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:529af13c5f4b7a932fb0e1911d3a75da204eff023ee5e0e79c1751564221a5c8"}, - {file = "numpy-2.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6790654cb13eab303d8402354fabd47472b24635700f631f041bd0b65e37298a"}, - {file = "numpy-2.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbab9fc9c391700e3e1287666dfd82d8666d10e69a6c4a09ab97574c0b7ee0a7"}, - {file = "numpy-2.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:99d0d92a5e3613c33a5f01db206a33f8fdf3d71f2912b0de1739894668b7a93b"}, - {file = "numpy-2.0.1-cp312-cp312-win32.whl", hash = "sha256:173a00b9995f73b79eb0191129f2455f1e34c203f559dd118636858cc452a1bf"}, - {file = "numpy-2.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:bb2124fdc6e62baae159ebcfa368708867eb56806804d005860b6007388df171"}, - {file = "numpy-2.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bfc085b28d62ff4009364e7ca34b80a9a080cbd97c2c0630bb5f7f770dae9414"}, - {file = "numpy-2.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8fae4ebbf95a179c1156fab0b142b74e4ba4204c87bde8d3d8b6f9c34c5825ef"}, - {file = "numpy-2.0.1-cp39-cp39-macosx_14_0_arm64.whl", hash = "sha256:72dc22e9ec8f6eaa206deb1b1355eb2e253899d7347f5e2fae5f0af613741d06"}, - {file = "numpy-2.0.1-cp39-cp39-macosx_14_0_x86_64.whl", hash = "sha256:ec87f5f8aca726117a1c9b7083e7656a9d0d606eec7299cc067bb83d26f16e0c"}, - {file = "numpy-2.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f682ea61a88479d9498bf2091fdcd722b090724b08b31d63e022adc063bad59"}, - {file = "numpy-2.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8efc84f01c1cd7e34b3fb310183e72fcdf55293ee736d679b6d35b35d80bba26"}, - {file = "numpy-2.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3fdabe3e2a52bc4eff8dc7a5044342f8bd9f11ef0934fcd3289a788c0eb10018"}, - {file = "numpy-2.0.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:24a0e1befbfa14615b49ba9659d3d8818a0f4d8a1c5822af8696706fbda7310c"}, - {file = "numpy-2.0.1-cp39-cp39-win32.whl", hash = "sha256:f9cf5ea551aec449206954b075db819f52adc1638d46a6738253a712d553c7b4"}, - {file = "numpy-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:e9e81fa9017eaa416c056e5d9e71be93d05e2c3c2ab308d23307a8bc4443c368"}, - {file = "numpy-2.0.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:61728fba1e464f789b11deb78a57805c70b2ed02343560456190d0501ba37b0f"}, - {file = "numpy-2.0.1-pp39-pypy39_pp73-macosx_14_0_x86_64.whl", hash = "sha256:12f5d865d60fb9734e60a60f1d5afa6d962d8d4467c120a1c0cda6eb2964437d"}, - {file = "numpy-2.0.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eacf3291e263d5a67d8c1a581a8ebbcfd6447204ef58828caf69a5e3e8c75990"}, - {file = "numpy-2.0.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2c3a346ae20cfd80b6cfd3e60dc179963ef2ea58da5ec074fd3d9e7a1e7ba97f"}, - {file = "numpy-2.0.1.tar.gz", hash = "sha256:485b87235796410c3519a699cfe1faab097e509e90ebb05dcd098db2ae87e7b3"}, + {file = "numpy-1.26.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0"}, + {file = "numpy-1.26.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a"}, + {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4"}, + {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f"}, + {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:62b8e4b1e28009ef2846b4c7852046736bab361f7aeadeb6a5b89ebec3c7055a"}, + {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a4abb4f9001ad2858e7ac189089c42178fcce737e4169dc61321660f1a96c7d2"}, + {file = "numpy-1.26.4-cp310-cp310-win32.whl", hash = "sha256:bfe25acf8b437eb2a8b2d49d443800a5f18508cd811fea3181723922a8a82b07"}, + {file = "numpy-1.26.4-cp310-cp310-win_amd64.whl", hash = "sha256:b97fe8060236edf3662adfc2c633f56a08ae30560c56310562cb4f95500022d5"}, + {file = "numpy-1.26.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71"}, + {file = "numpy-1.26.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef"}, + {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e"}, + {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5"}, + {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a"}, + {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a"}, + {file = "numpy-1.26.4-cp311-cp311-win32.whl", hash = "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20"}, + {file = "numpy-1.26.4-cp311-cp311-win_amd64.whl", hash = "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2"}, + {file = "numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218"}, + {file = "numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b"}, + {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b"}, + {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed"}, + {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a"}, + {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0"}, + {file = "numpy-1.26.4-cp312-cp312-win32.whl", hash = "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110"}, + {file = "numpy-1.26.4-cp312-cp312-win_amd64.whl", hash = "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818"}, + {file = "numpy-1.26.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7349ab0fa0c429c82442a27a9673fc802ffdb7c7775fad780226cb234965e53c"}, + {file = "numpy-1.26.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:52b8b60467cd7dd1e9ed082188b4e6bb35aa5cdd01777621a1658910745b90be"}, + {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5241e0a80d808d70546c697135da2c613f30e28251ff8307eb72ba696945764"}, + {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f870204a840a60da0b12273ef34f7051e98c3b5961b61b0c2c1be6dfd64fbcd3"}, + {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:679b0076f67ecc0138fd2ede3a8fd196dddc2ad3254069bcb9faf9a79b1cebcd"}, + {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:47711010ad8555514b434df65f7d7b076bb8261df1ca9bb78f53d3b2db02e95c"}, + {file = "numpy-1.26.4-cp39-cp39-win32.whl", hash = "sha256:a354325ee03388678242a4d7ebcd08b5c727033fcff3b2f536aea978e15ee9e6"}, + {file = "numpy-1.26.4-cp39-cp39-win_amd64.whl", hash = "sha256:3373d5d70a5fe74a2c1bb6d2cfd9609ecf686d47a2d7b1d37a8f3b6bf6003aea"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:afedb719a9dcfc7eaf2287b839d8198e06dcd4cb5d276a3df279231138e83d30"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95a7476c59002f2f6c590b9b7b998306fba6a5aa646b1e22ddfeaf8f78c3a29c"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7e50d0a0cc3189f9cb0aeb3a6a6af18c16f59f004b866cd2be1c14b36134a4a0"}, + {file = "numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010"}, ] [[package]] @@ -1922,23 +2595,24 @@ httpx = ">=0.27.0,<0.28.0" [[package]] name = "openai" -version = "1.39.0" +version = "1.40.1" description = "The official Python library for the openai API" optional = false python-versions = ">=3.7.1" files = [ - {file = "openai-1.39.0-py3-none-any.whl", hash = "sha256:a712553a131c59a249c474d0bb6a0414f41df36dc186d3a018fa7e600e57fb7f"}, - {file = "openai-1.39.0.tar.gz", hash = "sha256:0cea446082f50985f26809d704a97749cb366a1ba230ef432c684a9745b3f2d9"}, + {file = "openai-1.40.1-py3-none-any.whl", hash = "sha256:cf5929076c6ca31c26f1ed207e9fd19eb05404cc9104f64c9d29bb0ac0c5bcd4"}, + {file = "openai-1.40.1.tar.gz", hash = "sha256:cb1294ac1f8c6a1acbb07e090698eb5ad74a7a88484e77126612a4f22579673d"}, ] [package.dependencies] anyio = ">=3.5.0,<5" distro = ">=1.7.0,<2" httpx = ">=0.23.0,<1" +jiter = ">=0.4.0,<1" pydantic = ">=1.9.0,<3" sniffio = "*" tqdm = ">4" -typing-extensions = ">=4.7,<5" +typing-extensions = ">=4.11,<5" [package.extras] datalib = ["numpy (>=1)", "pandas (>=1.2.3)", "pandas-stubs (>=1.1.0.11)"] @@ -1983,6 +2657,20 @@ files = [ [package.dependencies] et-xmlfile = "*" +[[package]] +name = "ordered-set" +version = "4.1.0" +description = "An OrderedSet is a custom MutableSet that remembers its order, so that every" +optional = false +python-versions = ">=3.7" +files = [ + {file = "ordered-set-4.1.0.tar.gz", hash = "sha256:694a8e44c87657c59292ede72891eb91d34131f6531463aab3009191c77364a8"}, + {file = "ordered_set-4.1.0-py3-none-any.whl", hash = "sha256:046e1132c71fcf3330438a539928932caf51ddbc582496833e23de611de14562"}, +] + +[package.extras] +dev = ["black", "mypy", "pytest"] + [[package]] name = "packaging" version = "24.1" @@ -1994,6 +2682,79 @@ files = [ {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, ] +[[package]] +name = "pandas" +version = "2.2.2" +description = "Powerful data structures for data analysis, time series, and statistics" +optional = false +python-versions = ">=3.9" +files = [ + {file = "pandas-2.2.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:90c6fca2acf139569e74e8781709dccb6fe25940488755716d1d354d6bc58bce"}, + {file = "pandas-2.2.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c7adfc142dac335d8c1e0dcbd37eb8617eac386596eb9e1a1b77791cf2498238"}, + {file = "pandas-2.2.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4abfe0be0d7221be4f12552995e58723c7422c80a659da13ca382697de830c08"}, + {file = "pandas-2.2.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8635c16bf3d99040fdf3ca3db669a7250ddf49c55dc4aa8fe0ae0fa8d6dcc1f0"}, + {file = "pandas-2.2.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:40ae1dffb3967a52203105a077415a86044a2bea011b5f321c6aa64b379a3f51"}, + {file = "pandas-2.2.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8e5a0b00e1e56a842f922e7fae8ae4077aee4af0acb5ae3622bd4b4c30aedf99"}, + {file = "pandas-2.2.2-cp310-cp310-win_amd64.whl", hash = "sha256:ddf818e4e6c7c6f4f7c8a12709696d193976b591cc7dc50588d3d1a6b5dc8772"}, + {file = "pandas-2.2.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:696039430f7a562b74fa45f540aca068ea85fa34c244d0deee539cb6d70aa288"}, + {file = "pandas-2.2.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8e90497254aacacbc4ea6ae5e7a8cd75629d6ad2b30025a4a8b09aa4faf55151"}, + {file = "pandas-2.2.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:58b84b91b0b9f4bafac2a0ac55002280c094dfc6402402332c0913a59654ab2b"}, + {file = "pandas-2.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d2123dc9ad6a814bcdea0f099885276b31b24f7edf40f6cdbc0912672e22eee"}, + {file = "pandas-2.2.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:2925720037f06e89af896c70bca73459d7e6a4be96f9de79e2d440bd499fe0db"}, + {file = "pandas-2.2.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0cace394b6ea70c01ca1595f839cf193df35d1575986e484ad35c4aeae7266c1"}, + {file = "pandas-2.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:873d13d177501a28b2756375d59816c365e42ed8417b41665f346289adc68d24"}, + {file = "pandas-2.2.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9dfde2a0ddef507a631dc9dc4af6a9489d5e2e740e226ad426a05cabfbd7c8ef"}, + {file = "pandas-2.2.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e9b79011ff7a0f4b1d6da6a61aa1aa604fb312d6647de5bad20013682d1429ce"}, + {file = "pandas-2.2.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1cb51fe389360f3b5a4d57dbd2848a5f033350336ca3b340d1c53a1fad33bcad"}, + {file = "pandas-2.2.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eee3a87076c0756de40b05c5e9a6069c035ba43e8dd71c379e68cab2c20f16ad"}, + {file = "pandas-2.2.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3e374f59e440d4ab45ca2fffde54b81ac3834cf5ae2cdfa69c90bc03bde04d76"}, + {file = "pandas-2.2.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:43498c0bdb43d55cb162cdc8c06fac328ccb5d2eabe3cadeb3529ae6f0517c32"}, + {file = "pandas-2.2.2-cp312-cp312-win_amd64.whl", hash = "sha256:d187d355ecec3629624fccb01d104da7d7f391db0311145817525281e2804d23"}, + {file = "pandas-2.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0ca6377b8fca51815f382bd0b697a0814c8bda55115678cbc94c30aacbb6eff2"}, + {file = "pandas-2.2.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9057e6aa78a584bc93a13f0a9bf7e753a5e9770a30b4d758b8d5f2a62a9433cd"}, + {file = "pandas-2.2.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:001910ad31abc7bf06f49dcc903755d2f7f3a9186c0c040b827e522e9cef0863"}, + {file = "pandas-2.2.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66b479b0bd07204e37583c191535505410daa8df638fd8e75ae1b383851fe921"}, + {file = "pandas-2.2.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a77e9d1c386196879aa5eb712e77461aaee433e54c68cf253053a73b7e49c33a"}, + {file = "pandas-2.2.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:92fd6b027924a7e178ac202cfbe25e53368db90d56872d20ffae94b96c7acc57"}, + {file = "pandas-2.2.2-cp39-cp39-win_amd64.whl", hash = "sha256:640cef9aa381b60e296db324337a554aeeb883ead99dc8f6c18e81a93942f5f4"}, + {file = "pandas-2.2.2.tar.gz", hash = "sha256:9e79019aba43cb4fda9e4d983f8e88ca0373adbb697ae9c6c43093218de28b54"}, +] + +[package.dependencies] +numpy = [ + {version = ">=1.22.4", markers = "python_version < \"3.11\""}, + {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, + {version = ">=1.23.2", markers = "python_version == \"3.11\""}, +] +python-dateutil = ">=2.8.2" +pytz = ">=2020.1" +tzdata = ">=2022.7" + +[package.extras] +all = ["PyQt5 (>=5.15.9)", "SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)", "beautifulsoup4 (>=4.11.2)", "bottleneck (>=1.3.6)", "dataframe-api-compat (>=0.1.7)", "fastparquet (>=2022.12.0)", "fsspec (>=2022.11.0)", "gcsfs (>=2022.11.0)", "html5lib (>=1.1)", "hypothesis (>=6.46.1)", "jinja2 (>=3.1.2)", "lxml (>=4.9.2)", "matplotlib (>=3.6.3)", "numba (>=0.56.4)", "numexpr (>=2.8.4)", "odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "pandas-gbq (>=0.19.0)", "psycopg2 (>=2.9.6)", "pyarrow (>=10.0.1)", "pymysql (>=1.0.2)", "pyreadstat (>=1.2.0)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "qtpy (>=2.3.0)", "s3fs (>=2022.11.0)", "scipy (>=1.10.0)", "tables (>=3.8.0)", "tabulate (>=0.9.0)", "xarray (>=2022.12.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)", "zstandard (>=0.19.0)"] +aws = ["s3fs (>=2022.11.0)"] +clipboard = ["PyQt5 (>=5.15.9)", "qtpy (>=2.3.0)"] +compression = ["zstandard (>=0.19.0)"] +computation = ["scipy (>=1.10.0)", "xarray (>=2022.12.0)"] +consortium-standard = ["dataframe-api-compat (>=0.1.7)"] +excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)"] +feather = ["pyarrow (>=10.0.1)"] +fss = ["fsspec (>=2022.11.0)"] +gcp = ["gcsfs (>=2022.11.0)", "pandas-gbq (>=0.19.0)"] +hdf5 = ["tables (>=3.8.0)"] +html = ["beautifulsoup4 (>=4.11.2)", "html5lib (>=1.1)", "lxml (>=4.9.2)"] +mysql = ["SQLAlchemy (>=2.0.0)", "pymysql (>=1.0.2)"] +output-formatting = ["jinja2 (>=3.1.2)", "tabulate (>=0.9.0)"] +parquet = ["pyarrow (>=10.0.1)"] +performance = ["bottleneck (>=1.3.6)", "numba (>=0.56.4)", "numexpr (>=2.8.4)"] +plot = ["matplotlib (>=3.6.3)"] +postgresql = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "psycopg2 (>=2.9.6)"] +pyarrow = ["pyarrow (>=10.0.1)"] +spss = ["pyreadstat (>=1.2.0)"] +sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)"] +test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"] +xml = ["lxml (>=4.9.2)"] + [[package]] name = "passlib" version = "1.7.4" @@ -2022,6 +2783,24 @@ files = [ {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, ] +[[package]] +name = "patsy" +version = "0.5.6" +description = "A Python package for describing statistical models and for building design matrices." +optional = false +python-versions = "*" +files = [ + {file = "patsy-0.5.6-py2.py3-none-any.whl", hash = "sha256:19056886fd8fa71863fa32f0eb090267f21fb74be00f19f5c70b2e9d76c883c6"}, + {file = "patsy-0.5.6.tar.gz", hash = "sha256:95c6d47a7222535f84bff7f63d7303f2e297747a598db89cf5c67f0c0c7d2cdb"}, +] + +[package.dependencies] +numpy = ">=1.4" +six = "*" + +[package.extras] +test = ["pytest", "pytest-cov", "scipy"] + [[package]] name = "pgvector" version = "0.1.8" @@ -2203,6 +2982,70 @@ dev = ["black", "flake8", "flake8-print", "isort", "pre-commit"] sentry = ["django", "sentry-sdk"] test = ["coverage", "flake8", "freezegun (==0.3.15)", "mock (>=2.0.0)", "pylint", "pytest", "pytest-timeout"] +[[package]] +name = "pot" +version = "0.9.4" +description = "Python Optimal Transport Library" +optional = false +python-versions = ">=3.7" +files = [ + {file = "POT-0.9.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8418ab9c24f549290fdc452caebb58ded05b986a024063fe3354cfd2e704b378"}, + {file = "POT-0.9.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:096cd3b454f87ff9c8f48d8e221bc26509d8f9355ce99d9fefe83560f82278b5"}, + {file = "POT-0.9.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6e67d420a479ed66f4549c785e157bb3dce2c5489bf81a44ac922a6e9471fe69"}, + {file = "POT-0.9.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:107bc7225906a3fa3aafdb441e1d24c55eaf1ee3badd1c93ab6199865f689221"}, + {file = "POT-0.9.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dfee044f744b1722912654c8b905bc289ce160524db5ca0e853f1aa442ffea55"}, + {file = "POT-0.9.4-cp310-cp310-win32.whl", hash = "sha256:421c3efb8da2f1ce9605f9f2068047ea629b95de87baa15b8786b3e664de9dbd"}, + {file = "POT-0.9.4-cp310-cp310-win_amd64.whl", hash = "sha256:6e76194a62f29ddadc975e18cf7f07d22060735bd3fb9a023781e0e126a05822"}, + {file = "POT-0.9.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:148040b89063790ab784458d5d200ba4a7f36c54fdb62ea0842f8d5d4c5c6ccb"}, + {file = "POT-0.9.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1109fc77989834a1467be731ff957d90c2b558e772cff6c06fb90f7cbe58b014"}, + {file = "POT-0.9.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9f8218cd419e8457b37fe2b8060b5bf9bd07d4671d5f5fa4d5ac98c58b5be8c0"}, + {file = "POT-0.9.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ea0055f18e26917ff326f39dd5e5fd43bcc9eccaab4b09a4f8d7785c8921250"}, + {file = "POT-0.9.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f03b4af3f56234787d2a34e0637dac9c1e1de4cb3f7386ca4f91331f0c4af187"}, + {file = "POT-0.9.4-cp311-cp311-win32.whl", hash = "sha256:a69f6d554df1de47dd312fc065d9171bdbedf48c90c8409889485945ffaaeacf"}, + {file = "POT-0.9.4-cp311-cp311-win_amd64.whl", hash = "sha256:8791c8f09a852901e03e2dc1c6aec4f374b58b3ee905a90349713587aa16e26a"}, + {file = "POT-0.9.4-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:1a7a55b3fd528e6808f99de0165dcacf185eb86ae3aff4d358b850479b76a8ba"}, + {file = "POT-0.9.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a9bbd2507605be6eae4f0f0d6f6f0ff91ce3eeb5b7c8eeb350e4eb76bcc6940a"}, + {file = "POT-0.9.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5594ab0e78329307ce4cd293f2de409513876695d60fb4c1013b5dd46069f256"}, + {file = "POT-0.9.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c0ca658105d129b752c8d20751ff2cb965d1bdcaecec319ae489b135c58d9da9"}, + {file = "POT-0.9.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6732f1acd94959b8fa13a4fa250ad49c1e6894ece488a81f4427dbf13df4776"}, + {file = "POT-0.9.4-cp312-cp312-win32.whl", hash = "sha256:bf7f5253fee6ba7df5dd854b739540f701153cabab80dd25332dfac93d84bec1"}, + {file = "POT-0.9.4-cp312-cp312-win_amd64.whl", hash = "sha256:597ff64b06a157871feb84e6e82b3f5dfbfff57161c14660ab2ddbcc93c940e6"}, + {file = "POT-0.9.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:385b41606943fbc73f1ab96fd994117d79c4ad782c91bbb7ba74c0359e9de887"}, + {file = "POT-0.9.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b3f697e084243b9fe0a975331e471fd09610343c6aa28172232958e39100ede6"}, + {file = "POT-0.9.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b967fb9cafc6ad30a6d51b21d6307b384491a106d6dc75f37bee52a3f63575c3"}, + {file = "POT-0.9.4-cp37-cp37m-win32.whl", hash = "sha256:35926c2f4d2ee49309dce340f7f6646fe451ca1e0d11b2d017a851d482bf4468"}, + {file = "POT-0.9.4-cp37-cp37m-win_amd64.whl", hash = "sha256:f29fa1fcd591d1940e2279dc1422ff46c0c273f6be4ecbcaa819d91dd196573e"}, + {file = "POT-0.9.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:63f8b50f448e32a4ae274dd1e68e22b1a2bc291c53c5c6ec5afadfb930b6a809"}, + {file = "POT-0.9.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cabd13a728d2db40b3989ad57810769dfba8972b686ae7f4881dbd315252e5d9"}, + {file = "POT-0.9.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5984157d5a819bd6c55db3b0d8fe631ff398c243e80a9e9e933cbd1ee7c7588c"}, + {file = "POT-0.9.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4b8da4e3268eeee40dff96364f0a9f0326979d565d970ec74a1688b8ad338022"}, + {file = "POT-0.9.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ede957083299e4904627621f4d2c8a6b56af108fef9b486330f65519a395f10a"}, + {file = "POT-0.9.4-cp38-cp38-win32.whl", hash = "sha256:79716079d7970c6c0bf909f986c65d7103135e36b364ba5fa5caed97d7aa6464"}, + {file = "POT-0.9.4-cp38-cp38-win_amd64.whl", hash = "sha256:3246493745bcf2b353312183b9ab547466cae711936f991a6754b62f55ff1dec"}, + {file = "POT-0.9.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:223c4ca199b679e4c2b8a79fb49d31f2c7fab2975c2c37d1e68a0a7fbe2bc55d"}, + {file = "POT-0.9.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c30d77994d02984ad32665f5975e272e8c02e8d5288c4edfbec08617c5c38f91"}, + {file = "POT-0.9.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5b0fe5be45112c12cc0f6ab61fb85ed9161ca540b24a4037e5d53ab86f390a49"}, + {file = "POT-0.9.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ab68bdfeae54719d202e923f18ec29869c09b105e42f94568221fc92996f0f4d"}, + {file = "POT-0.9.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2847015e3bb65171eb70eca786f8cebe806960af40625ebc17c858b6314a9e0b"}, + {file = "POT-0.9.4-cp39-cp39-win32.whl", hash = "sha256:2e35d68c6e676108d6eeb7e6b119c4c19dca364992bca57f3f513660bfb1810c"}, + {file = "POT-0.9.4-cp39-cp39-win_amd64.whl", hash = "sha256:e7d029f024ed58f8d10b3e4d517df551bb9758ac12d0503be793f44258f2dffc"}, + {file = "pot-0.9.4.tar.gz", hash = "sha256:4cf8b46bf4992c37529161c32dd5e3334e0c089399142f08ed6d455b57015edd"}, +] + +[package.dependencies] +numpy = ">=1.16" +scipy = ">=1.6" + +[package.extras] +all = ["autograd", "cvxopt", "jax", "jaxlib", "matplotlib", "pymanopt", "scikit-learn", "tensorflow", "torch", "torch-geometric"] +backend-jax = ["jax", "jaxlib"] +backend-tf = ["tensorflow"] +backend-torch = ["torch"] +cvxopt = ["cvxopt"] +dr = ["autograd", "pymanopt", "scikit-learn"] +gnn = ["torch", "torch-geometric"] +plot = ["matplotlib"] + [[package]] name = "pre-commit" version = "2.21.0" @@ -2505,6 +3348,38 @@ dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.4.0)", "pre-commit", "pyte docs = ["sphinx", "sphinx-rtd-theme", "zope.interface"] tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] +[[package]] +name = "pynndescent" +version = "0.5.13" +description = "Nearest Neighbor Descent" +optional = false +python-versions = "*" +files = [ + {file = "pynndescent-0.5.13-py3-none-any.whl", hash = "sha256:69aabb8f394bc631b6ac475a1c7f3994c54adf3f51cd63b2730fefba5771b949"}, + {file = "pynndescent-0.5.13.tar.gz", hash = "sha256:d74254c0ee0a1eeec84597d5fe89fedcf778593eeabe32c2f97412934a9800fb"}, +] + +[package.dependencies] +joblib = ">=0.11" +llvmlite = ">=0.30" +numba = ">=0.51.2" +scikit-learn = ">=0.18" +scipy = ">=1.0" + +[[package]] +name = "pyparsing" +version = "3.1.2" +description = "pyparsing module - Classes and methods to define and execute parsing grammars" +optional = false +python-versions = ">=3.6.8" +files = [ + {file = "pyparsing-3.1.2-py3-none-any.whl", hash = "sha256:f9db75911801ed778fe61bb643079ff86601aca99fcae6345aa67292038fb742"}, + {file = "pyparsing-3.1.2.tar.gz", hash = "sha256:a1bac0ce561155ecc3ed78ca94d3c9378656ad4c94c1270de543f621420f94ad"}, +] + +[package.extras] +diagrams = ["jinja2", "railroad-diagrams"] + [[package]] name = "pypdf" version = "4.3.1" @@ -2701,62 +3576,64 @@ files = [ [[package]] name = "pyyaml" -version = "6.0.1" +version = "6.0.2" description = "YAML parser and emitter for Python" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, - {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, - {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, - {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, - {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, - {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, - {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, - {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, - {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, - {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, - {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, - {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, - {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, - {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, - {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, - {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, - {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, - {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, - {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, - {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, - {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, - {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, - {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, - {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, - {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, - {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, - {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, - {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, - {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, + {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, + {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, + {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, + {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, + {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, + {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, + {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, + {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, + {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, + {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, + {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"}, + {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"}, + {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"}, + {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, + {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, + {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, + {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, ] [[package]] @@ -2903,116 +3780,224 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "rpds-py" -version = "0.19.1" +version = "0.20.0" description = "Python bindings to Rust's persistent data structures (rpds)" optional = false python-versions = ">=3.8" files = [ - {file = "rpds_py-0.19.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:aaf71f95b21f9dc708123335df22e5a2fef6307e3e6f9ed773b2e0938cc4d491"}, - {file = "rpds_py-0.19.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ca0dda0c5715efe2ab35bb83f813f681ebcd2840d8b1b92bfc6fe3ab382fae4a"}, - {file = "rpds_py-0.19.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81db2e7282cc0487f500d4db203edc57da81acde9e35f061d69ed983228ffe3b"}, - {file = "rpds_py-0.19.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1a8dfa125b60ec00c7c9baef945bb04abf8ac772d8ebefd79dae2a5f316d7850"}, - {file = "rpds_py-0.19.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:271accf41b02687cef26367c775ab220372ee0f4925591c6796e7c148c50cab5"}, - {file = "rpds_py-0.19.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f9bc4161bd3b970cd6a6fcda70583ad4afd10f2750609fb1f3ca9505050d4ef3"}, - {file = "rpds_py-0.19.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f0cf2a0dbb5987da4bd92a7ca727eadb225581dd9681365beba9accbe5308f7d"}, - {file = "rpds_py-0.19.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b5e28e56143750808c1c79c70a16519e9bc0a68b623197b96292b21b62d6055c"}, - {file = "rpds_py-0.19.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:c7af6f7b80f687b33a4cdb0a785a5d4de1fb027a44c9a049d8eb67d5bfe8a687"}, - {file = "rpds_py-0.19.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e429fc517a1c5e2a70d576077231538a98d59a45dfc552d1ac45a132844e6dfb"}, - {file = "rpds_py-0.19.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d2dbd8f4990d4788cb122f63bf000357533f34860d269c1a8e90ae362090ff3a"}, - {file = "rpds_py-0.19.1-cp310-none-win32.whl", hash = "sha256:e0f9d268b19e8f61bf42a1da48276bcd05f7ab5560311f541d22557f8227b866"}, - {file = "rpds_py-0.19.1-cp310-none-win_amd64.whl", hash = "sha256:df7c841813f6265e636fe548a49664c77af31ddfa0085515326342a751a6ba51"}, - {file = "rpds_py-0.19.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:902cf4739458852fe917104365ec0efbea7d29a15e4276c96a8d33e6ed8ec137"}, - {file = "rpds_py-0.19.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f3d73022990ab0c8b172cce57c69fd9a89c24fd473a5e79cbce92df87e3d9c48"}, - {file = "rpds_py-0.19.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3837c63dd6918a24de6c526277910e3766d8c2b1627c500b155f3eecad8fad65"}, - {file = "rpds_py-0.19.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cdb7eb3cf3deb3dd9e7b8749323b5d970052711f9e1e9f36364163627f96da58"}, - {file = "rpds_py-0.19.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:26ab43b6d65d25b1a333c8d1b1c2f8399385ff683a35ab5e274ba7b8bb7dc61c"}, - {file = "rpds_py-0.19.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75130df05aae7a7ac171b3b5b24714cffeabd054ad2ebc18870b3aa4526eba23"}, - {file = "rpds_py-0.19.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c34f751bf67cab69638564eee34023909380ba3e0d8ee7f6fe473079bf93f09b"}, - {file = "rpds_py-0.19.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f2671cb47e50a97f419a02cd1e0c339b31de017b033186358db92f4d8e2e17d8"}, - {file = "rpds_py-0.19.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:3c73254c256081704dba0a333457e2fb815364018788f9b501efe7c5e0ada401"}, - {file = "rpds_py-0.19.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4383beb4a29935b8fa28aca8fa84c956bf545cb0c46307b091b8d312a9150e6a"}, - {file = "rpds_py-0.19.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:dbceedcf4a9329cc665452db1aaf0845b85c666e4885b92ee0cddb1dbf7e052a"}, - {file = "rpds_py-0.19.1-cp311-none-win32.whl", hash = "sha256:f0a6d4a93d2a05daec7cb885157c97bbb0be4da739d6f9dfb02e101eb40921cd"}, - {file = "rpds_py-0.19.1-cp311-none-win_amd64.whl", hash = "sha256:c149a652aeac4902ecff2dd93c3b2681c608bd5208c793c4a99404b3e1afc87c"}, - {file = "rpds_py-0.19.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:56313be667a837ff1ea3508cebb1ef6681d418fa2913a0635386cf29cff35165"}, - {file = "rpds_py-0.19.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6d1d7539043b2b31307f2c6c72957a97c839a88b2629a348ebabe5aa8b626d6b"}, - {file = "rpds_py-0.19.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e1dc59a5e7bc7f44bd0c048681f5e05356e479c50be4f2c1a7089103f1621d5"}, - {file = "rpds_py-0.19.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b8f78398e67a7227aefa95f876481485403eb974b29e9dc38b307bb6eb2315ea"}, - {file = "rpds_py-0.19.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ef07a0a1d254eeb16455d839cef6e8c2ed127f47f014bbda64a58b5482b6c836"}, - {file = "rpds_py-0.19.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8124101e92c56827bebef084ff106e8ea11c743256149a95b9fd860d3a4f331f"}, - {file = "rpds_py-0.19.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08ce9c95a0b093b7aec75676b356a27879901488abc27e9d029273d280438505"}, - {file = "rpds_py-0.19.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0b02dd77a2de6e49078c8937aadabe933ceac04b41c5dde5eca13a69f3cf144e"}, - {file = "rpds_py-0.19.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4dd02e29c8cbed21a1875330b07246b71121a1c08e29f0ee3db5b4cfe16980c4"}, - {file = "rpds_py-0.19.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:9c7042488165f7251dc7894cd533a875d2875af6d3b0e09eda9c4b334627ad1c"}, - {file = "rpds_py-0.19.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f809a17cc78bd331e137caa25262b507225854073fd319e987bd216bed911b7c"}, - {file = "rpds_py-0.19.1-cp312-none-win32.whl", hash = "sha256:3ddab996807c6b4227967fe1587febade4e48ac47bb0e2d3e7858bc621b1cace"}, - {file = "rpds_py-0.19.1-cp312-none-win_amd64.whl", hash = "sha256:32e0db3d6e4f45601b58e4ac75c6f24afbf99818c647cc2066f3e4b192dabb1f"}, - {file = "rpds_py-0.19.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:747251e428406b05fc86fee3904ee19550c4d2d19258cef274e2151f31ae9d38"}, - {file = "rpds_py-0.19.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:dc733d35f861f8d78abfaf54035461e10423422999b360966bf1c443cbc42705"}, - {file = "rpds_py-0.19.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bbda75f245caecff8faa7e32ee94dfaa8312a3367397975527f29654cd17a6ed"}, - {file = "rpds_py-0.19.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bd04d8cab16cab5b0a9ffc7d10f0779cf1120ab16c3925404428f74a0a43205a"}, - {file = "rpds_py-0.19.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e2d66eb41ffca6cc3c91d8387509d27ba73ad28371ef90255c50cb51f8953301"}, - {file = "rpds_py-0.19.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fdf4890cda3b59170009d012fca3294c00140e7f2abe1910e6a730809d0f3f9b"}, - {file = "rpds_py-0.19.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1fa67ef839bad3815124f5f57e48cd50ff392f4911a9f3cf449d66fa3df62a5"}, - {file = "rpds_py-0.19.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b82c9514c6d74b89a370c4060bdb80d2299bc6857e462e4a215b4ef7aa7b090e"}, - {file = "rpds_py-0.19.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c7b07959866a6afb019abb9564d8a55046feb7a84506c74a6f197cbcdf8a208e"}, - {file = "rpds_py-0.19.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:4f580ae79d0b861dfd912494ab9d477bea535bfb4756a2269130b6607a21802e"}, - {file = "rpds_py-0.19.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c6d20c8896c00775e6f62d8373aba32956aa0b850d02b5ec493f486c88e12859"}, - {file = "rpds_py-0.19.1-cp313-none-win32.whl", hash = "sha256:afedc35fe4b9e30ab240b208bb9dc8938cb4afe9187589e8d8d085e1aacb8309"}, - {file = "rpds_py-0.19.1-cp313-none-win_amd64.whl", hash = "sha256:1d4af2eb520d759f48f1073ad3caef997d1bfd910dc34e41261a595d3f038a94"}, - {file = "rpds_py-0.19.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:34bca66e2e3eabc8a19e9afe0d3e77789733c702c7c43cd008e953d5d1463fde"}, - {file = "rpds_py-0.19.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:24f8ae92c7fae7c28d0fae9b52829235df83f34847aa8160a47eb229d9666c7b"}, - {file = "rpds_py-0.19.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71157f9db7f6bc6599a852852f3389343bea34315b4e6f109e5cbc97c1fb2963"}, - {file = "rpds_py-0.19.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1d494887d40dc4dd0d5a71e9d07324e5c09c4383d93942d391727e7a40ff810b"}, - {file = "rpds_py-0.19.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7b3661e6d4ba63a094138032c1356d557de5b3ea6fd3cca62a195f623e381c76"}, - {file = "rpds_py-0.19.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:97fbb77eaeb97591efdc654b8b5f3ccc066406ccfb3175b41382f221ecc216e8"}, - {file = "rpds_py-0.19.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4cc4bc73e53af8e7a42c8fd7923bbe35babacfa7394ae9240b3430b5dcf16b2a"}, - {file = "rpds_py-0.19.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:35af5e4d5448fa179fd7fff0bba0fba51f876cd55212f96c8bbcecc5c684ae5c"}, - {file = "rpds_py-0.19.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:3511f6baf8438326e351097cecd137eb45c5f019944fe0fd0ae2fea2fd26be39"}, - {file = "rpds_py-0.19.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:57863d16187995c10fe9cf911b897ed443ac68189179541734502353af33e693"}, - {file = "rpds_py-0.19.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:9e318e6786b1e750a62f90c6f7fa8b542102bdcf97c7c4de2a48b50b61bd36ec"}, - {file = "rpds_py-0.19.1-cp38-none-win32.whl", hash = "sha256:53dbc35808c6faa2ce3e48571f8f74ef70802218554884787b86a30947842a14"}, - {file = "rpds_py-0.19.1-cp38-none-win_amd64.whl", hash = "sha256:8df1c283e57c9cb4d271fdc1875f4a58a143a2d1698eb0d6b7c0d7d5f49c53a1"}, - {file = "rpds_py-0.19.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:e76c902d229a3aa9d5ceb813e1cbcc69bf5bda44c80d574ff1ac1fa3136dea71"}, - {file = "rpds_py-0.19.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:de1f7cd5b6b351e1afd7568bdab94934d656abe273d66cda0ceea43bbc02a0c2"}, - {file = "rpds_py-0.19.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:24fc5a84777cb61692d17988989690d6f34f7f95968ac81398d67c0d0994a897"}, - {file = "rpds_py-0.19.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:74129d5ffc4cde992d89d345f7f7d6758320e5d44a369d74d83493429dad2de5"}, - {file = "rpds_py-0.19.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5e360188b72f8080fefa3adfdcf3618604cc8173651c9754f189fece068d2a45"}, - {file = "rpds_py-0.19.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:13e6d4840897d4e4e6b2aa1443e3a8eca92b0402182aafc5f4ca1f5e24f9270a"}, - {file = "rpds_py-0.19.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f09529d2332264a902688031a83c19de8fda5eb5881e44233286b9c9ec91856d"}, - {file = "rpds_py-0.19.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0d4b52811dcbc1aba08fd88d475f75b4f6db0984ba12275d9bed1a04b2cae9b5"}, - {file = "rpds_py-0.19.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:dd635c2c4043222d80d80ca1ac4530a633102a9f2ad12252183bcf338c1b9474"}, - {file = "rpds_py-0.19.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:f35b34a5184d5e0cc360b61664c1c06e866aab077b5a7c538a3e20c8fcdbf90b"}, - {file = "rpds_py-0.19.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:d4ec0046facab83012d821b33cead742a35b54575c4edfb7ed7445f63441835f"}, - {file = "rpds_py-0.19.1-cp39-none-win32.whl", hash = "sha256:f5b8353ea1a4d7dfb59a7f45c04df66ecfd363bb5b35f33b11ea579111d4655f"}, - {file = "rpds_py-0.19.1-cp39-none-win_amd64.whl", hash = "sha256:1fb93d3486f793d54a094e2bfd9cd97031f63fcb5bc18faeb3dd4b49a1c06523"}, - {file = "rpds_py-0.19.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:7d5c7e32f3ee42f77d8ff1a10384b5cdcc2d37035e2e3320ded909aa192d32c3"}, - {file = "rpds_py-0.19.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:89cc8921a4a5028d6dd388c399fcd2eef232e7040345af3d5b16c04b91cf3c7e"}, - {file = "rpds_py-0.19.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bca34e913d27401bda2a6f390d0614049f5a95b3b11cd8eff80fe4ec340a1208"}, - {file = "rpds_py-0.19.1-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5953391af1405f968eb5701ebbb577ebc5ced8d0041406f9052638bafe52209d"}, - {file = "rpds_py-0.19.1-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:840e18c38098221ea6201f091fc5d4de6128961d2930fbbc96806fb43f69aec1"}, - {file = "rpds_py-0.19.1-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6d8b735c4d162dc7d86a9cf3d717f14b6c73637a1f9cd57fe7e61002d9cb1972"}, - {file = "rpds_py-0.19.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce757c7c90d35719b38fa3d4ca55654a76a40716ee299b0865f2de21c146801c"}, - {file = "rpds_py-0.19.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a9421b23c85f361a133aa7c5e8ec757668f70343f4ed8fdb5a4a14abd5437244"}, - {file = "rpds_py-0.19.1-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:3b823be829407393d84ee56dc849dbe3b31b6a326f388e171555b262e8456cc1"}, - {file = "rpds_py-0.19.1-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:5e58b61dcbb483a442c6239c3836696b79f2cd8e7eec11e12155d3f6f2d886d1"}, - {file = "rpds_py-0.19.1-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:39d67896f7235b2c886fb1ee77b1491b77049dcef6fbf0f401e7b4cbed86bbd4"}, - {file = "rpds_py-0.19.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:8b32cd4ab6db50c875001ba4f5a6b30c0f42151aa1fbf9c2e7e3674893fb1dc4"}, - {file = "rpds_py-0.19.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:1c32e41de995f39b6b315d66c27dea3ef7f7c937c06caab4c6a79a5e09e2c415"}, - {file = "rpds_py-0.19.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:1a129c02b42d46758c87faeea21a9f574e1c858b9f358b6dd0bbd71d17713175"}, - {file = "rpds_py-0.19.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:346557f5b1d8fd9966059b7a748fd79ac59f5752cd0e9498d6a40e3ac1c1875f"}, - {file = "rpds_py-0.19.1-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:31e450840f2f27699d014cfc8865cc747184286b26d945bcea6042bb6aa4d26e"}, - {file = "rpds_py-0.19.1-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:01227f8b3e6c8961490d869aa65c99653df80d2f0a7fde8c64ebddab2b9b02fd"}, - {file = "rpds_py-0.19.1-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:69084fd29bfeff14816666c93a466e85414fe6b7d236cfc108a9c11afa6f7301"}, - {file = "rpds_py-0.19.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4d2b88efe65544a7d5121b0c3b003ebba92bfede2ea3577ce548b69c5235185"}, - {file = "rpds_py-0.19.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6ea961a674172ed2235d990d7edf85d15d8dfa23ab8575e48306371c070cda67"}, - {file = "rpds_py-0.19.1-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:5beffdbe766cfe4fb04f30644d822a1080b5359df7db3a63d30fa928375b2720"}, - {file = "rpds_py-0.19.1-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:720f3108fb1bfa32e51db58b832898372eb5891e8472a8093008010911e324c5"}, - {file = "rpds_py-0.19.1-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:c2087dbb76a87ec2c619253e021e4fb20d1a72580feeaa6892b0b3d955175a71"}, - {file = "rpds_py-0.19.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2ddd50f18ebc05ec29a0d9271e9dbe93997536da3546677f8ca00b76d477680c"}, - {file = "rpds_py-0.19.1.tar.gz", hash = "sha256:31dd5794837f00b46f4096aa8ccaa5972f73a938982e32ed817bb520c465e520"}, + {file = "rpds_py-0.20.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3ad0fda1635f8439cde85c700f964b23ed5fc2d28016b32b9ee5fe30da5c84e2"}, + {file = "rpds_py-0.20.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9bb4a0d90fdb03437c109a17eade42dfbf6190408f29b2744114d11586611d6f"}, + {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c6377e647bbfd0a0b159fe557f2c6c602c159fc752fa316572f012fc0bf67150"}, + {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eb851b7df9dda52dc1415ebee12362047ce771fc36914586b2e9fcbd7d293b3e"}, + {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e0f80b739e5a8f54837be5d5c924483996b603d5502bfff79bf33da06164ee2"}, + {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a8c94dad2e45324fc74dce25e1645d4d14df9a4e54a30fa0ae8bad9a63928e3"}, + {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8e604fe73ba048c06085beaf51147eaec7df856824bfe7b98657cf436623daf"}, + {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:df3de6b7726b52966edf29663e57306b23ef775faf0ac01a3e9f4012a24a4140"}, + {file = "rpds_py-0.20.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cf258ede5bc22a45c8e726b29835b9303c285ab46fc7c3a4cc770736b5304c9f"}, + {file = "rpds_py-0.20.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:55fea87029cded5df854ca7e192ec7bdb7ecd1d9a3f63d5c4eb09148acf4a7ce"}, + {file = "rpds_py-0.20.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ae94bd0b2f02c28e199e9bc51485d0c5601f58780636185660f86bf80c89af94"}, + {file = "rpds_py-0.20.0-cp310-none-win32.whl", hash = "sha256:28527c685f237c05445efec62426d285e47a58fb05ba0090a4340b73ecda6dee"}, + {file = "rpds_py-0.20.0-cp310-none-win_amd64.whl", hash = "sha256:238a2d5b1cad28cdc6ed15faf93a998336eb041c4e440dd7f902528b8891b399"}, + {file = "rpds_py-0.20.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:ac2f4f7a98934c2ed6505aead07b979e6f999389f16b714448fb39bbaa86a489"}, + {file = "rpds_py-0.20.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:220002c1b846db9afd83371d08d239fdc865e8f8c5795bbaec20916a76db3318"}, + {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d7919548df3f25374a1f5d01fbcd38dacab338ef5f33e044744b5c36729c8db"}, + {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:758406267907b3781beee0f0edfe4a179fbd97c0be2e9b1154d7f0a1279cf8e5"}, + {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3d61339e9f84a3f0767b1995adfb171a0d00a1185192718a17af6e124728e0f5"}, + {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1259c7b3705ac0a0bd38197565a5d603218591d3f6cee6e614e380b6ba61c6f6"}, + {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5c1dc0f53856b9cc9a0ccca0a7cc61d3d20a7088201c0937f3f4048c1718a209"}, + {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7e60cb630f674a31f0368ed32b2a6b4331b8350d67de53c0359992444b116dd3"}, + {file = "rpds_py-0.20.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:dbe982f38565bb50cb7fb061ebf762c2f254ca3d8c20d4006878766e84266272"}, + {file = "rpds_py-0.20.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:514b3293b64187172bc77c8fb0cdae26981618021053b30d8371c3a902d4d5ad"}, + {file = "rpds_py-0.20.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d0a26ffe9d4dd35e4dfdd1e71f46401cff0181c75ac174711ccff0459135fa58"}, + {file = "rpds_py-0.20.0-cp311-none-win32.whl", hash = "sha256:89c19a494bf3ad08c1da49445cc5d13d8fefc265f48ee7e7556839acdacf69d0"}, + {file = "rpds_py-0.20.0-cp311-none-win_amd64.whl", hash = "sha256:c638144ce971df84650d3ed0096e2ae7af8e62ecbbb7b201c8935c370df00a2c"}, + {file = "rpds_py-0.20.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a84ab91cbe7aab97f7446652d0ed37d35b68a465aeef8fc41932a9d7eee2c1a6"}, + {file = "rpds_py-0.20.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:56e27147a5a4c2c21633ff8475d185734c0e4befd1c989b5b95a5d0db699b21b"}, + {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2580b0c34583b85efec8c5c5ec9edf2dfe817330cc882ee972ae650e7b5ef739"}, + {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b80d4a7900cf6b66bb9cee5c352b2d708e29e5a37fe9bf784fa97fc11504bf6c"}, + {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:50eccbf054e62a7b2209b28dc7a22d6254860209d6753e6b78cfaeb0075d7bee"}, + {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:49a8063ea4296b3a7e81a5dfb8f7b2d73f0b1c20c2af401fb0cdf22e14711a96"}, + {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ea438162a9fcbee3ecf36c23e6c68237479f89f962f82dae83dc15feeceb37e4"}, + {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:18d7585c463087bddcfa74c2ba267339f14f2515158ac4db30b1f9cbdb62c8ef"}, + {file = "rpds_py-0.20.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d4c7d1a051eeb39f5c9547e82ea27cbcc28338482242e3e0b7768033cb083821"}, + {file = "rpds_py-0.20.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e4df1e3b3bec320790f699890d41c59d250f6beda159ea3c44c3f5bac1976940"}, + {file = "rpds_py-0.20.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2cf126d33a91ee6eedc7f3197b53e87a2acdac63602c0f03a02dd69e4b138174"}, + {file = "rpds_py-0.20.0-cp312-none-win32.whl", hash = "sha256:8bc7690f7caee50b04a79bf017a8d020c1f48c2a1077ffe172abec59870f1139"}, + {file = "rpds_py-0.20.0-cp312-none-win_amd64.whl", hash = "sha256:0e13e6952ef264c40587d510ad676a988df19adea20444c2b295e536457bc585"}, + {file = "rpds_py-0.20.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:aa9a0521aeca7d4941499a73ad7d4f8ffa3d1affc50b9ea11d992cd7eff18a29"}, + {file = "rpds_py-0.20.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4a1f1d51eccb7e6c32ae89243cb352389228ea62f89cd80823ea7dd1b98e0b91"}, + {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a86a9b96070674fc88b6f9f71a97d2c1d3e5165574615d1f9168ecba4cecb24"}, + {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6c8ef2ebf76df43f5750b46851ed1cdf8f109d7787ca40035fe19fbdc1acc5a7"}, + {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b74b25f024b421d5859d156750ea9a65651793d51b76a2e9238c05c9d5f203a9"}, + {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57eb94a8c16ab08fef6404301c38318e2c5a32216bf5de453e2714c964c125c8"}, + {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1940dae14e715e2e02dfd5b0f64a52e8374a517a1e531ad9412319dc3ac7879"}, + {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d20277fd62e1b992a50c43f13fbe13277a31f8c9f70d59759c88f644d66c619f"}, + {file = "rpds_py-0.20.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:06db23d43f26478303e954c34c75182356ca9aa7797d22c5345b16871ab9c45c"}, + {file = "rpds_py-0.20.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b2a5db5397d82fa847e4c624b0c98fe59d2d9b7cf0ce6de09e4d2e80f8f5b3f2"}, + {file = "rpds_py-0.20.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5a35df9f5548fd79cb2f52d27182108c3e6641a4feb0f39067911bf2adaa3e57"}, + {file = "rpds_py-0.20.0-cp313-none-win32.whl", hash = "sha256:fd2d84f40633bc475ef2d5490b9c19543fbf18596dcb1b291e3a12ea5d722f7a"}, + {file = "rpds_py-0.20.0-cp313-none-win_amd64.whl", hash = "sha256:9bc2d153989e3216b0559251b0c260cfd168ec78b1fac33dd485750a228db5a2"}, + {file = "rpds_py-0.20.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:f2fbf7db2012d4876fb0d66b5b9ba6591197b0f165db8d99371d976546472a24"}, + {file = "rpds_py-0.20.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:1e5f3cd7397c8f86c8cc72d5a791071431c108edd79872cdd96e00abd8497d29"}, + {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce9845054c13696f7af7f2b353e6b4f676dab1b4b215d7fe5e05c6f8bb06f965"}, + {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c3e130fd0ec56cb76eb49ef52faead8ff09d13f4527e9b0c400307ff72b408e1"}, + {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4b16aa0107ecb512b568244ef461f27697164d9a68d8b35090e9b0c1c8b27752"}, + {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aa7f429242aae2947246587d2964fad750b79e8c233a2367f71b554e9447949c"}, + {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af0fc424a5842a11e28956e69395fbbeab2c97c42253169d87e90aac2886d751"}, + {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b8c00a3b1e70c1d3891f0db1b05292747f0dbcfb49c43f9244d04c70fbc40eb8"}, + {file = "rpds_py-0.20.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:40ce74fc86ee4645d0a225498d091d8bc61f39b709ebef8204cb8b5a464d3c0e"}, + {file = "rpds_py-0.20.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:4fe84294c7019456e56d93e8ababdad5a329cd25975be749c3f5f558abb48253"}, + {file = "rpds_py-0.20.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:338ca4539aad4ce70a656e5187a3a31c5204f261aef9f6ab50e50bcdffaf050a"}, + {file = "rpds_py-0.20.0-cp38-none-win32.whl", hash = "sha256:54b43a2b07db18314669092bb2de584524d1ef414588780261e31e85846c26a5"}, + {file = "rpds_py-0.20.0-cp38-none-win_amd64.whl", hash = "sha256:a1862d2d7ce1674cffa6d186d53ca95c6e17ed2b06b3f4c476173565c862d232"}, + {file = "rpds_py-0.20.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:3fde368e9140312b6e8b6c09fb9f8c8c2f00999d1823403ae90cc00480221b22"}, + {file = "rpds_py-0.20.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9824fb430c9cf9af743cf7aaf6707bf14323fb51ee74425c380f4c846ea70789"}, + {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:11ef6ce74616342888b69878d45e9f779b95d4bd48b382a229fe624a409b72c5"}, + {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c52d3f2f82b763a24ef52f5d24358553e8403ce05f893b5347098014f2d9eff2"}, + {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9d35cef91e59ebbeaa45214861874bc6f19eb35de96db73e467a8358d701a96c"}, + {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d72278a30111e5b5525c1dd96120d9e958464316f55adb030433ea905866f4de"}, + {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4c29cbbba378759ac5786730d1c3cb4ec6f8ababf5c42a9ce303dc4b3d08cda"}, + {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6632f2d04f15d1bd6fe0eedd3b86d9061b836ddca4c03d5cf5c7e9e6b7c14580"}, + {file = "rpds_py-0.20.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:d0b67d87bb45ed1cd020e8fbf2307d449b68abc45402fe1a4ac9e46c3c8b192b"}, + {file = "rpds_py-0.20.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ec31a99ca63bf3cd7f1a5ac9fe95c5e2d060d3c768a09bc1d16e235840861420"}, + {file = "rpds_py-0.20.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:22e6c9976e38f4d8c4a63bd8a8edac5307dffd3ee7e6026d97f3cc3a2dc02a0b"}, + {file = "rpds_py-0.20.0-cp39-none-win32.whl", hash = "sha256:569b3ea770c2717b730b61998b6c54996adee3cef69fc28d444f3e7920313cf7"}, + {file = "rpds_py-0.20.0-cp39-none-win_amd64.whl", hash = "sha256:e6900ecdd50ce0facf703f7a00df12374b74bbc8ad9fe0f6559947fb20f82364"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:617c7357272c67696fd052811e352ac54ed1d9b49ab370261a80d3b6ce385045"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:9426133526f69fcaba6e42146b4e12d6bc6c839b8b555097020e2b78ce908dcc"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:deb62214c42a261cb3eb04d474f7155279c1a8a8c30ac89b7dcb1721d92c3c02"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fcaeb7b57f1a1e071ebd748984359fef83ecb026325b9d4ca847c95bc7311c92"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d454b8749b4bd70dd0a79f428731ee263fa6995f83ccb8bada706e8d1d3ff89d"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d807dc2051abe041b6649681dce568f8e10668e3c1c6543ebae58f2d7e617855"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3c20f0ddeb6e29126d45f89206b8291352b8c5b44384e78a6499d68b52ae511"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b7f19250ceef892adf27f0399b9e5afad019288e9be756d6919cb58892129f51"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:4f1ed4749a08379555cebf4650453f14452eaa9c43d0a95c49db50c18b7da075"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:dcedf0b42bcb4cfff4101d7771a10532415a6106062f005ab97d1d0ab5681c60"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:39ed0d010457a78f54090fafb5d108501b5aa5604cc22408fc1c0c77eac14344"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:bb273176be34a746bdac0b0d7e4e2c467323d13640b736c4c477881a3220a989"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f918a1a130a6dfe1d7fe0f105064141342e7dd1611f2e6a21cd2f5c8cb1cfb3e"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:f60012a73aa396be721558caa3a6fd49b3dd0033d1675c6d59c4502e870fcf0c"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3d2b1ad682a3dfda2a4e8ad8572f3100f95fad98cb99faf37ff0ddfe9cbf9d03"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:614fdafe9f5f19c63ea02817fa4861c606a59a604a77c8cdef5aa01d28b97921"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fa518bcd7600c584bf42e6617ee8132869e877db2f76bcdc281ec6a4113a53ab"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f0475242f447cc6cb8a9dd486d68b2ef7fbee84427124c232bff5f63b1fe11e5"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f90a4cd061914a60bd51c68bcb4357086991bd0bb93d8aa66a6da7701370708f"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:def7400461c3a3f26e49078302e1c1b38f6752342c77e3cf72ce91ca69fb1bc1"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:65794e4048ee837494aea3c21a28ad5fc080994dfba5b036cf84de37f7ad5074"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:faefcc78f53a88f3076b7f8be0a8f8d35133a3ecf7f3770895c25f8813460f08"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:5b4f105deeffa28bbcdff6c49b34e74903139afa690e35d2d9e3c2c2fba18cec"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:fdfc3a892927458d98f3d55428ae46b921d1f7543b89382fdb483f5640daaec8"}, + {file = "rpds_py-0.20.0.tar.gz", hash = "sha256:d72a210824facfdaf8768cf2d7ca25a042c30320b3020de2fa04640920d4e121"}, +] + +[[package]] +name = "scikit-learn" +version = "1.5.1" +description = "A set of python modules for machine learning and data mining" +optional = false +python-versions = ">=3.9" +files = [ + {file = "scikit_learn-1.5.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:781586c414f8cc58e71da4f3d7af311e0505a683e112f2f62919e3019abd3745"}, + {file = "scikit_learn-1.5.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:f5b213bc29cc30a89a3130393b0e39c847a15d769d6e59539cd86b75d276b1a7"}, + {file = "scikit_learn-1.5.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ff4ba34c2abff5ec59c803ed1d97d61b036f659a17f55be102679e88f926fac"}, + {file = "scikit_learn-1.5.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:161808750c267b77b4a9603cf9c93579c7a74ba8486b1336034c2f1579546d21"}, + {file = "scikit_learn-1.5.1-cp310-cp310-win_amd64.whl", hash = "sha256:10e49170691514a94bb2e03787aa921b82dbc507a4ea1f20fd95557862c98dc1"}, + {file = "scikit_learn-1.5.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:154297ee43c0b83af12464adeab378dee2d0a700ccd03979e2b821e7dd7cc1c2"}, + {file = "scikit_learn-1.5.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:b5e865e9bd59396220de49cb4a57b17016256637c61b4c5cc81aaf16bc123bbe"}, + {file = "scikit_learn-1.5.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:909144d50f367a513cee6090873ae582dba019cb3fca063b38054fa42704c3a4"}, + {file = "scikit_learn-1.5.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:689b6f74b2c880276e365fe84fe4f1befd6a774f016339c65655eaff12e10cbf"}, + {file = "scikit_learn-1.5.1-cp311-cp311-win_amd64.whl", hash = "sha256:9a07f90846313a7639af6a019d849ff72baadfa4c74c778821ae0fad07b7275b"}, + {file = "scikit_learn-1.5.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5944ce1faada31c55fb2ba20a5346b88e36811aab504ccafb9f0339e9f780395"}, + {file = "scikit_learn-1.5.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:0828673c5b520e879f2af6a9e99eee0eefea69a2188be1ca68a6121b809055c1"}, + {file = "scikit_learn-1.5.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:508907e5f81390e16d754e8815f7497e52139162fd69c4fdbd2dfa5d6cc88915"}, + {file = "scikit_learn-1.5.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97625f217c5c0c5d0505fa2af28ae424bd37949bb2f16ace3ff5f2f81fb4498b"}, + {file = "scikit_learn-1.5.1-cp312-cp312-win_amd64.whl", hash = "sha256:da3f404e9e284d2b0a157e1b56b6566a34eb2798205cba35a211df3296ab7a74"}, + {file = "scikit_learn-1.5.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:88e0672c7ac21eb149d409c74cc29f1d611d5158175846e7a9c2427bd12b3956"}, + {file = "scikit_learn-1.5.1-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:7b073a27797a283187a4ef4ee149959defc350b46cbf63a84d8514fe16b69855"}, + {file = "scikit_learn-1.5.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b59e3e62d2be870e5c74af4e793293753565c7383ae82943b83383fdcf5cc5c1"}, + {file = "scikit_learn-1.5.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1bd8d3a19d4bd6dc5a7d4f358c8c3a60934dc058f363c34c0ac1e9e12a31421d"}, + {file = "scikit_learn-1.5.1-cp39-cp39-win_amd64.whl", hash = "sha256:5f57428de0c900a98389c4a433d4a3cf89de979b3aa24d1c1d251802aa15e44d"}, + {file = "scikit_learn-1.5.1.tar.gz", hash = "sha256:0ea5d40c0e3951df445721927448755d3fe1d80833b0b7308ebff5d2a45e6414"}, +] + +[package.dependencies] +joblib = ">=1.2.0" +numpy = ">=1.19.5" +scipy = ">=1.6.0" +threadpoolctl = ">=3.1.0" + +[package.extras] +benchmark = ["matplotlib (>=3.3.4)", "memory_profiler (>=0.57.0)", "pandas (>=1.1.5)"] +build = ["cython (>=3.0.10)", "meson-python (>=0.16.0)", "numpy (>=1.19.5)", "scipy (>=1.6.0)"] +docs = ["Pillow (>=7.1.2)", "matplotlib (>=3.3.4)", "memory_profiler (>=0.57.0)", "numpydoc (>=1.2.0)", "pandas (>=1.1.5)", "plotly (>=5.14.0)", "polars (>=0.20.23)", "pooch (>=1.6.0)", "pydata-sphinx-theme (>=0.15.3)", "scikit-image (>=0.17.2)", "seaborn (>=0.9.0)", "sphinx (>=7.3.7)", "sphinx-copybutton (>=0.5.2)", "sphinx-design (>=0.5.0)", "sphinx-gallery (>=0.16.0)", "sphinx-prompt (>=1.4.0)", "sphinx-remove-toctrees (>=1.0.0.post1)", "sphinxcontrib-sass (>=0.3.4)", "sphinxext-opengraph (>=0.9.1)"] +examples = ["matplotlib (>=3.3.4)", "pandas (>=1.1.5)", "plotly (>=5.14.0)", "pooch (>=1.6.0)", "scikit-image (>=0.17.2)", "seaborn (>=0.9.0)"] +install = ["joblib (>=1.2.0)", "numpy (>=1.19.5)", "scipy (>=1.6.0)", "threadpoolctl (>=3.1.0)"] +maintenance = ["conda-lock (==2.5.6)"] +tests = ["black (>=24.3.0)", "matplotlib (>=3.3.4)", "mypy (>=1.9)", "numpydoc (>=1.2.0)", "pandas (>=1.1.5)", "polars (>=0.20.23)", "pooch (>=1.6.0)", "pyamg (>=4.0.0)", "pyarrow (>=12.0.0)", "pytest (>=7.1.2)", "pytest-cov (>=2.9.0)", "ruff (>=0.2.1)", "scikit-image (>=0.17.2)"] + +[[package]] +name = "scipy" +version = "1.12.0" +description = "Fundamental algorithms for scientific computing in Python" +optional = false +python-versions = ">=3.9" +files = [ + {file = "scipy-1.12.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:78e4402e140879387187f7f25d91cc592b3501a2e51dfb320f48dfb73565f10b"}, + {file = "scipy-1.12.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:f5f00ebaf8de24d14b8449981a2842d404152774c1a1d880c901bf454cb8e2a1"}, + {file = "scipy-1.12.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e53958531a7c695ff66c2e7bb7b79560ffdc562e2051644c5576c39ff8efb563"}, + {file = "scipy-1.12.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e32847e08da8d895ce09d108a494d9eb78974cf6de23063f93306a3e419960c"}, + {file = "scipy-1.12.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4c1020cad92772bf44b8e4cdabc1df5d87376cb219742549ef69fc9fd86282dd"}, + {file = "scipy-1.12.0-cp310-cp310-win_amd64.whl", hash = "sha256:75ea2a144096b5e39402e2ff53a36fecfd3b960d786b7efd3c180e29c39e53f2"}, + {file = "scipy-1.12.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:408c68423f9de16cb9e602528be4ce0d6312b05001f3de61fe9ec8b1263cad08"}, + {file = "scipy-1.12.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:5adfad5dbf0163397beb4aca679187d24aec085343755fcdbdeb32b3679f254c"}, + {file = "scipy-1.12.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c3003652496f6e7c387b1cf63f4bb720951cfa18907e998ea551e6de51a04467"}, + {file = "scipy-1.12.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b8066bce124ee5531d12a74b617d9ac0ea59245246410e19bca549656d9a40a"}, + {file = "scipy-1.12.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8bee4993817e204d761dba10dbab0774ba5a8612e57e81319ea04d84945375ba"}, + {file = "scipy-1.12.0-cp311-cp311-win_amd64.whl", hash = "sha256:a24024d45ce9a675c1fb8494e8e5244efea1c7a09c60beb1eeb80373d0fecc70"}, + {file = "scipy-1.12.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e7e76cc48638228212c747ada851ef355c2bb5e7f939e10952bc504c11f4e372"}, + {file = "scipy-1.12.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:f7ce148dffcd64ade37b2df9315541f9adad6efcaa86866ee7dd5db0c8f041c3"}, + {file = "scipy-1.12.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c39f92041f490422924dfdb782527a4abddf4707616e07b021de33467f917bc"}, + {file = "scipy-1.12.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a7ebda398f86e56178c2fa94cad15bf457a218a54a35c2a7b4490b9f9cb2676c"}, + {file = "scipy-1.12.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:95e5c750d55cf518c398a8240571b0e0782c2d5a703250872f36eaf737751338"}, + {file = "scipy-1.12.0-cp312-cp312-win_amd64.whl", hash = "sha256:e646d8571804a304e1da01040d21577685ce8e2db08ac58e543eaca063453e1c"}, + {file = "scipy-1.12.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:913d6e7956c3a671de3b05ccb66b11bc293f56bfdef040583a7221d9e22a2e35"}, + {file = "scipy-1.12.0-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:bba1b0c7256ad75401c73e4b3cf09d1f176e9bd4248f0d3112170fb2ec4db067"}, + {file = "scipy-1.12.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:730badef9b827b368f351eacae2e82da414e13cf8bd5051b4bdfd720271a5371"}, + {file = "scipy-1.12.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6546dc2c11a9df6926afcbdd8a3edec28566e4e785b915e849348c6dd9f3f490"}, + {file = "scipy-1.12.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:196ebad3a4882081f62a5bf4aeb7326aa34b110e533aab23e4374fcccb0890dc"}, + {file = "scipy-1.12.0-cp39-cp39-win_amd64.whl", hash = "sha256:b360f1b6b2f742781299514e99ff560d1fe9bd1bff2712894b52abe528d1fd1e"}, + {file = "scipy-1.12.0.tar.gz", hash = "sha256:4bf5abab8a36d20193c698b0f1fc282c1d083c94723902c447e5d2f1780936a3"}, +] + +[package.dependencies] +numpy = ">=1.22.4,<1.29.0" + +[package.extras] +dev = ["click", "cython-lint (>=0.12.2)", "doit (>=0.36.0)", "mypy", "pycodestyle", "pydevtool", "rich-click", "ruff", "types-psutil", "typing_extensions"] +doc = ["jupytext", "matplotlib (>2)", "myst-nb", "numpydoc", "pooch", "pydata-sphinx-theme (==0.9.0)", "sphinx (!=4.1.0)", "sphinx-design (>=0.2.0)"] +test = ["asv", "gmpy2", "hypothesis", "mpmath", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] + +[[package]] +name = "seaborn" +version = "0.13.2" +description = "Statistical data visualization" +optional = false +python-versions = ">=3.8" +files = [ + {file = "seaborn-0.13.2-py3-none-any.whl", hash = "sha256:636f8336facf092165e27924f223d3c62ca560b1f2bb5dff7ab7fad265361987"}, + {file = "seaborn-0.13.2.tar.gz", hash = "sha256:93e60a40988f4d65e9f4885df477e2fdaff6b73a9ded434c1ab356dd57eefff7"}, ] +[package.dependencies] +matplotlib = ">=3.4,<3.6.1 || >3.6.1" +numpy = ">=1.20,<1.24.0 || >1.24.0" +pandas = ">=1.2" + +[package.extras] +dev = ["flake8", "flit", "mypy", "pandas-stubs", "pre-commit", "pytest", "pytest-cov", "pytest-xdist"] +docs = ["ipykernel", "nbconvert", "numpydoc", "pydata_sphinx_theme (==0.10.0rc2)", "pyyaml", "sphinx (<6.0.0)", "sphinx-copybutton", "sphinx-design", "sphinx-issues"] +stats = ["scipy (>=1.7)", "statsmodels (>=0.12)"] + [[package]] name = "setuptools" version = "72.1.0" @@ -3040,6 +4025,31 @@ files = [ {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, ] +[[package]] +name = "smart-open" +version = "7.0.4" +description = "Utils for streaming large files (S3, HDFS, GCS, Azure Blob Storage, gzip, bz2...)" +optional = false +python-versions = "<4.0,>=3.7" +files = [ + {file = "smart_open-7.0.4-py3-none-any.whl", hash = "sha256:4e98489932b3372595cddc075e6033194775165702887216b65eba760dfd8d47"}, + {file = "smart_open-7.0.4.tar.gz", hash = "sha256:62b65852bdd1d1d516839fcb1f6bc50cd0f16e05b4ec44b52f43d38bcb838524"}, +] + +[package.dependencies] +wrapt = "*" + +[package.extras] +all = ["azure-common", "azure-core", "azure-storage-blob", "boto3", "google-cloud-storage (>=2.6.0)", "paramiko", "requests", "zstandard"] +azure = ["azure-common", "azure-core", "azure-storage-blob"] +gcs = ["google-cloud-storage (>=2.6.0)"] +http = ["requests"] +s3 = ["boto3"] +ssh = ["paramiko"] +test = ["azure-common", "azure-core", "azure-storage-blob", "boto3", "google-cloud-storage (>=2.6.0)", "moto[server]", "paramiko", "pytest", "pytest-rerunfailures", "requests", "responses", "zstandard"] +webhdfs = ["requests"] +zst = ["zstandard"] + [[package]] name = "sniffio" version = "1.3.1" @@ -3167,6 +4177,51 @@ typing-extensions = {version = ">=3.10.0", markers = "python_version < \"3.10\"" [package.extras] full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart (>=0.0.7)", "pyyaml"] +[[package]] +name = "statsmodels" +version = "0.14.2" +description = "Statistical computations and models for Python" +optional = false +python-versions = ">=3.9" +files = [ + {file = "statsmodels-0.14.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df5d6f95c46f0341da6c79ee7617e025bf2b371e190a8e60af1ae9cabbdb7a97"}, + {file = "statsmodels-0.14.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a87ef21fadb445b650f327340dde703f13aec1540f3d497afb66324499dea97a"}, + {file = "statsmodels-0.14.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5827a12e3ede2b98a784476d61d6bec43011fedb64aa815f2098e0573bece257"}, + {file = "statsmodels-0.14.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10f2b7611a61adb7d596a6d239abdf1a4d5492b931b00d5ed23d32844d40e48e"}, + {file = "statsmodels-0.14.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c254c66142f1167b4c7d031cf8db55294cc62ff3280e090fc45bd10a7f5fd029"}, + {file = "statsmodels-0.14.2-cp310-cp310-win_amd64.whl", hash = "sha256:0e46e9d59293c1af4cc1f4e5248f17e7e7bc596bfce44d327c789ac27f09111b"}, + {file = "statsmodels-0.14.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:50fcb633987779e795142f51ba49fb27648d46e8a1382b32ebe8e503aaabaa9e"}, + {file = "statsmodels-0.14.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:876794068abfaeed41df71b7887000031ecf44fbfa6b50d53ccb12ebb4ab747a"}, + {file = "statsmodels-0.14.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7a91f6c4943de13e3ce2e20ee3b5d26d02bd42300616a421becd53756f5deb37"}, + {file = "statsmodels-0.14.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4864a1c4615c5ea5f2e3b078a75bdedc90dd9da210a37e0738e064b419eccee2"}, + {file = "statsmodels-0.14.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:afbd92410e0df06f3d8c4e7c0e2e71f63f4969531f280fb66059e2ecdb6e0415"}, + {file = "statsmodels-0.14.2-cp311-cp311-win_amd64.whl", hash = "sha256:8e004cfad0e46ce73fe3f3812010c746f0d4cfd48e307b45c14e9e360f3d2510"}, + {file = "statsmodels-0.14.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:eb0ba1ad3627705f5ae20af6b2982f500546d43892543b36c7bca3e2f87105e7"}, + {file = "statsmodels-0.14.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:90fd2f0110b73fc3fa5a2f21c3ca99b0e22285cccf38e56b5b8fd8ce28791b0f"}, + {file = "statsmodels-0.14.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac780ad9ff552773798829a0b9c46820b0faa10e6454891f5e49a845123758ab"}, + {file = "statsmodels-0.14.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:55d1742778400ae67acb04b50a2c7f5804182f8a874bd09ca397d69ed159a751"}, + {file = "statsmodels-0.14.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f870d14a587ea58a3b596aa994c2ed889cc051f9e450e887d2c83656fc6a64bf"}, + {file = "statsmodels-0.14.2-cp312-cp312-win_amd64.whl", hash = "sha256:f450fcbae214aae66bd9d2b9af48e0f8ba1cb0e8596c6ebb34e6e3f0fec6542c"}, + {file = "statsmodels-0.14.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:201c3d00929c4a67cda1fe05b098c8dcf1b1eeefa88e80a8f963a844801ed59f"}, + {file = "statsmodels-0.14.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9edefa4ce08e40bc1d67d2f79bc686ee5e238e801312b5a029ee7786448c389a"}, + {file = "statsmodels-0.14.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29c78a7601fdae1aa32104c5ebff2e0b72c26f33e870e2f94ab1bcfd927ece9b"}, + {file = "statsmodels-0.14.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f36494df7c03d63168fccee5038a62f469469ed6a4dd6eaeb9338abedcd0d5f5"}, + {file = "statsmodels-0.14.2-cp39-cp39-win_amd64.whl", hash = "sha256:8875823bdd41806dc853333cc4e1b7ef9481bad2380a999e66ea42382cf2178d"}, + {file = "statsmodels-0.14.2.tar.gz", hash = "sha256:890550147ad3a81cda24f0ba1a5c4021adc1601080bd00e191ae7cd6feecd6ad"}, +] + +[package.dependencies] +numpy = ">=1.22.3" +packaging = ">=21.3" +pandas = ">=1.4,<2.1.0 || >2.1.0" +patsy = ">=0.5.6" +scipy = ">=1.8,<1.9.2 || >1.9.2" + +[package.extras] +build = ["cython (>=0.29.33)"] +develop = ["colorama", "cython (>=0.29.33)", "cython (>=3.0.10,<4)", "flake8", "isort", "joblib", "matplotlib (>=3)", "pytest (>=7.3.0,<8)", "pytest-cov", "pytest-randomly", "pytest-xdist", "pywinpty", "setuptools-scm[toml] (>=8.0,<9.0)"] +docs = ["ipykernel", "jupyter-client", "matplotlib", "nbconvert", "nbformat", "numpydoc", "pandas-datareader", "sphinx"] + [[package]] name = "termcolor" version = "2.4.0" @@ -3181,6 +4236,17 @@ files = [ [package.extras] tests = ["pytest", "pytest-cov"] +[[package]] +name = "threadpoolctl" +version = "3.5.0" +description = "threadpoolctl" +optional = false +python-versions = ">=3.8" +files = [ + {file = "threadpoolctl-3.5.0-py3-none-any.whl", hash = "sha256:56c1e26c150397e58c4926da8eeee87533b1e32bef131bd4bf6a2f45f3185467"}, + {file = "threadpoolctl-3.5.0.tar.gz", hash = "sha256:082433502dd922bf738de0d8bcc4fdcbf0979ff44c42bd40f5af8a282f6fa107"}, +] + [[package]] name = "tiktoken" version = "0.7.0" @@ -3417,6 +4483,41 @@ files = [ {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, ] +[[package]] +name = "tzdata" +version = "2024.1" +description = "Provider of IANA time zone data" +optional = false +python-versions = ">=2" +files = [ + {file = "tzdata-2024.1-py2.py3-none-any.whl", hash = "sha256:9068bc196136463f5245e51efda838afa15aaeca9903f49050dfa2679db4d252"}, + {file = "tzdata-2024.1.tar.gz", hash = "sha256:2674120f8d891909751c38abcdfd386ac0a5a1127954fbc332af6b5ceae07efd"}, +] + +[[package]] +name = "umap-learn" +version = "0.5.6" +description = "Uniform Manifold Approximation and Projection" +optional = false +python-versions = "*" +files = [ + {file = "umap-learn-0.5.6.tar.gz", hash = "sha256:5b3917a862c23ba0fc83bfcd67a7b719dec85b3d9c01fdc7d894cce455df4e03"}, + {file = "umap_learn-0.5.6-py3-none-any.whl", hash = "sha256:881cc0c2ee845b790bf0455aa1664f9f68b838d9d0fe12a1291b85c5a559c913"}, +] + +[package.dependencies] +numba = ">=0.51.2" +numpy = ">=1.17" +pynndescent = ">=0.5" +scikit-learn = ">=0.22" +scipy = ">=1.3.1" +tqdm = "*" + +[package.extras] +parametric-umap = ["tensorflow (>=2.1)"] +plot = ["bokeh", "colorcet", "datashader", "holoviews", "matplotlib", "pandas", "scikit-image", "seaborn"] +tbb = ["tbb (>=2019.0)"] + [[package]] name = "urllib3" version = "2.2.2" @@ -3710,4 +4811,4 @@ ingest-movies = ["moviepy", "opencv-python"] [metadata] lock-version = "2.0" python-versions = ">=3.9,<3.13" -content-hash = "e9ca4e0ec88980f4bbd5565ce980c039103a785a96776e123f5cc7c9a8b74b0c" +content-hash = "d6fe35a821e98c4721de40e75b1e3d743ed67f078ea0babb7cd4b00e679bc8d5" diff --git a/pyproject.toml b/pyproject.toml index 25ff50e09..a22f2ba98 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -68,6 +68,8 @@ poppler-utils = "^0.1.0" alembic = "^1.13.2" # unstructured = {version = "^0.15.0"} psutil = "^6.0.0" +deepdiff = "^7.0.1" +graspologic = "^3.4.1" [tool.poetry.extras] all = ["moviepy", "opencv-python"] @@ -86,6 +88,7 @@ pytest-asyncio = "^0.23.6" pytest-dependency = "^0.6.0" pytest-mock = "^3.14.0" pytest-cov = "^5.0.0" +colorama = "^0.4.6" [tool.poetry.scripts] r2r = "r2r.cli.cli:main" diff --git a/r2r/__init__.py b/r2r/__init__.py index e682de8ac..b31a2385b 100644 --- a/r2r/__init__.py +++ b/r2r/__init__.py @@ -2,7 +2,7 @@ # Keep '*' imports for enhanced development velocity # corresponding flake8 error codes are F403, F405 -from .agents import * +from .agent import * from .base import * from .integrations import * from .main import * @@ -30,85 +30,257 @@ # Optional: Prevent propagation to the root logger logger.propagate = False + +# TODO - Cleanup export strategy && slimmify release __all__ = [ + ## AGENT + # Base + "R2RAgent", + "R2RStreamingAgent", + # RAG Agents + "R2RRAGAgent", + "R2RStreamingRAGAgent", + ## BASE + # Base abstractions + "AsyncSyncMeta", + "syncable", + # Completion abstractions + "CompletionRecord", + "MessageType", + # Document abstractions + "DataType", + "Document", + "DocumentExtraction", + "DocumentFragment", + "DocumentInfo", + "DocumentStatus", + "DocumentType", + # Embedding abstractions + "EmbeddingPurpose", + "default_embedding_prefixes", + # Exception abstractions + "R2RDocumentProcessingError", "R2RException", + # KG abstractions + "Entity", + "KGExtraction", + "Triple", + "extract_triples", + # LLM abstractions + "GenerationConfig", + "LLMChatCompletion", + "LLMChatCompletionChunk", + "RAGCompletion", + # Prompt abstractions + "Prompt", + # Search abstractions + "AggregateSearchResult", + "KGSearchResult", + "KGSearchSettings", + "VectorSearchResult", + "VectorSearchSettings", + # User abstractions + "Token", + "TokenData", + "UserStats", + # Vector abstractions + "Vector", + "VectorEntry", + "VectorType", + ## AGENT + # Agent abstractions + "Agent", + "AgentConfig", + "Conversation", + "Message", + "Tool", + "ToolResult", + ## API + # Auth Responses + "GenericMessageResponse", + "TokenResponse", + "UserResponse", + ## LOGGING + # Basic types + "RunType", + "AnalysisTypes", + "LogAnalytics", + "LogAnalyticsConfig", + "LogFilterCriteria", + "LogProcessor", + # Logging Providers + "LocalRunLoggingProvider", "LoggingConfig", - "LocalKVLoggingProvider", "PostgresLoggingConfig", - "PostgresKVLoggingProvider", + "PostgresRunLoggingProvider", "RedisLoggingConfig", - "RedisKVLoggingProvider", - "KVLoggingSingleton", - "VectorEntry", - "VectorType", - "Vector", - "VectorSearchRequest", - "VectorSearchResult", - "AsyncPipe", - "PipeType", - "AsyncState", - "Prompt", - "DataType", - "DocumentType", - "Document", - "Extraction", - "ExtractionType", - "Fragment", - "FragmentType", - "SearchPipe", - # Parsers + "RedisRunLoggingProvider", + "RunLoggingSingleton", + # Run Manager + "RunManager", + "manage_run", + ## PARSERS + # Base parser "AsyncParser", - "CSVParser", - "CSVParserAdvanced", - "DOCXParser", - "HTMLParser", - "JSONParser", - "MDParser", - "PDFParser", - "PDFParserUnstructured", - "PPTParser", - "TextParser", - "XLSXParser", - "XSLXParserAdvanced", + ## PIPELINE + # Base pipeline "AsyncPipeline", - # Providers + ## PIPES + "AsyncPipe", + "AsyncState", + "PipeType", + ## PROVIDERS + # Base provider classes + "Provider", + "ProviderConfig", + # Auth provider + "AuthConfig", + "AuthProvider", + # Chunking provider + "ChunkingConfig", + "ChunkingProvider", + "Method", + # Crypto provider + "CryptoConfig", + "CryptoProvider", + # Database providers + "DatabaseConfig", + "DatabaseProvider", + "RelationalDBProvider", + "VectorDBProvider", + "VectorDBFilterValue", + # Embedding provider "EmbeddingConfig", "EmbeddingProvider", - "EvalConfig", - "EvalProvider", - "LLMEvalProvider", - "PromptConfig", - "PromptProvider", - "GenerationConfig", - "LLMChatCompletion", - "LLMChatCompletionChunk", + # Knowledge Graph provider + "KGConfig", + "KGProvider", + "extract_entities", + # LLM provider "CompletionConfig", "CompletionProvider", - "DatabaseConfig", - "DatabaseProvider", - "R2RConfig", - "TextSplitter", + # Parsing provider + "ParsingConfig", + "ParsingProvider", + "OverrideParser", + # Prompt provider + "PromptConfig", + "PromptProvider", + ## UTILS "RecursiveCharacterTextSplitter", + "TextSplitter", + "run_pipeline", + "to_async_generator", "generate_run_id", "generate_id_from_label", + "increment_version", + "EntityType", + "format_entity_types", + "format_relations", + ## MAIN + ## R2R ABSTRACTIONS + "R2RProviders", + "R2RPipes", + "R2RPipelines", + "R2RAgents", + ## R2R API + # Client + "R2RClient", + # Routes + "AuthRouter", + "IngestionRouter", + "ManagementRouter", + "RetrievalRouter", + "BaseRouter", + ## R2R APP + "R2RApp", + ## R2R APP ENTRY + # "r2r_app", + ## R2R ENGINE "R2REngine", - # Pipes + ## R2R EXECUTION + "R2RExecutionWrapper", + ## R2R ASSEMBLY + # Builder + "R2RBuilder", + # Config + "R2RConfig", + # Factory + "R2RProviderFactory", + "R2RPipeFactory", + "R2RPipelineFactory", + "R2RAgentFactory", + # Factory Extensions + "R2RPipeFactoryWithMultiSearch", + ## R2R + "R2R", + ## R2R SERVICES + "AuthService", + "IngestionService", + "ManagementService", + "RetrievalService", + ## PARSERS + # Media parsers + "AudioParser", + "DOCXParser", + "ImageParser", + "MovieParser", + "PDFParser", + "PDFParserUnstructured", + "PDFParserMarker", + "PPTParser", + # Structured parsers + "CSVParser", + "CSVParserAdvanced", + "JSONParser", + "XLSXParser", + "XLSXParserAdvanced", + # Text parsers + "MDParser", + "HTMLParser", + "TextParser", + ## PIPELINES + "IngestionPipeline", + "SearchPipeline", + "RAGPipeline", + ## PIPES + "SearchPipe", "EmbeddingPipe", - "EvalPipe", + "KGTriplesExtractionPipe", "ParsingPipe", + "ChunkingPipe", "QueryTransformPipe", "SearchRAGPipe", "StreamingSearchRAGPipe", "VectorSearchPipe", "VectorStoragePipe", - "R2RPromptProvider", "WebSearchPipe", - "R2RBuilder", - "R2R", "KGSearchSearchPipe", - # Prebuilts + "KGStoragePipe", "MultiSearchPipe", - "R2RPipeFactoryWithMultiSearch", - # Integrations - "SerperClient", + ## PROVIDERS + # Auth + "R2RAuthProvider", + # Chunking + "R2RChunkingProvider", + "UnstructuredChunkingProvider", + # Crypto + "BCryptProvider", + "BCryptConfig", + # Database + "PostgresDBProvider", + # Embeddings + "LiteLLMEmbeddingProvider", + "OllamaEmbeddingProvider", + "OpenAIEmbeddingProvider", + # KG + "Neo4jKGProvider", + # LLM + "OpenAICompletionProvider", + "LiteCompletionProvider", + # Parsing + "R2RParsingProvider", + "UnstructuredParsingProvider", + # Prompts + "R2RPromptProvider", ] diff --git a/r2r/agents/__init__.py b/r2r/agent/__init__.py similarity index 87% rename from r2r/agents/__init__.py rename to r2r/agent/__init__.py index 23058cebd..43f260c35 100644 --- a/r2r/agents/__init__.py +++ b/r2r/agent/__init__.py @@ -2,8 +2,10 @@ from .rag import R2RRAGAgent, R2RStreamingRAGAgent __all__ = [ + # Base "R2RAgent", "R2RStreamingAgent", + # RAG Agents "R2RRAGAgent", "R2RStreamingRAGAgent", ] diff --git a/r2r/agents/base.py b/r2r/agent/base.py similarity index 96% rename from r2r/agents/base.py rename to r2r/agent/base.py index 83b81e734..5fea403a7 100644 --- a/r2r/agents/base.py +++ b/r2r/agent/base.py @@ -2,15 +2,13 @@ from abc import ABCMeta from typing import AsyncGenerator, Generator, Optional -from r2r.base import ( - Agent, +from r2r.base.abstractions import ( AsyncSyncMeta, LLMChatCompletion, LLMChatCompletionChunk, - Message, - User, syncable, ) +from r2r.base.agent import Agent, Message class CombinedMeta(AsyncSyncMeta, ABCMeta): @@ -106,7 +104,6 @@ async def arun( self, system_instruction: Optional[str] = None, messages: Optional[list[Message]] = None, - user: Optional[User] = None, *args, **kwargs, ) -> AsyncGenerator[str, None]: @@ -129,7 +126,7 @@ async def arun( generation_config, ) async for chunk in self.process_llm_response( - stream, user=user, *args, **kwargs + stream, *args, **kwargs ): yield chunk finally: @@ -144,7 +141,7 @@ def run( ) async def process_llm_response( - self, stream: LLMChatCompletionChunk, user, *args, **kwargs + self, stream: LLMChatCompletionChunk, *args, **kwargs ) -> AsyncGenerator[str, None]: function_name = None function_arguments = "" @@ -196,7 +193,7 @@ async def process_llm_response( function_name = None function_arguments = "" - self.arun(user=user, *args, **kwargs) + self.arun(*args, **kwargs) elif chunk.choices[0].finish_reason == "stop": if content_buffer: diff --git a/r2r/agents/rag.py b/r2r/agent/rag.py similarity index 93% rename from r2r/agents/rag.py rename to r2r/agent/rag.py index 52f84457a..910ba76b7 100644 --- a/r2r/agents/rag.py +++ b/r2r/agent/rag.py @@ -1,16 +1,14 @@ import json -from r2r.agents import R2RAgent, R2RStreamingAgent -from r2r.base import ( - AgentConfig, - CompletionProvider, +from r2r.agent import R2RAgent, R2RStreamingAgent +from r2r.base.abstractions import ( KGSearchSettings, - PromptProvider, - Tool, VectorSearchResult, VectorSearchSettings, - to_async_generator, ) +from r2r.base.agent import AgentConfig, Tool +from r2r.base.providers import CompletionProvider, PromptProvider +from r2r.base.utils import to_async_generator from r2r.pipelines import SearchPipeline diff --git a/r2r/base/__init__.py b/r2r/base/__init__.py index 4dd10601e..edcefcf00 100644 --- a/r2r/base/__init__.py +++ b/r2r/base/__init__.py @@ -1,203 +1,149 @@ -from .abstractions.agent import ( - Agent, - AgentConfig, - Conversation, - Message, - Tool, - ToolResult, -) -from .abstractions.base import AsyncSyncMeta, syncable -from .abstractions.completion import CompletionRecord, MessageType -from .abstractions.document import ( - DataType, - Document, - DocumentInfo, - DocumentType, - Entity, - Extraction, - ExtractionType, - Fragment, - FragmentType, - KGExtraction, - Triple, - extract_entities, - extract_triples, -) -from .abstractions.embedding import EmbeddingPurpose -from .abstractions.exception import R2RDocumentProcessingError, R2RException -from .abstractions.llama_abstractions import VectorStoreQuery -from .abstractions.llm import ( - GenerationConfig, - LLMChatCompletion, - LLMChatCompletionChunk, - RAGCompletion, -) -from .abstractions.prompt import Prompt -from .abstractions.search import ( - AggregateSearchResult, - KGSearchRequest, - KGSearchResult, - KGSearchSettings, - VectorSearchRequest, - VectorSearchResult, - VectorSearchSettings, -) -from .abstractions.user import Token, TokenData, User, UserCreate, UserStats -from .abstractions.vector import Vector, VectorEntry, VectorType -from .logging.kv_logger import ( - KVLoggingSingleton, - LocalKVLoggingProvider, - LoggingConfig, - PostgresKVLoggingProvider, - PostgresLoggingConfig, - RedisKVLoggingProvider, - RedisLoggingConfig, -) -from .logging.log_processor import ( - AnalysisTypes, - FilterCriteria, - LogAnalytics, - LogAnalyticsConfig, - LogProcessor, -) -from .logging.run_manager import RunManager, manage_run -from .parsers import AsyncParser -from .pipeline.base_pipeline import AsyncPipeline -from .pipes.base_pipe import AsyncPipe, AsyncState, PipeType -from .providers.auth import AuthConfig, AuthProvider -from .providers.chunking import ChunkingConfig, ChunkingProvider -from .providers.crypto import CryptoConfig, CryptoProvider -from .providers.database import ( - DatabaseConfig, - DatabaseProvider, - RelationalDatabaseProvider, - VectorDatabaseProvider, -) -from .providers.embedding import EmbeddingConfig, EmbeddingProvider -from .providers.eval import EvalConfig, EvalProvider -from .providers.kg import KGConfig, KGProvider, update_kg_prompt -from .providers.llm import CompletionConfig, CompletionProvider -from .providers.parsing import ParsingConfig, ParsingProvider -from .providers.prompt import PromptConfig, PromptProvider -from .utils import ( - EntityType, - RecursiveCharacterTextSplitter, - Relation, - TextSplitter, - format_entity_types, - format_relations, - generate_id_from_label, - generate_run_id, - increment_version, - run_pipeline, - to_async_generator, -) +from .abstractions import * +from .agent import * +from .api.models import * +from .logging import * +from .parsers import * +from .pipeline import * +from .pipes import * +from .providers import * +from .utils import * __all__ = [ - # Logging - "AsyncParser", - "AnalysisTypes", - "CompletionRecord", - "LogAnalytics", - "LogAnalyticsConfig", - "LogProcessor", - "LoggingConfig", - "LocalKVLoggingProvider", - "PostgresLoggingConfig", - "PostgresKVLoggingProvider", - "RedisLoggingConfig", + ## ABSTRACTIONS + # Base abstractions "AsyncSyncMeta", "syncable", - "Agent", - "AgentConfig", - "Tool", - "ToolResult", - "Message", + # Completion abstractions + "CompletionRecord", "MessageType", - "Conversation", - "RedisKVLoggingProvider", - "KVLoggingSingleton", - "RunManager", - "manage_run", - # Abstractions - "VectorEntry", - "VectorType", - "Vector", - "VectorSearchRequest", - "VectorSearchResult", - "VectorSearchSettings", - "Token", - "TokenData", - "User", - "UserCreate", - "KGSearchRequest", - "KGSearchResult", - "KGSearchSettings", - "AggregateSearchResult", - "AsyncPipe", - "PipeType", - "AsyncState", - "AsyncPipe", - "Prompt", + # Document abstractions "DataType", - "DocumentType", "Document", + "DocumentExtraction", + "DocumentFragment", "DocumentInfo", - "Extraction", - "ExtractionType", - "Fragment", - "FragmentType", - "extract_entities", - "Entity", - "extract_triples", + "DocumentStatus", + "DocumentType", + # Embedding abstractions "EmbeddingPurpose", - "R2RException", + "default_embedding_prefixes", + # Exception abstractions "R2RDocumentProcessingError", - "Triple", + "R2RException", + # KG abstractions + "Entity", "KGExtraction", - "UserStats", - # Pipelines - "AsyncPipeline", - # Providers - "ParsingConfig", - "ParsingProvider", - "ChunkingConfig", - "ChunkingProvider", - "EmbeddingConfig", - "EmbeddingProvider", - "EvalConfig", - "EvalProvider", - "PromptConfig", - "PromptProvider", + "Triple", + "extract_triples", + # LLM abstractions "GenerationConfig", - "RAGCompletion", - "VectorStoreQuery", "LLMChatCompletion", "LLMChatCompletionChunk", - "CompletionConfig", - "CompletionProvider", + "RAGCompletion", + # Prompt abstractions + "Prompt", + # Search abstractions + "AggregateSearchResult", + "KGSearchResult", + "KGSearchSettings", + "VectorSearchResult", + "VectorSearchSettings", + # User abstractions + "Token", + "TokenData", + "UserStats", + # Vector abstractions + "Vector", + "VectorEntry", + "VectorType", + ## AGENT + # Agent abstractions + "Agent", + "AgentConfig", + "Conversation", + "Message", + "Tool", + "ToolResult", + ## API + # Auth Responses + "GenericMessageResponse", + "TokenResponse", + "UserResponse", + ## LOGGING + # Basic types + "RunType", + "AnalysisTypes", + "LogAnalytics", + "LogAnalyticsConfig", + "LogFilterCriteria", + "LogProcessor", + # Logging Providers + "LocalRunLoggingProvider", + "LoggingConfig", + "PostgresLoggingConfig", + "PostgresRunLoggingProvider", + "RedisLoggingConfig", + "RedisRunLoggingProvider", + "RunLoggingSingleton", + # Run Manager + "RunManager", + "manage_run", + ## PARSERS + # Base parser + "AsyncParser", + ## PIPELINE + # Base pipeline + "AsyncPipeline", + ## PIPES + "AsyncPipe", + "AsyncState", + "PipeType", + ## PROVIDERS + # Base provider classes + "Provider", + "ProviderConfig", + # Auth provider "AuthConfig", "AuthProvider", + # Chunking provider + "ChunkingConfig", + "ChunkingProvider", + "Method", + # Crypto provider "CryptoConfig", "CryptoProvider", + # Database providers "DatabaseConfig", "DatabaseProvider", - "VectorDatabaseProvider", - "RelationalDatabaseProvider", - "KGProvider", + "RelationalDBProvider", + "VectorDBProvider", + "VectorDBFilterValue", + # Embedding provider + "EmbeddingConfig", + "EmbeddingProvider", + # Knowledge Graph provider "KGConfig", - "update_kg_prompt", - # Other - "FilterCriteria", - "TextSplitter", + "KGProvider", + "extract_entities", + # LLM provider + "CompletionConfig", + "CompletionProvider", + # Parsing provider + "ParsingConfig", + "ParsingProvider", + "OverrideParser", + # Prompt provider + "PromptConfig", + "PromptProvider", + ## UTILS "RecursiveCharacterTextSplitter", + "TextSplitter", + "run_pipeline", "to_async_generator", + "generate_run_id", + "generate_id_from_label", + "increment_version", "EntityType", - "Relation", "format_entity_types", "format_relations", - "increment_version", - "run_pipeline", - "generate_run_id", - "generate_id_from_label", ] diff --git a/r2r/base/abstractions/__init__.py b/r2r/base/abstractions/__init__.py index e69de29bb..ae33be385 100644 --- a/r2r/base/abstractions/__init__.py +++ b/r2r/base/abstractions/__init__.py @@ -0,0 +1,94 @@ +from .base import AsyncSyncMeta, syncable +from .completion import CompletionRecord, MessageType +from .document import ( + DataType, + Document, + DocumentExtraction, + DocumentFragment, + DocumentInfo, + DocumentStatus, + DocumentType, +) +from .embedding import EmbeddingPurpose, default_embedding_prefixes +from .exception import R2RDocumentProcessingError, R2RException +from .graph import ( + Community, + CommunityReport, + Entity, + EntityType, + KGExtraction, + RelationshipType, + Triple, + extract_entities, + extract_triples, +) +from .llm import ( + GenerationConfig, + LLMChatCompletion, + LLMChatCompletionChunk, + RAGCompletion, +) +from .prompt import Prompt +from .search import ( + AggregateSearchResult, + KGSearchResult, + KGSearchSettings, + VectorSearchResult, + VectorSearchSettings, +) +from .user import Token, TokenData, UserStats +from .vector import Vector, VectorEntry, VectorType + +__all__ = [ + # Base abstractions + "AsyncSyncMeta", + "syncable", + # Completion abstractions + "CompletionRecord", + "MessageType", + # Document abstractions + "DataType", + "Document", + "DocumentExtraction", + "DocumentFragment", + "DocumentInfo", + "DocumentStatus", + "DocumentType", + # Embedding abstractions + "EmbeddingPurpose", + "default_embedding_prefixes", + # Exception abstractions + "R2RDocumentProcessingError", + "R2RException", + # Graph abstractions + "Entity", + "EntityType", + "RelationshipType", + "Community", + "CommunityReport", + "KGExtraction", + "Triple", + "extract_entities", + "extract_triples", + # LLM abstractions + "GenerationConfig", + "LLMChatCompletion", + "LLMChatCompletionChunk", + "RAGCompletion", + # Prompt abstractions + "Prompt", + # Search abstractions + "AggregateSearchResult", + "KGSearchResult", + "KGSearchSettings", + "VectorSearchResult", + "VectorSearchSettings", + # User abstractions + "Token", + "TokenData", + "UserStats", + # Vector abstractions + "Vector", + "VectorEntry", + "VectorType", +] diff --git a/r2r/base/abstractions/document.py b/r2r/base/abstractions/document.py index 9b617ab66..3b9b936c1 100644 --- a/r2r/base/abstractions/document.py +++ b/r2r/base/abstractions/document.py @@ -2,10 +2,10 @@ import json import logging -import uuid from datetime import datetime from enum import Enum from typing import Optional, Union +from uuid import NAMESPACE_DNS, UUID, uuid4 from pydantic import BaseModel, Field @@ -14,6 +14,16 @@ DataType = Union[str, bytes] +class DocumentStatus(str, Enum): + """Status of document processing.""" + + PROCESSING = "processing" + # TODO - Extend support for `partial-failure` + # PARTIAL_FAILURE = "partial-failure" + FAILURE = "failure" + SUCCESS = "success" + + class DocumentType(str, Enum): """Types of documents that can be stored.""" @@ -36,7 +46,10 @@ class DocumentType(str, Enum): class Document(BaseModel): - id: uuid.UUID = Field(default_factory=uuid.uuid4) + id: UUID = Field(default_factory=uuid4) + group_ids: list[UUID] + user_id: UUID + type: DocumentType data: Union[str, bytes] metadata: dict @@ -53,7 +66,7 @@ def __init__(self, *args, **kwargs): data_str = data.decode("utf-8", errors="ignore") else: data_str = data - data_hash = uuid.uuid5(uuid.NAMESPACE_DNS, data_str) + data_hash = uuid4(NAMESPACE_DNS, data_str) kwargs["id"] = data_hash # Set the id based on the data hash super().__init__(*args, **kwargs) @@ -61,32 +74,23 @@ def __init__(self, *args, **kwargs): class Config: arbitrary_types_allowed = True json_encoders = { - uuid.UUID: str, + UUID: str, bytes: lambda v: v.decode("utf-8", errors="ignore"), } -class DocumentStatus(str, Enum): - """Status of document processing.""" - - PROCESSING = "processing" - # TODO - Extend support for `partial-failure` - # PARTIAL_FAILURE = "partial-failure" - FAILURE = "failure" - SUCCESS = "success" - - class DocumentInfo(BaseModel): """Base class for document information handling.""" - document_id: uuid.UUID + id: UUID + group_ids: list[UUID] + user_id: UUID + type: DocumentType + metadata: dict + title: Optional[str] = None version: str size_in_bytes: int - metadata: dict status: DocumentStatus = DocumentStatus.PROCESSING - - user_id: Optional[uuid.UUID] = None - title: Optional[str] = None created_at: Optional[datetime] = None updated_at: Optional[datetime] = None @@ -95,134 +99,38 @@ def convert_to_db_entry(self): now = datetime.now() return { - "document_id": str(self.document_id), - "title": self.title or "N/A", + "document_id": self.id, + "group_ids": self.group_ids, "user_id": self.user_id, + "type": self.type, + "metadata": json.dumps(self.metadata), + "title": self.title or "N/A", "version": self.version, "size_in_bytes": self.size_in_bytes, - "metadata": json.dumps(self.metadata), + "status": self.status, "created_at": self.created_at or now, "updated_at": self.updated_at or now, - "status": self.status, } -class ExtractionType(Enum): - """Types of extractions that can be performed.""" - - TXT = "txt" - IMG = "img" - MOV = "mov" - - -class Extraction(BaseModel): +class DocumentExtraction(BaseModel): """An extraction from a document.""" - id: uuid.UUID - type: ExtractionType = ExtractionType.TXT + id: UUID + document_id: UUID + group_ids: list[UUID] + user_id: UUID data: DataType metadata: dict - document_id: uuid.UUID - - -class FragmentType(Enum): - """A type of fragment that can be extracted from a document.""" - - TEXT = "text" - IMAGE = "image" - TABLE = "table" -class Fragment(BaseModel): +class DocumentFragment(BaseModel): """A fragment extracted from a document.""" - id: uuid.UUID - type: FragmentType + id: UUID + extraction_id: UUID + document_id: UUID + user_id: UUID + group_ids: list[UUID] data: DataType metadata: dict - document_id: uuid.UUID - extraction_id: uuid.UUID - - -class Entity(BaseModel): - """An entity extracted from a document.""" - - category: str - subcategory: Optional[str] = None - value: str - - def __str__(self): - return ( - f"{self.category}:{self.subcategory}:{self.value}" - if self.subcategory - else f"{self.category}:{self.value}" - ) - - -class Triple(BaseModel): - """A triple extracted from a document.""" - - subject: str - predicate: str - object: str - - -def extract_entities(llm_payload: list[str]) -> dict[str, Entity]: - entities = {} - for entry in llm_payload: - try: - if "], " in entry: # Check if the entry is an entity - entry_val = entry.split("], ")[0] + "]" - entry = entry.split("], ")[1] - colon_count = entry.count(":") - - if colon_count == 1: - category, value = entry.split(":") - subcategory = None - elif colon_count >= 2: - parts = entry.split(":", 2) - category, subcategory, value = ( - parts[0], - parts[1], - parts[2], - ) - else: - raise ValueError("Unexpected entry format") - - entities[entry_val] = Entity( - category=category, subcategory=subcategory, value=value - ) - except Exception as e: - logger.error(f"Error processing entity {entry}: {e}") - continue - return entities - - -def extract_triples( - llm_payload: list[str], entities: dict[str, Entity] -) -> list[Triple]: - triples = [] - for entry in llm_payload: - try: - if "], " not in entry: # Check if the entry is an entity - elements = entry.split(" ") - subject = elements[0] - predicate = elements[1] - object = " ".join(elements[2:]) - subject = entities[subject].value # Use entity.value - if "[" in object and "]" in object: - object = entities[object].value # Use entity.value - triples.append( - Triple(subject=subject, predicate=predicate, object=object) - ) - except Exception as e: - logger.error(f"Error processing triplet {entry}: {e}") - continue - return triples - - -class KGExtraction(BaseModel): - """An extraction from a document that is part of a knowledge graph.""" - - entities: dict[str, Entity] - triples: list[Triple] diff --git a/r2r/base/abstractions/graph.py b/r2r/base/abstractions/graph.py new file mode 100644 index 000000000..27300f131 --- /dev/null +++ b/r2r/base/abstractions/graph.py @@ -0,0 +1,452 @@ +import json +import logging +from collections.abc import Callable +from dataclasses import dataclass +from typing import Any, Optional, Union + +from pydantic import BaseModel + +logger = logging.getLogger(__name__) + + +@dataclass +class Identified: + """A protocol for an item with an ID.""" + + id: str + """The ID of the item.""" + + short_id: str | None + """Human readable ID used to refer to this community in prompts or texts displayed to users, such as in a report text (optional).""" + + +@dataclass +class Named(Identified): + """A protocol for an item with a name/title.""" + + title: str + """The name/title of the item.""" + + +class EntityType(BaseModel): + id: str + name: str + description: str | None = None + + +class RelationshipType(BaseModel): + id: str + name: str + description: str | None = None + + +class Entity(BaseModel): + """An entity extracted from a document.""" + + category: str + name: str + description: Optional[str] = None + description_embedding: list[float] = None + name_embedding: list[float] = None + graph_embedding: list[float] = None + community_ids: list[str] = None + text_unit_ids: list[str] = None + document_ids: list[str] = None + rank: int | None = 1 + attributes: dict[str, Any] | str = None + + def __str__(self): + return ( + f"{self.category}:{self.subcategory}:{self.value}" + if self.subcategory + else f"{self.category}:{self.value}" + ) + + def __init__(self, **kwargs): + super().__init__(**kwargs) + if isinstance(self.attributes, str): + try: + self.attributes = json.loads(self.attributes) + except Exception as e: + logger.error(f"Error loading attributes: {e}") + pass + + +class Triple(BaseModel): + """A relationship between two entities. This is a generic relationship, and can be used to represent any type of relationship between any two entities.""" + + subject: str | None = None + """The source entity name.""" + + predicate: str | None = None + """A description of the relationship (optional).""" + + object: str | None = None + """The target entity name.""" + + weight: float | None = 1.0 + """The edge weight.""" + + description: str | None = None + """A description of the relationship (optional).""" + + predicate_embedding: list[float] = [] + """The semantic embedding for the relationship description (optional).""" + + text_unit_ids: list[str] = [] + """List of text unit IDs in which the relationship appears (optional).""" + + document_ids: list[str] = [] + """List of document IDs in which the relationship appears (optional).""" + + attributes: dict[str, Any] | str = None + """Additional attributes associated with the relationship (optional). To be included in the search prompt""" + + def __init__(self, **kwargs): + super().__init__(**kwargs) + if isinstance(self.attributes, str): + self.attributes = json.loads(self.attributes) + + @classmethod + def from_dict( + cls, + d: dict[str, Any], + id_key: str = "id", + short_id_key: str = "short_id", + source_key: str = "subject", + target_key: str = "object", + predicate_key: str = "predicate", + description_key: str = "description", + weight_key: str = "weight", + text_unit_ids_key: str = "text_unit_ids", + document_ids_key: str = "document_ids", + attributes_key: str = "attributes", + ) -> "Triple": + """Create a new relationship from the dict data.""" + + return Triple( + id=d[id_key], + short_id=d.get(short_id_key), + subject=d[source_key], + object=d[target_key], + predicate=d.get(predicate_key), + description=d.get(description_key), + weight=d.get(weight_key, 1.0), + text_unit_ids=d.get(text_unit_ids_key), + document_ids=d.get(document_ids_key), + attributes=d.get(attributes_key, {}), + ) + + +@dataclass +class Community(BaseModel): + """A protocol for a community in the system.""" + + id: str + """The ID of the community.""" + + level: str = "" + """Community level.""" + + entity_ids: list[str] | None = None + """List of entity IDs related to the community (optional).""" + + relationship_ids: list[str] | None = None + """List of relationship IDs related to the community (optional).""" + + covariate_ids: dict[str, list[str]] | None = None + """Dictionary of different types of covariates related to the community (optional), e.g. claims""" + + attributes: dict[str, Any] | None = None + """A dictionary of additional attributes associated with the community (optional). To be included in the search prompt.""" + + summary: str = "" + """Summary of the report.""" + + full_content: str = "" + """Full content of the report.""" + + rank: float | None = 1.0 + """Rank of the report, used for sorting (optional). Higher means more important""" + + summary_embedding: list[float] | None = None + """The semantic (i.e. text) embedding of the report summary (optional).""" + + full_content_embedding: list[float] | None = None + """The semantic (i.e. text) embedding of the full report content (optional).""" + + def __init__(self, **kwargs): + super().__init__(**kwargs) + if isinstance(self.attributes, str): + self.attributes = json.loads(self.attributes) + + @classmethod + def from_dict( + cls, + d: dict[str, Any], + id_key: str = "id", + title_key: str = "title", + short_id_key: str = "short_id", + level_key: str = "level", + entities_key: str = "entity_ids", + relationships_key: str = "relationship_ids", + covariates_key: str = "covariate_ids", + attributes_key: str = "attributes", + ) -> "Community": + """Create a new community from the dict data.""" + return Community( + id=d[id_key], + title=d[title_key], + short_id=d.get(short_id_key), + level=d[level_key], + entity_ids=d.get(entities_key), + relationship_ids=d.get(relationships_key), + covariate_ids=d.get(covariates_key), + attributes=d.get(attributes_key), + ) + + +@dataclass +class CommunityReport(Named): + """Defines an LLM-generated summary report of a community.""" + + community_id: str + """The ID of the community this report is associated with.""" + + summary: str = "" + """Summary of the report.""" + + full_content: str = "" + """Full content of the report.""" + + rank: float | None = 1.0 + """Rank of the report, used for sorting (optional). Higher means more important""" + + summary_embedding: list[float] | None = None + """The semantic (i.e. text) embedding of the report summary (optional).""" + + full_content_embedding: list[float] | None = None + """The semantic (i.e. text) embedding of the full report content (optional).""" + + attributes: dict[str, Any] | None = None + """A dictionary of additional attributes associated with the report (optional).""" + + def __init__(self, **kwargs): + super().__init__(**kwargs) + if isinstance(self.attributes, str): + self.attributes = json.loads(self.attributes) + + @classmethod + def from_dict( + cls, + d: dict[str, Any], + id_key: str = "id", + title_key: str = "title", + community_id_key: str = "community_id", + short_id_key: str = "short_id", + summary_key: str = "summary", + full_content_key: str = "full_content", + rank_key: str = "rank", + summary_embedding_key: str = "summary_embedding", + full_content_embedding_key: str = "full_content_embedding", + attributes_key: str = "attributes", + ) -> "CommunityReport": + """Create a new community report from the dict data.""" + return CommunityReport( + id=d[id_key], + title=d[title_key], + community_id=d[community_id_key], + short_id=d.get(short_id_key), + summary=d[summary_key], + full_content=d[full_content_key], + rank=d[rank_key], + summary_embedding=d.get(summary_embedding_key), + full_content_embedding=d.get(full_content_embedding_key), + attributes=d.get(attributes_key), + ) + + +@dataclass +class Covariate(Identified): + """ + A protocol for a covariate in the system. + + Covariates are metadata associated with a subject, e.g. entity claims. + Each subject (e.g. entity) may be associated with multiple types of covariates. + """ + + subject_id: str + """The subject id.""" + + subject_type: str = "entity" + """The subject type.""" + + covariate_type: str = "claim" + """The covariate type.""" + + text_unit_ids: list[str] | None = None + """List of text unit IDs in which the covariate info appears (optional).""" + + document_ids: list[str] | None = None + """List of document IDs in which the covariate info appears (optional).""" + + attributes: dict[str, Any] | None = None + + def __init__(self, **kwargs): + super().__init__(**kwargs) + if isinstance(self.attributes, str): + self.attributes = json.loads(self.attributes) + + @classmethod + def from_dict( + cls, + d: dict[str, Any], + id_key: str = "id", + subject_id_key: str = "subject_id", + subject_type_key: str = "subject_type", + covariate_type_key: str = "covariate_type", + short_id_key: str = "short_id", + text_unit_ids_key: str = "text_unit_ids", + document_ids_key: str = "document_ids", + attributes_key: str = "attributes", + ) -> "Covariate": + """Create a new covariate from the dict data.""" + return Covariate( + id=d[id_key], + short_id=d.get(short_id_key), + subject_id=d[subject_id_key], + subject_type=d.get(subject_type_key, "entity"), + covariate_type=d.get(covariate_type_key, "claim"), + text_unit_ids=d.get(text_unit_ids_key), + document_ids=d.get(document_ids_key), + attributes=d.get(attributes_key), + ) + + +@dataclass +class TextUnit(Identified): + """A protocol for a TextUnit item in a Document database.""" + + text: str + """The text of the unit.""" + + text_embedding: list[float] | None = None + """The text embedding for the text unit (optional).""" + + entity_ids: list[str] | None = None + """List of entity IDs related to the text unit (optional).""" + + relationship_ids: list[str] | None = None + """List of relationship IDs related to the text unit (optional).""" + + covariate_ids: dict[str, list[str]] | None = None + "Dictionary of different types of covariates related to the text unit (optional)." + + n_tokens: int | None = None + """The number of tokens in the text (optional).""" + + document_ids: list[str] | None = None + """List of document IDs in which the text unit appears (optional).""" + + attributes: dict[str, Any] | None = None + """A dictionary of additional attributes associated with the text unit (optional).""" + + def __init__(self, **kwargs): + super().__init__(**kwargs) + if isinstance(self.attributes, str): + self.attributes = json.loads(self.attributes) + if isinstance(self.covariate_ids, str): + self.covariate_ids = json.loads(self.covariate_ids) + + @classmethod + def from_dict( + cls, + d: dict[str, Any], + id_key: str = "id", + short_id_key: str = "short_id", + text_key: str = "text", + text_embedding_key: str = "text_embedding", + entities_key: str = "entity_ids", + relationships_key: str = "relationship_ids", + covariates_key: str = "covariate_ids", + n_tokens_key: str = "n_tokens", + document_ids_key: str = "document_ids", + attributes_key: str = "attributes", + ) -> "TextUnit": + """Create a new text unit from the dict data.""" + return TextUnit( + id=d[id_key], + short_id=d.get(short_id_key), + text=d[text_key], + text_embedding=d.get(text_embedding_key), + entity_ids=d.get(entities_key), + relationship_ids=d.get(relationships_key), + covariate_ids=d.get(covariates_key), + n_tokens=d.get(n_tokens_key), + document_ids=d.get(document_ids_key), + attributes=d.get(attributes_key), + ) + + +TextEmbedder = Callable[[str], list[float]] + + +def extract_entities(llm_payload: list[str]) -> dict[str, Entity]: + entities = {} + for entry in llm_payload: + try: + if "], " in entry: # Check if the entry is an entity + entry_val = entry.split("], ")[0] + "]" + entry = entry.split("], ")[1] + colon_count = entry.count(":") + + if colon_count == 1: + category, value = entry.split(":") + subcategory = None + elif colon_count >= 2: + parts = entry.split(":", 2) + category, subcategory, value = ( + parts[0], + parts[1], + parts[2], + ) + else: + raise ValueError("Unexpected entry format") + + entities[entry_val] = Entity( + category=category, subcategory=subcategory, value=value + ) + except Exception as e: + logger.error(f"Error processing entity {entry}: {e}") + continue + return entities + + +def extract_triples( + llm_payload: list[str], entities: dict[str, Entity] +) -> list[Triple]: + triples = [] + for entry in llm_payload: + try: + if "], " not in entry: # Check if the entry is an entity + elements = entry.split(" ") + subject = elements[0] + predicate = elements[1] + object = " ".join(elements[2:]) + subject = entities[subject].value # Use entity.value + if "[" in object and "]" in object: + object = entities[object].value # Use entity.value + triples.append( + Triple(subject=subject, predicate=predicate, object=object) + ) + except Exception as e: + logger.error(f"Error processing triplet {entry}: {e}") + continue + return triples + + +class KGExtraction(BaseModel): + """An extraction from a document that is part of a knowledge graph.""" + + entities: Union[list[Entity], dict[str, Entity]] + triples: list[Triple] diff --git a/r2r/base/abstractions/llama_abstractions.py b/r2r/base/abstractions/llama_abstractions.py deleted file mode 100644 index f6bc36e62..000000000 --- a/r2r/base/abstractions/llama_abstractions.py +++ /dev/null @@ -1,439 +0,0 @@ -# abstractions are taken from LlamaIndex -# https://github.com/run-llama/llama_index -from abc import ABC, abstractmethod -from dataclasses import dataclass -from enum import Enum -from typing import Any, Dict, List, Optional, Tuple, Union - -from pydantic import BaseModel, Field, StrictFloat, StrictInt, StrictStr - - -class LabelledNode(BaseModel): - """An entity in a graph.""" - - label: str = Field(default="node", description="The label of the node.") - embedding: Optional[List[float]] = Field( - default=None, description="The embeddings of the node." - ) - properties: Dict[str, Any] = Field(default_factory=dict) - - @abstractmethod - def __str__(self) -> str: - """Return the string representation of the node.""" - ... - - @property - @abstractmethod - def id(self) -> str: - """Get the node id.""" - ... - - -class EntityNode(LabelledNode): - """An entity in a graph.""" - - name: str = Field(description="The name of the entity.") - label: str = Field(default="entity", description="The label of the node.") - properties: Dict[str, Any] = Field(default_factory=dict) - - def __str__(self) -> str: - """Return the string representation of the node.""" - return self.name - - @property - def id(self) -> str: - """Get the node id.""" - return self.name.replace('"', " ") - - -class ChunkNode(LabelledNode): - """A text chunk in a graph.""" - - text: str = Field(description="The text content of the chunk.") - id_: Optional[str] = Field( - default=None, - description="The id of the node. Defaults to a hash of the text.", - ) - label: str = Field( - default="text_chunk", description="The label of the node." - ) - properties: Dict[str, Any] = Field(default_factory=dict) - - def __str__(self) -> str: - """Return the string representation of the node.""" - return self.text - - @property - def id(self) -> str: - """Get the node id.""" - return str(hash(self.text)) if self.id_ is None else self.id_ - - -class Relation(BaseModel): - """A relation connecting two entities in a graph.""" - - label: str - source_id: str - target_id: str - properties: Dict[str, Any] = Field(default_factory=dict) - - def __str__(self) -> str: - """Return the string representation of the relation.""" - return self.label - - @property - def id(self) -> str: - """Get the relation id.""" - return self.label - - -Triplet = Tuple[LabelledNode, Relation, LabelledNode] - - -class VectorStoreQueryMode(str, Enum): - """Vector store query mode.""" - - DEFAULT = "default" - SPARSE = "sparse" - HYBRID = "hybrid" - TEXT_SEARCH = "text_search" - SEMANTIC_HYBRID = "semantic_hybrid" - - # fit learners - SVM = "svm" - LOGISTIC_REGRESSION = "logistic_regression" - LINEAR_REGRESSION = "linear_regression" - - # maximum marginal relevance - MMR = "mmr" - - -class FilterOperator(str, Enum): - """Vector store filter operator.""" - - # TODO add more operators - EQ = "==" # default operator (string, int, float) - GT = ">" # greater than (int, float) - LT = "<" # less than (int, float) - NE = "!=" # not equal to (string, int, float) - GTE = ">=" # greater than or equal to (int, float) - LTE = "<=" # less than or equal to (int, float) - IN = "in" # In array (string or number) - NIN = "nin" # Not in array (string or number) - ANY = "any" # Contains any (array of strings) - ALL = "all" # Contains all (array of strings) - TEXT_MATCH = "text_match" # full text match (allows you to search for a specific substring, token or phrase within the text field) - CONTAINS = "contains" # metadata array contains value (string or number) - - -class MetadataFilter(BaseModel): - """Comprehensive metadata filter for vector stores to support more operators. - - Value uses Strict* types, as int, float and str are compatible types and were all - converted to string before. - - See: https://docs.pydantic.dev/latest/usage/types/#strict-types - """ - - key: str - value: Union[ - StrictInt, - StrictFloat, - StrictStr, - List[StrictStr], - List[StrictFloat], - List[StrictInt], - ] - operator: FilterOperator = FilterOperator.EQ - - @classmethod - def from_dict( - cls, - filter_dict: Dict, - ) -> "MetadataFilter": - """Create MetadataFilter from dictionary. - - Args: - filter_dict: Dict with key, value and operator. - - """ - return MetadataFilter.parse_obj(filter_dict) - - -# # TODO: Deprecate ExactMatchFilter and use MetadataFilter instead -# # Keep class for now so that AutoRetriever can still work with old vector stores -# class ExactMatchFilter(BaseModel): -# key: str -# value: Union[StrictInt, StrictFloat, StrictStr] - -# set ExactMatchFilter to MetadataFilter -ExactMatchFilter = MetadataFilter - - -class FilterCondition(str, Enum): - """Vector store filter conditions to combine different filters.""" - - # TODO add more conditions - AND = "and" - OR = "or" - - -class MetadataFilters(BaseModel): - """Metadata filters for vector stores.""" - - # Exact match filters and Advanced filters with operators like >, <, >=, <=, !=, etc. - filters: List[Union[MetadataFilter, ExactMatchFilter, "MetadataFilters"]] - # and/or such conditions for combining different filters - condition: Optional[FilterCondition] = FilterCondition.AND - - -@dataclass -class VectorStoreQuery: - """Vector store query.""" - - query_embedding: Optional[List[float]] = None - similarity_top_k: int = 1 - doc_ids: Optional[List[str]] = None - node_ids: Optional[List[str]] = None - query_str: Optional[str] = None - output_fields: Optional[List[str]] = None - embedding_field: Optional[str] = None - - mode: VectorStoreQueryMode = VectorStoreQueryMode.DEFAULT - - # NOTE: only for hybrid search (0 for bm25, 1 for vector search) - alpha: Optional[float] = None - - # metadata filters - filters: Optional[MetadataFilters] = None - - # only for mmr - mmr_threshold: Optional[float] = None - - # NOTE: currently only used by postgres hybrid search - sparse_top_k: Optional[int] = None - # NOTE: return top k results from hybrid search. similarity_top_k is used for dense search top k - hybrid_top_k: Optional[int] = None - - -class PropertyGraphStore(ABC): - """Abstract labelled graph store protocol. - - This protocol defines the interface for a graph store, which is responsible - for storing and retrieving knowledge graph data. - - Attributes: - client: Any: The client used to connect to the graph store. - get: Callable[[str], List[List[str]]]: Get triplets for a given subject. - get_rel_map: Callable[[Optional[List[str]], int], Dict[str, List[List[str]]]]: - Get subjects' rel map in max depth. - upsert_triplet: Callable[[str, str, str], None]: Upsert a triplet. - delete: Callable[[str, str, str], None]: Delete a triplet. - persist: Callable[[str, Optional[fsspec.AbstractFileSystem]], None]: - Persist the graph store to a file. - """ - - supports_structured_queries: bool = False - supports_vector_queries: bool = False - - @property - def client(self) -> Any: - """Get client.""" - ... - - @abstractmethod - def get( - self, - properties: Optional[dict] = None, - ids: Optional[List[str]] = None, - ) -> List[LabelledNode]: - """Get nodes with matching values.""" - ... - - @abstractmethod - def get_triplets( - self, - entity_names: Optional[List[str]] = None, - relation_names: Optional[List[str]] = None, - properties: Optional[dict] = None, - ids: Optional[List[str]] = None, - ) -> List[Triplet]: - """Get triplets with matching values.""" - ... - - @abstractmethod - def get_rel_map( - self, - graph_nodes: List[LabelledNode], - depth: int = 2, - limit: int = 30, - ignore_rels: Optional[List[str]] = None, - ) -> List[Triplet]: - """Get depth-aware rel map.""" - ... - - @abstractmethod - def upsert_nodes(self, nodes: List[LabelledNode]) -> None: - """Upsert nodes.""" - ... - - @abstractmethod - def upsert_relations(self, relations: List[Relation]) -> None: - """Upsert relations.""" - ... - - @abstractmethod - def delete( - self, - entity_names: Optional[List[str]] = None, - relation_names: Optional[List[str]] = None, - properties: Optional[dict] = None, - ids: Optional[List[str]] = None, - ) -> None: - """Delete matching data.""" - ... - - @abstractmethod - def structured_query( - self, query: str, param_map: Optional[Dict[str, Any]] = None - ) -> Any: - """Query the graph store with statement and parameters.""" - ... - - @abstractmethod - def vector_query( - self, query: VectorStoreQuery, **kwargs: Any - ) -> Tuple[List[LabelledNode], List[float]]: - """Query the graph store with a vector store query.""" - ... - - # def persist( - # self, persist_path: str, fs: Optional[fsspec.AbstractFileSystem] = None - # ) -> None: - # """Persist the graph store to a file.""" - # return - - def get_schema(self, refresh: bool = False) -> Any: - """Get the schema of the graph store.""" - return None - - def get_schema_str(self, refresh: bool = False) -> str: - """Get the schema of the graph store as a string.""" - return str(self.get_schema(refresh=refresh)) - - ### ----- Async Methods ----- ### - - async def aget( - self, - properties: Optional[dict] = None, - ids: Optional[List[str]] = None, - ) -> List[LabelledNode]: - """Asynchronously get nodes with matching values.""" - return self.get(properties, ids) - - async def aget_triplets( - self, - entity_names: Optional[List[str]] = None, - relation_names: Optional[List[str]] = None, - properties: Optional[dict] = None, - ids: Optional[List[str]] = None, - ) -> List[Triplet]: - """Asynchronously get triplets with matching values.""" - return self.get_triplets(entity_names, relation_names, properties, ids) - - async def aget_rel_map( - self, - graph_nodes: List[LabelledNode], - depth: int = 2, - limit: int = 30, - ignore_rels: Optional[List[str]] = None, - ) -> List[Triplet]: - """Asynchronously get depth-aware rel map.""" - return self.get_rel_map(graph_nodes, depth, limit, ignore_rels) - - async def aupsert_nodes(self, nodes: List[LabelledNode]) -> None: - """Asynchronously add nodes.""" - return self.upsert_nodes(nodes) - - async def aupsert_relations(self, relations: List[Relation]) -> None: - """Asynchronously add relations.""" - return self.upsert_relations(relations) - - async def adelete( - self, - entity_names: Optional[List[str]] = None, - relation_names: Optional[List[str]] = None, - properties: Optional[dict] = None, - ids: Optional[List[str]] = None, - ) -> None: - """Asynchronously delete matching data.""" - return self.delete(entity_names, relation_names, properties, ids) - - async def astructured_query( - self, query: str, param_map: Optional[Dict[str, Any]] = {} - ) -> Any: - """Asynchronously query the graph store with statement and parameters.""" - return self.structured_query(query, param_map) - - async def avector_query( - self, query: VectorStoreQuery, **kwargs: Any - ) -> Tuple[List[LabelledNode], List[float]]: - """Asynchronously query the graph store with a vector store query.""" - return self.vector_query(query, **kwargs) - - async def aget_schema(self, refresh: bool = False) -> str: - """Asynchronously get the schema of the graph store.""" - return self.get_schema(refresh=refresh) - - async def aget_schema_str(self, refresh: bool = False) -> str: - """Asynchronously get the schema of the graph store as a string.""" - return str(await self.aget_schema(refresh=refresh)) - - -LIST_LIMIT = 128 - - -def clean_string_values(text: str) -> str: - return text.replace("\n", " ").replace("\r", " ") - - -def value_sanitize(d: Any) -> Any: - """Sanitize the input dictionary or list. - - Sanitizes the input by removing embedding-like values, - lists with more than 128 elements, that are mostly irrelevant for - generating answers in a LLM context. These properties, if left in - results, can occupy significant context space and detract from - the LLM's performance by introducing unnecessary noise and cost. - """ - if isinstance(d, dict): - new_dict = {} - for key, value in d.items(): - if isinstance(value, dict): - sanitized_value = value_sanitize(value) - if ( - sanitized_value is not None - ): # Check if the sanitized value is not None - new_dict[key] = sanitized_value - elif isinstance(value, list): - if len(value) < LIST_LIMIT: - sanitized_value = value_sanitize(value) - if ( - sanitized_value is not None - ): # Check if the sanitized value is not None - new_dict[key] = sanitized_value - # Do not include the key if the list is oversized - else: - new_dict[key] = value - return new_dict - elif isinstance(d, list): - if len(d) < LIST_LIMIT: - return [ - value_sanitize(item) - for item in d - if value_sanitize(item) is not None - ] - else: - return None - else: - return d diff --git a/r2r/base/abstractions/search.py b/r2r/base/abstractions/search.py index 401768168..6218ec33b 100644 --- a/r2r/base/abstractions/search.py +++ b/r2r/base/abstractions/search.py @@ -1,49 +1,62 @@ """Abstractions for search functionality.""" -import uuid +import json from typing import Any, Dict, List, Optional, Tuple +from uuid import UUID from pydantic import BaseModel, Field from .llm import GenerationConfig -class VectorSearchRequest(BaseModel): - """Request for a search operation.""" - - query: str - limit: int - filters: Optional[dict[str, Any]] = None - - class VectorSearchResult(BaseModel): """Result of a search operation.""" - id: uuid.UUID + fragment_id: UUID + extraction_id: UUID + document_id: UUID + user_id: UUID + group_ids: List[UUID] score: float + text: str metadata: dict[str, Any] def __str__(self) -> str: - return f"VectorSearchResult(id={self.id}, score={self.score}, metadata={self.metadata})" + return f"VectorSearchResult(fragment_id={self.fragment_id}, extraction_id={self.extraction_id}, document_id={self.document_id}, score={self.score})" def __repr__(self) -> str: - return f"VectorSearchResult(id={self.id}, score={self.score}, metadata={self.metadata})" + return self.__str__() def dict(self) -> dict: return { - "id": self.id, + "fragment_id": self.fragment_id, + "extraction_id": self.extraction_id, + "document_id": self.document_id, + "user_id": self.user_id, + "group_ids": self.group_ids, "score": self.score, + "text": self.text, "metadata": self.metadata, } + class Config: + schema_extra = [ + { + "fragment_id": "c68dc72e-fc23-5452-8f49-d7bd46088a96", + "extraction_id": "3f3d47f3-8baf-58eb-8bc2-0171fb1c6e09", + "document_id": "3e157b3a-8469-51db-90d9-52e7d896b49b", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "score": 0.23943702876567796, + "text": "Example text from the document", + "metadata": { + "title": "example_document.pdf", + "associatedQuery": "What is the capital of France?", + }, + } + ] -class KGSearchRequest(BaseModel): - """Request for a knowledge graph search operation.""" - query: str - - -# [query, ...] KGSearchResult = List[Tuple[str, List[Dict[str, Any]]]] @@ -71,16 +84,52 @@ def dict(self) -> dict: class VectorSearchSettings(BaseModel): - use_vector_search: bool = True - search_filters: dict[str, Any] = Field(default_factory=dict) - search_limit: int = 10 - do_hybrid_search: bool = False + use_vector_search: bool = Field( + default=True, description="Whether to use vector search" + ) + filters: dict[str, Any] = Field( + default_factory=dict, + description="Filters to apply to the vector search", + ) + search_limit: int = Field( + default=10, + description="Maximum number of results to return", + ge=1, + le=100, + ) + do_hybrid_search: bool = Field( + default=False, + description="Whether to perform a hybrid search (combining vector and keyword search)", + ) + selected_group_ids: List[UUID] = Field( + default_factory=list, + description="Group IDs to search for", + ) + + class Config: + json_encoders = {UUID: str} + + def model_dump(self, *args, **kwargs): + dump = super().model_dump(*args, **kwargs) + dump["selected_group_ids"] = [ + str(uuid) for uuid in dump["selected_group_ids"] + ] + return dump class KGSearchSettings(BaseModel): use_kg_search: bool = False + kg_search_type: str = "global" # 'global' or 'local' + kg_search_level: Optional[int] = None kg_search_generation_config: Optional[GenerationConfig] = Field( default_factory=GenerationConfig ) entity_types: list = [] relationships: list = [] + max_community_description_length: int = 4096 * 4 + max_llm_queries_for_global_search: int = 10 + local_search_limits: dict[str, int] = { + "__Entity__": 10, + "__Relationship__": 10, + "__Community__": 10, + } diff --git a/r2r/base/abstractions/user.py b/r2r/base/abstractions/user.py index b4045a6a6..5bc7229c8 100644 --- a/r2r/base/abstractions/user.py +++ b/r2r/base/abstractions/user.py @@ -1,31 +1,16 @@ from datetime import datetime -from typing import List, Optional +from typing import Optional from uuid import UUID -from pydantic import BaseModel, EmailStr, Field +from pydantic import BaseModel, Field from ..utils import generate_id_from_label -class UserBase(BaseModel): - email: EmailStr - - -class UserCreate(UserBase): - password: str - - -class User(BaseModel): - email: EmailStr +class Group(BaseModel): id: UUID = Field(default=None) - hashed_password: str - is_superuser: bool = False - is_active: bool = True - is_verified: bool = False - verification_code_expiry: Optional[datetime] = None - name: Optional[str] = None - bio: Optional[str] = None - profile_picture: Optional[str] = None + name: str + description: Optional[str] = None created_at: datetime = Field(default_factory=datetime.utcnow) updated_at: datetime = Field(default_factory=datetime.utcnow) @@ -35,19 +20,7 @@ class Config: def __init__(self, **data): super().__init__(**data) if self.id is None: - self.id = generate_id_from_label(self.email) - - -class UserResponse(UserBase): - id: UUID - is_superuser: bool - is_active: bool - is_verified: bool - created_at: datetime - updated_at: datetime - - class Config: - from_attributes = True + self.id = generate_id_from_label(self.name) class Token(BaseModel): @@ -65,4 +38,4 @@ class UserStats(BaseModel): user_id: UUID num_files: int total_size_in_bytes: int - document_ids: List[UUID] + document_ids: list[UUID] diff --git a/r2r/base/abstractions/vector.py b/r2r/base/abstractions/vector.py index 445f33025..b9ccfe61b 100644 --- a/r2r/base/abstractions/vector.py +++ b/r2r/base/abstractions/vector.py @@ -38,29 +38,40 @@ def __repr__(self) -> str: class VectorEntry: """A vector entry that can be stored directly in supported vector databases.""" - def __init__(self, id: UUID, vector: Vector, metadata: dict[str, Any]): + def __init__( + self, + fragment_id: UUID, + extraction_id: UUID, + document_id: UUID, + user_id: UUID, + group_ids: list[UUID], + vector: Vector, + text: str, + metadata: dict[str, Any], + ): """Create a new VectorEntry object.""" + self.fragment_id = fragment_id + self.extraction_id = extraction_id + self.document_id = document_id + self.user_id = user_id + self.group_ids = group_ids self.vector = vector - self.id = id + self.text = text self.metadata = metadata - def to_serializable(self) -> str: - """Return a serializable representation of the VectorEntry.""" - metadata = self.metadata - - for key in metadata: - if isinstance(metadata[key], UUID): - metadata[key] = str(metadata[key]) - return { - "id": str(self.id), - "vector": self.vector.data, - "metadata": metadata, - } - def __str__(self) -> str: """Return a string representation of the VectorEntry.""" - return f"VectorEntry(id={self.id}, vector={self.vector}, metadata={self.metadata})" + return ( + f"VectorEntry(fragment_id={self.fragment_id}, " + f"extraction_id={self.extraction_id}, " + f"document_id={self.document_id}, " + f"user_id={self.user_id}, " + f"group_ids={self.group_ids}, " + f"vector={self.vector}, " + f"text={self.text}, " + f"metadata={self.metadata})" + ) def __repr__(self) -> str: """Return an unambiguous string representation of the VectorEntry.""" - return f"VectorEntry(id={self.id}, vector={self.vector}, metadata={self.metadata})" + return self.__str__() diff --git a/r2r/base/agent/__init__.py b/r2r/base/agent/__init__.py new file mode 100644 index 000000000..0f31d707c --- /dev/null +++ b/r2r/base/agent/__init__.py @@ -0,0 +1,11 @@ +from .agent import Agent, AgentConfig, Conversation, Message, Tool, ToolResult + +__all__ = [ + # Agent abstractions + "Agent", + "AgentConfig", + "Conversation", + "Message", + "Tool", + "ToolResult", +] diff --git a/r2r/base/abstractions/agent.py b/r2r/base/agent/agent.py similarity index 88% rename from r2r/base/abstractions/agent.py rename to r2r/base/agent/agent.py index dc3af4c95..6bde2aa83 100644 --- a/r2r/base/abstractions/agent.py +++ b/r2r/base/agent/agent.py @@ -1,48 +1,17 @@ import json from abc import ABC, abstractmethod -from typing import ( - Any, - AsyncGenerator, - Callable, - Dict, - List, - Optional, - Type, - Union, -) +from typing import Any, AsyncGenerator, Dict, List, Optional, Type, Union from pydantic import BaseModel -from ..providers.llm import CompletionProvider, GenerationConfig -from ..providers.prompt import PromptProvider -from .completion import MessageType -from .llm import LLMChatCompletion - - -class Tool(BaseModel): - name: str - description: str - results_function: Callable - llm_format_function: Callable - stream_function: Optional[Callable] = None - parameters: Optional[Dict[str, Any]] = None - - class Config: - arbitrary_types_allowed = True - - -class ToolResult(BaseModel): - raw_result: Any - llm_formatted_result: str - stream_result: Optional[str] = None - +from r2r.base.abstractions import ( + GenerationConfig, + LLMChatCompletion, + MessageType, +) +from r2r.base.providers import CompletionProvider, PromptProvider -class Message(BaseModel): - role: Union[MessageType, str] - content: Optional[str] = None - name: Optional[str] = None - function_call: Optional[Dict[str, Any]] = None - tool_calls: Optional[List[Dict[str, Any]]] = None +from .base import Message, Tool, ToolResult class Conversation: diff --git a/r2r/base/agent/base.py b/r2r/base/agent/base.py new file mode 100644 index 000000000..e5d57c46c --- /dev/null +++ b/r2r/base/agent/base.py @@ -0,0 +1,31 @@ +from typing import Any, Callable, Dict, List, Optional, Union + +from pydantic import BaseModel + +from r2r.base.abstractions import MessageType + + +class Tool(BaseModel): + name: str + description: str + results_function: Callable + llm_format_function: Callable + stream_function: Optional[Callable] = None + parameters: Optional[Dict[str, Any]] = None + + class Config: + arbitrary_types_allowed = True + + +class ToolResult(BaseModel): + raw_result: Any + llm_formatted_result: str + stream_result: Optional[str] = None + + +class Message(BaseModel): + role: Union[MessageType, str] + content: Optional[str] = None + name: Optional[str] = None + function_call: Optional[Dict[str, Any]] = None + tool_calls: Optional[List[Dict[str, Any]]] = None diff --git a/r2r/base/api/models/__init__.py b/r2r/base/api/models/__init__.py new file mode 100644 index 000000000..d0afb1ec5 --- /dev/null +++ b/r2r/base/api/models/__init__.py @@ -0,0 +1,93 @@ +from .auth.responses import GenericMessageResponse, TokenResponse, UserResponse +from .ingestion.responses import ( + FailedDocument, + IngestionResponse, + ProcessedDocument, + WrappedIngestionResponse, +) +from .management.responses import ( + AnalyticsResponse, + AppSettingsResponse, + DeleteResponse, + DocumentChunkResponse, + DocumentOverviewResponse, + GroupOverviewResponse, + GroupResponse, + KnowledgeGraphResponse, + LogResponse, + PromptResponse, + ScoreCompletionResponse, + ServerStats, + UserOverviewResponse, + WrappedAddUserResponse, + WrappedAnalyticsResponse, + WrappedAppSettingsResponse, + WrappedDeleteResponse, + WrappedDocumentChunkResponse, + WrappedDocumentOverviewResponse, + WrappedGroupListResponse, + WrappedGroupOverviewResponse, + WrappedGroupResponse, + WrappedKnowledgeGraphResponse, + WrappedLogResponse, + WrappedPromptResponse, + WrappedScoreCompletionResponse, + WrappedServerStatsResponse, + WrappedUserOverviewResponse, +) +from .retrieval.responses import ( + RAGAgentResponse, + RAGResponse, + SearchResponse, + WrappedRAGAgentResponse, + WrappedRAGResponse, + WrappedSearchResponse, +) + +__all__ = [ + # Auth Responses + "GenericMessageResponse", + "TokenResponse", + "UserResponse", + # Ingestion Responses + "ProcessedDocument", + "FailedDocument", + "IngestionResponse", + "WrappedIngestionResponse", + # Management Responses + "PromptResponse", + "ServerStats", + "LogResponse", + "AnalyticsResponse", + "AppSettingsResponse", + "ScoreCompletionResponse", + "UserOverviewResponse", + "DeleteResponse", + "DocumentOverviewResponse", + "DocumentChunkResponse", + "KnowledgeGraphResponse", + "GroupResponse", + "GroupOverviewResponse", + "WrappedPromptResponse", + "WrappedServerStatsResponse", + "WrappedLogResponse", + "WrappedAnalyticsResponse", + "WrappedAppSettingsResponse", + "WrappedScoreCompletionResponse", + "WrappedUserOverviewResponse", + "WrappedDeleteResponse", + "WrappedDocumentOverviewResponse", + "WrappedDocumentChunkResponse", + "WrappedKnowledgeGraphResponse", + "WrappedGroupResponse", + "WrappedGroupListResponse", + "WrappedAddUserResponse", + "WrappedGroupOverviewResponse", + # Retrieval Responses + "SearchResponse", + "RAGResponse", + "RAGAgentResponse", + "WrappedSearchResponse", + "WrappedRAGResponse", + "WrappedRAGAgentResponse", +] diff --git a/r2r/base/api/models/auth/__init__.py b/r2r/base/api/models/auth/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/r2r/base/api/models/auth/responses.py b/r2r/base/api/models/auth/responses.py new file mode 100644 index 000000000..cc366a1b1 --- /dev/null +++ b/r2r/base/api/models/auth/responses.py @@ -0,0 +1,41 @@ +from datetime import datetime +from typing import Optional +from uuid import UUID + +from pydantic import BaseModel + +from r2r.base.abstractions import Token +from r2r.base.api.models.base import ResultsWrapper + + +class TokenResponse(BaseModel): + access_token: Token + refresh_token: Token + + +class UserResponse(BaseModel): + id: UUID + email: str + is_active: bool = True + is_superuser: bool = False + created_at: datetime = datetime.now() + updated_at: datetime = datetime.now() + is_verified: bool = False + group_ids: list[UUID] = [] + + # Optional fields (to update or set at creation) + hashed_password: Optional[str] = None + verification_code_expiry: Optional[datetime] = None + name: Optional[str] = None + bio: Optional[str] = None + profile_picture: Optional[str] = None + + +class GenericMessageResponse(BaseModel): + message: str + + +# Create wrapped versions of each response +WrappedTokenResponse = ResultsWrapper[TokenResponse] +WrappedUserResponse = ResultsWrapper[UserResponse] +WrappedGenericMessageResponse = ResultsWrapper[GenericMessageResponse] diff --git a/r2r/base/api/models/base.py b/r2r/base/api/models/base.py new file mode 100644 index 000000000..5c5af2d63 --- /dev/null +++ b/r2r/base/api/models/base.py @@ -0,0 +1,9 @@ +from typing import Generic, TypeVar + +from pydantic import BaseModel + +T = TypeVar("T") + + +class ResultsWrapper(BaseModel, Generic[T]): + results: T diff --git a/r2r/base/api/models/ingestion/__init__.py b/r2r/base/api/models/ingestion/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/r2r/base/api/models/ingestion/responses.py b/r2r/base/api/models/ingestion/responses.py new file mode 100644 index 000000000..76da3af35 --- /dev/null +++ b/r2r/base/api/models/ingestion/responses.py @@ -0,0 +1,77 @@ +from typing import Any, List, TypeVar +from uuid import UUID + +from pydantic import BaseModel, Field + +from r2r.base.api.models.base import ResultsWrapper + +T = TypeVar("T") + + +class ProcessedDocument(BaseModel): + id: UUID + title: str + + +class FailedDocument(BaseModel): + document_id: UUID + result: Any + + +class IngestionResponse(BaseModel): + processed_documents: List[ProcessedDocument] = Field( + ..., + description="List of successfully processed documents", + example=[ + { + "id": "123e4567-e89b-12d3-a456-426614174000", + "title": "Document 1", + }, + { + "id": "223e4567-e89b-12d3-a456-426614174000", + "title": "Document 2", + }, + ], + ) + failed_documents: List[FailedDocument] = Field( + ..., + description="List of documents that failed to process", + example=[ + { + "document_id": "323e4567-e89b-12d3-a456-426614174000", + "result": "Error: Invalid format", + } + ], + ) + skipped_documents: List[UUID] = Field( + ..., + description="List of document IDs that were skipped during processing", + example=["423e4567-e89b-12d3-a456-426614174000"], + ) + + class Config: + schema_extra = { + "example": { + "processed_documents": [ + { + "id": "123e4567-e89b-12d3-a456-426614174000", + "title": "Document 1", + }, + { + "id": "223e4567-e89b-12d3-a456-426614174000", + "title": "Document 2", + }, + ], + "failed_documents": [ + { + "document_id": "323e4567-e89b-12d3-a456-426614174000", + "result": "Error: Invalid format", + } + ], + "skipped_documents": ["423e4567-e89b-12d3-a456-426614174000"], + } + } + + +# Create wrapped version of the response +WrappedIngestionResponse = ResultsWrapper[IngestionResponse] diff --git a/r2r/base/api/models/management/__init__.py b/r2r/base/api/models/management/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/r2r/base/api/models/management/responses.py b/r2r/base/api/models/management/responses.py new file mode 100644 index 000000000..de5da333e --- /dev/null +++ b/r2r/base/api/models/management/responses.py @@ -0,0 +1,126 @@ +from datetime import datetime +from typing import Any, Dict, List, Optional +from uuid import UUID + +from pydantic import BaseModel + +from r2r.base.api.models.base import ResultsWrapper + + +class PromptResponse(BaseModel): + message: str + + +class LogEntry(BaseModel): + key: str + value: Any + timestamp: datetime + + +class LogResponse(BaseModel): + run_id: UUID + run_type: str + entries: List[LogEntry] + timestamp: Optional[datetime] + user_id: Optional[UUID] + + +class ServerStats(BaseModel): + start_time: datetime + uptime_seconds: float + cpu_usage: float + memory_usage: float + + +class AnalyticsResponse(BaseModel): + analytics_data: Any + filtered_logs: Dict[str, Any] + + +class AppSettingsResponse(BaseModel): + config: Dict[str, Any] + prompts: Dict[str, Any] + + +class ScoreCompletionResponse(BaseModel): + message: str + + +class UserOverviewResponse(BaseModel): + user_id: UUID + num_files: int + total_size_in_bytes: int + document_ids: List[UUID] + + +class DeleteResponse(BaseModel): + fragment_id: UUID + document_id: UUID + extraction_id: UUID + text: str + + +class DocumentOverviewResponse(BaseModel): + id: UUID + title: str + user_id: UUID + type: str + created_at: datetime + updated_at: datetime + status: str + version: str + + +class DocumentChunkResponse(BaseModel): + fragment_id: UUID + extraction_id: UUID + document_id: UUID + user_id: UUID + group_ids: list[UUID] + text: str + metadata: Dict[str, Any] + + +KnowledgeGraphResponse = str + + +class GroupResponse(BaseModel): + group_id: UUID + name: str + description: Optional[str] + created_at: datetime + updated_at: datetime + + +class GroupOverviewResponse(BaseModel): + group_id: UUID + name: str + description: Optional[str] + created_at: datetime + updated_at: datetime + user_count: int + document_count: int + + +class AddUserResponse(BaseModel): + result: bool + + +# Create wrapped versions of each response +WrappedPromptResponse = ResultsWrapper[PromptResponse] +WrappedServerStatsResponse = ResultsWrapper[ServerStats] +WrappedLogResponse = ResultsWrapper[List[LogResponse]] +WrappedAnalyticsResponse = ResultsWrapper[AnalyticsResponse] +WrappedAppSettingsResponse = ResultsWrapper[AppSettingsResponse] +WrappedScoreCompletionResponse = ResultsWrapper[ScoreCompletionResponse] +WrappedUserOverviewResponse = ResultsWrapper[List[UserOverviewResponse]] +WrappedDeleteResponse = ResultsWrapper[dict[str, DeleteResponse]] +WrappedDocumentOverviewResponse = ResultsWrapper[ + List[DocumentOverviewResponse] +] +WrappedDocumentChunkResponse = ResultsWrapper[List[DocumentChunkResponse]] +WrappedKnowledgeGraphResponse = ResultsWrapper[KnowledgeGraphResponse] +WrappedGroupResponse = ResultsWrapper[GroupResponse] +WrappedGroupListResponse = ResultsWrapper[List[GroupResponse]] +WrappedGroupOverviewResponse = ResultsWrapper[List[GroupOverviewResponse]] +WrappedAddUserResponse = ResultsWrapper[AddUserResponse] diff --git a/r2r/base/api/models/retrieval/__init__.py b/r2r/base/api/models/retrieval/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/r2r/base/api/models/retrieval/responses.py b/r2r/base/api/models/retrieval/responses.py new file mode 100644 index 000000000..b609b9a2b --- /dev/null +++ b/r2r/base/api/models/retrieval/responses.py @@ -0,0 +1,149 @@ +from typing import Any, List, Optional + +from pydantic import BaseModel, Field + +from r2r.base.abstractions.search import KGSearchResult, VectorSearchResult +from r2r.base.api.models.base import ResultsWrapper + + +class SearchResponse(BaseModel): + vector_search_results: List[VectorSearchResult] = Field( + ..., + description="List of vector search results", + ) + kg_search_results: Optional[KGSearchResult] = Field( + None, + description="Knowledge graph search results, if applicable", + ) + + class Config: + schema_extra = { + "example": { + "vector_search_results": [ + { + "fragment_id": "c68dc72e-fc23-5452-8f49-d7bd46088a96", + "extraction_id": "3f3d47f3-8baf-58eb-8bc2-0171fb1c6e09", + "document_id": "3e157b3a-8469-51db-90d9-52e7d896b49b", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "score": 0.23943702876567796, + "text": "Example text from the document", + "metadata": { + "title": "example_document.pdf", + "associatedQuery": "What is the capital of France?", + }, + } + ], + "kg_search_results": None, + } + } + + +class RAGResponse(BaseModel): + completion: Any = Field( + ..., + description="The generated completion from the RAG process", + ) + search_results: SearchResponse = Field( + ..., + description="The search results used for the RAG process", + ) + + class Config: + schema_extra = { + "example": { + "completion": { + "id": "chatcmpl-example123", + "choices": [ + { + "finish_reason": "stop", + "index": 0, + "logprobs": None, + "message": { + "content": "Paris is the capital of France.", + "role": "assistant", + }, + } + ], + }, + "search_results": { + "vector_search_results": [ + { + "fragment_id": "c68dc72e-fc23-5452-8f49-d7bd46088a96", + "extraction_id": "3f3d47f3-8baf-58eb-8bc2-0171fb1c6e09", + "document_id": "3e157b3a-8469-51db-90d9-52e7d896b49b", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "score": 0.23943702876567796, + "text": "Paris is the capital and most populous city of France.", + "metadata": { + "text": "Paris is the capital and most populous city of France.", + "title": "france_info.pdf", + "associatedQuery": "What is the capital of France?", + }, + } + ], + "kg_search_results": None, + }, + } + } + + +class RAGAgentResponse(BaseModel): + completion: Any = Field( + ..., + description="The generated completion from the RAG agent process", + ) + search_results: SearchResponse = Field( + ..., + description="The search results used for the RAG agent process", + ) + thought_process: Optional[str] = Field( + None, + description="The agent's thought process or reasoning", + ) + + class Config: + schema_extra = { + "example": { + "completion": { + "id": "chatcmpl-example456", + "choices": [ + { + "finish_reason": "stop", + "index": 0, + "logprobs": None, + "message": { + "content": "The capital of France is Paris. Paris is not only the capital but also the largest city in France, known for its iconic landmarks such as the Eiffel Tower, the Louvre Museum, and Notre-Dame Cathedral.", + "role": "assistant", + }, + } + ], + }, + "search_results": { + "vector_search_results": [ + { + "fragment_id": "d79ef23a-fc23-5452-8f49-d7bd46088a96", + "extraction_id": "4f3d47f3-8baf-58eb-8bc2-0171fb1c6e09", + "document_id": "5e157b3a-8469-51db-90d9-52e7d896b49b", + "user_id": "3acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "score": 0.89943702876567796, + "text": "Paris is the capital and most populous city of France. It is known for its iconic landmarks such as the Eiffel Tower, the Louvre Museum, and Notre-Dame Cathedral.", + "metadata": { + "title": "france_geography.pdf", + "associatedQuery": "What is the capital of France?", + }, + } + ], + "kg_search_results": None, + }, + "thought_process": "To answer this question, I'll need to search for information about France's capital. The search results provide clear information about Paris being the capital of France, along with some additional details about its landmarks.", + } + } + + +# Create wrapped versions of the responses +WrappedSearchResponse = ResultsWrapper[SearchResponse] +WrappedRAGResponse = ResultsWrapper[RAGResponse] +WrappedRAGAgentResponse = ResultsWrapper[RAGAgentResponse] diff --git a/r2r/base/logging/__init__.py b/r2r/base/logging/__init__.py index e69de29bb..e72199005 100644 --- a/r2r/base/logging/__init__.py +++ b/r2r/base/logging/__init__.py @@ -0,0 +1,39 @@ +from .base import RunType +from .log_processor import ( + AnalysisTypes, + LogAnalytics, + LogAnalyticsConfig, + LogFilterCriteria, + LogProcessor, +) +from .run_logger import ( + LocalRunLoggingProvider, + LoggingConfig, + PostgresLoggingConfig, + PostgresRunLoggingProvider, + RedisLoggingConfig, + RedisRunLoggingProvider, + RunLoggingSingleton, +) +from .run_manager import RunManager, manage_run + +__all__ = [ + # Basic types + "RunType", + "AnalysisTypes", + "LogAnalytics", + "LogAnalyticsConfig", + "LogFilterCriteria", + "LogProcessor", + # Logging Providers + "LocalRunLoggingProvider", + "LoggingConfig", + "PostgresLoggingConfig", + "PostgresRunLoggingProvider", + "RedisLoggingConfig", + "RedisRunLoggingProvider", + "RunLoggingSingleton", + # Run Manager + "RunManager", + "manage_run", +] diff --git a/r2r/base/logging/base.py b/r2r/base/logging/base.py new file mode 100644 index 000000000..fed478cb2 --- /dev/null +++ b/r2r/base/logging/base.py @@ -0,0 +1,11 @@ +from enum import Enum + + +class RunType(str, Enum): + """Enumeration of the different types of runs.""" + + RETRIEVAL = "RETRIEVAL" + MANAGEMENT = "MANAGEMENT" + INGESTION = "INGESTION" + AUTH = "AUTH" + UNSPECIFIED = "UNSPECIFIED" diff --git a/r2r/base/logging/log_processor.py b/r2r/base/logging/log_processor.py index e85d8de2e..4953016f7 100644 --- a/r2r/base/logging/log_processor.py +++ b/r2r/base/logging/log_processor.py @@ -10,7 +10,7 @@ logger = logging.getLogger(__name__) -class FilterCriteria(BaseModel): +class LogFilterCriteria(BaseModel): filters: Optional[dict[str, str]] = None diff --git a/r2r/base/logging/kv_logger.py b/r2r/base/logging/run_logger.py similarity index 55% rename from r2r/base/logging/kv_logger.py rename to r2r/base/logging/run_logger.py index 39db60eea..84d8ad23e 100644 --- a/r2r/base/logging/kv_logger.py +++ b/r2r/base/logging/run_logger.py @@ -1,25 +1,25 @@ import json import logging import os -import uuid from abc import abstractmethod from datetime import datetime from typing import Optional +from uuid import UUID import asyncpg from pydantic import BaseModel from ..providers.base import Provider, ProviderConfig +from .base import RunType logger = logging.getLogger(__name__) -# Todo: make user_id required in version 0.3.0 -class RunInfo(BaseModel): - run_id: uuid.UUID - log_type: str +class RunInfoLog(BaseModel): + run_id: UUID + run_type: str timestamp: datetime - user_id: Optional[str] = None + user_id: UUID class LoggingConfig(ProviderConfig): @@ -36,7 +36,7 @@ def supported_providers(self) -> list[str]: return ["local", "postgres", "redis"] -class KVLoggingProvider(Provider): +class RunLoggingProvider(Provider): @abstractmethod async def close(self): pass @@ -44,37 +44,46 @@ async def close(self): @abstractmethod async def log( self, - log_id: uuid.UUID, + run_id: UUID, key: str, value: str, - user_id: Optional[str] = None, ): pass @abstractmethod - async def get_run_info( + async def get_logs( self, - limit: int = 10, - log_type_filter: Optional[str] = None, - ) -> list[RunInfo]: + run_ids: list[UUID], + limit_per_run: int, + ) -> list: pass @abstractmethod - async def get_logs( + async def info_log( self, - run_ids: list[uuid.UUID], - limit_per_run: int, - ) -> list: + run_id: UUID, + run_type: RunType, + user_id: UUID, + ): + pass + + @abstractmethod + async def get_info_logs( + self, + limit: int = 10, + run_type_filter: Optional[RunType] = None, + user_ids: Optional[list[UUID]] = None, + ) -> list[RunInfoLog]: pass @abstractmethod async def score_completion( - self, log_id: uuid.UUID, message_id: uuid.UUID, score: float - ): + self, run_id: UUID, message_id: UUID, score: float + ) -> str: pass -class LocalKVLoggingProvider(KVLoggingProvider): +class LocalRunLoggingProvider(RunLoggingProvider): def __init__(self, config: LoggingConfig): self.log_table = config.log_table self.log_info_table = config.log_info_table @@ -92,19 +101,18 @@ def __init__(self, config: LoggingConfig): self.aiosqlite = aiosqlite except ImportError: raise ImportError( - "Please install aiosqlite to use the LocalKVLoggingProvider." + "Please install aiosqlite to use the LocalRunLoggingProvider." ) - async def init(self): + async def _init(self): self.conn = await self.aiosqlite.connect(self.logging_path) await self.conn.execute( f""" CREATE TABLE IF NOT EXISTS {self.log_table} ( timestamp DATETIME, - log_id TEXT, + run_id TEXT, key TEXT, - value TEXT, - user_id TEXT + value TEXT ) """ ) @@ -112,26 +120,17 @@ async def init(self): f""" CREATE TABLE IF NOT EXISTS {self.log_info_table} ( timestamp DATETIME, - log_id TEXT UNIQUE, - log_type TEXT, + run_id TEXT UNIQUE, + run_type TEXT, user_id TEXT ) """ ) await self.conn.commit() - # TODO: deprecated, remove in version 0.3.0 - cursor = await self.conn.execute( - f"PRAGMA table_info({self.log_table})" - ) - columns = await cursor.fetchall() - self.has_user_id = any( - column[1].lower() == "user_id" for column in columns - ) - async def __aenter__(self): if self.conn is None: - await self.init() + await self._init() return self async def __aexit__(self, exc_type, exc_val, exc_tb): @@ -144,82 +143,55 @@ async def close(self): async def log( self, - log_id: uuid.UUID, + run_id: UUID, key: str, value: str, - user_id: Optional[str] = None, - is_info_log=False, ): - collection = self.log_info_table if is_info_log else self.log_table - - # TODO: deprecated, remove in version 0.3.0 - if not self.has_user_id: - # TODO: add in link to migration guide - logger.warning( - "Logs excluding user ids are deprecated and will be removed in version 0.3.0. Please run `r2r migrate` to run database migrations." - ) - - # TODO: deprecated, remove conditional check in v0.3.0 - if is_info_log: - if "type" not in key: - raise ValueError("Info log keys must contain the text 'type'") - if self.has_user_id: - await self.conn.execute( - f""" - INSERT INTO {collection} (timestamp, log_id, log_type, user_id) - VALUES (datetime('now'), ?, ?, ?) - ON CONFLICT(log_id) DO UPDATE SET - timestamp = datetime('now'), - log_type = excluded.log_type, - user_id = excluded.user_id - """, - (str(log_id), value, str(user_id)), - ) - else: - await self.conn.execute( - f""" - INSERT INTO {collection} (timestamp, log_id, log_type, user_id) - VALUES (datetime('now'), ?, ?) - ON CONFLICT(log_id) DO UPDATE SET - timestamp = datetime('now'), - log_type = excluded.log_type, - """, - (str(log_id), value, str(user_id)), - ) - elif self.has_user_id: - await self.conn.execute( - f""" - INSERT INTO {collection} (timestamp, log_id, key, value, user_id) - VALUES (datetime('now'), ?, ?, ?, ?) - """, - (str(log_id), key, value, str(user_id)), - ) - else: - await self.conn.execute( - f""" - INSERT INTO {collection} (timestamp, log_id, key, value) - VALUES (datetime('now'), ?, ?, ?) - """, - (str(log_id), key, value), - ) + await self.conn.execute( + f""" + INSERT INTO {self.log_table} (timestamp, run_id, key, value) + VALUES (datetime('now'), ?, ?, ?) + """, + (str(run_id), key, value), + ) + await self.conn.commit() + async def info_log( + self, + run_id: UUID, + run_type: RunType, + user_id: UUID, + ): + await self.conn.execute( + f""" + INSERT INTO {self.log_info_table} (timestamp, run_id, run_type, user_id) + VALUES (datetime('now'), ?, ?, ?) + ON CONFLICT(run_id) DO UPDATE SET + timestamp = datetime('now'), + run_type = excluded.run_type, + user_id = excluded.user_id + """, + (str(run_id), run_type, str(user_id)), + ) await self.conn.commit() - async def get_run_info( + async def get_info_logs( self, limit: int = 10, - log_type_filter: Optional[str] = None, - ) -> list[RunInfo]: + run_type_filter: Optional[RunType] = None, + user_ids: Optional[list[UUID]] = None, + ) -> list[RunInfoLog]: cursor = await self.conn.cursor() - query = "SELECT log_id, log_type, timestamp" - if self.has_user_id: - query += ", user_id" + query = "SELECT run_id, run_type, timestamp, user_id" query += f" FROM {self.log_info_table}" conditions = [] params = [] - if log_type_filter: - conditions.append("log_type = ?") - params.append(log_type_filter) + if run_type_filter: + conditions.append("run_type = ?") + params.append(run_type_filter) + if user_ids: + conditions.append(f"user_id IN ({','.join(['?']*len(user_ids))})") + params.extend([str(user_id) for user_id in user_ids]) if conditions: query += " WHERE " + " AND ".join(conditions) query += " ORDER BY timestamp DESC LIMIT ?" @@ -227,53 +199,59 @@ async def get_run_info( await cursor.execute(query, params) rows = await cursor.fetchall() return [ - RunInfo( - run_id=uuid.UUID(row[0]), - log_type=row[1], + RunInfoLog( + run_id=UUID(row[0]), + run_type=row[1], timestamp=datetime.fromisoformat(row[2]), - user_id=row[3] if self.has_user_id and len(row) > 3 else None, + user_id=UUID(row[3]), ) for row in rows ] async def get_logs( self, - run_ids: list[uuid.UUID], + run_ids: list[UUID], limit_per_run: int = 10, ) -> list: if not run_ids: raise ValueError("No run ids provided.") cursor = await self.conn.cursor() placeholders = ",".join(["?" for _ in run_ids]) - query = "SELECT log_id, key, value, timestamp" - # TODO: unnecessary to check - if self.has_user_id: - query += ", user_id" - query += f""" - FROM ( - SELECT *, ROW_NUMBER() OVER (PARTITION BY log_id ORDER BY timestamp DESC) as rn - FROM {self.log_table} - WHERE log_id IN ({placeholders}) - ) - WHERE rn <= ? + query = f""" + SELECT run_id, key, value, timestamp + FROM {self.log_table} + WHERE run_id IN ({placeholders}) ORDER BY timestamp DESC """ - params = [str(ele) for ele in run_ids] + [limit_per_run] + params = [str(run_id) for run_id in run_ids] + await cursor.execute(query, params) rows = await cursor.fetchall() - return [ - dict(zip([d[0] for d in cursor.description], row)) for row in rows - ] + + # Post-process the results to limit per run_id and ensure only requested run_ids are included + result = [] + run_id_count = {str(run_id): 0 for run_id in run_ids} + for row in rows: + row_dict = dict(zip([d[0] for d in cursor.description], row)) + row_run_id = row_dict["run_id"] + if ( + row_run_id in run_id_count + and run_id_count[row_run_id] < limit_per_run + ): + row_dict["run_id"] = UUID(row_dict["run_id"]) + result.append(row_dict) + run_id_count[row_run_id] += 1 + return result async def score_completion( - self, log_id: uuid.UUID, message_id: uuid.UUID, score: float + self, run_id: UUID, message_id: UUID, score: float ): cursor = await self.conn.cursor() await cursor.execute( - f"SELECT value FROM {self.log_table} WHERE log_id = ? AND key = 'completion_record'", - (str(log_id),), + f"SELECT value FROM {self.log_table} WHERE run_id = ? AND key = 'completion_record'", + (str(run_id),), ) row = await cursor.fetchone() @@ -298,13 +276,13 @@ async def score_completion( ] await cursor.execute( - f"UPDATE {self.log_table} SET value = ? WHERE log_id = ? AND key = 'completion_record'", - (json.dumps(completion_record), str(log_id)), + f"UPDATE {self.log_table} SET value = ? WHERE run_id = ? AND key = 'completion_record'", + (json.dumps(completion_record), str(run_id)), ) await self.conn.commit() - return True + return {"message": "Score updated successfully."} - return False + return {"message": "Score not updated."} class PostgresLoggingConfig(LoggingConfig): @@ -329,13 +307,12 @@ def supported_providers(self) -> list[str]: return ["postgres"] -class PostgresKVLoggingProvider(KVLoggingProvider): +class PostgresRunLoggingProvider(RunLoggingProvider): def __init__(self, config: PostgresLoggingConfig): self.log_table = config.log_table self.log_info_table = config.log_info_table self.config = config self.pool = None - self.has_user_id = False if not os.getenv("POSTGRES_DBNAME"): raise ValueError( "Please set the environment variable POSTGRES_DBNAME." @@ -357,7 +334,7 @@ def __init__(self, config: PostgresLoggingConfig): "Please set the environment variable POSTGRES_PORT." ) - async def init(self): + async def _init(self): self.pool = await asyncpg.create_pool( database=os.getenv("POSTGRES_DBNAME"), user=os.getenv("POSTGRES_USER"), @@ -371,10 +348,9 @@ async def init(self): f""" CREATE TABLE IF NOT EXISTS {self.log_table} ( timestamp TIMESTAMPTZ, - log_id UUID, + run_id UUID, key TEXT, - value TEXT, - user_id TEXT + value TEXT ) """ ) @@ -382,24 +358,16 @@ async def init(self): f""" CREATE TABLE IF NOT EXISTS {self.log_info_table} ( timestamp TIMESTAMPTZ, - log_id UUID UNIQUE, - log_type TEXT, - user_id TEXT + run_id UUID UNIQUE, + run_type TEXT, + user_id UUID ) """ ) - # TODO: deprecated, remove in version 0.3.0 - columns = await conn.fetch( - f"SELECT column_name FROM information_schema.columns WHERE table_name = '{self.log_table}'" - ) - self.has_user_id = any( - column["column_name"] == "user_id" for column in columns - ) - async def __aenter__(self): if self.pool is None: - await self.init() + await self._init() return self async def __aexit__(self, exc_type, exc_val, exc_tb): @@ -412,88 +380,73 @@ async def close(self): async def log( self, - log_id: uuid.UUID, + run_id: UUID, key: str, value: str, - user_id: Optional[str] = None, - is_info_log=False, ): - collection = self.log_info_table if is_info_log else self.log_table - - # TODO: deprecated, remove in version 0.3.0 - if not self.has_user_id: - logger.warning( - "Logs excluding user ids are deprecated and will be removed in version 0.3.0. Please run `r2r migrate` to run database migrations." + async with self.pool.acquire() as conn: + await conn.execute( + f"INSERT INTO {self.log_table} (timestamp, run_id, key, value) VALUES (NOW(), $1, $2, $3)", + run_id, + key, + value, ) - # TODO: deprecated, remove conditional check in v0.3.0 - if is_info_log: - if "type" not in key: - raise ValueError( - "Info log key must contain the string `type`." - ) - async with self.pool.acquire() as conn: - if self.has_user_id: - await conn.execute( - f"INSERT INTO {collection} (timestamp, log_id, log_type, user_id) VALUES (NOW(), $1, $2, $3)", - log_id, - value, - user_id, - ) - else: - await conn.execute( - f"INSERT INTO {collection} (timestamp, log_id, log_type) VALUES (NOW(), $1, $2)", - log_id, - value, - ) - else: - async with self.pool.acquire() as conn: - if self.has_user_id: - await conn.execute( - f"INSERT INTO {collection} (timestamp, log_id, key, value, user_id) VALUES (NOW(), $1, $2, $3, $4)", - log_id, - key, - value, - user_id, - ) - else: - await conn.execute( - f"INSERT INTO {collection} (timestamp, log_id, key, value) VALUES (NOW(), $1, $2, $3)", - log_id, - key, - value, - ) + async def info_log( + self, + run_id: UUID, + run_type: RunType, + user_id: UUID, + ): + async with self.pool.acquire() as conn: + await conn.execute( + f"INSERT INTO {self.log_info_table} (timestamp, run_id, run_type, user_id) VALUES (NOW(), $1, $2, $3)", + run_id, + run_type, + user_id, + ) - async def get_run_info( - self, limit: int = 10, log_type_filter: Optional[str] = None - ) -> list[RunInfo]: - query = "SELECT log_id, log_type, timestamp" - if self.has_user_id: - query += ", user_id" - query += f" FROM {self.log_info_table}" + async def get_info_logs( + self, + limit: int = 10, + run_type_filter: Optional[RunType] = None, + user_ids: Optional[list[UUID]] = None, + ) -> list[RunInfoLog]: + query = f"SELECT run_id, run_type, timestamp, user_id FROM {self.log_info_table}" conditions = [] params = [] - if log_type_filter: - conditions.append("log_type = $1") - params.append(log_type_filter) + param_count = 1 + + if run_type_filter: + conditions.append(f"run_type = ${param_count}") + params.append(run_type_filter) + param_count += 1 + + if user_ids: + conditions.append(f"user_id = ANY(${param_count}::uuid[])") + params.append(user_ids) + param_count += 1 + if conditions: query += " WHERE " + " AND ".join(conditions) - query += " ORDER BY timestamp DESC LIMIT $2" + + query += f" ORDER BY timestamp DESC LIMIT ${param_count}" params.append(limit) + async with self.pool.acquire() as conn: rows = await conn.fetch(query, *params) return [ - RunInfo( - run_id=row["log_id"], - log_type=row["log_type"], + RunInfoLog( + run_id=row["run_id"], + run_type=row["run_type"], timestamp=row["timestamp"], - user_id=row["user_id"] if self.has_user_id else None, + user_id=row["user_id"], ) for row in rows ] async def get_logs( - self, run_ids: list[uuid.UUID], limit_per_run: int = 10 + self, run_ids: list[UUID], limit_per_run: int = 10 ) -> list: if not run_ids: raise ValueError("No run ids provided.") @@ -501,9 +454,9 @@ async def get_logs( placeholders = ",".join([f"${i + 1}" for i in range(len(run_ids))]) query = f""" SELECT * FROM ( - SELECT *, ROW_NUMBER() OVER (PARTITION BY log_id ORDER BY timestamp DESC) as rn + SELECT *, ROW_NUMBER() OVER (PARTITION BY run_id ORDER BY timestamp DESC) as rn FROM {self.log_table} - WHERE log_id::text IN ({placeholders}) + WHERE run_id::text IN ({placeholders}) ) sub WHERE sub.rn <= ${len(run_ids) + 1} ORDER BY sub.timestamp DESC @@ -514,12 +467,12 @@ async def get_logs( return [{key: row[key] for key in row.keys()} for row in rows] async def score_completion( - self, log_id: uuid.UUID, message_id: uuid.UUID, score: float + self, run_id: UUID, message_id: UUID, score: float ): async with self.pool.acquire() as conn: row = await conn.fetchrow( - f"SELECT value FROM {self.log_table} WHERE log_id = $1 AND key = 'completion_record'", - log_id, + f"SELECT value FROM {self.log_table} WHERE run_id = $1 AND key = 'completion_record'", + run_id, ) if row: @@ -545,13 +498,13 @@ async def score_completion( ] await conn.execute( - f"UPDATE {self.log_table} SET value = $1 WHERE log_id = $2 AND key = 'completion_record'", + f"UPDATE {self.log_table} SET value = $1 WHERE run_id = $2 AND key = 'completion_record'", json.dumps(completion_record), - log_id, + run_id, ) - return True + return {"message": "Score updated successfully."} - return False + return {"message": "Score not updated."} class RedisLoggingConfig(LoggingConfig): @@ -570,10 +523,10 @@ def supported_providers(self) -> list[str]: return ["redis"] -class RedisKVLoggingProvider(KVLoggingProvider): +class RedisRunLoggingProvider(RunLoggingProvider): def __init__(self, config: RedisLoggingConfig): logger.info( - f"Initializing RedisKVLoggingProvider with config: {config}" + f"Initializing RedisRunLoggingProvider with config: {config}" ) if not all( @@ -597,11 +550,8 @@ def __init__(self, config: RedisLoggingConfig): self.redis = Redis(host=cluster_ip, port=port, decode_responses=True) self.log_key = config.log_table self.log_info_key = config.log_info_table - self.has_user_id = False async def __aenter__(self): - # TODO: deprecated, remove in version 0.3.0 - await self.check_user_id_exists() return self async def __aexit__(self, exc_type, exc, tb): @@ -610,90 +560,84 @@ async def __aexit__(self, exc_type, exc, tb): async def close(self): await self.redis.close() - async def check_user_id_exists(self): - async for key in self.redis.scan_iter(f"{self.log_key}:*"): - logs = await self.redis.lrange(key, 0, -1) - for log in logs: - if "user_id" in json.loads(log): - self.has_user_id = True - return - - async for key in self.redis.scan_iter(f"{self.log_info_key}:*"): - log_info = await self.redis.hgetall(key) - for log_entry in log_info.values(): - if "user_id" in json.loads(log_entry): - self.has_user_id = True - return - async def log( self, - log_id: uuid.UUID, + run_id: UUID, key: str, value: str, - user_id: Optional[str] = None, - is_info_log=False, ): timestamp = datetime.now().timestamp() log_entry = { "timestamp": timestamp, - "log_id": str(log_id), + "run_id": str(run_id), "key": key, "value": value, } + await self.redis.lpush( + f"{self.log_key}:{str(run_id)}", json.dumps(log_entry) + ) - if user_id is not None: - log_entry["user_id"] = user_id - self.has_user_id = True - elif not self.has_user_id: - logger.warning( - "Logs excluding user ids are deprecated and will be removed in version 0.3.0. Please update your logging calls." - ) - - if is_info_log: - if "type" not in key: - raise ValueError("Metadata keys must contain the text 'type'") - log_entry["log_type"] = value - await self.redis.hset( - self.log_info_key, str(log_id), json.dumps(log_entry) - ) - await self.redis.zadd( - f"{self.log_info_key}_sorted", {str(log_id): timestamp} - ) - else: - await self.redis.lpush( - f"{self.log_key}:{str(log_id)}", json.dumps(log_entry) - ) + async def info_log( + self, + run_id: UUID, + run_type: RunType, + user_id: UUID, + ): + timestamp = datetime.now().timestamp() + log_entry = { + "timestamp": timestamp, + "run_id": str(run_id), + "run_type": run_type, + "user_id": str(user_id), + } + await self.redis.hset( + self.log_info_key, str(run_id), json.dumps(log_entry) + ) + await self.redis.zadd( + f"{self.log_info_key}_sorted", {str(run_id): timestamp} + ) - async def get_run_info( - self, limit: int = 10, log_type_filter: Optional[str] = None - ) -> list[RunInfo]: + async def get_info_logs( + self, + limit: int = 10, + run_type_filter: Optional[RunType] = None, + user_ids: Optional[list[UUID]] = None, + ) -> list[RunInfoLog]: run_info_list = [] start = 0 count_per_batch = 100 # Adjust batch size as needed while len(run_info_list) < limit: - log_ids = await self.redis.zrevrange( + run_ids = await self.redis.zrevrange( f"{self.log_info_key}_sorted", start, start + count_per_batch - 1, ) - if not log_ids: + if not run_ids: break # No more log IDs to process start += count_per_batch - for log_id in log_ids: + for run_id in run_ids: log_entry = json.loads( - await self.redis.hget(self.log_info_key, log_id) + await self.redis.hget(self.log_info_key, run_id) ) + + # Check if the log entry matches the filters if ( - log_type_filter - and log_entry["log_type"] == log_type_filter - ) or not log_type_filter: + run_type_filter is None + or log_entry["run_type"] == run_type_filter + ) and ( + user_ids is None or UUID(log_entry["user_id"]) in user_ids + ): run_info_list.append( - RunInfo( - run_id=uuid.UUID(log_entry["log_id"]), - log_type=log_entry["log_type"], + RunInfoLog( + run_id=UUID(log_entry["run_id"]), + run_type=log_entry["run_type"], + timestamp=datetime.fromtimestamp( + log_entry["timestamp"] + ), + user_id=UUID(log_entry["user_id"]), ) ) @@ -703,7 +647,7 @@ async def get_run_info( return run_info_list[:limit] async def get_logs( - self, run_ids: list[uuid.UUID], limit_per_run: int = 10 + self, run_ids: list[UUID], limit_per_run: int = 10 ) -> list: logs = [] for run_id in run_ids: @@ -712,14 +656,14 @@ async def get_logs( ) for raw_log in raw_logs: json_log = json.loads(raw_log) - json_log["log_id"] = uuid.UUID(json_log["log_id"]) + json_log["run_id"] = UUID(json_log["run_id"]) logs.append(json_log) return logs async def score_completion( - self, log_id: uuid.UUID, message_id: uuid.UUID, score: float + self, run_id: UUID, message_id: UUID, score: float ): - log_key = f"{self.log_key}:{str(log_id)}" + log_key = f"{self.log_key}:{str(run_id)}" logs = await self.redis.lrange(log_key, 0, -1) for i, log_entry in enumerate(logs): @@ -748,19 +692,19 @@ async def score_completion( log_data["value"] = json.dumps(completion_record) await self.redis.lset(log_key, i, json.dumps(log_data)) - return True + return {"message": "Score updated successfully."} - return False + return {"message": "Score not updated."} -class KVLoggingSingleton: +class RunLoggingSingleton: _instance = None _is_configured = False SUPPORTED_PROVIDERS = { - "local": LocalKVLoggingProvider, - "postgres": PostgresKVLoggingProvider, - "redis": RedisKVLoggingProvider, + "local": LocalRunLoggingProvider, + "postgres": PostgresRunLoggingProvider, + "redis": RedisRunLoggingProvider, } @classmethod @@ -775,47 +719,54 @@ def configure( cls._config = logging_config cls._is_configured = True else: - raise Exception("KVLoggingSingleton is already configured.") + raise Exception("RunLoggingSingleton is already configured.") @classmethod async def log( cls, - log_id: uuid.UUID, + run_id: UUID, key: str, value: str, - user_id: Optional[str] = None, - is_info_log: bool = False, ): try: async with cls.get_instance() as provider: - await provider.log( - log_id, - key, - value, - user_id=user_id, - is_info_log=is_info_log, - ) + await provider.log(run_id, key, value) + except Exception as e: + logger.error(f"Error logging data {(run_id, key, value)}: {e}") + + @classmethod + async def info_log( + cls, + run_id: UUID, + run_type: RunType, + user_id: UUID, + ): + try: + async with cls.get_instance() as provider: + await provider.info_log(run_id, run_type, user_id) except Exception as e: logger.error( - f"Error logging data {(log_id, key, value, user_id)}: {e}" + f"Error logging info data {(run_id, run_type, user_id)}: {e}" ) @classmethod - async def get_run_info( + async def get_info_logs( cls, limit: int = 10, - log_type_filter: Optional[str] = None, - ) -> list[RunInfo]: + run_type_filter: Optional[RunType] = None, + user_ids: Optional[list[UUID]] = None, + ) -> list[RunInfoLog]: async with cls.get_instance() as provider: - return await provider.get_run_info( + return await provider.get_info_logs( limit, - log_type_filter=log_type_filter, + run_type_filter=run_type_filter, + user_ids=user_ids, ) @classmethod async def get_logs( cls, - run_ids: list[uuid.UUID], + run_ids: list[UUID], limit_per_run: int = 10, ) -> list: async with cls.get_instance() as provider: @@ -823,7 +774,7 @@ async def get_logs( @classmethod async def score_completion( - cls, log_id: uuid.UUID, message_id: uuid.UUID, score: float + cls, run_id: UUID, message_id: UUID, score: float ): async with cls.get_instance() as provider: - return await provider.score_completion(log_id, message_id, score) + return await provider.score_completion(run_id, message_id, score) diff --git a/r2r/base/logging/run_manager.py b/r2r/base/logging/run_manager.py index c2f449b8f..389c1c5e3 100644 --- a/r2r/base/logging/run_manager.py +++ b/r2r/base/logging/run_manager.py @@ -1,17 +1,18 @@ import contextvars import uuid from contextlib import asynccontextmanager -from typing import Any, Optional +from typing import Optional -from r2r.base import User +from r2r.base.api.models.auth.responses import UserResponse +from r2r.base.logging.base import RunType -from .kv_logger import KVLoggingSingleton +from .run_logger import RunLoggingSingleton run_id_var = contextvars.ContextVar("run_id", default=None) class RunManager: - def __init__(self, logger: KVLoggingSingleton): + def __init__(self, logger: RunLoggingSingleton): self.logger = logger self.run_info = {} @@ -19,36 +20,34 @@ def generate_run_id(self) -> uuid.UUID: return uuid.uuid4() async def set_run_info( - self, pipeline_type: str, run_id: Optional[uuid.UUID] = None + self, run_type: str, run_id: Optional[uuid.UUID] = None ): run_id = run_id or run_id_var.get() if run_id is None: run_id = self.generate_run_id() token = run_id_var.set(run_id) - self.run_info[run_id] = {"pipeline_type": pipeline_type} + self.run_info[run_id] = {"run_type": run_type} else: token = run_id_var.set(run_id) return run_id, token - async def get_run_info(self): + async def get_info_logs(self): run_id = run_id_var.get() return self.run_info.get(run_id, None) async def log_run_info( self, - key: str, - value: Any, - is_info_log: bool = False, - user: Optional[User] = None, + run_type: RunType, + user: UserResponse, ): if run_id := run_id_var.get(): - await self.logger.log( - log_id=run_id, - key=key, - value=value, - user_id=user.id if user else None, - is_info_log=is_info_log, + await self.logger.info_log( + run_id=run_id, + run_type=run_type, + user_id=user.id, ) + else: + raise ValueError("No run ID set") async def clear_run_info(self, token: contextvars.Token): run_id = run_id_var.get() @@ -60,12 +59,16 @@ async def clear_run_info(self, token: contextvars.Token): @asynccontextmanager async def manage_run( run_manager: RunManager, - pipeline_type: str, + run_type: RunType = RunType.UNSPECIFIED, run_id: Optional[uuid.UUID] = None, ): - run_id, token = await run_manager.set_run_info(pipeline_type, run_id) + run_id, token = await run_manager.set_run_info(run_type, run_id) try: yield run_id finally: - # Note: Do not clear the run info to ensure the run ID remains the same - run_id_var.reset(token) + # Check if we're in a test environment + if isinstance(token, contextvars.Token): + run_id_var.reset(token) + else: + # We're in a test environment, just reset the run_id_var + run_id_var.set(None) diff --git a/r2r/base/pipeline/__init__.py b/r2r/base/pipeline/__init__.py index e69de29bb..a7f78aa43 100644 --- a/r2r/base/pipeline/__init__.py +++ b/r2r/base/pipeline/__init__.py @@ -0,0 +1,5 @@ +from .base_pipeline import AsyncPipeline + +__all__ = [ + "AsyncPipeline", +] diff --git a/r2r/base/pipeline/base_pipeline.py b/r2r/base/pipeline/base_pipeline.py index f6feee687..917af2c1a 100644 --- a/r2r/base/pipeline/base_pipeline.py +++ b/r2r/base/pipeline/base_pipeline.py @@ -2,40 +2,27 @@ import asyncio import logging -from enum import Enum +import traceback from typing import Any, AsyncGenerator, Optional -from r2r.base import User - -from ..logging.kv_logger import KVLoggingSingleton +from ..logging.run_logger import RunLoggingSingleton from ..logging.run_manager import RunManager, manage_run from ..pipes.base_pipe import AsyncPipe, AsyncState logger = logging.getLogger(__name__) -class PipelineTypes(Enum): - AGENT = "agent" - EVAL = "eval" - INGESTION = "ingestion" - OTHER = "other" - RAG = "rag" - SEARCH = "search" - - class AsyncPipeline: """Pipeline class for running a sequence of pipes.""" - pipeline_type: str = "other" - def __init__( self, - pipe_logger: Optional[KVLoggingSingleton] = None, + pipe_logger: Optional[RunLoggingSingleton] = None, run_manager: Optional[RunManager] = None, ): self.pipes: list[AsyncPipe] = [] self.upstream_outputs: list[list[dict[str, str]]] = [] - self.pipe_logger = pipe_logger or KVLoggingSingleton() + self.pipe_logger = pipe_logger or RunLoggingSingleton() self.run_manager = run_manager or RunManager(self.pipe_logger) self.futures = {} self.level = 0 @@ -59,31 +46,15 @@ async def run( state: Optional[AsyncState] = None, stream: bool = False, run_manager: Optional[RunManager] = None, - log_run_info: bool = True, - user: Optional[User] = None, *args: Any, **kwargs: Any, ): """Run the pipeline.""" run_manager = run_manager or self.run_manager - try: - PipelineTypes(self.pipeline_type) - except ValueError as e: - raise ValueError( - f"Invalid pipeline type: {self.pipeline_type}, must be one of {PipelineTypes.__members__.keys()}" - ) from e - self.state = state or AsyncState() current_input = input - async with manage_run(run_manager, self.pipeline_type): - if log_run_info: - await run_manager.log_run_info( - key="pipeline_type", - value=self.pipeline_type, - is_info_log=True, - user=user, - ) + async with manage_run(run_manager): try: for pipe_num in range(len(self.pipes)): config_name = self.pipes[pipe_num].config.name @@ -103,7 +74,10 @@ async def run( else await self._consume_all(current_input) ) except Exception as error: - logger.error(f"Pipeline failed with error: {error}") + error_trace = traceback.format_exc() + logger.error( + f"Pipeline failed with error: {error}\n\nStack trace:\n{error_trace}" + ) raise error async def _consume_all(self, gen: AsyncGenerator) -> list[Any]: @@ -175,6 +149,7 @@ async def replay_items_as_async_gen(items): ] # Handle the pipe generator + async for ele in await pipe.run( pipe.Input(**input_dict), self.state, @@ -200,35 +175,6 @@ def get_pipe_index(upstream_output): return sorted_outputs -class EvalPipeline(AsyncPipeline): - """A pipeline for evaluation.""" - - pipeline_type: str = "eval" - - async def run( - self, - input: Any, - state: Optional[AsyncState] = None, - stream: bool = False, - run_manager: Optional[RunManager] = None, - *args: Any, - **kwargs: Any, - ): - return await super().run( - input, state, stream, run_manager, *args, **kwargs - ) - - def add_pipe( - self, - pipe: AsyncPipe, - add_upstream_outputs: Optional[list[dict[str, str]]] = None, - *args, - **kwargs, - ) -> None: - logger.debug(f"Adding pipe {pipe.config.name} to the EvalPipeline") - return super().add_pipe(pipe, add_upstream_outputs, *args, **kwargs) - - async def dequeue_requests(queue: asyncio.Queue) -> AsyncGenerator: """Create an async generator to dequeue requests.""" while True: diff --git a/r2r/base/pipes/__init__.py b/r2r/base/pipes/__init__.py index e69de29bb..ff9035fab 100644 --- a/r2r/base/pipes/__init__.py +++ b/r2r/base/pipes/__init__.py @@ -0,0 +1,3 @@ +from .base_pipe import AsyncPipe, AsyncState, PipeType + +__all__ = ["AsyncPipe", "AsyncState", "PipeType"] diff --git a/r2r/base/pipes/base_pipe.py b/r2r/base/pipes/base_pipe.py index 63e3d04e8..5cddea982 100644 --- a/r2r/base/pipes/base_pipe.py +++ b/r2r/base/pipes/base_pipe.py @@ -7,7 +7,7 @@ from pydantic import BaseModel -from r2r.base.logging.kv_logger import KVLoggingSingleton +from r2r.base.logging.run_logger import RunLoggingSingleton from r2r.base.logging.run_manager import RunManager, manage_run logger = logging.getLogger(__name__) @@ -15,7 +15,6 @@ class PipeType(Enum): INGESTOR = "ingestor" - EVAL = "eval" GENERATOR = "generator" SEARCH = "search" TRANSFORM = "transform" @@ -89,12 +88,12 @@ def __init__( self, type: PipeType = PipeType.OTHER, config: Optional[PipeConfig] = None, - pipe_logger: Optional[KVLoggingSingleton] = None, + pipe_logger: Optional[RunLoggingSingleton] = None, run_manager: Optional[RunManager] = None, ): self._config = config or self.PipeConfig() self._type = type - self.pipe_logger = pipe_logger or KVLoggingSingleton() + self.pipe_logger = pipe_logger or RunLoggingSingleton() self.log_queue = asyncio.Queue() self.log_worker_task = None self._run_manager = run_manager or RunManager(self.pipe_logger) diff --git a/r2r/base/providers/__init__.py b/r2r/base/providers/__init__.py index e69de29bb..487756f6b 100644 --- a/r2r/base/providers/__init__.py +++ b/r2r/base/providers/__init__.py @@ -0,0 +1,54 @@ +from .auth import AuthConfig, AuthProvider +from .base import Provider, ProviderConfig +from .chunking import ChunkingConfig, ChunkingProvider, Method +from .crypto import CryptoConfig, CryptoProvider +from .database import ( + DatabaseConfig, + DatabaseProvider, + RelationalDBProvider, + VectorDBFilterValue, + VectorDBProvider, +) +from .embedding import EmbeddingConfig, EmbeddingProvider +from .kg import KGConfig, KGProvider +from .llm import CompletionConfig, CompletionProvider +from .parsing import OverrideParser, ParsingConfig, ParsingProvider +from .prompt import PromptConfig, PromptProvider + +__all__ = [ + # Base provider classes + "Provider", + "ProviderConfig", + # Auth provider + "AuthConfig", + "AuthProvider", + # Chunking provider + "ChunkingConfig", + "ChunkingProvider", + "Method", + # Crypto provider + "CryptoConfig", + "CryptoProvider", + # Database providers + "DatabaseConfig", + "DatabaseProvider", + "RelationalDBProvider", + "VectorDBProvider", + "VectorDBFilterValue", + # Embedding provider + "EmbeddingConfig", + "EmbeddingProvider", + # Knowledge Graph provider + "KGConfig", + "KGProvider", + # LLM provider + "CompletionConfig", + "CompletionProvider", + # Parsing provider + "ParsingConfig", + "ParsingProvider", + "OverrideParser", + # Prompt provider + "PromptConfig", + "PromptProvider", +] diff --git a/r2r/base/providers/auth.py b/r2r/base/providers/auth.py index cdcbbf211..88a86f103 100644 --- a/r2r/base/providers/auth.py +++ b/r2r/base/providers/auth.py @@ -5,8 +5,9 @@ from fastapi import Security from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer -from ..abstractions.exception import R2RException -from ..abstractions.user import Token, TokenData, User, UserCreate +from ..abstractions import R2RException, Token, TokenData +from ..api.models import UserResponse +from ..utils import generate_id_from_label from .base import Provider, ProviderConfig logger = logging.getLogger(__name__) @@ -42,8 +43,9 @@ def __init__(self, config: AuthConfig): self.admin_password = config.default_admin_password super().__init__(config) - def _get_default_admin_user(self) -> User: - return User( + def _get_default_admin_user(self) -> UserResponse: + return UserResponse( + id=generate_id_from_label(self.admin_email), email=self.admin_email, hashed_password=self.crypto_provider.get_password_hash( self.admin_password @@ -66,15 +68,17 @@ def decode_token(self, token: str) -> TokenData: pass @abstractmethod - def user(self, token: str) -> User: + def user(self, token: str) -> UserResponse: pass @abstractmethod - def get_current_active_user(self, current_user: User) -> User: + def get_current_active_user( + self, current_user: UserResponse + ) -> UserResponse: pass @abstractmethod - def register(self, user: UserCreate) -> Dict[str, str]: + def register(self, email: str, password: str) -> Dict[str, str]: pass @abstractmethod @@ -93,7 +97,7 @@ def refresh_access_token( async def auth_wrapper( self, auth: Optional[HTTPAuthorizationCredentials] = Security(security) - ) -> User: + ) -> UserResponse: if not self.config.require_authentication and auth is None: return self._get_default_admin_user() diff --git a/r2r/base/providers/chunking.py b/r2r/base/providers/chunking.py index 439d980a9..57fc5a510 100644 --- a/r2r/base/providers/chunking.py +++ b/r2r/base/providers/chunking.py @@ -1,10 +1,7 @@ from abc import ABC, abstractmethod from enum import Enum -from typing import Any, AsyncGenerator, List, Optional +from typing import AsyncGenerator, Optional -from pydantic import BaseModel, Field - -from ..abstractions.document import Document, DocumentType from .base import Provider, ProviderConfig @@ -24,6 +21,10 @@ class ChunkingConfig(ProviderConfig): def validate(self) -> None: if self.provider not in self.supported_providers: raise ValueError(f"Provider {self.provider} is not supported.") + if self.chunk_size <= 0: + raise ValueError("chunk_size must be greater than 0") + if self.chunk_overlap < 0: + raise ValueError("chunk_overlap must be non-negative") @property def supported_providers(self) -> list[str]: diff --git a/r2r/base/providers/database.py b/r2r/base/providers/database.py index b8fcad304..ddc1a120e 100644 --- a/r2r/base/providers/database.py +++ b/r2r/base/providers/database.py @@ -1,17 +1,17 @@ import logging -import uuid from abc import ABC, abstractmethod from datetime import datetime from typing import Optional, Union +from uuid import UUID -from ..abstractions.document import DocumentInfo -from ..abstractions.search import VectorSearchResult -from ..abstractions.user import User, UserCreate, UserResponse -from ..abstractions.vector import VectorEntry +from ..abstractions import DocumentInfo, VectorEntry, VectorSearchResult +from ..api.models import UserResponse from .base import Provider, ProviderConfig logger = logging.getLogger(__name__) +VectorDBFilterValue = Union[str, UUID] + class DatabaseConfig(ProviderConfig): def __post_init__(self): @@ -29,13 +29,13 @@ def supported_providers(self) -> list[str]: return ["postgres", None] -class VectorDatabaseProvider(Provider, ABC): +class VectorDBProvider(Provider, ABC): @abstractmethod def _initialize_vector_db(self, dimension: int) -> None: pass @abstractmethod - def copy(self, entry: VectorEntry, commit: bool = True) -> None: + def create_index(self, index_type, column_name, index_options): pass @abstractmethod @@ -46,7 +46,7 @@ def upsert(self, entry: VectorEntry, commit: bool = True) -> None: def search( self, query_vector: list[float], - filters: dict[str, Union[bool, int, str]] = {}, + filters: dict[str, VectorDBFilterValue] = {}, limit: int = 10, *args, **kwargs, @@ -59,7 +59,7 @@ def hybrid_search( query_text: str, query_vector: list[float], limit: int = 10, - filters: Optional[dict[str, Union[bool, int, str]]] = None, + filters: Optional[dict[str, VectorDBFilterValue]] = None, full_text_weight: float = 1.0, semantic_weight: float = 1.0, rrf_k: int = 20, @@ -69,44 +69,11 @@ def hybrid_search( pass @abstractmethod - def create_index(self, index_type, column_name, index_options): + def delete(self, filters: dict[str, VectorDBFilterValue]) -> list[str]: pass - @abstractmethod - def delete_by_metadata( - self, - metadata_fields: list[str], - metadata_values: list[Union[bool, int, str]], - ) -> list[str]: - pass - @abstractmethod - def get_metadatas( - self, - metadata_fields: list[str], - filter_field: Optional[str] = None, - filter_value: Optional[str] = None, - ) -> list[str]: - pass - - def upsert_entries( - self, entries: list[VectorEntry], commit: bool = True - ) -> None: - for entry in entries: - self.upsert(entry, commit=commit) - - def copy_entries( - self, entries: list[VectorEntry], commit: bool = True - ) -> None: - for entry in entries: - self.copy(entry, commit=commit) - - @abstractmethod - def get_document_chunks(self, document_id: str) -> list[dict]: - pass - - -class RelationalDatabaseProvider(Provider, ABC): +class RelationalDBProvider(Provider, ABC): @abstractmethod def _initialize_relational_db(self) -> None: pass @@ -120,8 +87,9 @@ def upsert_documents_overview( @abstractmethod def get_documents_overview( self, + filter_user_ids: Optional[str] = None, + filter_group_ids: Optional[list[str]] = None, filter_document_ids: Optional[list[str]] = None, - filter_user_ids: Optional[list[str]] = None, ) -> list[DocumentInfo]: pass @@ -136,31 +104,31 @@ def get_users_overview(self, user_ids: Optional[list[str]] = None) -> dict: pass @abstractmethod - def create_user(self, user: UserCreate) -> User: + def create_user(self, email: str, password: str) -> UserResponse: pass @abstractmethod - def get_user_by_email(self, email: str) -> Optional[User]: + def get_user_by_email(self, email: str) -> Optional[UserResponse]: pass @abstractmethod def store_verification_code( - self, user_id: uuid.UUID, verification_code: str, expiry: datetime + self, user_id: UUID, verification_code: str, expiry: datetime ): pass @abstractmethod def get_user_id_by_verification_code( self, verification_code: str - ) -> Optional[uuid.UUID]: + ) -> Optional[UUID]: pass @abstractmethod - def mark_user_as_verified(self, user_id: uuid.UUID): + def mark_user_as_verified(self, user_id: UUID): pass @abstractmethod - def mark_user_as_superuser(self, user_id: uuid.UUID): + def mark_user_as_superuser(self, user_id: UUID): pass @abstractmethod @@ -168,15 +136,22 @@ def remove_verification_code(self, verification_code: str): pass @abstractmethod - def get_user_by_id(self, user_id: uuid.UUID) -> Optional[User]: + def get_user_by_id(self, user_id: UUID) -> Optional[UserResponse]: pass @abstractmethod - def update_user(self, user: User) -> User: + def update_user( + self, + user_id: UUID, + email: Optional[str], + name: Optional[str], + bio: Optional[str], + profile_picture: Optional[str], + ) -> UserResponse: pass @abstractmethod - def delete_user(self, user_id: uuid.UUID): + def delete_user(self, user_id: UUID): pass @abstractmethod @@ -193,21 +168,15 @@ def __init__(self, config: DatabaseConfig): ) logger.info(f"Initializing DatabaseProvider with config {config}.") super().__init__(config) - self.vector: VectorDatabaseProvider = self._initialize_vector_db() - self.relational: RelationalDatabaseProvider = ( + self.vector: VectorDBProvider = self._initialize_vector_db() + self.relational: RelationalDBProvider = ( self._initialize_relational_db() ) @abstractmethod - def _initialize_vector_db(self) -> VectorDatabaseProvider: + def _initialize_vector_db(self) -> VectorDBProvider: pass @abstractmethod - def _initialize_relational_db(self) -> RelationalDatabaseProvider: + def _initialize_relational_db(self) -> RelationalDBProvider: pass - - -# Example usage: -# db_provider = DatabaseProvider(config) -# db_provider.vector.search(...) -# db_provider.relational.get_documents_overview(...) diff --git a/r2r/base/providers/embedding.py b/r2r/base/providers/embedding.py index 5bfcf0ef9..e213b44da 100644 --- a/r2r/base/providers/embedding.py +++ b/r2r/base/providers/embedding.py @@ -6,10 +6,7 @@ from enum import Enum from typing import Any, Optional -from ..abstractions.embedding import ( - EmbeddingPurpose, - default_embedding_prefixes, -) +from ..abstractions import EmbeddingPurpose, default_embedding_prefixes from ..abstractions.search import VectorSearchResult from .base import Provider, ProviderConfig diff --git a/r2r/base/providers/eval.py b/r2r/base/providers/eval.py deleted file mode 100644 index a84298483..000000000 --- a/r2r/base/providers/eval.py +++ /dev/null @@ -1,46 +0,0 @@ -from typing import Optional, Union - -from ..abstractions.llm import GenerationConfig -from .base import Provider, ProviderConfig -from .llm import CompletionConfig - - -class EvalConfig(ProviderConfig): - """A base eval config class""" - - llm: Optional[CompletionConfig] = None - - def validate(self) -> None: - if self.provider not in self.supported_providers: - raise ValueError(f"Provider {self.provider} not supported.") - if self.provider and not self.llm: - raise ValueError( - "EvalConfig must have a `llm` attribute when specifying a provider." - ) - - @property - def supported_providers(self) -> list[str]: - return [None, "local"] - - -class EvalProvider(Provider): - """An abstract class to provide a common interface for evaluation providers.""" - - def __init__(self, config: EvalConfig): - if not isinstance(config, EvalConfig): - raise ValueError( - "EvalProvider must be initialized with a `EvalConfig`." - ) - - super().__init__(config) - - def evaluate( - self, - query: str, - context: str, - completion: str, - eval_generation_config: Optional[GenerationConfig] = None, - ) -> dict[str, dict[str, Union[str, float]]]: - return self._evaluate( - query, context, completion, eval_generation_config - ) diff --git a/r2r/base/providers/kg.py b/r2r/base/providers/kg.py index 9a6dd394d..fc4c60305 100644 --- a/r2r/base/providers/kg.py +++ b/r2r/base/providers/kg.py @@ -1,21 +1,13 @@ """Base classes for knowledge graph providers.""" -import json import logging from abc import ABC, abstractmethod -from typing import TYPE_CHECKING, Any, Optional, Tuple +from typing import Any, Optional, Tuple -from ..abstractions.llama_abstractions import EntityNode, LabelledNode -from ..abstractions.llama_abstractions import Relation as LlamaRelation -from ..abstractions.llama_abstractions import VectorStoreQuery -from .base import ProviderConfig -from .prompt import PromptProvider - -if TYPE_CHECKING: - from r2r.main import R2RClient - -from ...base.utils.base_utils import EntityType, Relation +from ...base.utils.base_utils import RelationshipType +from ..abstractions.graph import Entity, KGExtraction, Triple from ..abstractions.llm import GenerationConfig +from .base import ProviderConfig logger = logging.getLogger(__name__) @@ -24,10 +16,11 @@ class KGConfig(ProviderConfig): """A base KG config class""" provider: Optional[str] = None - batch_size: int = 1 + batch_size: Optional[int] = 1 kg_extraction_prompt: Optional[str] = "few_shot_ner_kg_extraction" kg_search_prompt: Optional[str] = "kg_search" kg_extraction_config: Optional[GenerationConfig] = None + kg_store_path: Optional[str] = None def validate(self) -> None: if self.provider not in self.supported_providers: @@ -35,7 +28,7 @@ def validate(self) -> None: @property def supported_providers(self) -> list[str]: - return [None, "neo4j"] + return [None, "neo4j", "local"] class KGProvider(ABC): @@ -75,12 +68,33 @@ def get_rel_map( pass @abstractmethod - def upsert_nodes(self, nodes: list[EntityNode]) -> None: + def upsert_entities(self, entities: list[Entity], *args, **kwargs) -> None: """Abstract method to add triplet.""" pass @abstractmethod - def upsert_relations(self, relations: list[LlamaRelation]) -> None: + def upsert_triples(self, triples: list[Triple]) -> None: + """Abstract method to add triplet.""" + pass + + @abstractmethod + def get_entities( + self, + entity_ids: list[str] | None = None, + with_description: bool = False, + ) -> list[Entity]: + """Abstract method to get entities.""" + pass + + @abstractmethod + def get_triples(self, triple_ids: list[str] | None = None) -> list[Triple]: + """Abstract method to get triples.""" + pass + + @abstractmethod + def upsert_nodes_and_relationships( + self, kg_extractions: list[KGExtraction] + ) -> None: """Abstract method to add triplet.""" pass @@ -103,8 +117,8 @@ def structured_query( @abstractmethod def vector_query( - self, query: VectorStoreQuery, **kwargs: Any - ) -> Tuple[list[LabelledNode], list[float]]: + self, query, **kwargs: Any + ) -> Tuple[list[Entity], list[float]]: """Abstract method to query the graph store with a vector store query.""" # TODO - Type this method. @@ -113,7 +127,7 @@ def update_extraction_prompt( self, prompt_provider: Any, entity_types: list[Any], - relations: list[Relation], + relationship_types: list[RelationshipType], ): """Abstract method to update the KG extraction prompt.""" pass @@ -124,7 +138,7 @@ def update_kg_search_prompt( self, prompt_provider: Any, entity_types: list[Any], - relations: list[Relation], + relationship_types: list[RelationshipType], ): """Abstract method to update the KG agent prompt.""" pass @@ -137,59 +151,3 @@ def escape_braces(s: str) -> str: """ # Implement your escape_braces logic here return s.replace("{", "{{").replace("}", "}}") - - -# TODO - Make this more configurable / intelligent -def update_kg_prompt( - client: "R2RClient", - r2r_prompts: PromptProvider, - prompt_base: str, - entity_types: list[EntityType], - relations: list[Relation], -) -> None: - # TODO - DO NOT HARD CODE THIS! - if len(entity_types) > 10: - raise ValueError( - "Too many entity types to update prompt, limited to 10" - ) - if len(relations) > 20: - raise ValueError("Too many relations to update prompt, limited to 20") - # Get the default extraction template - template_name: str = f"{prompt_base}_with_spec" - - new_template: str = r2r_prompts.get_prompt( - template_name, - { - "entity_types": json.dumps( - { - "entity_types": [ - str(entity.name.replace(" ", "_").upper()) - for entity in entity_types - ] - }, - indent=4, - ), - "relations": json.dumps( - { - "predicates": [ - str(relation.name.replace(" ", "_").upper()) - for relation in relations - ] - }, - indent=4, - ), - "input": """\n{input}""", - }, - ) - - # Escape all braces in the template, except for the {input} placeholder, for formatting - escaped_template: str = escape_braces(new_template).replace( - """{{input}}""", """{input}""" - ) - - # Update the client's prompt - client.update_prompt( - prompt_base, - template=escaped_template, - input_types={"input": "str"}, - ) diff --git a/r2r/base/utils/__init__.py b/r2r/base/utils/__init__.py index 104d50eb0..591054546 100644 --- a/r2r/base/utils/__init__.py +++ b/r2r/base/utils/__init__.py @@ -1,6 +1,4 @@ from .base_utils import ( - EntityType, - Relation, format_entity_types, format_relations, generate_id_from_label, @@ -12,15 +10,14 @@ from .splitter.text import RecursiveCharacterTextSplitter, TextSplitter __all__ = [ - "RecursiveCharacterTextSplitter", - "TextSplitter", - "run_pipeline", - "to_async_generator", - "generate_run_id", - "generate_id_from_label", - "increment_version", - "EntityType", - "Relation", "format_entity_types", "format_relations", + "generate_id_from_label", + "generate_run_id", + "increment_version", + "run_pipeline", + "to_async_generator", + # Text splitter + "RecursiveCharacterTextSplitter", + "TextSplitter", ] diff --git a/r2r/base/utils/base_utils.py b/r2r/base/utils/base_utils.py index df7db0b2e..a1aa48590 100644 --- a/r2r/base/utils/base_utils.py +++ b/r2r/base/utils/base_utils.py @@ -2,6 +2,8 @@ import uuid from typing import TYPE_CHECKING, Any, AsyncGenerator, Iterable +from ..abstractions.graph import EntityType, RelationshipType + if TYPE_CHECKING: from ..pipeline.base_pipeline import AsyncPipeline @@ -40,21 +42,11 @@ def increment_version(version: str) -> str: return f"{prefix}{suffix + 1}" -class EntityType: - def __init__(self, name: str): - self.name = name - - -class Relation: - def __init__(self, name: str): - self.name = name - - def format_entity_types(entity_types: list[EntityType]) -> str: lines = [entity.name for entity in entity_types] return "\n".join(lines) -def format_relations(predicates: list[Relation]) -> str: +def format_relations(predicates: list[RelationshipType]) -> str: lines = [predicate.name for predicate in predicates] return "\n".join(lines) diff --git a/r2r/base/utils/splitter/text.py b/r2r/base/utils/splitter/text.py index 5458310c6..b06389f77 100644 --- a/r2r/base/utils/splitter/text.py +++ b/r2r/base/utils/splitter/text.py @@ -292,7 +292,7 @@ def to_json_not_implemented(obj: object) -> SerializedNotImplemented: return result -class Document(Serializable): +class SplitterDocument(Serializable): """Class for storing a piece of text and associated metadata.""" page_content: str @@ -356,8 +356,8 @@ async def atransform_documents( @abstractmethod def transform_documents( - self, documents: Sequence[Document], **kwargs: Any - ) -> Sequence[Document]: + self, documents: Sequence[SplitterDocument], **kwargs: Any + ) -> Sequence[SplitterDocument]: """Transform a list of documents. Args: @@ -368,8 +368,8 @@ def transform_documents( """ async def atransform_documents( - self, documents: Sequence[Document], **kwargs: Any - ) -> Sequence[Document]: + self, documents: Sequence[SplitterDocument], **kwargs: Any + ) -> Sequence[SplitterDocument]: """Asynchronously transform a list of documents. Args: @@ -466,7 +466,7 @@ def split_text(self, text: str) -> List[str]: def create_documents( self, texts: List[str], metadatas: Optional[List[dict]] = None - ) -> List[Document]: + ) -> List[SplitterDocument]: """Create documents from a list of texts.""" _metadatas = metadatas or [{}] * len(texts) documents = [] @@ -480,11 +480,15 @@ def create_documents( index = text.find(chunk, max(0, offset)) metadata["start_index"] = index previous_chunk_len = len(chunk) - new_doc = Document(page_content=chunk, metadata=metadata) + new_doc = SplitterDocument( + page_content=chunk, metadata=metadata + ) documents.append(new_doc) return documents - def split_documents(self, documents: Iterable[Document]) -> List[Document]: + def split_documents( + self, documents: Iterable[SplitterDocument] + ) -> List[SplitterDocument]: """Split documents.""" texts, metadatas = [], [] for doc in documents: @@ -615,8 +619,8 @@ def _tiktoken_encoder(text: str) -> int: return cls(length_function=_tiktoken_encoder, **kwargs) def transform_documents( - self, documents: Sequence[Document], **kwargs: Any - ) -> Sequence[Document]: + self, documents: Sequence[SplitterDocument], **kwargs: Any + ) -> Sequence[SplitterDocument]: """Transform sequence of documents by splitting them.""" return self.split_documents(list(documents)) @@ -691,7 +695,7 @@ def __init__( def aggregate_lines_to_chunks( self, lines: List[LineType] - ) -> List[Document]: + ) -> List[SplitterDocument]: """Combine lines with common metadata into chunks Args: lines: Line of text / associated header metadata @@ -730,11 +734,13 @@ def aggregate_lines_to_chunks( aggregated_chunks.append(line) return [ - Document(page_content=chunk["content"], metadata=chunk["metadata"]) + SplitterDocument( + page_content=chunk["content"], metadata=chunk["metadata"] + ) for chunk in aggregated_chunks ] - def split_text(self, text: str) -> List[Document]: + def split_text(self, text: str) -> List[SplitterDocument]: """Split markdown file Args: text: Markdown file""" @@ -858,7 +864,7 @@ def split_text(self, text: str) -> List[Document]: return self.aggregate_lines_to_chunks(lines_with_metadata) else: return [ - Document( + SplitterDocument( page_content=chunk["content"], metadata=chunk["metadata"] ) for chunk in lines_with_metadata @@ -899,7 +905,7 @@ def __init__( def aggregate_elements_to_chunks( self, elements: List[ElementType] - ) -> List[Document]: + ) -> List[SplitterDocument]: """Combine elements with common metadata into chunks Args: @@ -921,11 +927,13 @@ def aggregate_elements_to_chunks( aggregated_chunks.append(element) return [ - Document(page_content=chunk["content"], metadata=chunk["metadata"]) + SplitterDocument( + page_content=chunk["content"], metadata=chunk["metadata"] + ) for chunk in aggregated_chunks ] - def split_text_from_url(self, url: str) -> List[Document]: + def split_text_from_url(self, url: str) -> List[SplitterDocument]: """Split HTML from web URL Args: @@ -934,7 +942,7 @@ def split_text_from_url(self, url: str) -> List[Document]: r = requests.get(url) return self.split_text_from_file(BytesIO(r.content)) - def split_text(self, text: str) -> List[Document]: + def split_text(self, text: str) -> List[SplitterDocument]: """Split HTML text string Args: @@ -942,7 +950,7 @@ def split_text(self, text: str) -> List[Document]: """ return self.split_text_from_file(StringIO(text)) - def split_text_from_file(self, file: Any) -> List[Document]: + def split_text_from_file(self, file: Any) -> List[SplitterDocument]: """Split HTML file Args: @@ -1021,7 +1029,7 @@ def split_text_from_file(self, file: Any) -> List[Document]: return self.aggregate_elements_to_chunks(elements) else: return [ - Document( + SplitterDocument( page_content=chunk["content"], metadata=chunk["metadata"] ) for chunk in elements @@ -1221,12 +1229,21 @@ def __init__( separators: Optional[List[str]] = None, keep_separator: bool = True, is_separator_regex: bool = False, + chunk_size: int = 4000, + chunk_overlap: int = 200, **kwargs: Any, ) -> None: """Create a new TextSplitter.""" - super().__init__(keep_separator=keep_separator, **kwargs) + super().__init__( + chunk_size=chunk_size, + chunk_overlap=chunk_overlap, + keep_separator=keep_separator, + **kwargs, + ) self._separators = separators or ["\n\n", "\n", " ", ""] self._is_separator_regex = is_separator_regex + self.chunk_size = chunk_size + self.chunk_overlap = chunk_overlap def _split_text(self, text: str, separators: List[str]) -> List[str]: """Split incoming text and return chunks.""" @@ -1965,7 +1982,7 @@ def create_documents( texts: List[Dict], convert_lists: bool = False, metadatas: Optional[List[dict]] = None, - ) -> List[Document]: + ) -> List[SplitterDocument]: """Create documents from a list of json objects (Dict).""" _metadatas = metadatas or [{}] * len(texts) documents = [] @@ -1974,6 +1991,8 @@ def create_documents( json_data=text, convert_lists=convert_lists ): metadata = copy.deepcopy(_metadatas[i]) - new_doc = Document(page_content=chunk, metadata=metadata) + new_doc = SplitterDocument( + page_content=chunk, metadata=metadata + ) documents.append(new_doc) return documents diff --git a/r2r/cli/__init__.py b/r2r/cli/__init__.py index e69de29bb..275abbc6c 100644 --- a/r2r/cli/__init__.py +++ b/r2r/cli/__init__.py @@ -0,0 +1,23 @@ +from .cli import cli, main +from .command_group import cli as command_group_cli +from .commands import ( + auth_operations, + document_operations, + oberservability_operations, + rag_operations, + server_operations, +) + +__all__ = [ + # From cli.py + "cli", + "main", + # From Command Group + "command_group_cli", + # From Commands + "auth_operations", + "document_operations", + "oberservability_operations", + "rag_operations", + "server_operations", +] diff --git a/r2r/cli/cli.py b/r2r/cli/cli.py index d45d0c436..0e7fbdadf 100644 --- a/r2r/cli/cli.py +++ b/r2r/cli/cli.py @@ -2,6 +2,7 @@ from r2r.cli.commands import ( auth_operations, document_operations, + kg_operations, oberservability_operations, rag_operations, server_operations, @@ -39,6 +40,8 @@ cli.add_command(oberservability_operations.logs) cli.add_command(oberservability_operations.users_overview) +cli.add_command(kg_operations.enrich_graph) + def main(): cli() diff --git a/r2r/cli/commands/document_operations.py b/r2r/cli/commands/document_operations.py index 9c6e73af5..237918d85 100644 --- a/r2r/cli/commands/document_operations.py +++ b/r2r/cli/commands/document_operations.py @@ -5,41 +5,48 @@ @cli.command() -@click.option("--keys", multiple=True, help="Keys for deletion") -@click.option("--values", multiple=True, help="Values for deletion") +@click.option( + "--filter", + "-f", + multiple=True, + help="Filters for deletion in the format key:operator:value", +) @click.pass_obj -def delete(obj, keys, values): - """Delete documents based on keys and values.""" - if len(keys) != len(values): - raise click.UsageError("Number of keys must match number of values") +def delete(obj, filter): + """Delete documents based on filters.""" + filters = {} + for f in filter: + key, operator, value = f.split(":", 2) + if key not in filters: + filters[key] = {} + filters[key][f"${operator}"] = value with timer(): - response = obj.delete(list(keys), list(values)) + response = obj.delete(filters=filters) click.echo(response) @cli.command() @click.option("--document-ids", multiple=True, help="Document IDs to overview") -@click.option("--user-ids", multiple=True, help="User IDs to overview") @click.pass_obj -def documents_overview(obj, document_ids, user_ids): +def documents_overview(obj, document_ids): """Get an overview of documents.""" document_ids = list(document_ids) if document_ids else None - user_ids = list(user_ids) if user_ids else None with timer(): - response = obj.documents_overview(document_ids, user_ids) + response = obj.documents_overview(document_ids) for document in response: click.echo(document) @cli.command() -@click.argument("document_id") +@click.argument("document-id") @click.pass_obj def document_chunks(obj, document_id): """Get chunks of a specific document.""" + print(document_id) with timer(): response = obj.document_chunks(document_id) diff --git a/r2r/cli/commands/kg_operations.py b/r2r/cli/commands/kg_operations.py new file mode 100644 index 000000000..a596e153d --- /dev/null +++ b/r2r/cli/commands/kg_operations.py @@ -0,0 +1,16 @@ +import click + +from r2r.cli.command_group import cli +from r2r.cli.utils.timer import timer + + +@cli.command() +@click.pass_obj +def enrich_graph(obj): + """Enrich the knowledge graph with specified documents.""" + # document_ids = list(document_ids) if document_ids else None + + with timer(): + response = obj.enrich_graph() + + click.echo(response) diff --git a/r2r/cli/commands/oberservability_operations.py b/r2r/cli/commands/oberservability_operations.py index 247bf6875..76d80b4a6 100644 --- a/r2r/cli/commands/oberservability_operations.py +++ b/r2r/cli/commands/oberservability_operations.py @@ -1,6 +1,5 @@ -import json -import uuid from typing import Any, Dict +from uuid import UUID import click @@ -32,15 +31,15 @@ def app_settings(obj): @cli.command() -@click.option("--log-type-filter", help="Filter for log types") +@click.option("--run-type-filter", help="Filter for log types") @click.option( "--max-runs", default=100, help="Maximum number of runs to fetch" ) @click.pass_obj -def logs(obj, log_type_filter, max_runs): +def logs(obj, run_type_filter, max_runs): """Retrieve logs with optional type filter.""" with timer(): - response = obj.logs(log_type_filter, max_runs) + response = obj.logs(run_type_filter, max_runs) for log in response: click.echo(f"Run ID: {log['run_id']}") @@ -66,9 +65,7 @@ def logs(obj, log_type_filter, max_runs): @click.pass_obj def users_overview(obj, user_ids): """Get an overview of users.""" - user_ids = ( - [uuid.UUID(user_id) for user_id in user_ids] if user_ids else None - ) + user_ids = [UUID(user_id) for user_id in user_ids] if user_ids else None with timer(): response = obj.users_overview(user_ids) diff --git a/r2r/cli/commands/rag_operations.py b/r2r/cli/commands/rag_operations.py index 7081ed8b5..fb101b5de 100644 --- a/r2r/cli/commands/rag_operations.py +++ b/r2r/cli/commands/rag_operations.py @@ -23,7 +23,7 @@ def inspect_knowledge_graph(obj, limit): @click.option( "--use-vector-search", is_flag=True, default=True, help="Use vector search" ) -@click.option("--search-filters", type=JSON, help="Search filters as JSON") +@click.option("--filters", type=JSON, help="Search filters as JSON") @click.option( "--search-limit", default=10, help="Number of search results to return" ) @@ -39,7 +39,7 @@ def rag( obj, query, use_vector_search, - search_filters, + filters, search_limit, do_hybrid_search, use_kg_search, @@ -59,7 +59,7 @@ def rag( response = obj.rag( query, use_vector_search, - search_filters, + filters, search_limit, do_hybrid_search, use_kg_search, @@ -86,7 +86,7 @@ def rag( @click.option( "--use-vector-search", is_flag=True, default=True, help="Use vector search" ) -@click.option("--search-filters", type=JSON, help="Search filters as JSON") +@click.option("--filters", type=JSON, help="Search filters as JSON") @click.option( "--search-limit", default=10, help="Number of search results to return" ) @@ -95,16 +95,22 @@ def rag( "--use-kg-search", is_flag=True, help="Use knowledge graph search" ) @click.option("--kg-search-model", default=None, help="Model for KG agent") +@click.option("--kg-search-type", default="global", help="Local or Global") +@click.option("--kg-search-level", default=None, help="Level of KG search") @click.pass_obj def search( obj, query, use_vector_search, - search_filters, + filters, search_limit, do_hybrid_search, use_kg_search, kg_search_model, + kg_search_type, + kg_search_level, + entity_types=[], + relationships=[], ): """Perform a search query.""" kg_search_generation_config = {} @@ -114,14 +120,21 @@ def search( with timer(): results = obj.search( query, - use_vector_search, - search_filters, - search_limit, - do_hybrid_search, - use_kg_search, - kg_search_generation_config, + use_vector_search=use_vector_search, + filters=filters, + search_limit=search_limit, + do_hybrid_search=do_hybrid_search, + use_kg_search=use_kg_search, + entity_types=entity_types, + relationships=relationships, + kg_search_type=kg_search_type, + kg_search_generation_config=kg_search_generation_config, + kg_search_level=kg_search_level, ) + print("KG_Search Enabled", use_kg_search) + print("KG_Search Type", kg_search_type) + if isinstance(results, dict) and "results" in results: results = results["results"] @@ -129,5 +142,8 @@ def search( click.echo("Vector search results:") for result in results["vector_search_results"]: click.echo(result) + if "kg_search_results" in results and results["kg_search_results"]: - click.echo("KG search results:", results["kg_search_results"]) + click.echo("KG search results:") + for result in results["kg_search_results"]: + click.echo(result) diff --git a/r2r/examples/configs/graphrag.toml b/r2r/examples/configs/graphrag.toml new file mode 100644 index 000000000..5af5d4549 --- /dev/null +++ b/r2r/examples/configs/graphrag.toml @@ -0,0 +1,61 @@ +[completion] +provider = "litellm" +concurrent_request_limit = 256 + + [completion.generation_config] + model = "gpt-4o-mini" + temperature = 0.1 + top_p = 1 + max_tokens_to_sample = 1_024 + stream = false + add_generation_kwargs = { } + +[embedding] +provider = "openai" +base_model = "text-embedding-3-small" +base_dimension = 1_536 +batch_size = 256 +add_title_as_prefix = true + +[ingestion] +excluded_parsers = [ "gif", "jpeg", "jpg", "png", "svg", "mp3", "mp4" ] + +[kg] +provider = "local" +batch_size = 1024 +max_entities = 10 +max_relations = 20 +kg_extraction_prompt = "graphrag_triplet_extraction_zero_shot" +kg_store_path = "/Users/shreyas/r2rr2r/graph_data" + + [kg.kg_extraction_config] + model = "gpt-4o-mini" + temperature = 1 + top_p = 1 + max_tokens_to_sample = 1_024 + stream = false + add_generation_kwargs = { } + +# [kg] +# provider = "local" +# batch_size = 256 +# kg_extraction_prompt = "graphrag_triplet_extraction_zero_shot" + + +# [kg.kg_extraction_config] +# model = "gpt-4o-mini" +# temperature = 1 +# top_p = 1 +# max_tokens_to_sample = 1_024 +# stream = false +# add_generation_kwargs = { } + +[database] +provider = "postgres" + +[agent] +system_instruction_name = "rag_agent" +tool_names = ["search"] + + [agent.generation_config] + model = "gpt-4o-mini" diff --git a/r2r/examples/configs/neo4j_kg.toml b/r2r/examples/configs/neo4j_kg.toml index e8ec13a8d..ae78dfe12 100644 --- a/r2r/examples/configs/neo4j_kg.toml +++ b/r2r/examples/configs/neo4j_kg.toml @@ -1,11 +1,45 @@ +[completion] +provider = "litellm" +concurrent_request_limit = 256 + + [completion.generation_config] + model = "gpt-4o-mini" + temperature = 0.1 + top_p = 1 + max_tokens_to_sample = 1_024 + stream = false + add_generation_kwargs = { } + +[embedding] +provider = "openai" +base_model = "text-embedding-3-small" +base_dimension = 1_536 +batch_size = 256 +add_title_as_prefix = true + +[ingestion] +excluded_parsers = [ "gif", "jpeg", "jpg", "png", "svg", "mp3", "mp4" ] + [kg] provider = "neo4j" -batch_size = 1 +batch_size = 256 +kg_extraction_prompt = "graphrag_triplet_extraction_zero_shot" + [kg.kg_extraction_config] - model = "gpt-4o" - temperature = 0.1 + model = "gpt-4o-mini" + temperature = 1 top_p = 1 max_tokens_to_sample = 1_024 stream = false add_generation_kwargs = { } + +[database] +provider = "postgres" + +[agent] +system_instruction_name = "rag_agent" +tool_names = ["search"] + + [agent.generation_config] + model = "gpt-4o-mini" diff --git a/r2r/examples/scripts/advanced_kg_cookbook.py b/r2r/examples/scripts/advanced_kg_cookbook.py index 7e5779849..e6270a46e 100644 --- a/r2r/examples/scripts/advanced_kg_cookbook.py +++ b/r2r/examples/scripts/advanced_kg_cookbook.py @@ -4,13 +4,7 @@ import requests from bs4 import BeautifulSoup, Comment -from r2r import ( - EntityType, - R2RClient, - R2RPromptProvider, - Relation, - update_kg_prompt, -) +from r2r import EntityType, R2RClient, R2RPromptProvider, update_kg_prompt def escape_braces(text): @@ -134,13 +128,9 @@ def main( client = R2RClient(base_url=base_url) r2r_prompts = R2RPromptProvider() - prompt_base = ( - "zero_shot_ner_kg_extraction" - if local_mode - else "few_shot_ner_kg_extraction" - ) + prompt = "graphrag_triplet_extraction_few_shot" - update_kg_prompt(client, r2r_prompts, prompt_base, entity_types, relations) + update_kg_prompt(client, r2r_prompts, prompt, entity_types, relations) url_map = get_all_yc_co_directory_urls() @@ -166,7 +156,8 @@ def main( except: continue - print(client.inspect_knowledge_graph(1_000)["results"]) + print("Inspecting Knowledge Graph") + print(client.inspect_knowledge_graph(1000)["results"]) if not local_mode: @@ -174,18 +165,19 @@ def main( client, r2r_prompts, "kg_search", entity_types, relations ) + # support local and global result = client.search( query="Find up to 10 founders that worked at Google", - kg_search_settings={"use_kg_search": True}, + kg_search_settings={"ause_kg_search": True}, )["results"] - print("Search Result:\n", result["kg_search_results"]) + # print("Search Result:\n", result["kg_search_results"]) - result = client.rag( - query="Find up to 10 founders that worked at Google", - kg_search_settings={"use_kg_search": True}, - ) - print("RAG Result:\n", result) + # result = client.rag( + # query="Find up to 10 founders that worked at Google", + # kg_search_settings={"use_kg_search": True}, + # ) + # print("RAG Result:\n", result) if __name__ == "__main__": diff --git a/r2r/examples/scripts/sample_data_ingestor.py b/r2r/examples/scripts/sample_data_ingestor.py index 4fe9590cf..b245a1c11 100644 --- a/r2r/examples/scripts/sample_data_ingestor.py +++ b/r2r/examples/scripts/sample_data_ingestor.py @@ -31,8 +31,8 @@ def get_sample_files(no_media: bool = True) -> list[str]: os.path.join(examples_dir, "data", "pg_essay_5.html"), os.path.join(examples_dir, "data", "lyft_2021.pdf"), os.path.join(examples_dir, "data", "uber_2021.pdf"), - os.path.join(examples_dir, "data", "sample.mp3"), - os.path.join(examples_dir, "data", "sample2.mp3"), + # os.path.join(examples_dir, "data", "sample.mp3"), + # os.path.join(examples_dir, "data", "sample2.mp3"), ] if no_media: excluded_types = ["jpeg", "jpg", "png", "svg", "mp3", "mp4"] diff --git a/r2r/examples/scripts/test_e2e.py b/r2r/examples/scripts/test_e2e.py deleted file mode 100644 index 11829f94f..000000000 --- a/r2r/examples/scripts/test_e2e.py +++ /dev/null @@ -1,321 +0,0 @@ -import json -import math -from datetime import datetime, timezone -from uuid import UUID - -from r2r.main.execution import R2RExecutionWrapper - -expected_logs = [ - { - "run_id": ..., - "run_type": "ingestion", - "entries": [ - { - "key": "document_parse_result", - "value": "Document 'aristotle.txt' processed successfully.", - } - ], - }, - { - "run_id": ..., - "run_type": "search", - "entries": [ - {"key": "search_latency", "value": "0.45"}, - { - "key": "search_results", - "value": '["{\\"id\\":\\"7ed3a01c-88dc-5a58-a68b-6e5d9f292df2\\",\\"score\\":0.773841586847122,\\"metadata\\":{\\"text\\":\\"Aristotle[A] (Greek: \\u1f08\\u03c1\\u03b9\\u03c3\\u03c4\\u03bf\\u03c4\\u03ad\\u03bb\\u03b7\\u03c2 Aristot\\u00e9l\\u0113s, pronounced [aristot\\u00e9l\\u025b\\u02d0s]; 384\\u2013322 BC) was an Ancient Greek philosopher and polymath. His writings cover a broad range of subjects spanning the natural sciences, philosophy, linguistics, economics, politics, psychology, and the arts. As the founder of the Peripatetic school of philosophy in the Lyceum in Athens, he began the wider Aristotelian tradition that followed, which set the groundwork for the development of modern science.\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":0,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"e6f58828-2e6d-5eb1-94f3-efbc0b7c1699\\",\\"score\\":0.669298529624939,\\"metadata\\":{\\"text\\":\\"Aristotle was revered among medieval Muslim scholars as \\\\\\"The First Teacher\\\\\\", and among medieval Christians like Thomas Aquinas as simply \\\\\\"The Philosopher\\\\\\", while the poet Dante called him \\\\\\"the master of those who know\\\\\\". His works contain the earliest known formal study of logic, and were studied by medieval scholars such as Peter Abelard and Jean Buridan. Aristotle\'s influence on logic continued well into the 19th century. In addition, his ethics, although always influential, gained renewed interest with\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":5,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"c818bc72-2ac8-581b-b51a-0ca826f5f2b8\\",\\"score\\":0.652687707703574,\\"metadata\\":{\\"text\\":\\"Aristotle was born in 384 BC[C] in Stagira, Chalcidice,[2] about 55 km (34 miles) east of modern-day Thessaloniki.[3][4] His father, Nicomachus, was the personal physician to King Amyntas of Macedon. While he was young, Aristotle learned about biology and medical information, which was taught by his father.[5] Both of Aristotle\'s parents died when he was about thirteen, and Proxenus of Atarneus became his guardian.[6] Although little information about Aristotle\'s childhood has survived, he probably spent\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":8,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"d8ea40eb-cd48-5bd7-b2df-05f6268aed10\\",\\"score\\":0.636079056730387,\\"metadata\\":{\\"text\\":\\"Aristotle has been called the father of logic, biology, political science, zoology, embryology, natural law, scientific method, rhetoric, psychology, realism, criticism, individualism, teleology, and meteorology.[151]\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":177,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"b32f0e19-029f-5b3f-856c-e7e4141f52f5\\",\\"score\\":0.624098479747772,\\"metadata\\":{\\"text\\":\\"Among countless other achievements, Aristotle was the founder of formal logic,[146] pioneered the study of zoology, and left every future scientist and philosopher in his debt through his contributions to the scientific method.[2][147][148] Taneli Kukkonen, observes that his achievement in founding two sciences is unmatched, and his reach in influencing \\\\\\"every branch of intellectual enterprise\\\\\\" including Western ethical and political theory, theology, rhetoric, and literary analysis is equally long. As a\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":175,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"e6c5d5f6-7fc4-5bb8-847d-44cfa16f5178\\",\\"score\\":0.619364976882935,\\"metadata\\":{\\"text\\":\\"Little is known about Aristotle\'s life. He was born in the city of Stagira in northern Greece during the Classical period. His father, Nicomachus, died when Aristotle was a child, and he was brought up by a guardian. At 17 or 18, he joined Plato\'s Academy in Athens and remained there until the age of 37 (c.\\u2009347 BC). Shortly after Plato died, Aristotle left Athens and, at the request of Philip II of Macedon, tutored his son Alexander the Great beginning in 343 BC. He established a library in the Lyceum,\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":1,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"90b891ee-0a67-54ba-838a-e02e1647adab\\",\\"score\\":0.6177915291003779,\\"metadata\\":{\\"text\\":\\"Like his teacher Plato, Aristotle\'s philosophy aims at the universal. Aristotle\'s ontology places the universal (katholou) in particulars (kath\' hekaston), things in the world, whereas for Plato the universal is a separately existing form which actual things imitate. For Aristotle, \\\\\\"form\\\\\\" is still what phenomena are based on, but is \\\\\\"instantiated\\\\\\" in a particular substance.[34]\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":37,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"5f6213d1-a46b-5ed4-a15c-e95bab271621\\",\\"score\\":0.606411576271057,\\"metadata\\":{\\"text\\":\\"Aristotle was one of the most revered Western thinkers in early Islamic theology. Most of the still extant works of Aristotle,[167] as well as a number of the original Greek commentaries, were translated into Arabic and studied by Muslim philosophers, scientists and scholars. Averroes, Avicenna and Alpharabius, who wrote on Aristotle in great depth, also influenced Thomas Aquinas and other Western Christian scholastic philosophers. Alkindus greatly admired Aristotle\'s philosophy,[168] and Averroes spoke of\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":194,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"ce43de17-635c-5a01-aae2-e160a6d56f4b\\",\\"score\\":0.601802307421038,\\"metadata\\":{\\"text\\":\\"passed to Plato\'s nephew Speusippus, although it is possible that he feared the anti-Macedonian sentiments in Athens at that time and left before Plato died.[10] Aristotle then accompanied Xenocrates to the court of his friend Hermias of Atarneus in Asia Minor. After the death of Hermias, Aristotle travelled with his pupil Theophrastus to the island of Lesbos, where together they researched the botany and zoology of the island and its sheltered lagoon. While in Lesbos, Aristotle married Pythias, either\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":12,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"8550e2b7-43f8-5a59-9c13-c9678670a2da\\",\\"score\\":0.595871686935425,\\"metadata\\":{\\"text\\":\\"The immediate influence of Aristotle\'s work was felt as the Lyceum grew into the Peripatetic school. Aristotle\'s students included Aristoxenus, Dicaearchus, Demetrius of Phalerum, Eudemos of Rhodes, Harpalus, Hephaestion, Mnason of Phocis, Nicomachus, and Theophrastus. Aristotle\'s influence over Alexander the Great is seen in the latter\'s bringing with him on his expedition a host of zoologists, botanists, and researchers. He had also learned a great deal about Persian customs and traditions from his\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":181,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}"]', - }, - {"key": "search_query", "value": "who is aristotle?"}, - ], - }, - # {'run_id': ..., 'run_type': 'search', 'entries': [{'key': 'search_query', 'value': 'who is aristotle?'}, {'key': 'search_latency', 'value': '0.51'}, {'key': 'search_results', 'value': '["{\\"id\\":\\"7ed3a01c-88dc-5a58-a68b-6e5d9f292df2\\",\\"score\\":0.773841586847122,\\"metadata\\":{\\"text\\":\\"Aristotle[A] (Greek: \\u1f08\\u03c1\\u03b9\\u03c3\\u03c4\\u03bf\\u03c4\\u03ad\\u03bb\\u03b7\\u03c2 Aristot\\u00e9l\\u0113s, pronounced [aristot\\u00e9l\\u025b\\u02d0s]; 384\\u2013322 BC) was an Ancient Greek philosopher and polymath. His writings cover a broad range of subjects spanning the natural sciences, philosophy, linguistics, economics, politics, psychology, and the arts. As the founder of the Peripatetic school of philosophy in the Lyceum in Athens, he began the wider Aristotelian tradition that followed, which set the groundwork for the development of modern science.\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":0,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"e6f58828-2e6d-5eb1-94f3-efbc0b7c1699\\",\\"score\\":0.669298529624939,\\"metadata\\":{\\"text\\":\\"Aristotle was revered among medieval Muslim scholars as \\\\\\"The First Teacher\\\\\\", and among medieval Christians like Thomas Aquinas as simply \\\\\\"The Philosopher\\\\\\", while the poet Dante called him \\\\\\"the master of those who know\\\\\\". His works contain the earliest known formal study of logic, and were studied by medieval scholars such as Peter Abelard and Jean Buridan. Aristotle\'s influence on logic continued well into the 19th century. In addition, his ethics, although always influential, gained renewed interest with\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":5,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"c818bc72-2ac8-581b-b51a-0ca826f5f2b8\\",\\"score\\":0.652687707703574,\\"metadata\\":{\\"text\\":\\"Aristotle was born in 384 BC[C] in Stagira, Chalcidice,[2] about 55 km (34 miles) east of modern-day Thessaloniki.[3][4] His father, Nicomachus, was the personal physician to King Amyntas of Macedon. While he was young, Aristotle learned about biology and medical information, which was taught by his father.[5] Both of Aristotle\'s parents died when he was about thirteen, and Proxenus of Atarneus became his guardian.[6] Although little information about Aristotle\'s childhood has survived, he probably spent\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":8,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"d8ea40eb-cd48-5bd7-b2df-05f6268aed10\\",\\"score\\":0.636050164699554,\\"metadata\\":{\\"text\\":\\"Aristotle has been called the father of logic, biology, political science, zoology, embryology, natural law, scientific method, rhetoric, psychology, realism, criticism, individualism, teleology, and meteorology.[151]\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":177,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"b32f0e19-029f-5b3f-856c-e7e4141f52f5\\",\\"score\\":0.624127291194959,\\"metadata\\":{\\"text\\":\\"Among countless other achievements, Aristotle was the founder of formal logic,[146] pioneered the study of zoology, and left every future scientist and philosopher in his debt through his contributions to the scientific method.[2][147][148] Taneli Kukkonen, observes that his achievement in founding two sciences is unmatched, and his reach in influencing \\\\\\"every branch of intellectual enterprise\\\\\\" including Western ethical and political theory, theology, rhetoric, and literary analysis is equally long. As a\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":175,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"e6c5d5f6-7fc4-5bb8-847d-44cfa16f5178\\",\\"score\\":0.619364976882935,\\"metadata\\":{\\"text\\":\\"Little is known about Aristotle\'s life. He was born in the city of Stagira in northern Greece during the Classical period. His father, Nicomachus, died when Aristotle was a child, and he was brought up by a guardian. At 17 or 18, he joined Plato\'s Academy in Athens and remained there until the age of 37 (c.\\u2009347 BC). Shortly after Plato died, Aristotle left Athens and, at the request of Philip II of Macedon, tutored his son Alexander the Great beginning in 343 BC. He established a library in the Lyceum,\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":1,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"90b891ee-0a67-54ba-838a-e02e1647adab\\",\\"score\\":0.6177915291003779,\\"metadata\\":{\\"text\\":\\"Like his teacher Plato, Aristotle\'s philosophy aims at the universal. Aristotle\'s ontology places the universal (katholou) in particulars (kath\' hekaston), things in the world, whereas for Plato the universal is a separately existing form which actual things imitate. For Aristotle, \\\\\\"form\\\\\\" is still what phenomena are based on, but is \\\\\\"instantiated\\\\\\" in a particular substance.[34]\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":37,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"5f6213d1-a46b-5ed4-a15c-e95bab271621\\",\\"score\\":0.606407422018273,\\"metadata\\":{\\"text\\":\\"Aristotle was one of the most revered Western thinkers in early Islamic theology. Most of the still extant works of Aristotle,[167] as well as a number of the original Greek commentaries, were translated into Arabic and studied by Muslim philosophers, scientists and scholars. Averroes, Avicenna and Alpharabius, who wrote on Aristotle in great depth, also influenced Thomas Aquinas and other Western Christian scholastic philosophers. Alkindus greatly admired Aristotle\'s philosophy,[168] and Averroes spoke of\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":194,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"ce43de17-635c-5a01-aae2-e160a6d56f4b\\",\\"score\\":0.601802307421038,\\"metadata\\":{\\"text\\":\\"passed to Plato\'s nephew Speusippus, although it is possible that he feared the anti-Macedonian sentiments in Athens at that time and left before Plato died.[10] Aristotle then accompanied Xenocrates to the court of his friend Hermias of Atarneus in Asia Minor. After the death of Hermias, Aristotle travelled with his pupil Theophrastus to the island of Lesbos, where together they researched the botany and zoology of the island and its sheltered lagoon. While in Lesbos, Aristotle married Pythias, either\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":12,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"8550e2b7-43f8-5a59-9c13-c9678670a2da\\",\\"score\\":0.5959202888059449,\\"metadata\\":{\\"text\\":\\"The immediate influence of Aristotle\'s work was felt as the Lyceum grew into the Peripatetic school. Aristotle\'s students included Aristoxenus, Dicaearchus, Demetrius of Phalerum, Eudemos of Rhodes, Harpalus, Hephaestion, Mnason of Phocis, Nicomachus, and Theophrastus. Aristotle\'s influence over Alexander the Great is seen in the latter\'s bringing with him on his expedition a host of zoologists, botanists, and researchers. He had also learned a great deal about Persian customs and traditions from his\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":181,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"1175585b-fc58-5e44-bfcb-cb1996289936\\",\\"score\\":0.594988668263635,\\"metadata\\":{\\"text\\":\\"after friends and relatives, and to deal with the latter as with beasts or plants\\\\\\".[13] By 335 BC, Aristotle had returned to Athens, establishing his own school there known as the Lyceum. Aristotle conducted courses at the school for the next twelve years. While in Athens, his wife Pythias died and Aristotle became involved with Herpyllis of Stagira. They had a son whom Aristotle named after his father, Nicomachus. If the Suda \\u2013 an uncritical compilation from the Middle Ages \\u2013 is accurate, he may also have\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":16,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"8f8f5140-2d4b-5877-9cfb-d2df590831c2\\",\\"score\\":0.5928938565520601,\\"metadata\\":{\\"text\\":\\"In Protrepticus, the character \'Aristotle\' states:[123]\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":147,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"ee40bbc8-16f7-5808-8f14-c8fd16391cfc\\",\\"score\\":0.591026663780212,\\"metadata\\":{\\"text\\":\\"Transmission\\\\nFurther information: List of writers influenced by Aristotle\\\\nMore than 2300 years after his death, Aristotle remains one of the most influential people who ever lived.[142][143][144] He contributed to almost every field of human knowledge then in existence, and he was the founder of many new fields. According to the philosopher Bryan Magee, \\\\\\"it is doubtful whether any human being has ever known as much as he did\\\\\\".[145]\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":174,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"703219b2-3284-533f-8df7-fee42f52c3d2\\",\\"score\\":0.5850032146276001,\\"metadata\\":{\\"text\\":\\"At the age of seventeen or eighteen, Aristotle moved to Athens to continue his education at Plato\'s Academy.[8] He probably experienced the Eleusinian Mysteries as he wrote when describing the sights one viewed at the Eleusinian Mysteries, \\\\\\"to experience is to learn\\\\\\" [\\u03c0\\u03b1\\u03b8\\u03b5\\u03af\\u03bd \\u03bc\\u03b1\\u03b8\\u03b5\\u0129\\u03bd].[9] Aristotle remained in Athens for nearly twenty years before leaving in 348/47 BC. The traditional story about his departure records that he was disappointed with the Academy\'s direction after control passed to Plato\'s\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":11,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"044a1a8a-7661-52b9-af63-83c243216d34\\",\\"score\\":0.5834955821337959,\\"metadata\\":{\\"text\\":\\"\\u2014\\u200aAristotle. Politics, Book 4, 1294b.10\\u201318\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":152,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"4173b9bc-4b39-5dc1-b9af-a2fc0e282389\\",\\"score\\":0.5787635539488301,\\"metadata\\":{\\"text\\":\\"This period in Athens, between 335 and 323 BC, is when Aristotle is believed to have composed many of his works.[12] He wrote many dialogues, of which only fragments have survived. Those works that have survived are in treatise form and were not, for the most part, intended for widespread publication; they are generally thought to be lecture aids for his students. His most important treatises include Physics, Metaphysics, Nicomachean Ethics, Politics, On the Soul and Poetics. Aristotle studied and made\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":19,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"038127f5-6603-5258-8658-7c60eaf3dae3\\",\\"score\\":0.575957238674164,\\"metadata\\":{\\"text\\":\\"Averroes spoke of Aristotle as the \\\\\\"exemplar\\\\\\" for all future philosophers.[169] Medieval Muslim scholars regularly described Aristotle as the \\\\\\"First Teacher\\\\\\".[167] The title was later used by Western philosophers (as in the famous poem of Dante) who were influenced by the tradition of Islamic philosophy.[170]\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":195,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"5fb90839-d04c-50b0-8f7f-ffc1a938c019\\",\\"score\\":0.574642419815063,\\"metadata\\":{\\"text\\":\\"Aristotle was appointed as the head of the royal Academy of Macedon. During Aristotle\'s time in the Macedonian court, he gave lessons not only to Alexander but also to two other future kings: Ptolemy and Cassander.[13] Aristotle encouraged Alexander toward eastern conquest, and Aristotle\'s own attitude towards Persia was unabashedly ethnocentric. In one famous example, he counsels Alexander to be \\\\\\"a leader to the Greeks and a despot to the barbarians, to look after the former as after friends and\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":15,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"76a117a7-706b-5d7f-a856-e5fc4bb0d8a2\\",\\"score\\":0.5701740640298101,\\"metadata\\":{\\"text\\":\\"Life\\\\nIn general, the details of Aristotle\'s life are not well-established. The biographies written in ancient times are often speculative and historians only agree on a few salient points.[B]\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":7,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"d64af737-640e-5ea0-9259-4c83638a714d\\",\\"score\\":0.565754532814026,\\"metadata\\":{\\"text\\":\\"Aristotle was the first person to study biology systematically,[61] and biology forms a large part of his writings. He spent two years observing and describing the zoology of Lesbos and the surrounding seas, including in particular the Pyrrha lagoon in the centre of Lesbos.[62][63] His data in History of Animals, Generation of Animals, Movement of Animals, and Parts of Animals are assembled from his own observations,[64] statements given by people with specialized knowledge, such as beekeepers and\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":85,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"d00de43e-11c4-59b9-ba09-c16ad525a3d3\\",\\"score\\":0.56225860118866,\\"metadata\\":{\\"text\\":\\"Aristotle wrote his works on papyrus scrolls, the common writing medium of that era.[O] His writings are divisible into two groups: the \\\\\\"exoteric\\\\\\", intended for the public, and the \\\\\\"esoteric\\\\\\", for use within the Lyceum school.[208][P][209] Aristotle\'s \\\\\\"lost\\\\\\" works stray considerably in characterization from the surviving Aristotelian corpus. Whereas the lost works appear to have been originally written with a view to subsequent publication, the surviving works mostly resemble lecture notes not intended for\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":222,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"dec8fec3-2b27-554b-b953-27db6a221078\\",\\"score\\":0.561229228973389,\\"metadata\\":{\\"text\\":\\"Aristotle\'s views profoundly shaped medieval scholarship. The influence of his physical science extended from late antiquity and the Early Middle Ages into the Renaissance, and was not replaced systematically until the Enlightenment and theories such as classical mechanics were developed. He influenced Judeo-Islamic philosophies during the Middle Ages, as well as Christian theology, especially the Neoplatonism of the Early Church and the scholastic tradition of the Catholic Church.\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":4,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"eb18cdd3-981e-54bb-835d-5988776c5bb9\\",\\"score\\":0.557450473308563,\\"metadata\\":{\\"text\\":\\"With the loss of the study of ancient Greek in the early medieval Latin West, Aristotle was practically unknown there from c.\\u2009CE 600 to c.\\u20091100 except through the Latin translation of the Organon made by Boethius. In the twelfth and thirteenth centuries, interest in Aristotle revived and Latin Christians had translations made, both from Arabic translations, such as those by Gerard of Cremona,[171] and from the original Greek, such as those by James of Venice and William of Moerbeke.\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":197,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"40014d76-eba6-5a2a-9c2b-672ac6ddd212\\",\\"score\\":0.557388577305591,\\"metadata\\":{\\"text\\":\\"The Dutch historian of science Eduard Jan Dijksterhuis writes that Aristotle and his predecessors showed the difficulty of science by \\\\\\"proceed[ing] so readily to frame a theory of such a general character\\\\\\" on limited evidence from their senses.[192] In 1985, the biologist Peter Medawar could still state in \\\\\\"pure seventeenth century\\\\\\"[193] tones that Aristotle had assembled \\\\\\"a strange and generally speaking rather tiresome farrago of hearsay, imperfect observation, wishful thinking and credulity amounting to\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":212,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"65c3d9cd-0ab5-5ef7-8296-a1baeff3592d\\",\\"score\\":0.5566293664728881,\\"metadata\\":{\\"text\\":\\"Aristotle made substantial contributions to economic thought, especially to thought in the Middle Ages.[128] In Politics, Aristotle addresses the city, property, and trade. His response to criticisms of private property, in Lionel Robbins\'s view, anticipated later proponents of private property among philosophers and economists, as it related to the overall utility of social arrangements.[128] Aristotle believed that although communal arrangements may seem beneficial to society, and that although private\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":156,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"a2cc5fc4-99a4-53c5-8c74-2c68399f2a7e\\",\\"score\\":0.549582594682865,\\"metadata\\":{\\"text\\":\\"Practical philosophy\\\\nAristotle\'s practical philosophy covers areas such as ethics, politics, economics, and rhetoric.[40]\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":134,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"27a6a904-7b94-59ca-81ea-8b99b2816f81\\",\\"score\\":0.547278100576631,\\"metadata\\":{\\"text\\":\\"After the Scholastic Thomas Aquinas wrote his Summa Theologica, working from Moerbeke\'s translations and calling Aristotle \\\\\\"The Philosopher\\\\\\",[172] the demand for Aristotle\'s writings grew, and the Greek manuscripts returned to the West, stimulating a revival of Aristotelianism in Europe that continued into the Renaissance.[173] These thinkers blended Aristotelian philosophy with Christianity, bringing the thought of Ancient Greece into the Middle Ages. Scholars such as Boethius, Peter Abelard, and John\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":198,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"d4fcaaff-1d1e-5ed4-8d60-6a71a5721ea4\\",\\"score\\":0.544766214801896,\\"metadata\\":{\\"text\\":\\"Aristotle\'s view, incapable of participating in political life.[124] On this ground, proponents of feminist metaphysics have accused Aristotle of misogyny[125] and sexism.[126] However, Aristotle gave equal weight to women\'s happiness as he did to men\'s, and commented in his Rhetoric that the things that lead to happiness need to be in women as well as men.[N]\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":154,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"fe38e23d-4798-5cd3-8d42-e858f7e97537\\",\\"score\\":0.54476398229599,\\"metadata\\":{\\"text\\":\\"Theoretical philosophy\\\\nLogic\\\\nMain article: Term logic\\\\nFurther information: Non-Aristotelian logic\\\\nWith the Prior Analytics, Aristotle is credited with the earliest study of formal logic,[23] and his conception of it was the dominant form of Western logic until 19th-century advances in mathematical logic.[24] Kant stated in the Critique of Pure Reason that with Aristotle, logic reached its completion.[25]\\\\n\\\\nOrganon\\\\nMain article: Organon\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":23,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"b29f4f0e-c033-5613-a8fa-62ea11f951ed\\",\\"score\\":0.5409726500511169,\\"metadata\\":{\\"text\\":\\"Zoologists have frequently mocked Aristotle for errors and unverified secondhand reports. However, modern observation has confirmed several of his more surprising claims.[195][196][197] Aristotle\'s work remains largely unknown to modern scientists, though zoologists sometimes mention him as the father of biology[150] or in particular of marine biology.[198] Practising zoologists are unlikely to adhere to Aristotle\'s chain of being, but its influence is still perceptible in the use of the terms \\\\\\"lower\\\\\\" and\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":214,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"cb6775dd-85a1-5e62-bd23-b00842a34231\\",\\"score\\":0.53917521238327,\\"metadata\\":{\\"text\\":\\"Ethics\\\\nMain article: Aristotelian ethics\\\\nAristotle considered ethics to be a practical rather than theoretical study, i.e., one aimed at becoming good and doing good rather than knowing for its own sake. He wrote several treatises on ethics, most notably including the Nicomachean Ethics.[117]\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":136,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"31ddcd60-5b19-5b9c-9f47-6b144001308f\\",\\"score\\":0.5359366855583609,\\"metadata\\":{\\"text\\":\\"Aristotle has been depicted by major artists including Lucas Cranach the Elder,[218] Justus van Gent, Raphael, Paolo Veronese, Jusepe de Ribera,[219] Rembrandt,[220] and Francesco Hayez over the centuries. Among the best-known depictions is Raphael\'s fresco The School of Athens, in the Vatican\'s Apostolic Palace, where the figures of Plato and Aristotle are central to the image, at the architectural vanishing point, reflecting their importance.[221] Rembrandt\'s Aristotle with a Bust of Homer, too, is a\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":231,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"c3c15401-51cf-5c53-8182-feac4f7fc6cf\\",\\"score\\":0.535427896056898,\\"metadata\\":{\\"text\\":\\"Though Aristotle wrote many elegant treatises and dialogues for publication, only around a third of his original output has survived, none of it intended for publication. Aristotle provided a complex synthesis of the various philosophies existing prior to him. His teachings and methods of inquiry have had a significant impact across the world, and remain a subject of contemporary philosophical discussion.\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":3,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"b5da0460-6b55-550a-ad14-3eae61df567f\\",\\"score\\":0.53429651260376,\\"metadata\\":{\\"text\\":\\"Aristotle\'s views on women influenced later Western philosophers, who quoted him as an authority until the end of the Middle Ages, but these views have been controversial in modern times. Aristotle\'s analysis of procreation describes an active, ensouling masculine element bringing life to an inert, passive female element. The biological differences are a result of the fact that the female body is well-suited for reproduction, which changes her body temperature, which in turn makes her, in Aristotle\'s view,\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":153,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"bbb9c9e5-c084-5068-ac8a-019c8441eebb\\",\\"score\\":0.532585024833679,\\"metadata\\":{\\"text\\":\\"The scholar Taneli Kukkonen notes that \\\\\\"in the best 20th-century scholarship Aristotle comes alive as a thinker wrestling with the full weight of the Greek philosophical tradition.\\\\\\"[148] What follows is an overview of the transmission and influence of his texts and ideas into the modern era.\\\\n\\\\nHis successor, Theophrastus\\\\nMain articles: Theophrastus and Historia Plantarum (Theophrastus)\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":178,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"8b9081fd-5603-5704-9ba6-8957525f0c05\\",\\"score\\":0.532379746437073,\\"metadata\\":{\\"text\\":\\"Politics\\\\nMain article: Politics (Aristotle)\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":141,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"f56f324f-e2fe-5552-b4fd-a2324d080e97\\",\\"score\\":0.5316953063011169,\\"metadata\\":{\\"text\\":\\"equally long. As a result, Kukkonen argues, any analysis of reality today \\\\\\"will almost certainly carry Aristotelian overtones ... evidence of an exceptionally forceful mind.\\\\\\"[148] Jonathan Barnes wrote that \\\\\\"an account of Aristotle\'s intellectual afterlife would be little less than a history of European thought\\\\\\".[149]\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":176,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"1e64fff6-6f61-5490-8743-4947487cced2\\",\\"score\\":0.5270282030105591,\\"metadata\\":{\\"text\\":\\"Present science\\\\nThe philosopher Bertrand Russell claims that \\\\\\"almost every serious intellectual advance has had to begin with an attack on some Aristotelian doctrine\\\\\\". Russell calls Aristotle\'s ethics \\\\\\"repulsive\\\\\\", and labelled his logic \\\\\\"as definitely antiquated as Ptolemaic astronomy\\\\\\". Russell states that these errors make it difficult to do historical justice to Aristotle, until one remembers what an advance he made upon all of his predecessors.[191]\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":211,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"68446969-0dbf-5cbb-852a-07612d886c46\\",\\"score\\":0.525567233562469,\\"metadata\\":{\\"text\\":\\"Plato (left) and Aristotle in Raphael\'s 1509 fresco, The School of Athens. Aristotle holds his Nicomachean Ethics and gestures to the earth, representing his view in immanent realism, whilst Plato gestures to the heavens, indicating his Theory of Forms, and holds his Timaeus.[26][27]\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":24,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"794a7a47-8157-5a75-b3d4-7bd51dd9f04e\\",\\"score\\":0.523991107940674,\\"metadata\\":{\\"text\\":\\"The works of Aristotle that have survived from antiquity through medieval manuscript transmission are collected in the Corpus Aristotelicum. These texts, as opposed to Aristotle\'s lost works, are technical philosophical treatises from within Aristotle\'s school.[205] Reference to them is made according to the organization of Immanuel Bekker\'s Royal Prussian Academy edition (Aristotelis Opera edidit Academia Regia Borussica, Berlin, 1831\\u20131870), which in turn is based on ancient classifications of these\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":219,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"30561c1d-cdf7-5281-beb5-25d98903fb8f\\",\\"score\\":0.523762373700001,\\"metadata\\":{\\"text\\":\\"Charles Darwin regarded Aristotle as the most important contributor to the subject of biology. In an 1882 letter he wrote that \\\\\\"Linnaeus and Cuvier have been my two gods, though in very different ways, but they were mere schoolboys to old Aristotle\\\\\\".[187][188] Also, in later editions of the book \\\\\\"On the Origin of Species\', Darwin traced evolutionary ideas as far back as Aristotle;[189] the text he cites is a summary by Aristotle of the ideas of the earlier Greek philosopher Empedocles.[190]\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":210,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"a0dafc12-79f1-506c-8916-41733f864a76\\",\\"score\\":0.522506475448608,\\"metadata\\":{\\"text\\":\\"traditions from his teacher. Although his respect for Aristotle was diminished as his travels made it clear that much of Aristotle\'s geography was clearly wrong, when the old philosopher released his works to the public, Alexander complained \\\\\\"Thou hast not done well to publish thy acroamatic doctrines; for in what shall I surpass other men if those doctrines wherein I have been trained are to be all men\'s common property?\\\\\\"[155]\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":182,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"d2e3d3b2-a20d-510a-a96f-9705b02411be\\",\\"score\\":0.5219854116439819,\\"metadata\\":{\\"text\\":\\"Moses Maimonides (considered to be the foremost intellectual figure of medieval Judaism)[179] adopted Aristotelianism from the Islamic scholars and based his Guide for the Perplexed on it and that became the basis of Jewish scholastic philosophy. Maimonides also considered Aristotle to be the greatest philosopher that ever lived, and styled him as the \\\\\\"chief of the philosophers\\\\\\".[180][181][182] Also, in his letter to Samuel ibn Tibbon, Maimonides observes that there is no need for Samuel to study the\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":203,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"c2c7aa9c-8a52-5ccf-b5e6-ab9e918cac18\\",\\"score\\":0.5219346284866331,\\"metadata\\":{\\"text\\":\\"Metaphysics\\\\nMain article: Metaphysics (Aristotle)\\\\nThe word \\\\\\"metaphysics\\\\\\" appears to have been coined by the first century AD editor who assembled various small selections of Aristotle\'s works to the treatise we know by the name Metaphysics.[34] Aristotle called it \\\\\\"first philosophy\\\\\\", and distinguished it from mathematics and natural science (physics) as the contemplative (theoretik\\u0113) philosophy which is \\\\\\"theological\\\\\\" and studies the divine. He wrote in his Metaphysics (1026a16):\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":30,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"fad6a42d-845f-5f75-9416-560f6bdfc622\\",\\"score\\":0.5203073620796199,\\"metadata\\":{\\"text\\":\\"Near the end of his life, Alexander and Aristotle became estranged over Alexander\'s relationship with Persia and Persians. A widespread tradition in antiquity suspected Aristotle of playing a role in Alexander\'s death, but the only evidence of this is an unlikely claim made some six years after the death.[16] Following Alexander\'s death, anti-Macedonian sentiment in Athens was rekindled. In 322 BC, Demophilus and Eurymedon the Hierophant reportedly denounced Aristotle for impiety,[17] prompting him to flee\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":21,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"ccfa969d-8634-5dd8-8b8f-e664667f95a0\\",\\"score\\":0.520039439201355,\\"metadata\\":{\\"text\\":\\"In addition to his works on ethics, which address the individual, Aristotle addressed the city in his work titled Politics. Aristotle considered the city to be a natural community. Moreover, he considered the city to be prior in importance to the family, which in turn is prior to the individual, \\\\\\"for the whole must of necessity be prior to the part\\\\\\".[120] He famously stated that \\\\\\"man is by nature a political animal\\\\\\" and argued that humanity\'s defining factor among others in the animal kingdom is its\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":142,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"f5db5c10-ace8-5a28-9b15-d1ef88ac2754\\",\\"score\\":0.519339799880981,\\"metadata\\":{\\"text\\":\\"sense, Aristotle\'s biology is scientific.[78]\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":96,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"5c80f870-f275-5109-a752-5f9e0caf859c\\",\\"score\\":0.517741410866893,\\"metadata\\":{\\"text\\":\\"Aristotle\'s \\\\\\"natural philosophy\\\\\\" spans a wide range of natural phenomena including those now covered by physics, biology and other natural sciences.[40] In Aristotle\'s terminology, \\\\\\"natural philosophy\\\\\\" is a branch of philosophy examining the phenomena of the natural world, and includes fields that would be regarded today as physics, biology and other natural sciences. Aristotle\'s work encompassed virtually all facets of intellectual inquiry. Aristotle makes philosophy in the broad sense coextensive with\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":51,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"87154733-18e0-56c0-9d00-a6e3d3601277\\",\\"score\\":0.513434050865886,\\"metadata\\":{\\"text\\":\\"Aristotle\'s writings on motion remained influential until the Early Modern period. John Philoponus (in Late antiquity) and Galileo (in Early modern period) are said to have shown by experiment that Aristotle\'s claim that a heavier object falls faster than a lighter object is incorrect.[40] A contrary opinion is given by Carlo Rovelli, who argues that Aristotle\'s physics of motion is correct within its domain of validity, that of objects in the Earth\'s gravitational field immersed in a fluid such as air. In\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":64,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"d7fed20f-2710-529e-8518-33e31335ee4e\\",\\"score\\":0.513187944889069,\\"metadata\\":{\\"text\\":\\"Aristotle taught that virtue has to do with the proper function (ergon) of a thing. An eye is only a good eye in so much as it can see, because the proper function of an eye is sight. Aristotle reasoned that humans must have a function specific to humans, and that this function must be an activity of the psuch\\u0113 (soul) in accordance with reason (logos). Aristotle identified such an optimum activity (the virtuous mean, between the accompanying vices of excess or deficiency[15]) of the soul as the aim of all\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":137,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"604d5540-35cf-5575-90ac-e77cddf30b79\\",\\"score\\":0.50912079269414,\\"metadata\\":{\\"text\\":\\"Aristotle also made many observations about the hydrologic cycle. For example, he made some of the earliest observations about desalination: he observed early \\u2013 and correctly \\u2013 that when seawater is heated, freshwater evaporates and that the oceans are then replenished by the cycle of rainfall and river runoff (\\\\\\"I have proved by experiment that salt water evaporated forms fresh and the vapor does not when it condenses condense into sea water again.\\\\\\")[60]\\\\n\\\\nBiology\\\\nMain article: Aristotle\'s biology\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":83,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"a1d385d3-062f-5b72-9ee6-8b6ba0d68140\\",\\"score\\":0.506430864334106,\\"metadata\\":{\\"text\\":\\"According to Strabo and Plutarch, after Aristotle\'s death, his library and writings went to Theophrastus (Aristotle\'s successor as head of the Lycaeum and the Peripatetic school).[215] After the death of Theophrastus, the peripatetic library went to Neleus of Scepsis.[216]:\\u200a5\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":225,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"3f156748-3db2-5d2a-bce2-4267f9b46784\\",\\"score\\":0.502232283220752,\\"metadata\\":{\\"text\\":\\"Most of Aristotle\'s work is probably not in its original form, because it was most likely edited by students and later lecturers. The logical works of Aristotle were compiled into a set of six books called the Organon around 40 BC by Andronicus of Rhodes or others among his followers.[28] The books are:\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":25,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"75295549-fd8c-562c-8a19-26ba3276c9e8\\",\\"score\\":0.500771760848554,\\"metadata\\":{\\"text\\":\\"Islamic portrayal of Aristotle (right) in the Kit\\u0101b na\\u02bft al-\\u1e25ayaw\\u0101n, c.\\u20091220.[166]\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":193,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"bf8a1c08-f7fb-5636-83bf-87b9af9561e1\\",\\"score\\":0.500191748119388,\\"metadata\\":{\\"text\\":\\"Aristotle did not do experiments in the modern sense.[74] He used the ancient Greek term pepeiramenoi to mean observations, or at most investigative procedures like dissection.[75] In Generation of Animals, he finds a fertilized hen\'s egg of a suitable stage and opens it to see the embryo\'s heart beating inside.[76][77]\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":94,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"ace70c54-12d0-5dc2-9b27-b566e985e0f7\\",\\"score\\":0.49837121377162896,\\"metadata\\":{\\"text\\":\\"Portrait bust of Aristotle; an Imperial Roman (1st or 2nd century AD) copy of a lost bronze sculpture made by Lysippos.\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":18,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"900f6eb4-d13b-5129-9ed6-3f78b31b83b1\\",\\"score\\":0.49812573194503795,\\"metadata\\":{\\"text\\":\\"The first medical teacher at Alexandria, Herophilus of Chalcedon, corrected Aristotle, placing intelligence in the brain, and connected the nervous system to motion and sensation. Herophilus also distinguished between veins and arteries, noting that the latter pulse while the former do not.[157] Though a few ancient atomists such as Lucretius challenged the teleological viewpoint of Aristotelian ideas about life, teleology (and after the rise of Christianity, natural theology) would remain central to\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":184,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"4c6bf2b3-9140-5fe5-adba-27579b339647\\",\\"score\\":0.49481466443451305,\\"metadata\\":{\\"text\\":\\"One of Aristotle\'s types of syllogism[D]\\\\nIn words\\\\tIn\\\\nterms[E]\\\\tIn equations[F]\\\\n All men are mortal.\\\\n\\\\n All Greeks are men.\\\\n\\\\n\\u2234 All Greeks are mortal.\\\\tM a P\\\\n\\\\nS a M\\\\n\\\\nS a P\\\\nWhat is today called Aristotelian logic with its types of syllogism (methods of logical argument),[32] Aristotle himself would have labelled \\\\\\"analytics\\\\\\". The term \\\\\\"logic\\\\\\" he reserved to mean dialectics.\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":29,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"d1966c66-9f90-5d28-81c2-80e662e3b977\\",\\"score\\":0.49248007029532903,\\"metadata\\":{\\"text\\":\\"terms \\\\\\"lower\\\\\\" and \\\\\\"upper\\\\\\" to designate taxa such as groups of plants.[199] The evolutionary biologist Armand Marie Leroi has reconstructed Aristotle\'s biology,[200] while Niko Tinbergen\'s four questions, based on Aristotle\'s four causes, are used to analyse animal behaviour; they examine function, phylogeny, mechanism, and ontogeny.[201][202] The concept of homology began with Aristotle;[203] the evolutionary developmental biologist Lewis I. Held commented that he would be interested in the concept of deep\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":215,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"2eeb68da-6525-56d6-be4d-d42ab93c4172\\",\\"score\\":0.49181364403489203,\\"metadata\\":{\\"text\\":\\"Aristotle taught that to achieve a virtuous and potentially happy character requires a first stage of having the fortune to be habituated not deliberately, but by teachers, and experience, leading to a later stage in which one consciously chooses to do the best things. When the best people come to live life this way their practical wisdom (phronesis) and their intellect (nous) can develop with each other towards the highest possible human virtue, the wisdom of an accomplished theoretical or speculative\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":139,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"93bcfe9d-e093-5543-b47b-3e0b9b075801\\",\\"score\\":0.491194203233546,\\"metadata\\":{\\"text\\":\\"Aristotle was one of the first people to record any geological observations. He stated that geological change was too slow to be observed in one person\'s lifetime.[56][57] The geologist Charles Lyell noted that Aristotle described such change, including \\\\\\"lakes that had dried up\\\\\\" and \\\\\\"deserts that had become watered by rivers\\\\\\", giving as examples the growth of the Nile delta since the time of Homer, and \\\\\\"the upheaving of one of the Aeolian islands, previous to a volcanic eruption.\\\\\\"\'[58]\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":81,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"399db731-efe2-5198-84b7-5b9cdf6d3a08\\",\\"score\\":0.48828518320829895,\\"metadata\\":{\\"text\\":\\"Poetics\\\\nMain article: Poetics (Aristotle)\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":166,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"8f369acc-7504-5cec-ad88-89cb1d3889c0\\",\\"score\\":0.487353653469465,\\"metadata\\":{\\"text\\":\\"Epistemology\\\\nAristotle\'s immanent realism means his epistemology is based on the study of things that exist or happen in the world, and rises to knowledge of the universal, whereas for Plato epistemology begins with knowledge of universal Forms (or ideas) and descends to knowledge of particular imitations of these.[31] Aristotle uses induction from examples alongside deduction, whereas Plato relies on deduction from a priori principles.[31]\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":49,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"084c501e-c5e7-53c8-9316-4734ba5f5045\\",\\"score\\":0.48603272438049305,\\"metadata\\":{\\"text\\":\\"Through meticulous commentaries and critical engagements, figures like Al-Farabi and Ibn Sina (Avicenna) breathed new life into Aristotle\'s ideas. They harmonized his logic with Islamic theology, employed his scientific methodologies to explore the natural world, and even reinterpreted his ethics within the framework of Islamic morality. This revival was not mere imitation. Islamic thinkers embraced Aristotle\'s rigorous methods while simultaneously challenging his conclusions where they diverged from their\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":187,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"a4c8191b-7a5c-576b-883d-4ffdc9840553\\",\\"score\\":0.484963147936056,\\"metadata\\":{\\"text\\":\\"Greek Christian scribes played a crucial role in the preservation of Aristotle by copying all the extant Greek language manuscripts of the corpus. The first Greek Christians to comment extensively on Aristotle were Philoponus, Elias, and David in the sixth century, and Stephen of Alexandria in the early seventh century.[162] John Philoponus stands out for having attempted a fundamental critique of Aristotle\'s views on the eternity of the world, movement, and other elements of Aristotelian thought.[163]\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":190,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"65c94370-53be-543f-bf07-c9c8ac8a5b3c\\",\\"score\\":0.48229515552520796,\\"metadata\\":{\\"text\\":\\"is Aristotle\'s division of sensation and thought, which generally differed from the concepts of previous philosophers, with the exception of Alcmaeon.[95]\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":111,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"b95901dc-798d-5206-994d-9948ebf10aba\\",\\"score\\":0.48190322518348705,\\"metadata\\":{\\"text\\":\\"coextensive with reasoning, which he also would describe as \\\\\\"science\\\\\\". However, his use of the term science carries a different meaning than that covered by the term \\\\\\"scientific method\\\\\\". For Aristotle, \\\\\\"all science (dianoia) is either practical, poetical or theoretical\\\\\\" (Metaphysics 1025b25). His practical science includes ethics and politics; his poetical science means the study of fine arts including poetry; his theoretical science covers physics, mathematics and metaphysics.[40]\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":52,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"7d161587-aad7-5a0a-9e16-01b8542cb93c\\",\\"score\\":0.47876675237120203,\\"metadata\\":{\\"text\\":\\"\\\\\\"Aristotle tutoring Alexander\\\\\\" by Jean Leon Gerome Ferris.\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":14,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"c890996c-f87d-51f2-8d47-316d460893f3\\",\\"score\\":0.477234495630966,\\"metadata\\":{\\"text\\":\\"Samuel to study the writings of philosophers who preceded Aristotle because the works of the latter are \\\\\\"sufficient by themselves and [superior] to all that were written before them. His intellect, Aristotle\'s is the extreme limit of human intellect, apart from him upon whom the divine emanation has flowed forth to such an extent that they reach the level of prophecy, there being no level higher\\\\\\".[183]\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":204,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"c2892882-5619-5283-a785-c1701168b0c9\\",\\"score\\":0.476796509218425,\\"metadata\\":{\\"text\\":\\"As Plato\'s disciple Aristotle was rather critical concerning democracy and, following the outline of certain ideas from Plato\'s Statesman, he developed a coherent theory of integrating various forms of power into a so-called mixed state:\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":150,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"91f7b4b9-700c-581c-bac0-028515f34bae\\",\\"score\\":0.47289261221885703,\\"metadata\\":{\\"text\\":\\"Aristotle suggested that the reason for anything coming about can be attributed to four different types of simultaneously active factors. His term aitia is traditionally translated as \\\\\\"cause\\\\\\", but it does not always refer to temporal sequence; it might be better translated as \\\\\\"explanation\\\\\\", but the traditional rendering will be employed here.[48][49]\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":68,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"195a8d75-0627-5531-bef5-5354cbfd8bdf\\",\\"score\\":0.472823365712862,\\"metadata\\":{\\"text\\":\\"Byzantine scholars\\\\nSee also: Commentaries on Aristotle and Byzantine Aristotelianism\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":189,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"e639d635-0587-59dc-b038-21633a6e025d\\",\\"score\\":0.47108021378517195,\\"metadata\\":{\\"text\\":\\"The order of the books (or the teachings from which they are composed) is not certain, but this list was derived from analysis of Aristotle\'s writings. It goes from the basics, the analysis of simple terms in the Categories, the analysis of propositions and their elementary relations in On Interpretation, to the study of more complex forms, namely, syllogisms (in the Analytics)[29][30] and dialectics (in the Topics and Sophistical Refutations). The first three treatises form the core of the logical theory\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":27,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"7f0b2712-d35d-5ceb-bacb-04b3916a9cc2\\",\\"score\\":0.46897770371966696,\\"metadata\\":{\\"text\\":\\"Aristotle believed the chain of thought, which ends in recollection of certain impressions, was connected systematically in relationships such as similarity, contrast, and contiguity, described in his laws of association. Aristotle believed that past experiences are hidden within the mind. A force operates to awaken the hidden material to bring up the actual experience. According to Aristotle, association is the power innate in a mental state, which operates upon the unexpressed remains of former\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":123,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"ed4d0d2c-73dc-5baa-8351-065482dbdf9b\\",\\"score\\":0.46736327008227996,\\"metadata\\":{\\"text\\":\\"According to scholar Roger Theodore Lafferty, Dante built up the philosophy of the Comedy with the works of Aristotle as a foundation, just as the scholastics used Aristotle as the basis for their thinking. Dante knew Aristotle directly from Latin translations of his works and indirectly through quotations in the works of Albert Magnus.[175] Dante even acknowledges Aristotle\'s influence explicitly in the poem, specifically when Virgil justifies the Inferno\'s structure by citing the Nicomachean Ethics.[176]\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":200,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"e7513658-792c-5fb4-9458-162178a5b72b\\",\\"score\\":0.465195149183273,\\"metadata\\":{\\"text\\":\\"but while Aristotle was aware that new mutations or hybridizations could occur, he saw these as rare accidents. For Aristotle, accidents, like heat waves in winter, must be considered distinct from natural causes. He was thus critical of Empedocles\'s materialist theory of a \\\\\\"survival of the fittest\\\\\\" origin of living things and their organs, and ridiculed the idea that accidents could lead to orderly results.[72] To put his views into modern terms, he nowhere says that different species can have a common\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":90,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"f475f7c3-1f6a-5867-8e0c-af0054425446\\",\\"score\\":0.46305066347122203,\\"metadata\\":{\\"text\\":\\"When Sulla seized Athens in 86 BC, he seized the library and transferred it to Rome. There, Andronicus of Rhodes organized the texts into the first complete edition of Aristotle\'s works (and works attributed to him).[217] The Aristotelian texts we have today are based on these.[216]:\\u200a6\\u20138\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":229,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"a586637b-49bb-59c8-b33a-5db313349a89\\",\\"score\\":0.462634655080161,\\"metadata\\":{\\"text\\":\\"Aristotle distinguished about 500 species of animals,[82][83] arranging these in the History of Animals in a graded scale of perfection, a nonreligious version of the scala naturae, with man at the top. His system had eleven grades of animal, from highest potential to lowest, expressed in their form at birth: the highest gave live birth to hot and wet creatures, the lowest laid cold, dry mineral-like eggs. Animals came above plants, and these in turn were above minerals.[84][85] He grouped what the modern\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":101,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"e3fecc19-7a17-59c2-ba78-f5f2b7c98fb9\\",\\"score\\":0.46187688069435096,\\"metadata\\":{\\"text\\":\\"School of Aristotle in Mieza, Macedonia, Greece.\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":10,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"baddd21e-a650-5789-b8ef-cfe8468da3dc\\",\\"score\\":0.45838105430490195,\\"metadata\\":{\\"text\\":\\"Plato\'s forms exist as universals, like the ideal form of an apple. For Aristotle, both matter and form belong to the individual thing (hylomorphism).\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":36,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"e15c86e4-94c7-5b98-aafa-64f117bd3e75\\",\\"score\\":0.45783278597398,\\"metadata\\":{\\"text\\":\\"about it.[98] Aristotle\'s other criticism is that Plato\'s view of reincarnation entails that it is possible for a soul and its body to be mis-matched; in principle, Aristotle alleges, any soul can go with any body, according to Plato\'s theory.[99] Aristotle\'s claim that the soul is the form of a living being eliminates that possibility and thus rules out reincarnation.[100]\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":113,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"feb50519-0826-5af7-9ef2-13f642f968ca\\",\\"score\\":0.45751739054711305,\\"metadata\\":{\\"text\\":\\"In On the Soul, Aristotle famously criticizes Plato\'s theory of the soul and develops his own in response. The first criticism is against Plato\'s view of the soul in the Timaeus that the soul takes up space and is able to come into physical contact with bodies.[96] 20th-century scholarship overwhelmingly opposed Aristotle\'s interpretation of Plato and maintained that he had misunderstood him.[97] Today\'s scholars have tended to re-assess Aristotle\'s interpretation and been more positive about it.[98]\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":112,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"fa12e1f8-09bb-5b05-8606-f2c141b484be\\",\\"score\\":0.45727583765983604,\\"metadata\\":{\\"text\\":\\"kingdom is its rationality.[121] Aristotle conceived of politics as being like an organism rather than like a machine, and as a collection of parts none of which can exist without the others. Aristotle\'s conception of the city is organic, and he is considered one of the first to conceive of the city in this manner.[122]\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":143,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"70eb9c23-af31-5dda-a721-5b6c8577d64e\\",\\"score\\":0.45682342221806704,\\"metadata\\":{\\"text\\":\\"Abelard, and John Buridan worked on Aristotelian logic.[174]\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":199,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"bf6b1961-f96b-50c5-b8a9-c60a7b80bc0b\\",\\"score\\":0.452890230801411,\\"metadata\\":{\\"text\\":\\"studied and made significant contributions to \\\\\\"logic, metaphysics, mathematics, physics, biology, botany, ethics, politics, agriculture, medicine, dance, and theatre.\\\\\\"[15]\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":20,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"694a4266-0e4c-5691-948e-05dacf99a30a\\",\\"score\\":0.45269417762756303,\\"metadata\\":{\\"text\\":\\"Revival\\\\nIn the slumbering centuries following the decline of the Roman Empire, Aristotle\'s vast philosophical and scientific corpus lay largely dormant in the West. But in the burgeoning intellectual heartland of the Abbasid Caliphate, his works underwent a remarkable revival.[159] Translated into Arabic alongside other Greek classics, Aristotle\'s logic, ethics, and natural philosophy ignited the minds of early Islamic scholars.[160]\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":186,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"a614876f-67b2-58e7-aaf1-12917410baff\\",\\"score\\":0.44979420603548304,\\"metadata\\":{\\"text\\":\\"Pythias, either Hermias\'s adoptive daughter or niece. They had a daughter, whom they also named Pythias. In 343 BC, Aristotle was invited by Philip II of Macedon to become the tutor to his son Alexander.[11][12]\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":13,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"cd03f71f-20c8-501b-9468-cfce807ab7a7\\",\\"score\\":0.44468317095242205,\\"metadata\\":{\\"text\\":\\"Economics\\\\nMain article: Politics (Aristotle)\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":155,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"8897fd3b-6eae-576b-9322-6dc057fbeb69\\",\\"score\\":0.444220006465912,\\"metadata\\":{\\"text\\":\\"not intended for publication.[210][208] Cicero\'s description of Aristotle\'s literary style as \\\\\\"a river of gold\\\\\\" must have applied to the published works, not the surviving notes.[Q] A major question in the history of Aristotle\'s works is how the exoteric writings were all lost, and how the ones now possessed came to be found.[212] The consensus is that Andronicus of Rhodes collected the esoteric works of Aristotle\'s school which existed in the form of smaller, separate works, distinguished them from those\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":223,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"f8e157ac-289f-57f7-9912-678686e2e358\\",\\"score\\":0.44353434443473805,\\"metadata\\":{\\"text\\":\\"In his On Generation and Corruption, Aristotle related each of the four elements proposed earlier by Empedocles, earth, water, air, and fire, to two of the four sensible qualities, hot, cold, wet, and dry. In the Empedoclean scheme, all matter was made of the four elements, in differing proportions. Aristotle\'s scheme added the heavenly aether, the divine substance of the heavenly spheres, stars and planets.[41]\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":55,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"3728064f-4f14-5a96-a9ac-318385e7a9c2\\",\\"score\\":0.441104352474213,\\"metadata\\":{\\"text\\":\\"One component of Aristotle\'s theory of dreams disagrees with previously held beliefs. He claimed that dreams are not foretelling and not sent by a divine being. Aristotle reasoned naturalistically that instances in which dreams do resemble future events are simply coincidences.[116] Aristotle claimed that a dream is first established by the fact that the person is asleep when they experience it. If a person had an image appear for a moment after waking up or if they see something in the dark it is not\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":132,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"be401ab8-f58a-59da-a40a-deceae5b2fc2\\",\\"score\\":0.43738391622209105,\\"metadata\\":{\\"text\\":\\"Aristotle\'s Rhetoric proposes that a speaker can use three basic kinds of appeals to persuade his audience: ethos (an appeal to the speaker\'s character), pathos (an appeal to the audience\'s emotion), and logos (an appeal to logical reasoning).[130] He also categorizes rhetoric into three genres: epideictic (ceremonial speeches dealing with praise or blame), forensic (judicial speeches over guilt or innocence), and deliberative (speeches calling on an audience to make a decision on an issue).[131] Aristotle\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":164,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"e663ee7c-62bc-52cf-b4a1-197ae5e91d4b\\",\\"score\\":0.43465039134025596,\\"metadata\\":{\\"text\\":\\"Instead, he practiced a different style of science: systematically gathering data, discovering patterns common to whole groups of animals, and inferring possible causal explanations from these.[78][79] This style is common in modern biology when large amounts of data become available in a new field, such as genomics. It does not result in the same certainty as experimental science, but it sets out testable hypotheses and constructs a narrative explanation of what is observed. In this sense, Aristotle\'s\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":95,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"dd14665e-c7e3-56af-9d31-dac1e78b5b9f\\",\\"score\\":0.43291583257412003,\\"metadata\\":{\\"text\\":\\"Aristotle examines the concepts of substance (ousia) and essence (to ti \\u00ean einai, \\\\\\"the what it was to be\\\\\\") in his Metaphysics (Book VII), and he concludes that a particular substance is a combination of both matter and form, a philosophical theory called hylomorphism. In Book VIII, he distinguishes the matter of the substance as the substratum, or the stuff of which it is composed. For example, the matter of a house is the bricks, stones, timbers, etc., or whatever constitutes the potential house, while\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":33,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"58ba0cc5-4324-5dd5-a4d4-5338cdf69b0e\\",\\"score\\":0.432026573177988,\\"metadata\\":{\\"text\\":\\"Hellenistic science\\\\nFurther information: Ancient Greek medicine\\\\nAfter Theophrastus, the Lyceum failed to produce any original work. Though interest in Aristotle\'s ideas survived, they were generally taken unquestioningly.[156] It is not until the age of Alexandria under the Ptolemies that advances in biology can be again found.\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":183,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"a5ddeb77-7da5-561f-af07-ce2a71d1a8dd\\",\\"score\\":0.430962983908476,\\"metadata\\":{\\"text\\":\\"Medieval Europe\\\\nFurther information: Aristotelianism and Syllogism \\u00a7 Medieval\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":196,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"3932c7f5-e252-5209-a9a3-48c309e2bbf4\\",\\"score\\":0.43086590950882,\\"metadata\\":{\\"text\\":\\"\\ud835\\udc63\\\\n=\\\\n\\ud835\\udc50\\\\n\\ud835\\udc4a\\\\n\\ud835\\udf0c{\\\\\\\\displaystyle v=c{\\\\\\\\frac {W}{\\\\\\\\rho }}}\\\\nAristotle implies that in a vacuum the speed of fall would become infinite, and concludes from this apparent absurdity that a vacuum is not possible.[45][43] Opinions have varied on whether Aristotle intended to state quantitative laws. Henri Carteron held the \\\\\\"extreme view\\\\\\"[43] that Aristotle\'s concept of force was basically qualitative,[46] but other authors reject this.[43]\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":62,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"b4134b8e-7569-5df5-93f3-9803da687c7a\\",\\"score\\":0.427144382766225,\\"metadata\\":{\\"text\\":\\"thought.[163] Philoponus questioned Aristotle\'s teaching of physics, noting its flaws and introducing the theory of impetus to explain his observations.[164]\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":191,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"ef9af951-f06e-5c1a-8c57-8964ee147dfa\\",\\"score\\":0.426049922344094,\\"metadata\\":{\\"text\\":\\"For Aristotle, the soul is the form of a living being. Because all beings are composites of form and matter, the form of living beings is that which endows them with what is specific to living beings, e.g. the ability to initiate movement (or in the case of plants, growth and transformations, which Aristotle considers types of movement).[11] In contrast to earlier philosophers, but in accordance with the Egyptians, he placed the rational soul in the heart, rather than the brain.[94] Notable is Aristotle\'s\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":110,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"71044b07-177e-5e0a-8267-941c535226f0\\",\\"score\\":0.423012614250183,\\"metadata\\":{\\"text\\":\\"exceptions, such as that sharks had a placenta like the tetrapods. To a modern biologist, the explanation, not available to Aristotle, is convergent evolution.[86] Philosophers of science have generally concluded that Aristotle was not interested in taxonomy,[87][88] but zoologists who studied this question in the early 21st century think otherwise.[89][90][91] He believed that purposive final causes guided all natural processes; this teleological view justified his observed data as an expression of formal\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":103,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}"]'}]}, - {}, - { - "run_id": ..., - "run_type": "search", - "entries": [ - {"key": "search_latency", "value": "0.47"}, - { - "key": "search_results", - "value": '["{\\"id\\":\\"c818bc72-2ac8-581b-b51a-0ca826f5f2b8\\",\\"score\\":1.0,\\"metadata\\":{\\"text\\":\\"Aristotle was born in 384 BC[C] in Stagira, Chalcidice,[2] about 55 km (34 miles) east of modern-day Thessaloniki.[3][4] His father, Nicomachus, was the personal physician to King Amyntas of Macedon. While he was young, Aristotle learned about biology and medical information, which was taught by his father.[5] Both of Aristotle\'s parents died when he was about thirteen, and Proxenus of Atarneus became his guardian.[6] Although little information about Aristotle\'s childhood has survived, he probably spent\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":8,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"5f6213d1-a46b-5ed4-a15c-e95bab271621\\",\\"score\\":1.0,\\"metadata\\":{\\"text\\":\\"Aristotle was one of the most revered Western thinkers in early Islamic theology. Most of the still extant works of Aristotle,[167] as well as a number of the original Greek commentaries, were translated into Arabic and studied by Muslim philosophers, scientists and scholars. Averroes, Avicenna and Alpharabius, who wrote on Aristotle in great depth, also influenced Thomas Aquinas and other Western Christian scholastic philosophers. Alkindus greatly admired Aristotle\'s philosophy,[168] and Averroes spoke of\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":194,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"e6c5d5f6-7fc4-5bb8-847d-44cfa16f5178\\",\\"score\\":1.0,\\"metadata\\":{\\"text\\":\\"Little is known about Aristotle\'s life. He was born in the city of Stagira in northern Greece during the Classical period. His father, Nicomachus, died when Aristotle was a child, and he was brought up by a guardian. At 17 or 18, he joined Plato\'s Academy in Athens and remained there until the age of 37 (c.\\u2009347 BC). Shortly after Plato died, Aristotle left Athens and, at the request of Philip II of Macedon, tutored his son Alexander the Great beginning in 343 BC. He established a library in the Lyceum,\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":1,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"1175585b-fc58-5e44-bfcb-cb1996289936\\",\\"score\\":1.0,\\"metadata\\":{\\"text\\":\\"after friends and relatives, and to deal with the latter as with beasts or plants\\\\\\".[13] By 335 BC, Aristotle had returned to Athens, establishing his own school there known as the Lyceum. Aristotle conducted courses at the school for the next twelve years. While in Athens, his wife Pythias died and Aristotle became involved with Herpyllis of Stagira. They had a son whom Aristotle named after his father, Nicomachus. If the Suda \\u2013 an uncritical compilation from the Middle Ages \\u2013 is accurate, he may also have\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":16,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"5fb90839-d04c-50b0-8f7f-ffc1a938c019\\",\\"score\\":1.0,\\"metadata\\":{\\"text\\":\\"Aristotle was appointed as the head of the royal Academy of Macedon. During Aristotle\'s time in the Macedonian court, he gave lessons not only to Alexander but also to two other future kings: Ptolemy and Cassander.[13] Aristotle encouraged Alexander toward eastern conquest, and Aristotle\'s own attitude towards Persia was unabashedly ethnocentric. In one famous example, he counsels Alexander to be \\\\\\"a leader to the Greeks and a despot to the barbarians, to look after the former as after friends and\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":15,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"8550e2b7-43f8-5a59-9c13-c9678670a2da\\",\\"score\\":1.0,\\"metadata\\":{\\"text\\":\\"The immediate influence of Aristotle\'s work was felt as the Lyceum grew into the Peripatetic school. Aristotle\'s students included Aristoxenus, Dicaearchus, Demetrius of Phalerum, Eudemos of Rhodes, Harpalus, Hephaestion, Mnason of Phocis, Nicomachus, and Theophrastus. Aristotle\'s influence over Alexander the Great is seen in the latter\'s bringing with him on his expedition a host of zoologists, botanists, and researchers. He had also learned a great deal about Persian customs and traditions from his\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":181,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"7ed3a01c-88dc-5a58-a68b-6e5d9f292df2\\",\\"score\\":1.0,\\"metadata\\":{\\"text\\":\\"Aristotle[A] (Greek: \\u1f08\\u03c1\\u03b9\\u03c3\\u03c4\\u03bf\\u03c4\\u03ad\\u03bb\\u03b7\\u03c2 Aristot\\u00e9l\\u0113s, pronounced [aristot\\u00e9l\\u025b\\u02d0s]; 384\\u2013322 BC) was an Ancient Greek philosopher and polymath. His writings cover a broad range of subjects spanning the natural sciences, philosophy, linguistics, economics, politics, psychology, and the arts. As the founder of the Peripatetic school of philosophy in the Lyceum in Athens, he began the wider Aristotelian tradition that followed, which set the groundwork for the development of modern science.\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":0,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"ed4d0d2c-73dc-5baa-8351-065482dbdf9b\\",\\"score\\":1.0,\\"metadata\\":{\\"text\\":\\"According to scholar Roger Theodore Lafferty, Dante built up the philosophy of the Comedy with the works of Aristotle as a foundation, just as the scholastics used Aristotle as the basis for their thinking. Dante knew Aristotle directly from Latin translations of his works and indirectly through quotations in the works of Albert Magnus.[175] Dante even acknowledges Aristotle\'s influence explicitly in the poem, specifically when Virgil justifies the Inferno\'s structure by citing the Nicomachean Ethics.[176]\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":200,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"e6f58828-2e6d-5eb1-94f3-efbc0b7c1699\\",\\"score\\":1.0,\\"metadata\\":{\\"text\\":\\"Aristotle was revered among medieval Muslim scholars as \\\\\\"The First Teacher\\\\\\", and among medieval Christians like Thomas Aquinas as simply \\\\\\"The Philosopher\\\\\\", while the poet Dante called him \\\\\\"the master of those who know\\\\\\". His works contain the earliest known formal study of logic, and were studied by medieval scholars such as Peter Abelard and Jean Buridan. Aristotle\'s influence on logic continued well into the 19th century. In addition, his ethics, although always influential, gained renewed interest with\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":5,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}", "{\\"id\\":\\"5c80f870-f275-5109-a752-5f9e0caf859c\\",\\"score\\":1.0,\\"metadata\\":{\\"text\\":\\"Aristotle\'s \\\\\\"natural philosophy\\\\\\" spans a wide range of natural phenomena including those now covered by physics, biology and other natural sciences.[40] In Aristotle\'s terminology, \\\\\\"natural philosophy\\\\\\" is a branch of philosophy examining the phenomena of the natural world, and includes fields that would be regarded today as physics, biology and other natural sciences. Aristotle\'s work encompassed virtually all facets of intellectual inquiry. Aristotle makes philosophy in the broad sense coextensive with\\",\\"title\\":\\"aristotle.txt\\",\\"user_id\\":\\"063edaf8-3e63-4cb9-a4d6-a855f36376c3\\",\\"version\\":\\"v0\\",\\"chunk_order\\":51,\\"document_id\\":\\"c9bdbac7-0ea3-5c9e-b590-018bd09b127b\\",\\"extraction_id\\":\\"472d6921-b4cd-5514-bf62-90b05c9102cb\\",\\"associatedQuery\\":\\"who is aristotle?\\"}}"]', - }, - {"key": "search_query", "value": "who is aristotle?"}, - ], - }, -] - - -def approx_equal(a, b, tolerance=1e-3): - """Compare two float values for approximate equality.""" - return math.isclose(a, b, rel_tol=tolerance) - - -def compare_search_results(actual, expected): - """Compare search results while allowing for slight differences in scores.""" - actual_results = json.loads(actual) - expected_results = json.loads(expected) - - if len(actual_results) != len(expected_results): - return False - - for actual_item, expected_item in zip(actual_results, expected_results): - actual_dict = json.loads(actual_item) - expected_dict = json.loads(expected_item) - - if actual_dict["id"] != expected_dict["id"]: - raise AssertionError( - f"IDs do not match: {actual_dict['id']} != {expected_dict['id']}" - ) - - if not approx_equal( - actual_dict["score"], expected_dict["score"], tolerance=1e-2 - ): - raise AssertionError( - f"Scores do not match: {actual_dict['score']} != {expected_dict['score']}" - ) - - if actual_dict["metadata"] != expected_dict["metadata"]: - raise AssertionError( - f"Metadata does not match: {actual_dict['metadata']} != {expected_dict['metadata']}" - ) - - return True - - -def test_ingestion_success(wrapper): - """Test the initial successful ingestion process.""" - result = wrapper.ingest_sample_file() - expected_payload = { - "processed_documents": [ - "Document 'aristotle.txt' processed successfully." - ], - "failed_documents": [], - "skipped_documents": [], - } - for key in expected_payload: - assert key in result - assert len(result[key]) == len(expected_payload[key]) - for i, value in enumerate(result[key]): - assert value == expected_payload[key][i] - print("Initial ingestion test passed successfully.") - - -def test_full_ingestion_success(wrapper): - """Test the initial successful ingestion process.""" - result = wrapper.ingest_sample_files() - - expected_processed = { - "Document 'lyft_2021.pdf' processed successfully.", - "Document 'uber_2021.pdf' processed successfully.", - "Document 'pg_essay_3.html' processed successfully.", - "Document 'pg_essay_2.html' processed successfully.", - "Document 'pg_essay_4.html' processed successfully.", - "Document 'got.txt' processed successfully.", - "Document 'pg_essay_5.html' processed successfully.", - "Document 'pg_essay_1.html' processed successfully.", - } - expected_failed = set() - expected_skipped = { - "Document 'aristotle.txt' skipped since it already exists." - } - - assert set(result["processed_documents"]) == expected_processed - assert set(result["failed_documents"]) == expected_failed - assert set(result["skipped_documents"]) == expected_skipped - - assert len(result["processed_documents"]) == len(expected_processed) - assert len(result["failed_documents"]) == len(expected_failed) - assert len(result["skipped_documents"]) == len(expected_skipped) - - print("Initial ingestion test passed successfully.") - - -def test_ingestion_failure(wrapper): - """Test the subsequent ingestion process that should fail.""" - try: - wrapper.ingest_sample_file() - raise AssertionError("Expected an exception, but none was raised.") - except Exception as e: - assert ( - str(e) - == "Document with ID c9bdbac7-0ea3-5c9e-b590-018bd09b127b was already successfully processed." - ) - print("Subsequent ingestion test passed: Expected error was raised.") - - -def test_logs(wrapper, expected_length): - """Test the logging functionality.""" - logs = wrapper.logs() - assert len(logs) == expected_length - log = logs[0] - expected_log = expected_logs[expected_length - 1] - - assert log["run_id"] is not None - assert log["run_type"] == expected_log["run_type"] - assert len(log["entries"]) == len(expected_log["entries"]) - - for i in range(len(log["entries"])): - entry = log["entries"][i] - print("entry: ", entry) - expected_entry = None - for expected_entry in expected_log["entries"]: - if expected_entry["key"] == entry["key"]: - break - if expected_entry is None: - raise AssertionError(f"Unexpected entry: {entry}") - print("expected_entry: ", expected_entry) - - if "latency" in entry["key"]: - continue - elif "search_results" == entry["key"]: - assert compare_search_results( - entry["value"], expected_entry["value"] - ) - else: - assert entry["key"] == entry["key"] - assert entry["value"] == expected_entry["value"] - print("Logs test passed.") - - -def test_vector_search( - wrapper, query, expected_scores, do_hybrid_search=False, search_limit=10 -): - """Test search functionality with given parameters.""" - search_results = wrapper.search( - query, do_hybrid_search=do_hybrid_search, search_limit=search_limit - ) - assert "vector_search_results" in search_results - scores = [ - result["score"] for result in search_results["vector_search_results"] - ] - if expected_scores: - assert len(scores) == len(expected_scores) - assert all(approx_equal(a, b) for a, b in zip(scores, expected_scores)) - print( - f"Search test passed for query: '{query}', hybrid: {do_hybrid_search}, limit: {search_limit}" - ) - return search_results["vector_search_results"] - - -def test_documents_overview(wrapper): - """Test the documents_overview functionality.""" - documents_overview = wrapper.documents_overview() - assert len(documents_overview) == 1 - doc_info = documents_overview[0] - - assert isinstance(doc_info.document_id, UUID) - assert doc_info.document_id == UUID("c9bdbac7-0ea3-5c9e-b590-018bd09b127b") - assert doc_info.version == "v0" - assert doc_info.size_in_bytes == 73353 - assert doc_info.metadata == { - "title": "aristotle.txt", - "user_id": "063edaf8-3e63-4cb9-a4d6-a855f36376c3", - } - assert doc_info.status.value == "success" - assert doc_info.user_id == UUID("063edaf8-3e63-4cb9-a4d6-a855f36376c3") - assert doc_info.title == "aristotle.txt" - assert isinstance(doc_info.created_at, datetime) - assert isinstance(doc_info.updated_at, datetime) - assert doc_info.created_at.tzinfo == timezone.utc - assert doc_info.updated_at.tzinfo == timezone.utc - - -def test_users_overview(wrapper): - """Test the users_overview functionality.""" - users_overview = wrapper.users_overview() - assert len(users_overview) == 1 - user_stats = users_overview[0] - - assert isinstance(user_stats.user_id, UUID) - assert user_stats.user_id == UUID("063edaf8-3e63-4cb9-a4d6-a855f36376c3") - assert user_stats.num_files == 1 - assert user_stats.total_size_in_bytes == 73353 - assert len(user_stats.document_ids) == 1 - assert user_stats.document_ids[0] == UUID( - "c9bdbac7-0ea3-5c9e-b590-018bd09b127b" - ) - - print("Users overview test passed successfully.") - - -def test_document_chunks(wrapper): - """Test the document_chunks functionality.""" - document_chunks = wrapper.document_chunks( - "c9bdbac7-0ea3-5c9e-b590-018bd09b127b" - ) - assert len(document_chunks) == 233 - first_chunk = document_chunks[0] - assert ( - first_chunk["text"] - == "Aristotle[A] (Greek: Ἀριστοτέλης Aristotélēs, pronounced [aristotélɛːs]; 384–322 BC) was an Ancient Greek philosopher and polymath. His writings cover a broad range of subjects spanning the natural sciences, philosophy, linguistics, economics, politics, psychology, and the arts. As the founder of the Peripatetic school of philosophy in the Lyceum in Athens, he began the wider Aristotelian tradition that followed, which set the groundwork for the development of modern science." - ) - assert first_chunk["chunk_order"] == 0 - print("Document chunks test passed successfully.") - - -def main(): - wrapper = R2RExecutionWrapper(client_mode=False) - - # Test ingestion - test_ingestion_success(wrapper) - - # Test logs - test_logs(wrapper, expected_length=1) - - # Test the document overview table - _ = test_documents_overview(wrapper) - - # Test the users overview table - test_users_overview(wrapper) - - # Test the document chunks method - test_document_chunks(wrapper) - - # Test subsequent ingestion (expecting failure) - test_ingestion_failure(wrapper) - - # Test regular search - regular_expected_scores = [ - 0.7737913131713869, - 0.669298529624939, - 0.652687707703574, - 0.636050164699554, - 0.624127291194959, - 0.619364976882935, - 0.6177915291003779, - 0.606354117393494, - 0.601802307421038, - 0.595915484915322, - ] - _ = test_vector_search( - wrapper, "who is aristotle?", regular_expected_scores - ) - test_logs(wrapper, expected_length=2) - - # Test search with larger limit - large_filter_results = test_vector_search( - wrapper, "who is aristotle?", None, search_limit=100 - ) - assert len(large_filter_results) == 100 - assert approx_equal( - large_filter_results[0]["score"], regular_expected_scores[0] - ) - # test_logs(wrapper, expected_length=3) - - # Test hybrid search - hybrid_expected_zero_result = "Aristotle was born in 384 BC[C] in Stagira, Chalcidice,[2] about 55 km (34 miles) east of modern-day Thessaloniki.[3][4] His father, Nicomachus, was the personal physician to King Amyntas of Macedon. While he was young, Aristotle learned about biology and medical information, which was taught by his father.[5] Both of Aristotle's parents died when he was about thirteen, and Proxenus of Atarneus became his guardian.[6] Although little information about Aristotle's childhood has survived, he probably spent" - hybrid_expected_scores = [1] * 10 - hybrid_results = test_vector_search( - wrapper, - "who is aristotle?", - hybrid_expected_scores, - do_hybrid_search=True, - ) - assert hybrid_results[0]["metadata"]["text"] == hybrid_expected_zero_result - # test_logs(wrapper, expected_length=4) - - test_full_ingestion_success(wrapper) - - -if __name__ == "__main__": - main() diff --git a/r2r/main/__init__.py b/r2r/main/__init__.py index e8166432a..0501c9d48 100644 --- a/r2r/main/__init__.py +++ b/r2r/main/__init__.py @@ -1,59 +1,59 @@ -from .abstractions import R2RAgents, R2RPipelines, R2RProviders -from .api.client import R2RClient -from .api.routes.ingestion.requests import ( - R2RIngestFilesRequest, - R2RUpdateFilesRequest, -) -from .api.routes.management.requests import ( - R2RAnalyticsRequest, - R2RDeleteRequest, - R2RDocumentChunksRequest, - R2RDocumentsOverviewRequest, - R2RUpdatePromptRequest, - R2RUsersOverviewRequest, -) -from .api.routes.retrieval.requests import ( - R2REvalRequest, - R2RRAGRequest, - R2RSearchRequest, -) +from .abstractions import R2RAgents, R2RPipelines, R2RPipes, R2RProviders +from .api import * from .app import R2RApp -from .assembly.builder import R2RBuilder -from .assembly.config import R2RConfig -from .assembly.factory import ( - R2RPipeFactory, - R2RPipelineFactory, - R2RProviderFactory, -) -from .assembly.factory_extensions import R2RPipeFactoryWithMultiSearch + +# from .app_entry import r2r_app +from .assembly import * from .engine import R2REngine from .execution import R2RExecutionWrapper from .r2r import R2R +from .services import ( + AuthService, + IngestionService, + ManagementService, + RetrievalService, +) __all__ = [ - "R2R", - "R2RPipelines", + ## R2R ABSTRACTIONS "R2RProviders", + "R2RPipes", + "R2RPipelines", "R2RAgents", - "R2RUpdatePromptRequest", - "R2RIngestFilesRequest", - "R2RUpdateFilesRequest", - "R2RSearchRequest", - "R2RRAGRequest", - "R2REvalRequest", - "R2RDeleteRequest", - "R2RAnalyticsRequest", - "R2RUsersOverviewRequest", - "R2RDocumentsOverviewRequest", - "R2RDocumentChunksRequest", + ## R2R API + # Client + "R2RClient", + # Routes + "AuthRouter", + "IngestionRouter", + "ManagementRouter", + "RetrievalRouter", + "BaseRouter", + ## R2R APP + "R2RApp", + ## R2R APP ENTRY + # "r2r_app", + ## R2R ENGINE "R2REngine", + ## R2R EXECUTION "R2RExecutionWrapper", + ## R2R ASSEMBLY + # Builder + "R2RBuilder", + # Config "R2RConfig", - "R2RClient", + # Factory + "R2RProviderFactory", "R2RPipeFactory", "R2RPipelineFactory", - "R2RProviderFactory", + "R2RAgentFactory", + # Factory Extensions "R2RPipeFactoryWithMultiSearch", - "R2RBuilder", - "R2RApp", + ## R2R + "R2R", + ## R2R SERVICES + "AuthService", + "IngestionService", + "ManagementService", + "RetrievalService", ] diff --git a/r2r/main/abstractions.py b/r2r/main/abstractions.py index 9826b9a01..fa3648a6d 100644 --- a/r2r/main/abstractions.py +++ b/r2r/main/abstractions.py @@ -2,22 +2,21 @@ from pydantic import BaseModel -from r2r.agents import R2RRAGAgent, R2RStreamingRAGAgent -from r2r.base import ( - AsyncPipe, +from r2r.agent import R2RRAGAgent, R2RStreamingRAGAgent +from r2r.base.pipes import AsyncPipe +from r2r.base.providers import ( AuthProvider, ChunkingProvider, CompletionProvider, DatabaseProvider, EmbeddingProvider, - EvalProvider, KGProvider, ParsingProvider, PromptProvider, ) from r2r.pipelines import ( - EvalPipeline, IngestionPipeline, + KGEnrichmentPipeline, RAGPipeline, SearchPipeline, ) @@ -30,7 +29,6 @@ class R2RProviders(BaseModel): database: Optional[DatabaseProvider] embedding: Optional[EmbeddingProvider] prompt: Optional[PromptProvider] - eval: Optional[EvalProvider] kg: Optional[KGProvider] parsing: Optional[ParsingProvider] @@ -46,21 +44,24 @@ class R2RPipes(BaseModel): vector_search_pipe: Optional[AsyncPipe] rag_pipe: Optional[AsyncPipe] streaming_rag_pipe: Optional[AsyncPipe] - eval_pipe: Optional[AsyncPipe] kg_pipe: Optional[AsyncPipe] kg_storage_pipe: Optional[AsyncPipe] kg_search_search_pipe: Optional[AsyncPipe] + kg_node_extraction_pipe: Optional[AsyncPipe] + kg_node_description_pipe: Optional[AsyncPipe] + kg_clustering_pipe: Optional[AsyncPipe] + chunking_pipe: Optional[AsyncPipe] class Config: arbitrary_types_allowed = True class R2RPipelines(BaseModel): - eval_pipeline: EvalPipeline ingestion_pipeline: IngestionPipeline search_pipeline: SearchPipeline rag_pipeline: RAGPipeline streaming_rag_pipeline: RAGPipeline + kg_pipeline: KGEnrichmentPipeline class Config: arbitrary_types_allowed = True diff --git a/r2r/main/api/__init__.py b/r2r/main/api/__init__.py index e69de29bb..a0d60b0c4 100644 --- a/r2r/main/api/__init__.py +++ b/r2r/main/api/__init__.py @@ -0,0 +1,17 @@ +from .client import R2RClient +from .routes.auth.base import AuthRouter +from .routes.base_router import BaseRouter +from .routes.ingestion.base import IngestionRouter +from .routes.management.base import ManagementRouter +from .routes.retrieval.base import RetrievalRouter + +__all__ = [ + # Client + "R2RClient", + # Routes + "AuthRouter", + "IngestionRouter", + "ManagementRouter", + "RetrievalRouter", + "BaseRouter", +] diff --git a/r2r/main/api/client.py b/r2r/main/api/client.py deleted file mode 100644 index 06677b046..000000000 --- a/r2r/main/api/client.py +++ /dev/null @@ -1,620 +0,0 @@ -import asyncio -import json -import os -import uuid -from contextlib import ExitStack -from typing import Any, AsyncGenerator, Dict, Generator, Optional, Union - -import fire -import httpx -import nest_asyncio -import requests -from fastapi.testclient import TestClient - -from r2r.base import ( - AnalysisTypes, - ChunkingConfig, - FilterCriteria, - GenerationConfig, - KGSearchSettings, - R2RException, - UserCreate, - VectorSearchSettings, -) - -from .routes.ingestion.requests import ( - R2RIngestFilesRequest, - R2RUpdateFilesRequest, -) -from .routes.management.requests import ( - R2RAnalyticsRequest, - R2RDeleteRequest, - R2RDocumentChunksRequest, - R2RDocumentsOverviewRequest, - R2RLogsRequest, - R2RPrintRelationshipsRequest, - R2RScoreCompletionRequest, - R2RUpdatePromptRequest, - R2RUsersOverviewRequest, -) -from .routes.retrieval.requests import ( - R2RAgentRequest, - R2RRAGRequest, - R2RSearchRequest, -) - -nest_asyncio.apply() - - -def handle_request_error(response): - if response.status_code < 400: - return - - try: - error_content = response.json() - if isinstance(error_content, dict) and "detail" in error_content: - detail = error_content["detail"] - if isinstance(detail, dict): - message = detail.get("message", str(response.text)) - else: - message = str(detail) - else: - message = str(error_content) - except json.JSONDecodeError: - message = response.text - - raise R2RException( - status_code=response.status_code, - message=message, - ) - - -class R2RClient: - def __init__( - self, - base_url: str = "http://localhost:8000", - prefix: str = "/v1", - custom_client=None, - timeout: float = 60.0, - ): - self.base_url = base_url - self.prefix = prefix - self.access_token = None - self._refresh_token = None - self.client = custom_client or requests - self.timeout = timeout - - def _make_request(self, method, endpoint, **kwargs): - url = f"{self.base_url}{self.prefix}/{endpoint}" - headers = kwargs.pop("headers", {}) - if self.access_token and endpoint not in [ - "register", - "login", - "verify_email", - ]: - headers.update(self._get_auth_header()) - if isinstance(self.client, TestClient): - response = getattr(self.client, method.lower())( - url, headers=headers, **kwargs - ) - else: - response = self.client.request( - method, url, headers=headers, **kwargs - ) - - handle_request_error(response) - return response.json() - - def _get_auth_header(self) -> dict: - if not self.access_token: - {} # Return empty dict if no access token - return {"Authorization": f"Bearer {self.access_token}"} - - def register(self, email: str, password: str) -> dict: - user = UserCreate(email=email, password=password) - return self._make_request("POST", "register", json=user.dict()) - - def verify_email(self, verification_code: str) -> dict: - return self._make_request("POST", f"verify_email/{verification_code}") - - def login(self, email: str, password: str) -> dict: - form_data = {"username": email, "password": password} - response = self._make_request("POST", "login", data=form_data) - self.access_token = response["results"]["access_token"]["token"] - self._refresh_token = response["results"]["refresh_token"]["token"] - return response - - def user(self) -> dict: - return self._make_request("GET", "user") - - def refresh_access_token(self) -> dict: - if not self._refresh_token: - raise ValueError("No refresh token available. Please login again.") - response = self._make_request( - "POST", - "refresh_access_token", - json={"refresh_token": self._refresh_token}, - ) - self.access_token = response["results"]["access_token"]["token"] - self._refresh_token = response["results"]["refresh_token"][ - "token" - ] # Update the refresh token - return response - - def _ensure_authenticated(self): - pass - # if not self.access_token: - # raise ValueError("Not authenticated. Please login first.") - - def health(self) -> dict: - return self._make_request("GET", "health") - - def server_stats(self) -> dict: - self._ensure_authenticated() - return self._make_request("GET", "server_stats") - - def update_prompt( - self, - name: str = "default_system", - template: Optional[str] = None, - input_types: Optional[dict] = None, - ) -> dict: - self._ensure_authenticated() - request = R2RUpdatePromptRequest( - name=name, template=template, input_types=input_types - ) - return self._make_request( - "POST", "update_prompt", json=json.loads(request.model_dump_json()) - ) - - def ingest_files( - self, - file_paths: list[str], - metadatas: Optional[list[dict]] = None, - document_ids: Optional[list[Union[uuid.UUID, str]]] = None, - versions: Optional[list[str]] = None, - chunking_config_override: Optional[Union[dict, ChunkingConfig]] = None, - ) -> dict: - self._ensure_authenticated() - - if isinstance(chunking_config_override, ChunkingConfig): - chunking_config_override = json.loads( - chunking_config_override.model_dump_json() - ) - - all_file_paths = [] - - for path in file_paths: - if os.path.isdir(path): - for root, _, files in os.walk(path): - all_file_paths.extend( - os.path.join(root, file) for file in files - ) - else: - all_file_paths.append(path) - - files_to_upload = [ - ( - "files", - ( - os.path.basename(file), - open(file, "rb"), - "application/octet-stream", - ), - ) - for file in all_file_paths - ] - request = R2RIngestFilesRequest( - metadatas=metadatas, - document_ids=( - [str(ele) for ele in document_ids] if document_ids else None - ), - versions=versions, - chunking_config_override=chunking_config_override, - ) - try: - return self._make_request( - "POST", - "ingest_files", - data={ - k: json.dumps(v) - for k, v in json.loads(request.model_dump_json()).items() - }, - files=files_to_upload, - ) - finally: - for _, file_tuple in files_to_upload: - file_tuple[1].close() - - def update_files( - self, - file_paths: list[str], - document_ids: list[str], - metadatas: Optional[list[dict]] = None, - chunking_config_override: Optional[Union[dict, ChunkingConfig]] = None, - ) -> dict: - self._ensure_authenticated() - - request = R2RUpdateFilesRequest( - metadatas=metadatas, - document_ids=document_ids, - chunking_config_override=chunking_config_override, - ) - with ExitStack() as stack: - return self._make_request( - "POST", - "update_files", - data={ - k: json.dumps(v) - for k, v in json.loads(request.model_dump_json()).items() - }, - files=[ - ( - "files", - ( - path.split("/")[-1], - stack.enter_context(open(path, "rb")), - "application/octet-stream", - ), - ) - for path in file_paths - ], - ) - - def search( - self, - query: str, - vector_search_settings: Optional[ - Union[dict, VectorSearchSettings] - ] = None, - kg_search_settings: Optional[Union[dict, KGSearchSettings]] = None, - ) -> dict: - self._ensure_authenticated() - if vector_search_settings and isinstance( - vector_search_settings, VectorSearchSettings - ): - vector_search_settings = json.loads( - vector_search_settings.model_dump_json() - ) - if kg_search_settings and isinstance( - kg_search_settings, KGSearchSettings - ): - kg_search_settings = json.loads( - kg_search_settings.model_dump_json() - ) - - request = R2RSearchRequest( - query=query, - vector_search_settings=vector_search_settings, - kg_search_settings=kg_search_settings, - ) - return self._make_request( - "POST", "search", json=json.loads(request.model_dump_json()) - ) - - def rag( - self, - query: str, - vector_search_settings: Optional[ - Union[dict, VectorSearchSettings] - ] = None, - kg_search_settings: Optional[Union[dict, KGSearchSettings]] = None, - rag_generation_config: Optional[Union[dict, GenerationConfig]] = None, - task_prompt_override: Optional[str] = None, - include_title_if_available: Optional[bool] = None, - ) -> dict: - self._ensure_authenticated() - - if isinstance(vector_search_settings, VectorSearchSettings): - vector_search_settings = json.loads( - vector_search_settings.model_dump_json() - ) - if isinstance(kg_search_settings, KGSearchSettings): - kg_search_settings = json.loads( - kg_search_settings.model_dump_json() - ) - if isinstance(rag_generation_config, GenerationConfig): - rag_generation_config = json.loads( - rag_generation_config.model_dump_json() - ) - - request = R2RRAGRequest( - query=query, - vector_search_settings=vector_search_settings, - kg_search_settings=kg_search_settings, - rag_generation_config=rag_generation_config or {"stream": False}, - task_prompt_override=task_prompt_override, - include_title_if_available=include_title_if_available, - ) - print("request = ", request) - - if rag_generation_config and rag_generation_config.get( - "stream", False - ): - return self._stream_rag_sync(request) - else: - return self._make_request( - "POST", "rag", json=json.loads(request.model_dump_json()) - ) - - async def _stream_rag( - self, rag_request: R2RRAGRequest - ) -> AsyncGenerator[str, None]: - url = f"{self.base_url}{self.prefix}/rag" - async with httpx.AsyncClient() as client: - async with client.stream( - "POST", - url, - json=json.loads( - rag_request.model_dump_json(), - ), - timeout=self.timeout, - ) as response: - handle_request_error(response) - async for chunk in response.aiter_text(): - yield chunk - - def _stream_rag_sync( - self, rag_request: R2RRAGRequest - ) -> Generator[str, None, None]: - async def run_async_generator(): - async for chunk in self._stream_rag(rag_request): - yield chunk - - loop = asyncio.new_event_loop() - asyncio.set_event_loop(loop) - - async_gen = run_async_generator() - - try: - while True: - yield loop.run_until_complete(async_gen.__anext__()) - except StopAsyncIteration: - pass - finally: - loop.close() - - def agent( - self, - messages: list[dict], - vector_search_settings: Optional[ - Union[dict, VectorSearchSettings] - ] = None, - kg_search_settings: Optional[Union[dict, KGSearchSettings]] = None, - rag_generation_config: Optional[Union[dict, GenerationConfig]] = None, - task_prompt_override: Optional[str] = None, - ) -> dict: - self._ensure_authenticated() - - if isinstance(vector_search_settings, VectorSearchSettings): - vector_search_settings = json.loads( - vector_search_settings.model_dump_json() - ) - if isinstance(kg_search_settings, KGSearchSettings): - kg_search_settings = json.loads( - kg_search_settings.model_dump_json() - ) - if isinstance(rag_generation_config, GenerationConfig): - rag_generation_config = json.loads( - rag_generation_config.model_dump_json() - ) - request = R2RAgentRequest( - messages=messages, - vector_search_settings=vector_search_settings, - kg_search_settings=kg_search_settings, - rag_generation_config=rag_generation_config, - task_prompt_override=task_prompt_override, - ) - - if rag_generation_config and rag_generation_config.get( - "stream", False - ): - return self._stream_agent_sync(request) - else: - return self._make_request( - "POST", "agent", json=json.loads(request.model_dump_json()) - ) - - async def _stream_agent( - self, rag_agent_request: R2RAgentRequest - ) -> AsyncGenerator[str, None]: - url = f"{self.base_url}{self.prefix}/agent" - async with httpx.AsyncClient() as client: - async with client.stream( - "POST", - url, - json=json.loads( - rag_agent_request.model_dump_json(), - ), - timeout=self.timeout, - ) as response: - handle_request_error(response) - async for chunk in response.aiter_text(): - yield chunk - - def _stream_agent_sync( - self, rag_agent_request: R2RAgentRequest - ) -> Generator[str, None, None]: - async def run_async_generator(): - async for chunk in self._stream_agent(rag_agent_request): - yield chunk - - loop = asyncio.new_event_loop() - asyncio.set_event_loop(loop) - - async_gen = run_async_generator() - - try: - while True: - yield loop.run_until_complete(async_gen.__anext__()) - except StopAsyncIteration: - pass - finally: - loop.close() - - def delete( - self, keys: list[str], values: list[Union[bool, int, str]] - ) -> dict: - self._ensure_authenticated() - - request = R2RDeleteRequest(keys=keys, values=values) - return self._make_request( - "DELETE", "delete", json=json.loads(request.model_dump_json()) - ) - - def logs( - self, - log_type_filter: Optional[str] = None, - max_runs: int = 100, - ) -> dict: - self._ensure_authenticated() - - request = R2RLogsRequest( - log_type_filter=log_type_filter, - max_runs_requested=max_runs, - ) - return self._make_request( - "GET", "logs", json=json.loads(request.model_dump_json()) - ) - - def app_settings(self) -> dict: - self._ensure_authenticated() - - return self._make_request("GET", "app_settings") - - def score_completion( - self, - message_id: str = None, - score: float = None, - ) -> dict: - self._ensure_authenticated() - - request = R2RScoreCompletionRequest( - message_id=message_id, - score=score, - ) - return self._make_request( - "POST", - "score_completion", - json=json.loads(request.model_dump_json()), - ) - - def analytics( - self, - filter_criteria: Optional[Dict[str, Any]], - analysis_types: Optional[Dict[str, Any]], - ) -> dict: - self._ensure_authenticated() - - request = R2RAnalyticsRequest( - filter_criteria=FilterCriteria(filters=filter_criteria), - analysis_types=AnalysisTypes(analysis_types=analysis_types), - ) - return self._make_request( - "GET", "analytics", json=request.model_dump(exclude_none=True) - ) - - def users_overview( - self, user_ids: Optional[list[uuid.UUID]] = None - ) -> dict: - self._ensure_authenticated() - - request = R2RUsersOverviewRequest(user_ids=user_ids) - return self._make_request( - "GET", "users_overview", json=json.loads(request.model_dump_json()) - ) - - def documents_overview( - self, - document_ids: Optional[list[str]] = None, - user_ids: Optional[list[str]] = None, - ) -> dict: - self._ensure_authenticated() - - request = R2RDocumentsOverviewRequest( - document_ids=( - [uuid.UUID(did) for did in document_ids] - if document_ids - else None - ), - user_ids=( - [uuid.UUID(uid) for uid in user_ids] if user_ids else None - ), - ) - return self._make_request( - "GET", - "documents_overview", - json=json.loads(request.model_dump_json()), - ) - - def document_chunks(self, document_id: str) -> dict: - self._ensure_authenticated() - - request = R2RDocumentChunksRequest(document_id=document_id) - return self._make_request( - "GET", - "document_chunks", - json=json.loads(request.model_dump_json()), - ) - - def inspect_knowledge_graph(self, limit: int = 100) -> str: - self._ensure_authenticated() - - request = R2RPrintRelationshipsRequest(limit=limit) - return self._make_request( - "POST", - "inspect_knowledge_graph", - json=json.loads(request.model_dump_json()), - ) - - def change_password( - self, current_password: str, new_password: str - ) -> dict: - self._ensure_authenticated() - return self._make_request( - "POST", - "change_password", - json={ - "current_password": current_password, - "new_password": new_password, - }, - ) - - def request_password_reset(self, email: str) -> dict: - return self._make_request( - "POST", "request_password_reset", json={"email": email} - ) - - def confirm_password_reset( - self, reset_token: str, new_password: str - ) -> dict: - return self._make_request( - "POST", - f"reset_password/{reset_token}", - json={"new_password": new_password}, - ) - - def logout(self) -> dict: - self._ensure_authenticated() - response = self._make_request("POST", "logout") - self.access_token = None - self._refresh_token = None - return response - - def update_user(self, user_data: dict) -> dict: - self._ensure_authenticated() - return self._make_request("PUT", "user", json=user_data) - - def delete_user(self, password: str) -> dict: - self._ensure_authenticated() - response = self._make_request( - "DELETE", "user", json={"password": password} - ) - self.access_token = None - self._refresh_token = None - return response - - -if __name__ == "__main__": - client = R2RClient(base_url="http://localhost:8000") - fire.Fire(client) diff --git a/r2r/main/api/client/__init__.py b/r2r/main/api/client/__init__.py new file mode 100644 index 000000000..64ce2e9f6 --- /dev/null +++ b/r2r/main/api/client/__init__.py @@ -0,0 +1 @@ +from .client import R2RClient diff --git a/r2r/main/api/client/auth.py b/r2r/main/api/client/auth.py new file mode 100644 index 000000000..63b1afb9e --- /dev/null +++ b/r2r/main/api/client/auth.py @@ -0,0 +1,93 @@ +import uuid +from typing import Optional + +from r2r.base import Token +from r2r.base.api.models.auth.responses import UserResponse + + +class AuthMethods: + + @staticmethod + async def register(client, email: str, password: str) -> UserResponse: + data = {"email": email, "password": password} + return await client._make_request("POST", "register", json=data) + + async def verify_email(client, verification_code: str) -> dict: + return await client._make_request( + "POST", + "verify_email", + json={"verification_code": verification_code}, + ) + + async def login(client, email: str, password: str) -> dict[str, Token]: + data = {"username": email, "password": password} + response = await client._make_request("POST", "login", data=data) + client.access_token = response["results"]["access_token"]["token"] + client._refresh_token = response["results"]["refresh_token"]["token"] + return response["results"] + + async def user(client) -> UserResponse: + return await client._make_request("GET", "user") + + async def refresh_access_token(client) -> dict[str, Token]: + data = {"refresh_token": client._refresh_token} + response = await client._make_request( + "POST", "refresh_access_token", json=data + ) + client.access_token = response["results"]["access_token"]["token"] + client._refresh_token = response["results"]["refresh_token"]["token"] + return response["results"] + + async def change_password( + client, current_password: str, new_password: str + ) -> dict: + data = { + "current_password": current_password, + "new_password": new_password, + } + return await client._make_request("POST", "change_password", json=data) + + async def request_password_reset(client, email: str) -> dict: + return await client._make_request( + "POST", "request_password_reset", json={"email": email} + ) + + async def confirm_password_reset( + client, reset_token: str, new_password: str + ) -> dict: + data = {"reset_token": reset_token, "new_password": new_password} + return await client._make_request("POST", "reset_password", json=data) + + async def logout(client) -> dict: + response = await client._make_request("POST", "logout") + client.access_token = None + client._refresh_token = None + return response + + async def get_user_profile(client, user_id: uuid.UUID) -> UserResponse: + return await client._make_request("GET", f"user/{user_id}") + + async def update_user( + client, + email: Optional[str] = None, + name: Optional[str] = None, + bio: Optional[str] = None, + profile_picture: Optional[str] = None, + ) -> UserResponse: + data = { + "email": email, + "name": name, + "bio": bio, + "profile_picture": profile_picture, + } + data = {k: v for k, v in data.items() if v is not None} + return await client._make_request("PUT", "user", json=data) + + async def delete_user( + client, user_id: uuid.UUID, password: Optional[str] = None + ) -> dict: + data = {"user_id": str(user_id), "password": password} + response = await client._make_request("DELETE", "user", json=data) + client.access_token = None + client._refresh_token = None + return response diff --git a/r2r/main/api/client/client.py b/r2r/main/api/client/client.py new file mode 100644 index 000000000..7f0cf3bfd --- /dev/null +++ b/r2r/main/api/client/client.py @@ -0,0 +1,198 @@ +import asyncio +import inspect +import json + +import httpx +import nest_asyncio +from fastapi.testclient import TestClient + +from r2r.base import R2RException + +# Import the new client modules +from .auth import AuthMethods +from .ingestion import IngestionMethods +from .management import ManagementMethods +from .restructure import RestructureMethods +from .retrieval import RetrievalMethods + +nest_asyncio.apply() + +# The empty args become necessary after a recent modification to `base_endpoint` +# TODO - Remove the explicitly empty args +EMPTY_ARGS = {"args": "", "kwargs": "{}"} + + +def handle_request_error(response): + if response.status_code < 400: + return + + try: + error_content = response.json() + if isinstance(error_content, dict) and "detail" in error_content: + detail = error_content["detail"] + if isinstance(detail, dict): + message = detail.get("message", str(response.text)) + else: + message = str(detail) + else: + message = str(error_content) + except json.JSONDecodeError: + message = response.text + + raise R2RException( + status_code=response.status_code, + message=message, + ) + + +async def handle_request_error_async(response): + if response.status_code < 400: + return + + try: + if response.headers.get("content-type") == "application/json": + error_content = await response.json() + else: + error_content = await response.text() + + if isinstance(error_content, dict) and "detail" in error_content: + detail = error_content["detail"] + if isinstance(detail, dict): + message = detail.get("message", str(error_content)) + else: + message = str(detail) + else: + message = str(error_content) + except Exception: + message = response.text() + + raise R2RException( + status_code=response.status_code, + message=message, + ) + + +class R2RAsyncClient: + def __init__( + self, + base_url: str = "http://localhost:8000", + prefix: str = "/v1", + custom_client=None, + timeout: float = 60.0, + ): + self.base_url = base_url + self.prefix = prefix + self.access_token = None + self._refresh_token = None + self.client = custom_client or httpx.AsyncClient(timeout=timeout) + self.timeout = timeout + + # Initialize method groups + self._auth = AuthMethods + self._retrieval = RetrievalMethods + self._ingestion = IngestionMethods + self._restructure = RestructureMethods + self._management = ManagementMethods + + # Collect all methods from the method groups + self._methods = {} + for group in [ + self._auth, + self._retrieval, + self._ingestion, + self._restructure, + self._management, + ]: + for name, method in inspect.getmembers( + group, predicate=inspect.isfunction + ): + if not name.startswith("_"): + self._methods[name] = method + + async def _make_request(self, method, endpoint, **kwargs): + url = f"{self.base_url}{self.prefix}/{endpoint}" + headers = kwargs.pop("headers", {}) + if self.access_token and endpoint not in [ + "register", + "login", + "verify_email", + ]: + headers.update(self._get_auth_header()) + params = kwargs.pop("params", {}) + params = {**params, **EMPTY_ARGS} + + if isinstance(self.client, TestClient): + response = getattr(self.client, method.lower())( + url, headers=headers, **kwargs + ) + else: + try: + response = await self.client.request( + method, url, headers=headers, params=params, **kwargs + ) + await handle_request_error_async(response) + return response.json() + except httpx.RequestError as e: + raise R2RException( + status_code=500, message=f"Request failed: {str(e)}" + ) + + def _get_auth_header(self) -> dict: + if not self.access_token: + return {} + return {"Authorization": f"Bearer {self.access_token}"} + + def _ensure_authenticated(self): + if not self.access_token: + raise R2RException( + status_code=401, + message="Not authenticated. Please login first.", + ) + + async def health(self) -> dict: + return await self._make_request("GET", "health") + + async def close(self): + await self.client.aclose() + + async def __aenter__(self): + return self + + async def __aexit__(self, exc_type, exc_val, exc_tb): + await self.close() + + def __getattr__(self, name): + if name in self._methods: + return lambda *args, **kwargs: self._methods[name]( + self, *args, **kwargs + ) + raise AttributeError(f"'R2RClient' object has no attribute '{name}'") + + def __dir__(self): + return list(set(super().__dir__() + list(self._methods.keys()))) + + +class R2RClient: + def __init__(self, *args, **kwargs): + self.async_client = R2RAsyncClient(*args, **kwargs) + + def __getattr__(self, name): + async_attr = getattr(self.async_client, name) + if callable(async_attr): + + def sync_wrapper(*args, **kwargs): + return asyncio.get_event_loop().run_until_complete( + async_attr(*args, **kwargs) + ) + + return sync_wrapper + return async_attr + + def __dir__(self): + return dir(self.async_client) + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + asyncio.get_event_loop().run_until_complete(self.async_client.close()) diff --git a/r2r/main/api/client/ingestion.py b/r2r/main/api/client/ingestion.py new file mode 100644 index 000000000..5e85e8304 --- /dev/null +++ b/r2r/main/api/client/ingestion.py @@ -0,0 +1,230 @@ +import json +import os +import uuid +from contextlib import ExitStack +from typing import List, Optional, Union + +from r2r.base import ChunkingConfig, Document, DocumentType + + +class IngestionMethods: + @staticmethod + async def ingest_documents( + client, + documents: List[Document], + versions: Optional[List[str]] = None, + chunking_config_override: Optional[Union[dict, ChunkingConfig]] = None, + ) -> dict: + """ + Ingest a list of documents into the system. + + Args: + documents (List[Document]): List of Document objects to ingest. + versions (Optional[List[str]]): List of version strings for each document. + chunking_config_override (Optional[Union[dict, ChunkingConfig]]): Custom chunking configuration. + + Returns: + dict: Ingestion results containing processed, failed, and skipped documents. + """ + data = { + "documents": [doc.dict() for doc in documents], + "versions": versions, + "chunking_config_override": ( + chunking_config_override.dict() + if isinstance(chunking_config_override, ChunkingConfig) + else chunking_config_override + ), + } + return await client._make_request( + "POST", "ingest_documents", json=data + ) + + @staticmethod + async def ingest_files( + client, + file_paths: List[str], + metadatas: Optional[List[dict]] = None, + document_ids: Optional[List[Union[uuid.UUID, str]]] = None, + versions: Optional[List[str]] = None, + chunking_config_override: Optional[Union[dict, ChunkingConfig]] = None, + ) -> dict: + """ + Ingest files into the system. + + Args: + file_paths (List[str]): List of file paths to ingest. + metadatas (Optional[List[dict]]): List of metadata dictionaries for each file. + document_ids (Optional[List[Union[uuid.UUID, str]]]): List of document IDs. + versions (Optional[List[str]]): List of version strings for each file. + chunking_config_override (Optional[Union[dict, ChunkingConfig]]): Custom chunking configuration. + + Returns: + dict: Ingestion results containing processed, failed, and skipped documents. + """ + all_file_paths = [] + for path in file_paths: + if os.path.isdir(path): + for root, _, files in os.walk(path): + all_file_paths.extend( + os.path.join(root, file) for file in files + ) + else: + all_file_paths.append(path) + + with ExitStack() as stack: + files = [ + ( + "files", + ( + os.path.basename(file), + stack.enter_context(open(file, "rb")), + "application/octet-stream", + ), + ) + for file in all_file_paths + ] + + data = { + "metadatas": json.dumps(metadatas) if metadatas else None, + "document_ids": ( + json.dumps([str(doc_id) for doc_id in document_ids]) + if document_ids + else None + ), + "versions": json.dumps(versions) if versions else None, + "chunking_config_override": ( + json.dumps( + chunking_config_override.dict() + if isinstance(chunking_config_override, ChunkingConfig) + else chunking_config_override + ) + if chunking_config_override + else None + ), + } + + return await client._make_request( + "POST", "ingest_files", data=data, files=files + ) + + @staticmethod + async def update_files( + client, + file_paths: List[str], + document_ids: List[str], + metadatas: Optional[List[dict]] = None, + chunking_config_override: Optional[Union[dict, ChunkingConfig]] = None, + ) -> dict: + """ + Update existing files in the system. + + Args: + file_paths (List[str]): List of file paths to update. + document_ids (List[str]): List of document IDs to update. + metadatas (Optional[List[dict]]): List of updated metadata dictionaries for each file. + chunking_config_override (Optional[Union[dict, ChunkingConfig]]): Custom chunking configuration. + + Returns: + dict: Update results containing processed, failed, and skipped documents. + """ + if len(file_paths) != len(document_ids): + raise ValueError( + "Number of file paths must match number of document IDs." + ) + + with ExitStack() as stack: + files = [ + ( + "files", + ( + os.path.basename(file), + stack.enter_context(open(file, "rb")), + "application/octet-stream", + ), + ) + for file in file_paths + ] + + data = { + "document_ids": json.dumps(document_ids), + "metadatas": json.dumps(metadatas) if metadatas else None, + "chunking_config_override": ( + json.dumps( + chunking_config_override.dict() + if isinstance(chunking_config_override, ChunkingConfig) + else chunking_config_override + ) + if chunking_config_override + else None + ), + } + + return await client._make_request( + "POST", "update_files", data=data, files=files + ) + + @staticmethod + async def get_document_info(client, document_id: str) -> dict: + """ + Retrieve information about a specific document. + + Args: + document_id (str): The ID of the document to retrieve information for. + + Returns: + dict: Document information including metadata, status, and version. + """ + return await client._make_request( + "GET", f"document_info/{document_id}" + ) + + @staticmethod + async def delete_document(client, document_id: str) -> dict: + """ + Delete a specific document from the system. + + Args: + document_id (str): The ID of the document to delete. + + Returns: + dict: Confirmation of document deletion. + """ + return await client._make_request( + "DELETE", f"delete_document/{document_id}" + ) + + @staticmethod + async def list_documents( + client, + user_id: Optional[str] = None, + group_ids: Optional[List[str]] = None, + document_type: Optional[DocumentType] = None, + status: Optional[str] = None, + page: int = 1, + page_size: int = 50, + ) -> dict: + """ + List documents based on various filters. + + Args: + user_id (Optional[str]): Filter by user ID. + group_ids (Optional[List[str]]): Filter by group IDs. + document_type (Optional[DocumentType]): Filter by document type. + status (Optional[str]): Filter by document status. + page (int): Page number for pagination. + page_size (int): Number of items per page. + + Returns: + dict: List of documents matching the specified filters. + """ + params = { + "user_id": user_id, + "group_ids": json.dumps(group_ids) if group_ids else None, + "document_type": document_type.value if document_type else None, + "status": status, + "page": page, + "page_size": page_size, + } + return await client._make_request( + "GET", "list_documents", params=params + ) diff --git a/r2r/main/api/client/management.py b/r2r/main/api/client/management.py new file mode 100644 index 000000000..b056c6034 --- /dev/null +++ b/r2r/main/api/client/management.py @@ -0,0 +1,267 @@ +import uuid +from typing import Optional + +from r2r.base import VectorDBFilterValue + + +class ManagementMethods: + @staticmethod + async def server_stats(client) -> dict: + return await client._make_request("GET", "server_stats") + + @staticmethod + async def update_prompt( + client, + name: str, + template: Optional[str] = None, + input_types: Optional[dict[str, str]] = {}, + ) -> dict: + data = { + "name": name, + "template": template, + "input_types": input_types, + } + return await client._make_request("POST", "update_prompt", json=data) + + @staticmethod + async def logs( + client, + run_type_filter: Optional[str] = None, + max_runs: int = 100, + ) -> dict: + params = { + "run_type_filter": run_type_filter, + "max_runs": max_runs, + } + return await client._make_request("GET", "logs", params=params) + + @staticmethod + async def app_settings(client) -> dict: + return await client._make_request("GET", "app_settings") + + @staticmethod + async def score_completion( + client, + message_id: uuid.UUID, + score: float = 0.0, + ) -> dict: + data = { + "message_id": str(message_id), + "score": score, + } + return await client._make_request( + "POST", "score_completion", json=data + ) + + @staticmethod + async def users_overview( + client, + user_ids: Optional[list[uuid.UUID]] = None, + ) -> dict: + params = { + "user_ids": [str(uid) for uid in user_ids] if user_ids else None + } + return await client._make_request( + "GET", "users_overview", params=params + ) + + @staticmethod + async def delete( + client, + filters: dict[str, VectorDBFilterValue], + ) -> dict: + return await client._make_request( + "DELETE", "delete", json={"filters": filters} + ) + + @staticmethod + async def documents_overview( + client, + user_ids: Optional[list[uuid.UUID]] = None, + group_ids: Optional[list[uuid.UUID]] = None, + document_ids: Optional[list[uuid.UUID]] = None, + ) -> dict: + params = { + "user_ids": [str(uid) for uid in user_ids] if user_ids else None, + "group_ids": ( + [str(gid) for gid in group_ids] if group_ids else None + ), + "document_ids": ( + [str(did) for did in document_ids] if document_ids else None + ), + } + return await client._make_request( + "GET", "documents_overview", params=params + ) + + @staticmethod + async def document_chunks( + client, + document_id: uuid.UUID, + ) -> dict: + return await client._make_request( + "GET", f"document_chunks/{document_id}" + ) + + @staticmethod + async def inspect_knowledge_graph( + client, + limit: int = 10000, + ) -> str: + params = {"limit": limit} + return await client._make_request( + "GET", "inspect_knowledge_graph", params=params + ) + + @staticmethod + async def assign_document_to_group( + client, + document_id: str, + group_id: uuid.UUID, + ) -> dict: + data = { + "document_id": document_id, + "group_id": str(group_id), + } + return await client._make_request( + "POST", "assign_document_to_group", json=data + ) + + @staticmethod + async def remove_document_from_group( + client, + document_id: str, + group_id: uuid.UUID, + ) -> dict: + data = { + "document_id": document_id, + "group_id": str(group_id), + } + return await client._make_request( + "POST", "remove_document_from_group", json=data + ) + + @staticmethod + async def get_document_groups( + client, + document_id: str, + ) -> dict: + return await client._make_request( + "GET", f"get_document_groups/{document_id}" + ) + + @staticmethod + async def create_group( + client, + name: str, + description: str = "", + ) -> dict: + data = { + "name": name, + "description": description, + } + return await client._make_request("POST", "create_group", json=data) + + @staticmethod + async def get_group( + client, + group_id: uuid.UUID, + ) -> dict: + return await client._make_request("GET", f"get_group/{group_id}") + + @staticmethod + async def update_group( + client, + group_id: uuid.UUID, + name: Optional[str] = None, + description: Optional[str] = None, + ) -> dict: + data = { + "group_id": str(group_id), + "name": name, + "description": description, + } + return await client._make_request("PUT", "update_group", json=data) + + @staticmethod + async def delete_group( + client, + group_id: uuid.UUID, + ) -> dict: + return await client._make_request("DELETE", f"delete_group/{group_id}") + + @staticmethod + async def list_groups( + client, + offset: int = 0, + limit: int = 100, + ) -> dict: + params = { + "offset": offset, + "limit": limit, + } + return await client._make_request("GET", "list_groups", params=params) + + @staticmethod + async def add_user_to_group( + client, + user_id: uuid.UUID, + group_id: uuid.UUID, + ) -> dict: + data = { + "user_id": str(user_id), + "group_id": str(group_id), + } + return await client._make_request( + "POST", "add_user_to_group", json=data + ) + + @staticmethod + async def remove_user_from_group( + client, + user_id: uuid.UUID, + group_id: uuid.UUID, + ) -> dict: + data = { + "user_id": str(user_id), + "group_id": str(group_id), + } + return await client._make_request( + "POST", "remove_user_from_group", json=data + ) + + @staticmethod + async def get_users_in_group( + client, + group_id: uuid.UUID, + offset: int = 0, + limit: int = 100, + ) -> dict: + params = { + "offset": offset, + "limit": limit, + } + return await client._make_request( + "GET", f"get_users_in_group/{group_id}", params=params + ) + + @staticmethod + async def get_groups_for_user( + client, + user_id: uuid.UUID, + ) -> dict: + return await client._make_request( + "GET", f"get_groups_for_user/{user_id}" + ) + + @staticmethod + async def groups_overview( + client, + group_ids: Optional[list[uuid.UUID]] = None, + ) -> dict: + params = { + "group_ids": [str(gid) for gid in group_ids] if group_ids else None + } + return await client._make_request( + "GET", "groups_overview", params=params + ) diff --git a/r2r/main/api/client/restructure.py b/r2r/main/api/client/restructure.py new file mode 100644 index 000000000..e117243f8 --- /dev/null +++ b/r2r/main/api/client/restructure.py @@ -0,0 +1,51 @@ +from typing import Any, Dict, List, Optional + +from r2r.base import Document + + +class RestructureMethods: + @staticmethod + async def enrich_graph( + client, documents: Optional[List[Document]] = None + ) -> Dict[str, Any]: + """ + Perform graph enrichment on the given documents. + + Args: + documents (Optional[List[Document]]): List of documents to enrich. If None, enriches the entire graph. + + Returns: + Dict[str, Any]: Results of the graph enrichment process. + """ + data = { + "documents": ( + [doc.model_dump() for doc in documents] if documents else None + ) + } + return await client._make_request("POST", "kg/enrich_graph", json=data) + + @staticmethod + async def query_graph(client, query: str) -> Dict[str, Any]: + """ + Query the knowledge graph. + + Args: + query (str): The query to run against the knowledge graph. + + Returns: + Dict[str, Any]: Results of the graph query. + """ + params = {"query": query} + return await client._make_request( + "GET", "kg/query_graph", params=params + ) + + @staticmethod + async def get_graph_statistics(self) -> Dict[str, Any]: + """ + Get statistics about the knowledge graph. + + Returns: + Dict[str, Any]: Statistics about the knowledge graph. + """ + return await client._make_request("GET", "kg/graph_statistics") diff --git a/r2r/main/api/client/retrieval.py b/r2r/main/api/client/retrieval.py new file mode 100644 index 000000000..93771a85a --- /dev/null +++ b/r2r/main/api/client/retrieval.py @@ -0,0 +1,146 @@ +from typing import AsyncGenerator, Optional, Union + +from r2r.base import ( + GenerationConfig, + KGSearchSettings, + Message, + VectorSearchSettings, +) +from r2r.base.api.models import RAGResponse, SearchResponse + + +class RetrievalMethods: + @staticmethod + async def search( + client, + query: str, + vector_search_settings: Optional[ + Union[dict, VectorSearchSettings] + ] = None, + kg_search_settings: Optional[Union[dict, KGSearchSettings]] = None, + *args, + **kwargs + ) -> SearchResponse: + if isinstance(vector_search_settings, dict): + vector_search_settings = VectorSearchSettings( + **vector_search_settings + ) + if isinstance(kg_search_settings, dict): + kg_search_settings = KGSearchSettings(**kg_search_settings) + + data = { + "query": query, + "vector_search_settings": ( + vector_search_settings.dict() + if vector_search_settings + else None + ), + "kg_search_settings": ( + kg_search_settings.dict() if kg_search_settings else None + ), + } + response = await client._make_request("POST", "search", json=data) + return SearchResponse(**response["results"]) + + @staticmethod + async def rag( + client, + query: str, + rag_generation_config: Union[dict, GenerationConfig], + vector_search_settings: Optional[ + Union[dict, VectorSearchSettings] + ] = None, + kg_search_settings: Optional[Union[dict, KGSearchSettings]] = None, + *args, + **kwargs + ) -> Union[RAGResponse, AsyncGenerator[RAGResponse, None]]: + if isinstance(rag_generation_config, dict): + rag_generation_config = GenerationConfig(**rag_generation_config) + if isinstance(vector_search_settings, dict): + vector_search_settings = VectorSearchSettings( + **vector_search_settings + ) + if isinstance(kg_search_settings, dict): + kg_search_settings = KGSearchSettings(**kg_search_settings) + + data = { + "query": query, + "rag_generation_config": rag_generation_config.dict(), + "vector_search_settings": ( + vector_search_settings.dict() + if vector_search_settings + else None + ), + "kg_search_settings": ( + kg_search_settings.dict() if kg_search_settings else None + ), + } + + if rag_generation_config.stream: + + async def stream_response(): + async for chunk in await client._make_request( + "POST", "rag", json=data, stream=True + ): + yield RAGResponse(**chunk) + + return stream_response() + else: + response = await client._make_request("POST", "rag", json=data) + return RAGResponse(**response["results"]) + + @staticmethod + async def agent( + client, + messages: list[Union[dict, Message]], + rag_generation_config: Union[dict, GenerationConfig], + vector_search_settings: Optional[ + Union[dict, VectorSearchSettings] + ] = None, + kg_search_settings: Optional[Union[dict, KGSearchSettings]] = None, + task_prompt_override: Optional[str] = None, + include_title_if_available: Optional[bool] = False, + *args, + **kwargs + ) -> Union[list[Message], AsyncGenerator[Message, None]]: + if isinstance(rag_generation_config, dict): + rag_generation_config = GenerationConfig(**rag_generation_config) + if isinstance(vector_search_settings, dict): + vector_search_settings = VectorSearchSettings( + **vector_search_settings + ) + if isinstance(kg_search_settings, dict): + kg_search_settings = KGSearchSettings(**kg_search_settings) + + messages = [ + Message(**msg) if isinstance(msg, dict) else msg + for msg in messages + ] + + data = { + "messages": [msg.dict() for msg in messages], + "rag_generation_config": rag_generation_config.dict(), + "vector_search_settings": ( + vector_search_settings.dict() + if vector_search_settings + else None + ), + "kg_search_settings": ( + kg_search_settings.dict() if kg_search_settings else None + ), + "task_prompt_override": task_prompt_override, + "include_title_if_available": include_title_if_available, + } + + if rag_generation_config.stream: + + async def stream_response(): + async for chunk in await client._make_request( + "POST", "agent", json=data, stream=True + ): + yield Message(**chunk) + + return stream_response() + else: + response = await client._make_request("POST", "agent", json=data) + return [Message(**msg) for msg in response["results"]] diff --git a/r2r/main/api/routes/auth/base.py b/r2r/main/api/routes/auth/base.py index b37b23a16..f824bb66a 100644 --- a/r2r/main/api/routes/auth/base.py +++ b/r2r/main/api/routes/auth/base.py @@ -1,134 +1,223 @@ +import uuid +from typing import TYPE_CHECKING + from fastapi import Body, Depends, Path from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm -from pydantic import BaseModel +from pydantic import EmailStr -from r2r.base import Token, User, UserCreate -from r2r.main.api.routes.auth.requests import ( - PasswordChangeRequest, - PasswordResetConfirmRequest, - PasswordResetRequest, +from r2r.base.api.models.auth.responses import ( + GenericMessageResponse, + WrappedGenericMessageResponse, + WrappedTokenResponse, + WrappedUserResponse, ) -from ....engine import R2REngine from ..base_router import BaseRouter -oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") - - -class UserResponse(BaseModel): - results: User - +if TYPE_CHECKING: + from ....engine import R2REngine -class TokenResponse(BaseModel): - results: dict[str, Token] - - -class UserProfileUpdate(BaseModel): - email: str | None = None - name: str | None = None - bio: str | None = None - profile_picture: str | None = None +oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") class AuthRouter(BaseRouter): - def __init__(self, engine: R2REngine): + def __init__(self, engine: "R2REngine"): super().__init__(engine) - if self.engine.providers.auth: - self.setup_routes() + self.setup_routes() def setup_routes(self): - @self.router.post("/register", response_model=UserResponse) + @self.router.post("/register", response_model=WrappedUserResponse) @self.base_endpoint - async def register_app(user: UserCreate): - return await self.engine.aregister(user) + async def register_app( + email: EmailStr = Body(..., description="User's email address"), + password: str = Body(..., description="User's password"), + ): + """ + Register a new user. + """ + result = await self.engine.aregister(email, password) + return result - @self.router.post("/verify_email/{verification_code}") + @self.router.post( + "/verify_email", response_model=WrappedGenericMessageResponse + ) @self.base_endpoint - async def verify_email_app(verification_code: str): - return await self.engine.averify_email(verification_code) + async def verify_email_app( + verification_code: str = Body( + ..., description="Email verification code" + ) + ): + """ + Verify a user's email address. - @self.router.post("/login", response_model=TokenResponse) + This endpoint is used to confirm a user's email address using the verification code + sent to their email after registration. + """ + result = await self.engine.averify_email(verification_code) + return GenericMessageResponse(message=result["message"]) + + @self.router.post("/login", response_model=WrappedTokenResponse) @self.base_endpoint - async def login_app(form_data: OAuth2PasswordRequestForm = Depends()): + async def login_app( + form_data: OAuth2PasswordRequestForm = Depends(), + ): + """ + Authenticate a user and provide access tokens. + + This endpoint authenticates a user using their email (username) and password, + and returns access and refresh tokens upon successful authentication. + """ login_result = await self.engine.alogin( form_data.username, form_data.password ) return login_result - @self.router.get("/user", response_model=UserResponse) + @self.router.get("/user", response_model=WrappedUserResponse) @self.base_endpoint async def get_user_app( auth_user=Depends(self.engine.providers.auth.auth_wrapper), ): + """ + Get the current user's profile information. + + This endpoint returns the profile information of the currently authenticated user. + """ return auth_user - @self.router.put("/user", response_model=UserResponse) + @self.router.put("/user", response_model=WrappedUserResponse) @self.base_endpoint async def put_user_app( - profile_update: UserProfileUpdate, + email: EmailStr | None = Body( + None, description="Updated email address" + ), + name: str | None = Body(None, description="Updated user name"), + bio: str | None = Body(None, description="Updated user bio"), + profile_picture: str | None = Body( + None, description="Updated profile picture URL" + ), auth_user=Depends(self.engine.providers.auth.auth_wrapper), ): + """ + Update the current user's profile information. + + This endpoint allows the authenticated user to update their profile information. + """ return await self.engine.aupdate_user( - auth_user.id, profile_update.dict(exclude_unset=True) + user_id=auth_user.id, + email=email, + name=name, + bio=bio, + profile_picture=profile_picture, ) @self.router.post( - "/refresh_access_token", response_model=TokenResponse + "/refresh_access_token", response_model=WrappedTokenResponse ) @self.base_endpoint async def refresh_access_token_app( - refresh_token: str = Body(..., embed=True), + refresh_token: str = Body(..., description="Refresh token"), auth_user=Depends(self.engine.providers.auth.auth_wrapper), ): + """ + Refresh the access token using a refresh token. + + This endpoint allows users to obtain a new access token using their refresh token. + """ refresh_result = await self.engine.arefresh_access_token( user_email=auth_user.email, refresh_token=refresh_token, ) return refresh_result - @self.router.post("/change_password") + @self.router.post( + "/change_password", response_model=WrappedGenericMessageResponse + ) @self.base_endpoint async def change_password_app( - password_change: PasswordChangeRequest, + current_password: str = Body(..., description="Current password"), + new_password: str = Body(..., description="New password"), auth_user=Depends(self.engine.providers.auth.auth_wrapper), ): - return await self.engine.achange_password( + """ + Change the authenticated user's password. + + This endpoint allows users to change their password by providing their current password + and a new password. + """ + result = await self.engine.achange_password( auth_user, - password_change.current_password, - password_change.new_password, + current_password, + new_password, ) + return GenericMessageResponse(message=result["message"]) - @self.router.post("/request_password_reset") + @self.router.post( + "/request_password_reset", + response_model=WrappedGenericMessageResponse, + ) @self.base_endpoint async def request_password_reset_app( - reset_request: PasswordResetRequest, + email: EmailStr = Body(..., description="User's email address") ): - return await self.engine.arequest_password_reset( - reset_request.email - ) + """ + Request a password reset for a user. + + This endpoint initiates the password reset process by sending a reset link + to the specified email address. + """ + result = await self.engine.arequest_password_reset(email) + return GenericMessageResponse(message=result["message"]) - @self.router.post("/reset_password/{reset_token}") + @self.router.post( + "/reset_password/{reset_token}", + response_model=WrappedGenericMessageResponse, + ) @self.base_endpoint async def reset_password_app( - reset_token: str = Path(...), - reset_confirm: PasswordResetConfirmRequest = Body(...), + reset_token: str = Path(..., description="Password reset token"), + new_password: str = Body(..., description="New password"), ): - return await self.engine.aconfirm_password_reset( - reset_token, reset_confirm.new_password + result = await self.engine.aconfirm_password_reset( + reset_token, new_password ) + return GenericMessageResponse(message=result["message"]) - @self.router.post("/logout") + @self.router.post( + "/logout", response_model=WrappedGenericMessageResponse + ) @self.base_endpoint async def logout_app( - auth_user=Depends(self.engine.providers.auth.auth_wrapper), token: str = Depends(oauth2_scheme), + auth_user=Depends(self.engine.providers.auth.auth_wrapper), ): - return await self.engine.alogout(token) + """ + Log out the current user. - @self.router.delete("/user") + This endpoint invalidates the user's current access token, effectively logging them out. + """ + result = await self.engine.alogout(token) + return GenericMessageResponse(message=result["message"]) + + @self.router.delete( + "/user", response_model=WrappedGenericMessageResponse + ) @self.base_endpoint async def delete_user_app( - password: str = Body(..., embed=True), + user_id: uuid.UUID = Body( + ..., description="ID of the user to delete" + ), + password: str | None = Body( + None, description="User's current password" + ), auth_user=Depends(self.engine.providers.auth.auth_wrapper), ): - return await self.engine.adelete_user(auth_user.id, password) + """ + Delete a user account. + + This endpoint allows users to delete their own account or, for superusers, + to delete any user account. + """ + if auth_user.id != user_id and not auth_user.is_superuser: + raise Exception("User ID does not match authenticated user") + result = await self.engine.adelete_user(user_id, password) + return GenericMessageResponse(message=result["message"]) diff --git a/r2r/main/api/routes/auth/requests.py b/r2r/main/api/routes/auth/requests.py deleted file mode 100644 index ef09dd50d..000000000 --- a/r2r/main/api/routes/auth/requests.py +++ /dev/null @@ -1,14 +0,0 @@ -from pydantic import BaseModel - - -class PasswordChangeRequest(BaseModel): - current_password: str - new_password: str - - -class PasswordResetRequest(BaseModel): - email: str - - -class PasswordResetConfirmRequest(BaseModel): - new_password: str diff --git a/r2r/main/api/routes/base_router.py b/r2r/main/api/routes/base_router.py index 45ae47957..6c270fdbf 100644 --- a/r2r/main/api/routes/base_router.py +++ b/r2r/main/api/routes/base_router.py @@ -5,21 +5,30 @@ from fastapi.responses import StreamingResponse from r2r.base import R2RException, manage_run +from r2r.base.logging.base import RunType logger = logging.getLogger(__name__) class BaseRouter: - def __init__(self, engine): + def __init__(self, engine, run_type: RunType = RunType.UNSPECIFIED): self.engine = engine + self.run_type = run_type self.router = APIRouter() - def base_endpoint(self, func): + def base_endpoint(self, func: callable): @functools.wraps(func) async def wrapper(*args, **kwargs): async with manage_run( self.engine.run_manager, func.__name__ ) as run_id: + auth_user = kwargs.get("auth_user") + if auth_user: + await self.engine.run_manager.log_run_info( + run_type=self.run_type, + user=auth_user, + ) + try: results = await func(*args, **kwargs) if isinstance(results, StreamingResponse): @@ -34,28 +43,10 @@ async def wrapper(*args, **kwargs): }, ) except Exception as e: - # Get the pipeline name based on the function name - pipeline_name = f"{func.__name__.split('_')[0]}_pipeline" - - # Safely get the pipeline object and its type - pipeline = getattr( - self.engine.pipelines, pipeline_name, None - ) - pipeline_type = getattr( - pipeline, "pipeline_type", "unknown" - ) - - await self.engine.logging_connection.log( - log_id=run_id, - key="pipeline_type", - value=pipeline_type, - is_info_log=True, - ) await self.engine.logging_connection.log( - log_id=run_id, + run_id=run_id, key="error", value=str(e), - is_info_log=False, ) logger.error(f"{func.__name__}() - \n\n{str(e)})") raise HTTPException( diff --git a/r2r/main/api/routes/ingestion/base.py b/r2r/main/api/routes/ingestion/base.py index 43fc4a75c..8da142dca 100644 --- a/r2r/main/api/routes/ingestion/base.py +++ b/r2r/main/api/routes/ingestion/base.py @@ -1,16 +1,20 @@ -from fastapi import Depends, File, UploadFile +import json +import logging +import uuid +from typing import List, Optional -from r2r.base import ChunkingConfig -from r2r.main.api.routes.ingestion.requests import ( - R2RIngestFilesRequest, - R2RUpdateFilesRequest, -) +from fastapi import Depends, File, Form, UploadFile +from fastapi.openapi.models import Example + +from r2r.base import ChunkingConfig, R2RException +from r2r.base.api.models.ingestion.responses import WrappedIngestionResponse from ....assembly.factory import R2RProviderFactory from ....engine import R2REngine -from ....services.ingestion_service import IngestionService from ..base_router import BaseRouter +logger = logging.getLogger(__name__) + class IngestionRouter(BaseRouter): def __init__(self, engine: R2REngine): @@ -18,58 +22,446 @@ def __init__(self, engine: R2REngine): self.setup_routes() def setup_routes(self): - @self.router.post("/ingest_files") + + # Note, we use the following verbose input parameters because FastAPI struggles to handle `File` input and `Body` inputs + # at the same time. Therefore, we must ues `Form` inputs for the metadata, document_ids, and versions inputs. + @self.router.post( + "/ingest_files", + openapi_extra={ + "x-codeSamples": [ + { + "lang": "Python", + "source": """from r2r import R2RClient + +client = R2RClient("http://localhost:8000") +# when using auth, do client.login(...) + +result = client.ingest_files( + files=["pg_essay_1.html", "got.txt"], + metadatas=[{"metadata_1":"some random metadata"}, {"metadata_2": "some other random metadata"}], + document_ids=None, + versions=None +) +""", + }, + { + "lang": "Shell", + "source": """curl -X POST "https://api.example.com/ingest_files" \\ + -H "Content-Type: multipart/form-data" \\ + -H "Authorization: Bearer YOUR_API_KEY" \\ + -F "file=@pg_essay_1.html;type=text/html" \\ + -F "file=@got.txt;type=text/plain" \\ + -F 'metadatas=[{},{}]' \\ + -F 'document_ids=null' \\ + -F 'versions=null' +""", + }, + ] + }, + responses={ + 200: { + "description": "Successful Response", + "content": { + "application/json": { + "example": { + "results": { + "processed_documents": [ + { + "id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "title": "pg_essay_1.html", + }, + { + "id": "716fea3a-826b-5b27-8e59-ffbd1a35455a", + "title": "got.txt", + }, + ], + "failed_documents": [], + "skipped_documents": [], + } + } + } + }, + }, + 422: { + "description": "Validation Error", + "content": { + "application/json": { + "example": { + "detail": [ + { + "message": "All documents were already successfully processed", + "error_type": "R2RException", + } + ] + } + } + }, + }, + }, + response_model=WrappedIngestionResponse, + ) @self.base_endpoint async def ingest_files_app( - files: list[UploadFile] = File(...), - request: R2RIngestFilesRequest = Depends( - IngestionService.parse_ingest_files_form_data + files: List[UploadFile] = File( + ..., + description="A list of file paths to be ingested. E.g. `file1.txt`, `file2.txt`", ), - auth_user=( - Depends(self.engine.providers.auth.auth_wrapper) - if self.engine.providers.auth - else None + metadatas: Optional[str] = Form( + None, + description="JSON string containing metadata for each file, e.g. `{'title': 'Document 1', 'author': 'John Doe'}`", + examples=[ + Example( + summary="Sample metadata", + description="JSON string with metadata for two documents", + value='[{"title": "Document 1", "author": "John Doe"}, {"title": "Document 2", "author": "Jane Smith"}]', + ) + ], ), + document_ids: Optional[str] = Form( + None, + description="Comma-separated list of document IDs, e.g. `3e157b3a-8469-51db-90d9-52e7d896b49b,223e4567-e89b-12d3-a456-426614174000`", + examples=[ + Example( + summary="Sample document IDs", + description="Comma-separated list of document IDs", + value="3e157b3a-8469-51db-90d9-52e7d896b49b,223e4567-e89b-12d3-a456-426614174000", + ) + ], + ), + versions: Optional[str] = Form( + None, + description="Comma-separated list of versions, e.g. `1.0,1.1`", + examples=[ + Example( + summary="Sample versions", + description="Comma-separated list of versions", + value="1.0,1.1", + ) + ], + ), + chunking_config_override: Optional[str] = Form( + None, + description="JSON string for chunking configuration override", + examples=[ + Example( + summary="Sample chunking config override", + description="JSON string for chunking configuration override", + value='{"chunk_size": 1000, "chunk_overlap": 200}', + ) + ], + ), + auth_user=Depends(self.engine.providers.auth.auth_wrapper), ): - chunking_config_override = None - if request.chunking_config_override: - config = ChunkingConfig(**request.chunking_config_override) - chunking_config_override = ( + """ + Ingest files into the system. + + This endpoint supports multipart/form-data requests, enabling you to update files along with their inside of R2R. A valid user authentication token is required to access this endpoint. Regular users can only update documents they have permission to access. + """ + try: + parsed_data = self.parse_ingest_files_form_data( + metadatas, document_ids, versions, chunking_config_override + ) + except R2RException as e: + raise e + + kwargs = {} + if chunking_config_override: + config = ChunkingConfig(**chunking_config_override) + config.validate() + kwargs["chunking_provider"] = ( R2RProviderFactory.create_chunking_provider(config) ) + else: + logger.info( + "No chunking config override provided. Using default." + ) + + # Check if the user is a superuser + is_superuser = auth_user and auth_user.is_superuser + + # Handle user management logic at the request level + if not auth_user: + for metadata in metadatas or []: + if "user_id" in metadata: + if not is_superuser and metadata["user_id"] != str( + auth_user.id + ): + raise R2RException( + status_code=403, + message="Non-superusers cannot set user_id in metadata.", + ) + if "group_ids" in metadata: + if not is_superuser: + raise R2RException( + status_code=403, + message="Non-superusers cannot set group_ids in metadata.", + ) - return await self.engine.aingest_files( + # If user is not a superuser, set user_id in metadata + metadata["user_id"] = str(auth_user.id) + + ingestion_result = await self.engine.aingest_files( files=files, - metadatas=request.metadatas, - document_ids=request.document_ids, - versions=request.versions, + metadatas=parsed_data["metadatas"], + document_ids=parsed_data["document_ids"], + versions=parsed_data["versions"], user=auth_user, - chunking_config_override=chunking_config_override, + **kwargs, ) - @self.router.post("/update_files") + # If superuser, assign documents to groups + if is_superuser: + for idx, metadata in enumerate(metadatas or []): + if "group_ids" in metadata: + document_id = ingestion_result["processed_documents"][ + idx + ] + for group_id in metadata["group_ids"]: + await self.engine.management_service.aassign_document_to_group( + document_id, group_id + ) + + return ingestion_result + + @self.router.post( + "/update_files", + openapi_extra={ + "x-codeSamples": [ + { + "lang": "Python", + "source": """from r2r import R2RClient + +client = R2RClient("http://localhost:8000") +# when using auth, do client.login(...) + +result = client.update_files( + files=["pg_essay_1_v2.txt"], + document_ids=["b4ac4dd6-5f27-596e-a55b-7cf242ca30aa"] +) +""", + }, + { + "lang": "Shell", + "source": """curl -X POST "https://api.example.com/update_files" \\ + -H "Content-Type: multipart/form-data" \\ + -H "Authorization: Bearer YOUR_API_KEY" \\ + -F "file=@pg_essay_1_v2.txt;type=text/plain" \\ + -F 'document_ids=["b4ac4dd6-5f27-596e-a55b-7cf242ca30aa"]' +""", + }, + ] + }, + responses={ + 200: { + "description": "Successful Response", + "content": { + "application/json": { + "example": { + "results": { + "processed_documents": [ + { + "id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "title": "pg_essay_1_v2.html", + }, + ], + "failed_documents": [], + "skipped_documents": [], + } + } + } + }, + }, + 422: { + "description": "Validation Error", + "content": { + "application/json": { + "example": { + "detail": [ + { + "message": "Document 'b4ac4dd6-5f27-596e-a55b-7cf242ca30aa' does not exist.", + "error_type": "R2RException", + } + ] + } + } + }, + }, + }, + response_model=WrappedIngestionResponse, + ) @self.base_endpoint async def update_files_app( - files: list[UploadFile] = File(...), - request: R2RUpdateFilesRequest = Depends( - IngestionService.parse_update_files_form_data + files: List[UploadFile] = File( + ..., + description="List of files to update", ), - auth_user=( - Depends(self.engine.providers.auth.auth_wrapper) - if self.engine.providers.auth - else None + metadatas: Optional[str] = Form( + None, + description="JSON string containing updated metadata for each file", + examples=[ + Example( + summary="Sample updated metadata", + description="JSON string with updated metadata for two documents", + value='[{"title": "Updated Document 1", "version": "1.1"}, {"title": "Updated Document 2", "version": "1.2"}]', + ) + ], ), + document_ids: Optional[str] = Form( + None, + description="Comma-separated list of document IDs to update", + examples=[ + Example( + summary="Sample document IDs", + description="Comma-separated list of document IDs to update", + value="3e157b3a-8469-51db-90d9-52e7d896b49b,223e4567-e89b-12d3-a456-426614174000", + ) + ], + ), + chunking_config_override: Optional[str] = Form( + None, + description="JSON string for chunking configuration override", + examples=[ + Example( + summary="Sample chunking config override", + description="JSON string for chunking configuration override", + value='{"chunk_size": 1200, "chunk_overlap": 250}', + ) + ], + ), + auth_user=Depends(self.engine.providers.auth.auth_wrapper), ): + """ + Update existing files in the system. + + This endpoint supports multipart/form-data requests, enabling you to update files along with their inside of R2R. A valid user authentication token is required to access this endpoint. Regular users can only update documents they have permission to access. + """ + + try: + parsed_data = self.parse_update_files_form_data( + metadatas, document_ids, chunking_config_override + ) + except R2RException as e: + raise e + chunking_config_override = None - if request.chunking_config_override: - config = ChunkingConfig(**request.chunking_config_override) + if chunking_config_override: + config = ChunkingConfig(**chunking_config_override) chunking_config_override = ( R2RProviderFactory.create_chunking_provider(config) ) return await self.engine.aupdate_files( files=files, - metadatas=request.metadatas, - document_ids=request.document_ids, + metadatas=parsed_data["metadatas"], + document_ids=parsed_data["document_ids"], + chunking_config_override=chunking_config_override, user=auth_user, ) + + @staticmethod + def parse_ingest_files_form_data( + metadatas: Optional[str], + document_ids: Optional[str], + versions: Optional[str], + chunking_config_override: Optional[str], + ) -> dict: + try: + parsed_metadatas = ( + json.loads(metadatas) + if metadatas and metadatas != "null" + else None + ) + if parsed_metadatas is not None and not isinstance( + parsed_metadatas, list + ): + raise ValueError("metadatas must be a list of dictionaries") + + parsed_document_ids = ( + json.loads(document_ids) + if document_ids and document_ids != "null" + else None + ) + if parsed_document_ids is not None: + parsed_document_ids = [ + uuid.UUID(doc_id) for doc_id in parsed_document_ids + ] + + parsed_versions = ( + json.loads(versions) + if versions and versions != "null" + else None + ) + + parsed_chunking_config = ( + json.loads(chunking_config_override) + if chunking_config_override + and chunking_config_override != "null" + else None + ) + + return { + "metadatas": parsed_metadatas, + "document_ids": parsed_document_ids, + "versions": parsed_versions, + "chunking_config_override": parsed_chunking_config, + } + except json.JSONDecodeError as e: + raise R2RException( + status_code=400, message=f"Invalid JSON in form data: {e}" + ) + except ValueError as e: + raise R2RException(status_code=400, message=str(e)) + except Exception as e: + raise R2RException( + status_code=400, message=f"Error processing form data: {e}" + ) + + @staticmethod + def parse_update_files_form_data( + metadatas: Optional[str], + document_ids: str, + chunking_config_override: Optional[str], + ): + try: + parsed_metadatas = ( + json.loads(metadatas) + if metadatas and metadatas != "null" + else None + ) + if parsed_metadatas is not None and not isinstance( + parsed_metadatas, list + ): + raise ValueError("metadatas must be a list of dictionaries") + + if not document_ids or document_ids == "null": + raise ValueError("document_ids is required and cannot be null") + + parsed_document_ids = json.loads(document_ids) + if not isinstance(parsed_document_ids, list): + raise ValueError("document_ids must be a list") + parsed_document_ids = [ + uuid.UUID(doc_id) for doc_id in parsed_document_ids + ] + + parsed_chunking_config = ( + json.loads(chunking_config_override) + if chunking_config_override + and chunking_config_override != "null" + else None + ) + + return { + "metadatas": parsed_metadatas, + "document_ids": parsed_document_ids, + "chunking_config_override": parsed_chunking_config, + } + except json.JSONDecodeError as e: + raise R2RException( + status_code=400, message=f"Invalid JSON in form data: {e}" + ) + except ValueError as e: + raise R2RException(status_code=400, message=str(e)) + except Exception as e: + raise R2RException( + status_code=400, message=f"Error processing form data: {e}" + ) diff --git a/r2r/main/api/routes/ingestion/requests.py b/r2r/main/api/routes/ingestion/requests.py deleted file mode 100644 index 45cefbcb5..000000000 --- a/r2r/main/api/routes/ingestion/requests.py +++ /dev/null @@ -1,17 +0,0 @@ -import uuid -from typing import Optional - -from pydantic import BaseModel - - -class R2RUpdateFilesRequest(BaseModel): - metadatas: Optional[list[dict]] = None - document_ids: Optional[list[uuid.UUID]] = None - chunking_config_override: Optional[dict] = None - - -class R2RIngestFilesRequest(BaseModel): - document_ids: Optional[list[uuid.UUID]] = None - metadatas: Optional[list[dict]] = None - versions: Optional[list[str]] = None - chunking_config_override: Optional[dict] = None diff --git a/r2r/main/api/routes/kg/__init__.py b/r2r/main/api/routes/kg/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/r2r/main/api/routes/kg/base.py b/r2r/main/api/routes/kg/base.py new file mode 100644 index 000000000..1dd1e400f --- /dev/null +++ b/r2r/main/api/routes/kg/base.py @@ -0,0 +1,23 @@ +from fastapi import Depends + +from r2r.main.api.routes.base_router import BaseRouter +from r2r.main.engine import R2REngine + + +class KGRouter(BaseRouter): + def __init__(self, engine: R2REngine): + super().__init__(engine) + self.setup_routes() + + def setup_routes(self): + @self.router.post("/enrich_graph") + @self.base_endpoint + async def enrich_graph( + request: dict, + auth_user=( + Depends(self.engine.providers.auth.auth_wrapper) + if self.engine.providers.auth + else None + ), + ): + return await self.engine.enrich_graph() diff --git a/r2r/main/api/routes/kg/requests.py b/r2r/main/api/routes/kg/requests.py new file mode 100644 index 000000000..213227768 --- /dev/null +++ b/r2r/main/api/routes/kg/requests.py @@ -0,0 +1,10 @@ +from typing import List, Optional + +from pydantic import BaseModel + + +class KGEnrichGraphRequest(BaseModel): + query: str + entity_types: Optional[List[str]] = None + relationships: Optional[List[str]] = None + generation_config: Optional[dict] = None diff --git a/r2r/main/api/routes/management/base.py b/r2r/main/api/routes/management/base.py index dd6f0e649..fc3b3250b 100644 --- a/r2r/main/api/routes/management/base.py +++ b/r2r/main/api/routes/management/base.py @@ -1,21 +1,30 @@ # TODO - Cleanup the handling for non-auth configurations +import json +import uuid from datetime import datetime, timezone +from typing import Optional import psutil -from fastapi import Depends +from fastapi import Body, Depends, Path, Query from pydantic import BaseModel from r2r.base import R2RException -from r2r.main.api.routes.management.requests import ( - R2RAnalyticsRequest, - R2RDeleteRequest, - R2RDocumentChunksRequest, - R2RDocumentsOverviewRequest, - R2RLogsRequest, - R2RPrintRelationshipsRequest, - R2RScoreCompletionRequest, - R2RUpdatePromptRequest, - R2RUsersOverviewRequest, +from r2r.base.api.models.management.responses import ( + WrappedAddUserResponse, + WrappedAnalyticsResponse, + WrappedAppSettingsResponse, + WrappedDeleteResponse, + WrappedDocumentChunkResponse, + WrappedDocumentOverviewResponse, + WrappedGroupListResponse, + WrappedGroupOverviewResponse, + WrappedGroupResponse, + WrappedKnowledgeGraphResponse, + WrappedLogResponse, + WrappedPromptResponse, + WrappedScoreCompletionResponse, + WrappedServerStatsResponse, + WrappedUserOverviewResponse, ) from ....engine import R2REngine @@ -30,18 +39,15 @@ def __init__(self, engine: R2REngine): def setup_routes(self): @self.router.get("/health") + @self.base_endpoint async def health_check(): return {"response": "ok"} @self.router.get("/server_stats") @self.base_endpoint async def server_stats( - auth_user=( - Depends(self.engine.providers.auth.auth_wrapper) - if self.engine.providers.auth - else None - ), - ): + auth_user=Depends(self.engine.providers.auth.auth_wrapper), + ) -> WrappedServerStatsResponse: if not auth_user.is_superuser: raise R2RException( "Only an authorized user can call the `server_stats` endpoint.", @@ -59,104 +65,93 @@ async def server_stats( @self.router.post("/update_prompt") @self.base_endpoint async def update_prompt_app( - request: R2RUpdatePromptRequest, - auth_user=( - Depends(self.engine.providers.auth.auth_wrapper) - if self.engine.providers.auth - else None + name: str = Body(..., description="Prompt name"), + template: Optional[str] = Body( + None, description="Prompt template" ), - ): + input_types: Optional[dict[str, str]] = Body( + {}, description="Input types" + ), + auth_user=Depends(self.engine.providers.auth.auth_wrapper), + ) -> WrappedPromptResponse: if not auth_user.is_superuser: raise R2RException( "Only a superuser can call the `update_prompt` endpoint.", 403, ) - return await self.engine.aupdate_prompt( - request.name, request.template, request.input_types + result = await self.engine.aupdate_prompt( + name, template, input_types ) + return result - @self.router.post("/logs") @self.router.get("/logs") @self.base_endpoint async def logs_app( - request: R2RLogsRequest, - auth_user=( - Depends(self.engine.providers.auth.auth_wrapper) - if self.engine.providers.auth - else None - ), - ): + run_type_filter: Optional[str] = Query(""), + max_runs: int = Query(100, ge=1, le=1000), + auth_user=Depends(self.engine.providers.auth.auth_wrapper), + ) -> WrappedLogResponse: if not auth_user.is_superuser: raise R2RException( "Only a superuser can call the `logs` endpoint.", 403 ) return await self.engine.alogs( - log_type_filter=request.log_type_filter, - max_runs_requested=request.max_runs_requested, + run_type_filter=run_type_filter, + max_runs=max_runs, ) - @self.router.post("/analytics") @self.router.get("/analytics") @self.base_endpoint async def get_analytics_app( - request: R2RAnalyticsRequest, - auth_user=( - Depends(self.engine.providers.auth.auth_wrapper) - if self.engine.providers.auth - else None - ), - ): + filter_criteria: Optional[str] = Query("{}"), + analysis_types: Optional[str] = Query("{}"), + auth_user=Depends(self.engine.providers.auth.auth_wrapper), + ) -> WrappedAnalyticsResponse: if not auth_user.is_superuser: raise R2RException( "Only a superuser can call the `analytics` endpoint.", 403 ) - return await self.engine.aanalytics( - filter_criteria=request.filter_criteria, - analysis_types=request.analysis_types, - ) + try: + # Parse the query parameters + filter_criteria_dict = ( + json.loads(filter_criteria) if filter_criteria else {} + ) + analysis_types_dict = ( + json.loads(analysis_types) if analysis_types else {} + ) - @self.router.delete("/delete") - @self.base_endpoint - async def delete_app( - request: R2RDeleteRequest, - auth_user=( - Depends(self.engine.providers.auth.auth_wrapper) - if self.engine.providers.auth - else None - ), - ): - if not auth_user.is_superuser and ( - "user_id" in request.keys - and request.values[request.keys.index("user_id")] - != auth_user.id - ): + return await self.engine.aanalytics( + filter_criteria=filter_criteria_dict, + analysis_types=analysis_types_dict, + ) + except json.JSONDecodeError as e: raise R2RException( - "Only a superuser can delete arbitrary user data.", 403 + f"Invalid JSON in query parameters: {str(e)}", 400 + ) + except ValueError as e: + raise R2RException( + f"Invalid data in query parameters: {str(e)}", 400 ) - if "user_id" not in request.keys: - request.keys.append("user_id") - request.values.append(auth_user.id) - - return await self.engine.adelete( - keys=request.keys, values=request.values - ) + @self.router.delete("/delete") + @self.base_endpoint + async def delete_app( + filters: Optional[str] = Query("{}"), + auth_user=Depends(self.engine.providers.auth.auth_wrapper), + ) -> WrappedDeleteResponse: + filters_dict = json.loads(filters) if filters else None + return await self.engine.adelete(filters=filters_dict) - @self.router.post("/document_chunks") @self.router.get("/document_chunks") @self.base_endpoint async def document_chunks_app( - request: R2RDocumentChunksRequest, - auth_user=( - Depends(self.engine.providers.auth.auth_wrapper) - if self.engine.providers.auth - else None - ), - ): - chunks = await self.engine.adocument_chunks(request.document_id) + document_id: uuid.UUID = Query(...), + auth_user=Depends(self.engine.providers.auth.auth_wrapper), + ) -> WrappedDocumentChunkResponse: + chunks = await self.engine.adocument_chunks(document_id) if not chunks: raise R2RException( @@ -174,77 +169,53 @@ async def document_chunks_app( return chunks - @self.router.post("/users_overview") @self.router.get("/users_overview") @self.base_endpoint async def users_overview_app( - request: R2RUsersOverviewRequest, - auth_user=( - Depends(self.engine.providers.auth.auth_wrapper) - if self.engine.providers.auth - else None - ), - ): + user_ids: list[uuid.UUID] = Query([]), + auth_user=Depends(self.engine.providers.auth.auth_wrapper), + ) -> WrappedUserOverviewResponse: if not auth_user.is_superuser: raise R2RException( "Only a superuser can call the `users_overview` endpoint.", 403, ) - return await self.engine.ausers_overview(user_ids=request.user_ids) + return await self.engine.ausers_overview(user_ids=user_ids) - @self.router.post("/documents_overview") @self.router.get("/documents_overview") @self.base_endpoint async def documents_overview_app( - request: R2RDocumentsOverviewRequest, - auth_user=( - Depends(self.engine.providers.auth.auth_wrapper) - if self.engine.providers.auth - else None - ), - ): - request_user_ids = request.user_ids - - if request_user_ids and not auth_user.is_superuser: - raise R2RException( - "Only a superuser can call the `documents_overview` endpoint for arbitrary users.", - 403, - ) - request_user_ids = request_user_ids or [str(auth_user.id)] + document_id: list[uuid.UUID] = Query([]), + auth_user=Depends(self.engine.providers.auth.auth_wrapper), + ) -> WrappedDocumentOverviewResponse: + request_user_ids = ( + [auth_user.id] if not auth_user.is_superuser else None + ) return await self.engine.adocuments_overview( - document_ids=request.document_ids, user_ids=request_user_ids + user_ids=request_user_ids, + group_ids=auth_user.group_ids, + document_ids=document_id, ) - @self.router.post("/inspect_knowledge_graph") @self.router.get("/inspect_knowledge_graph") @self.base_endpoint async def inspect_knowledge_graph( - request: R2RPrintRelationshipsRequest, - auth_user=( - Depends(self.engine.providers.auth.auth_wrapper) - if self.engine.providers.auth - else None - ), - ): + limit: int = 100, + auth_user=Depends(self.engine.providers.auth.auth_wrapper), + ) -> WrappedKnowledgeGraphResponse: if not auth_user.is_superuser: raise R2RException( "Only a superuser can call the `inspect_knowledge_graph` endpoint.", 403, ) - return await self.engine.ainspect_knowledge_graph( - limit=request.limit - ) + return await self.engine.ainspect_knowledge_graph(limit=limit) @self.router.get("/app_settings") @self.base_endpoint async def app_settings( - auth_user=( - Depends(self.engine.providers.auth.auth_wrapper) - if self.engine.providers.auth - else None - ), - ): + auth_user=Depends(self.engine.providers.auth.auth_wrapper), + ) -> WrappedAppSettingsResponse: if not auth_user.is_superuser: raise R2RException( "Only a superuser can call the `app_settings` endpoint.", @@ -252,15 +223,190 @@ async def app_settings( ) return await self.engine.aapp_settings() + @self.router.post("/create_group") + @self.base_endpoint + async def create_group_app( + name: str = Body(..., description="Group name"), + description: Optional[str] = Body( + "", description="Group description" + ), + auth_user=Depends(self.engine.providers.auth.auth_wrapper), + ) -> WrappedGroupResponse: + if not auth_user.is_superuser: + raise R2RException("Only a superuser can create groups.", 403) + return await self.engine.acreate_group(name, description) + + @self.router.get("/get_group/{group_id}") + @self.base_endpoint + async def get_group_app( + group_id: uuid.UUID = Path(..., description="Group ID"), + auth_user=Depends(self.engine.providers.auth.auth_wrapper), + ) -> WrappedGroupResponse: + if not auth_user.is_superuser: + raise R2RException( + "Only a superuser can get group details.", 403 + ) + result = await self.engine.aget_group(group_id) + print(result) + return result + + @self.router.put("/update_group") + @self.base_endpoint + async def update_group_app( + group_id: uuid.UUID = Body(..., description="Group ID"), + name: Optional[str] = Body(None, description="Updated group name"), + description: Optional[str] = Body( + None, description="Updated group description" + ), + auth_user=Depends(self.engine.providers.auth.auth_wrapper), + ) -> WrappedGroupResponse: + if not auth_user.is_superuser: + raise R2RException("Only a superuser can update groups.", 403) + return await self.engine.aupdate_group(group_id, name, description) + + @self.router.delete("/delete_group/{group_id}") + @self.base_endpoint + async def delete_group_app( + group_id: uuid.UUID = Path(..., description="Group ID"), + auth_user=Depends(self.engine.providers.auth.auth_wrapper), + ) -> WrappedGroupResponse: + if not auth_user.is_superuser: + raise R2RException("Only a superuser can delete groups.", 403) + return await self.engine.adelete_group(group_id) + + @self.router.get("/list_groups") + @self.base_endpoint + async def list_groups_app( + offset: int = Query(0, ge=0), + limit: int = Query(100, ge=1, le=1000), + auth_user=Depends(self.engine.providers.auth.auth_wrapper), + ) -> WrappedGroupListResponse: + if not auth_user.is_superuser: + raise R2RException( + "Only a superuser can list all groups.", 403 + ) + return await self.engine.alist_groups(offset, limit) + + @self.router.post("/add_user_to_group") + @self.base_endpoint + async def add_user_to_group_app( + user_id: uuid.UUID = Body(..., description="User ID"), + group_id: uuid.UUID = Body(..., description="Group ID"), + auth_user=Depends(self.engine.providers.auth.auth_wrapper), + ) -> WrappedAddUserResponse: + if not auth_user.is_superuser: + raise R2RException( + "Only a superuser can add users to groups.", 403 + ) + result = await self.engine.aadd_user_to_group(user_id, group_id) + return {"result": result} + + @self.router.post("/remove_user_from_group") + @self.base_endpoint + async def remove_user_from_group_app( + user_id: uuid.UUID = Body(..., description="User ID"), + group_id: uuid.UUID = Body(..., description="Group ID"), + auth_user=Depends(self.engine.providers.auth.auth_wrapper), + ) -> WrappedGroupResponse: + if not auth_user.is_superuser: + raise R2RException( + "Only a superuser can remove users from groups.", 403 + ) + return await self.engine.aremove_user_from_group(user_id, group_id) + + # TODO - Proivde response model + @self.router.get("/get_users_in_group/{group_id}/{offset}/{limit}") + @self.base_endpoint + async def get_users_in_group_app( + group_id: uuid.UUID = Path(..., description="Group ID"), + offset: int = Path(..., description="Offset"), + limit: int = Path(..., description="limit"), + auth_user=Depends(self.engine.providers.auth.auth_wrapper), + ): + if not auth_user.is_superuser: + raise R2RException( + "Only a superuser can get users in a group.", 403 + ) + return await self.engine.aget_users_in_group( + group_id, offset, limit + ) + + @self.router.get("/get_groups_for_user/{user_id}") + @self.base_endpoint + async def get_groups_for_user_app( + user_id: uuid.UUID = Path(..., description="User ID"), + auth_user=Depends(self.engine.providers.auth.auth_wrapper), + ) -> WrappedGroupListResponse: + if not auth_user.is_superuser and auth_user.id != user_id: + raise R2RException( + "You can only get groups for yourself unless you're a superuser.", + 403, + ) + return await self.engine.aget_groups_for_user(user_id) + + @self.router.get("/groups_overview") + @self.base_endpoint + async def groups_overview_app( + group_ids: Optional[list[uuid.UUID]] = Query(None), + auth_user=Depends(self.engine.providers.auth.auth_wrapper), + ) -> WrappedGroupOverviewResponse: + if not auth_user.is_superuser: + raise R2RException( + "Only a superuser can call the `groups_overview` endpoint.", + 403, + ) + + return await self.engine.agroups_overview(group_ids=group_ids) + @self.router.post("/score_completion") @self.base_endpoint async def score_completion( - request: R2RScoreCompletionRequest, - ): + message_id: uuid.UUID = Body(..., description="Message ID"), + score: float = Body(..., description="Completion score"), + auth_user=Depends(self.engine.providers.auth.auth_wrapper), + ) -> WrappedScoreCompletionResponse: return await self.engine.ascore_completion( - message_id=request.message_id, score=request.score + message_id=message_id, score=score + ) + + @self.router.post("/assign_document_to_group") + @self.base_endpoint + async def assign_document_to_group_app( + document_id: str = Body(..., description="Document ID"), + group_id: uuid.UUID = Body(..., description="Group ID"), + auth_user=Depends(self.engine.providers.auth.auth_wrapper), + ) -> WrappedGroupResponse: + if not auth_user.is_superuser: + raise R2RException( + "Only a superuser can assign documents to groups.", 403 + ) + return await self.engine.aassign_document_to_group( + document_id, group_id ) + @self.router.post("/remove_document_from_group") + @self.base_endpoint + async def remove_document_from_group_app( + document_id: str = Body(..., description="Document ID"), + group_id: uuid.UUID = Body(..., description="Group ID"), + auth_user=Depends(self.engine.providers.auth.auth_wrapper), + ) -> WrappedGroupResponse: + if not auth_user.is_superuser: + raise R2RException( + "Only a superuser can remove documents from groups.", 403 + ) + return await self.engine.aremove_document_from_group( + document_id, group_id + ) + + @self.router.get("/get_document_groups/{document_id}") + @self.base_endpoint + async def get_document_groups_app( + document_id: str = Path(..., description="Document ID"), + auth_user=Depends(self.engine.providers.auth.auth_wrapper), + ) -> WrappedGroupListResponse: + return await self.engine.aget_document_groups(document_id) + class R2RExtractionRequest(BaseModel): entity_types: list[str] diff --git a/r2r/main/api/routes/management/requests.py b/r2r/main/api/routes/management/requests.py deleted file mode 100644 index a67a19d6e..000000000 --- a/r2r/main/api/routes/management/requests.py +++ /dev/null @@ -1,49 +0,0 @@ -import uuid -from typing import Optional, Union - -from pydantic import BaseModel - -from r2r.base import AnalysisTypes, FilterCriteria - - -class R2RUpdatePromptRequest(BaseModel): - name: str - template: Optional[str] = None - input_types: Optional[dict[str, str]] = {} - - -class R2RDeleteRequest(BaseModel): - keys: list[str] - values: list[Union[bool, int, str]] - - -class R2RAnalyticsRequest(BaseModel): - filter_criteria: FilterCriteria - analysis_types: AnalysisTypes - - -class R2RUsersOverviewRequest(BaseModel): - user_ids: Optional[list[uuid.UUID]] - - -class R2RDocumentsOverviewRequest(BaseModel): - document_ids: Optional[list[uuid.UUID]] - user_ids: Optional[list[uuid.UUID]] - - -class R2RDocumentChunksRequest(BaseModel): - document_id: uuid.UUID - - -class R2RLogsRequest(BaseModel): - log_type_filter: Optional[str] = (None,) - max_runs_requested: int = 100 - - -class R2RPrintRelationshipsRequest(BaseModel): - limit: int = 100 - - -class R2RScoreCompletionRequest(BaseModel): - message_id: uuid.UUID = None - score: float = None diff --git a/r2r/main/api/routes/retrieval/base.py b/r2r/main/api/routes/retrieval/base.py index 42afba217..f52a69748 100644 --- a/r2r/main/api/routes/retrieval/base.py +++ b/r2r/main/api/routes/retrieval/base.py @@ -1,13 +1,16 @@ -from fastapi import Depends +from typing import Optional + +from fastapi import Body, Depends from fastapi.responses import StreamingResponse -from r2r.base import GenerationConfig, KGSearchSettings, VectorSearchSettings -from r2r.main.api.routes.retrieval.requests import ( - R2RAgentRequest, - R2REvalRequest, - R2RRAGRequest, - R2RSearchRequest, +from r2r.base import ( + GenerationConfig, + KGSearchSettings, + Message, + RunType, + VectorSearchSettings, ) +from r2r.base.api.models import WrappedRAGResponse, WrappedSearchResponse from ....engine import R2REngine from ..base_router import BaseRouter @@ -18,87 +21,375 @@ def __init__(self, engine: R2REngine): super().__init__(engine) self.setup_routes() + def retrieval_endpoint(self, run_type: RunType = RunType.RETRIEVAL): + return self.base_endpoint(run_type) + def setup_routes(self): - @self.router.post("/search") - @self.base_endpoint + @self.router.post( + "/search", + responses={ + 200: { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "results": { + "type": "object", + "properties": { + "vector_search_results": { + "type": "array", + "items": { + "type": "object", + "properties": { + "fragment_id": { + "type": "string" + }, + "extraction_id": { + "type": "string" + }, + "document_id": { + "type": "string" + }, + "user_id": { + "type": "string" + }, + "group_ids": { + "type": "array", + "items": { + "type": "string" + }, + }, + "score": { + "type": "number" + }, + "text": { + "type": "string" + }, + "metadata": { + "type": "object" + }, + }, + }, + }, + "kg_search_results": { + "type": "object", + "nullable": True, + }, + }, + } + }, + }, + "example": { + "results": { + "vector_search_results": [ + { + "fragment_id": "c68dc72e-fc23-5452-8f49-d7bd46088a96", + "extraction_id": "3f3d47f3-8baf-58eb-8bc2-0171fb1c6e09", + "document_id": "3e157b3a-8469-51db-90d9-52e7d896b49b", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "score": 0.93943702876567796, + "text": "The capital of France is Paris.", + "metadata": { + "title": "france_information.pdf", + "associatedQuery": "What is the capital of France?", + }, + }, + "... Results continued ...", + ], + "kg_search_results": None, + } + }, + } + }, + } + }, + openapi_extra={ + "x-codeSamples": [ + { + "lang": "Python", + "source": """from r2r import R2RClient + +client = R2RClient("http://localhost:8000") +# when using auth, do client.login(...) + +result = client.search( + query="What is the capital of France?", + vector_search_settings={ + "use_vector_search": True, + "filters": {"document_id": {"eq": "3e157b3a-8469-51db-90d9-52e7d896b49b"}}, + "search_limit": 20, + "do_hybrid_search": True + } +) +""", + }, + { + "lang": "Shell", + "source": """curl -X POST "https://api.example.com/search" \\ + -H "Content-Type: application/json" \\ + -H "Authorization: Bearer YOUR_API_KEY" \\ + -d '{ + "query": "What is the capital of France?", + "vector_search_settings": { + "use_vector_search": true, + "filters": {"document_id": {"eq": "3e157b3a-8469-51db-90d9-52e7d896b49b"}}, + "search_limit": 20, + "do_hybrid_search": true + } + }' +""", + }, + ] + }, + ) + @self.retrieval_endpoint async def search_app( - request: R2RSearchRequest, - auth_user=( - Depends(self.engine.providers.auth.auth_wrapper) - if self.engine.providers.auth - else None + query: str = Body(..., description="Search query"), + vector_search_settings: VectorSearchSettings = Body( + default_factory=VectorSearchSettings, + description="Vector search settings", + example={ + "use_vector_search": True, + "filters": {"category": "technology"}, + "search_limit": 20, + "do_hybrid_search": True, + }, ), - ): - kg_search_settings = request.kg_search_settings or {} + kg_search_settings: KGSearchSettings = Body( + default_factory=KGSearchSettings, + description="Knowledge graph search settings", + ), + auth_user=Depends(self.engine.providers.auth.auth_wrapper), + ) -> WrappedSearchResponse: + """ + Perform a search query on the vector database and knowledge graph. - if "entity_types" not in kg_search_settings: - kg_search_settings["entity_types"] = [] - elif not isinstance(kg_search_settings["entity_types"], list): - kg_search_settings["entity_types"] = [ - kg_search_settings["entity_types"] - ] + This endpoint allows for complex filtering of search results using PostgreSQL-based queries. + Filters can be applied to various fields such as document_id, and internal metadata values. + Allowed operators include eq, neq, gt, gte, lt, lte, like, ilike, in, and nin. - if "kg_search_generation_config" in kg_search_settings: - kg_search_settings["kg_search_generation_config"] = ( - GenerationConfig( - **kg_search_settings["kg_search_generation_config"] - or {} - ) + """ + + user_groups = set(auth_user.group_ids) + print("user_groups = ", user_groups) + selected_groups = set(vector_search_settings.selected_group_ids) + print("selected_groups = ", selected_groups) + allowed_groups = user_groups.intersection(selected_groups) + print("allowed_groups = ", allowed_groups) + if selected_groups - allowed_groups != set(): + raise ValueError( + "User does not have access to the specified group(s): " + f"{selected_groups - allowed_groups}" ) + vector_search_settings.filters = { + "$or": [ + {"user_id": str(auth_user.id)}, + {"group_ids": {"$overlap": list(allowed_groups)}}, + ], + "$and": vector_search_settings.filters, + } + print("filters = ", vector_search_settings) + results = await self.engine.asearch( - query=request.query, - vector_search_settings=VectorSearchSettings( - **(request.vector_search_settings or {}) - ), - kg_search_settings=KGSearchSettings(**kg_search_settings), + query=query, + vector_search_settings=vector_search_settings, + kg_search_settings=kg_search_settings, user=auth_user, ) + print("Returning Results:", results) return results - @self.router.post("/rag") - @self.base_endpoint + @self.router.post( + "/rag", + responses={ + 200: { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "results": { + "type": "object", + "properties": { + "completion": { + "type": "object", + "properties": { + "id": {"type": "string"}, + "choices": { + "type": "array", + "items": { + "type": "object", + "properties": { + "finish_reason": { + "type": "string" + }, + "index": { + "type": "integer" + }, + "message": { + "type": "object", + "properties": { + "content": { + "type": "string" + }, + "role": { + "type": "string" + }, + }, + }, + }, + }, + }, + }, + }, + "search_results": { + "$ref": "#/components/schemas/SearchResponse" + }, + }, + } + }, + }, + "example": { + "results": { + "completion": { + "id": "chatcmpl-123", + "choices": [ + { + "finish_reason": "stop", + "index": 0, + "message": { + "content": "The capital of France is Paris. It is known for its iconic landmarks such as the Eiffel Tower, the Louvre Museum, and Notre-Dame Cathedral.", + "role": "assistant", + }, + } + ], + }, + "search_results": { + "vector_search_results": [ + { + "fragment_id": "c68dc72e-fc23-5452-8f49-d7bd46088a96", + "extraction_id": "3f3d47f3-8baf-58eb-8bc2-0171fb1c6e09", + "document_id": "3e157b3a-8469-51db-90d9-52e7d896b49b", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "score": 0.93943702876567796, + "text": "Paris is the capital of France and is famous for its landmarks.", + "metadata": { + "title": "france_information.pdf", + "associatedQuery": "What is the capital of France?", + }, + } + ], + "kg_search_results": None, + }, + } + }, + } + }, + } + }, + openapi_extra={ + "x-codeSamples": [ + { + "lang": "Python", + "source": """from r2r import R2RClient + +client = R2RClient("http://localhost:8000") +# when using auth, do client.login(...) + +result = client.rag( + query="What is the capital of France?", + vector_search_settings={ + "use_vector_search": True, + "filters": {"document_id": {"eq": "3e157b3a-8469-51db-90d9-52e7d896b49b"}}, + "search_limit": 20, + "do_hybrid_search": True + }, + rag_generation_config={ + "stream": False, + "temperature": 0.7, + "max_tokens": 150 + } +) +""", + }, + { + "lang": "Shell", + "source": """curl -X POST "https://api.example.com/rag" \\ + -H "Content-Type: application/json" \\ + -H "Authorization: Bearer YOUR_API_KEY" \\ + -d '{ + "query": "What is the capital of France?", + "vector_search_settings": { + "use_vector_search": true, + "filters": {"document_id": {"eq": "3e157b3a-8469-51db-90d9-52e7d896b49b"}}, + "search_limit": 20, + "do_hybrid_search": true + }, + "rag_generation_config": { + "stream": false, + "temperature": 0.7, + "max_tokens": 150 + } + }' +""", + }, + ] + }, + ) + @self.retrieval_endpoint async def rag_app( - request: R2RRAGRequest, - auth_user=( - Depends(self.engine.providers.auth.auth_wrapper) - if self.engine.providers.auth - else None + query: str = Body(..., description="RAG query"), + vector_search_settings: VectorSearchSettings = Body( + default_factory=VectorSearchSettings, + description="Vector search settings", ), - ): - if ( - request.kg_search_settings - and request.kg_search_settings - and "kg_search_generation_config" in request.kg_search_settings - ): - request.kg_search_settings["kg_search_generation_config"] = ( - GenerationConfig( - **( - request.kg_search_settings[ - "kg_search_generation_config" - ] - or {} - ) - ) - ) + kg_search_settings: KGSearchSettings = Body( + default_factory=KGSearchSettings, + description="Knowledge graph search settings", + ), + rag_generation_config: GenerationConfig = Body( + default_factory=GenerationConfig, + description="RAG generation configuration", + ), + task_prompt_override: Optional[str] = Body( + None, description="Task prompt override" + ), + auth_user=Depends(self.engine.providers.auth.auth_wrapper), + ) -> WrappedRAGResponse: + """ + Execute a RAG (Retrieval-Augmented Generation) query. + + This endpoint combines search results with language model generation. + It supports the same filtering capabilities as the search endpoint, + allowing for precise control over the retrieved context. + + The generation process can be customized using the rag_generation_config parameter. + """ + allowed_groups = set(auth_user.group_ids) + vector_search_settings.filters = { + "$or": [ + {"user_id": str(auth_user.id)}, + {"group_ids": {"$overlap": list(allowed_groups)}}, + ], + "$and": vector_search_settings.filters, + } + response = await self.engine.arag( - query=request.query, - vector_search_settings=VectorSearchSettings( - **(request.vector_search_settings or {}) - ), - kg_search_settings=KGSearchSettings( - **(request.kg_search_settings or {}) - ), - rag_generation_config=GenerationConfig( - **(request.rag_generation_config or {}) - ), - task_prompt_override=request.task_prompt_override, + query=query, + vector_search_settings=vector_search_settings, + kg_search_settings=kg_search_settings, + rag_generation_config=rag_generation_config, + task_prompt_override=task_prompt_override, user=auth_user, ) - if ( - request.rag_generation_config - and request.rag_generation_config.get("stream", False) - ): + + if rag_generation_config.stream: async def stream_generator(): async for chunk in response: @@ -110,51 +401,214 @@ async def stream_generator(): else: return response - @self.router.post("/agent") - @self.base_endpoint + @self.router.post( + "/agent", + responses={ + 200: { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "results": { + "type": "array", + "items": { + "type": "object", + "properties": { + "role": {"type": "string"}, + "content": {"type": "string"}, + "name": { + "type": "string", + "nullable": True, + }, + "function_call": { + "type": "object", + "nullable": True, + }, + "tool_calls": { + "type": "array", + "nullable": True, + }, + }, + }, + } + }, + }, + "example": { + "results": [ + { + "role": "system", + "content": "## You are a helpful assistant that can search for information.\n\nWhen asked a question, perform a search to find relevant information and provide a response.\n\nThe response should contain line-item attributions to relevent search results, and be as informative if possible.\nIf no relevant results are found, then state that no results were found.\nIf no obvious question is present, then do not carry out a search, and instead ask for clarification.", + "name": None, + "function_call": None, + "tool_calls": None, + }, + { + "role": "user", + "content": "Who is the greatest philospher of all time?", + "name": None, + "function_call": None, + "tool_calls": None, + }, + { + "role": "assistant", + "content": "Aristotle is widely considered the greatest philospher of all time.", + "name": None, + "function_call": None, + "tool_calls": None, + }, + { + "role": "user", + "content": "Can you tell me more about him?", + "name": None, + "function_call": None, + "tool_calls": None, + }, + { + "role": "assistant", + "content": None, + "name": None, + "function_call": { + "name": "search", + "arguments": '{"query":"Aristotle biography"}', + }, + "tool_calls": None, + }, + { + "role": "function", + "content": "1. Aristotle[A] (Greek: Ἀριστοτέλης Aristotélēs, pronounced [aristotélɛːs]; 384–322 BC) was an Ancient Greek philosopher and polymath. His writings cover a broad range of subjects spanning the natural sciences, philosophy, linguistics, economics, politics, psychology, and the arts. As the founder of the Peripatetic school of philosophy in the Lyceum in Athens, he began the wider Aristotelian tradition that followed, which set the groundwork for the development of modern science.\n2. Aristotle[A] (Greek: Ἀριστοτέλης Aristotélēs, pronounced [aristotélɛːs]; 384–322 BC) was an Ancient Greek philosopher and polymath. His writings cover a broad range of subjects spanning the natural sciences, philosophy, linguistics, economics, politics, psychology, and the arts. As the founder of the Peripatetic school of philosophy in the Lyceum in Athens, he began the wider Aristotelian tradition that followed, which set the groundwork for the development of modern science.\n3. Aristotle was born in 384 BC[C] in Stagira, Chalcidice,[2] about 55 km (34 miles) east of modern-day Thessaloniki.[3][4] His father, Nicomachus, was the personal physician to King Amyntas of Macedon. While he was young, Aristotle learned about biology and medical information, which was taught by his father.[5] Both of Aristotle's parents died when he was about thirteen, and Proxenus of Atarneus became his guardian.[6] Although little information about Aristotle's childhood has survived, he probably spent\n4. Aristotle was born in 384 BC[C] in Stagira, Chalcidice,[2] about 55 km (34 miles) east of modern-day Thessaloniki.[3][4] His father, Nicomachus, was the personal physician to King Amyntas of Macedon. While he was young, Aristotle learned about biology and medical information, which was taught by his father.[5] Both of Aristotle's parents died when he was about thirteen, and Proxenus of Atarneus became his guardian.[6] Although little information about Aristotle's childhood has survived, he probably spent\n5. Life\nIn general, the details of Aristotle's life are not well-established. The biographies written in ancient times are often speculative and historians only agree on a few salient points.[B]\n", + "name": "search", + "function_call": None, + "tool_calls": None, + }, + { + "role": "assistant", + "content": "Aristotle (384–322 BC) was an Ancient Greek philosopher and polymath whose contributions have had a profound impact on various fields of knowledge. Here are some key points about his life and work:\n\n1. **Early Life**: Aristotle was born in 384 BC in Stagira, Chalcidice, which is near modern-day Thessaloniki, Greece. His father, Nicomachus, was the personal physician to King Amyntas of Macedon, which exposed Aristotle to medical and biological knowledge from a young age [C].\n\n2. **Education and Career**: After the death of his parents, Aristotle was sent to Athens to study at Plato's Academy, where he remained for about 20 years. After Plato's death, Aristotle left Athens and eventually became the tutor of Alexander the Great [C].\n\n3. **Philosophical Contributions**: Aristotle founded the Lyceum in Athens, where he established the Peripatetic school of philosophy. His works cover a wide range of subjects, including metaphysics, ethics, politics, logic, biology, and aesthetics. His writings laid the groundwork for many modern scientific and philosophical inquiries [A].\n\n4. **Legacy**: Aristotle's influence extends beyond philosophy to the natural sciences, linguistics, economics, and psychology. His method of systematic observation and analysis has been foundational to the development of modern science [A].\n\nAristotle's comprehensive approach to knowledge and his systematic methodology have earned him a lasting legacy as one of the greatest philosophers of all time.\n\nSources:\n- [A] Aristotle's broad range of writings and influence on modern science.\n- [C] Details about Aristotle's early life and education.", + "name": None, + "function_call": None, + "tool_calls": None, + }, + ] + }, + } + }, + } + }, + openapi_extra={ + "x-codeSamples": [ + { + "lang": "Python", + "source": """from r2r import R2RClient + +client = R2RClient("http://localhost:8000") +# when using auth, do client.login(...) + +result = client.agent( + messages=[ + {"role": "user", "content": "Who is the greatest philospher of all time?"}, + {"role": "assistant", "content": "Aristotle is widely considered the greatest philospher of all time."}, + {"role": "user", "content": "Can you tell me more about him?"} + ], + vector_search_settings={ + "use_vector_search": True, + "filters": {"document_id": {"eq": "5e157b3a-8469-51db-90d9-52e7d896b49b"}}, + "search_limit": 20, + "do_hybrid_search": True + }, + rag_generation_config={ + "stream": False, + "temperature": 0.7, + "max_tokens": 200 + }, + include_title_if_available=True +) +""", + }, + { + "lang": "Shell", + "source": """curl -X POST "https://api.example.com/agent" \\ + -H "Content-Type: application/json" \\ + -H "Authorization: Bearer YOUR_API_KEY" \\ + -d '{ + "messages": [ + {"role": "user", "content": "Who is the greatest philospher of all time?"}, + {"role": "assistant", "content": "Aristotle is widely considered the greatest philospher of all time."}, + {"role": "user", "content": "Can you tell me more about him?"} + ], + "vector_search_settings": { + "use_vector_search": true, + "filters": {"document_id": {"eq": "5e157b3a-8469-51db-90d9-52e7d896b49b"}}, + "search_limit": 20, + "do_hybrid_search": true + }, + "rag_generation_config": { + "stream": false, + "temperature": 0.7, + "max_tokens": 200 + }, + "include_title_if_available": true + }' +""", + }, + ] + }, + ) + @self.retrieval_endpoint async def agent_app( - request: R2RAgentRequest, - auth_user=( - Depends(self.engine.providers.auth.auth_wrapper) - if self.engine.providers.auth - else None + messages: list[Message] = Body( + ..., description="List of message objects" + ), + vector_search_settings: VectorSearchSettings = Body( + default_factory=VectorSearchSettings, + description="Vector search settings", + ), + kg_search_settings: KGSearchSettings = Body( + default_factory=KGSearchSettings, + description="Knowledge graph search settings", + ), + rag_generation_config: GenerationConfig = Body( + default_factory=GenerationConfig, + description="RAG generation configuration", ), + task_prompt_override: Optional[str] = Body( + None, description="Task prompt override" + ), + include_title_if_available: bool = Body( + True, description="Include title if available" + ), + auth_user=Depends(self.engine.providers.auth.auth_wrapper), ): - if ( - request.kg_search_settings - and "kg_search_generation_config" in request.kg_search_settings - ): - request.kg_search_settings["kg_search_generation_config"] = ( - GenerationConfig( - **( - request.kg_search_settings[ - "kg_search_generation_config" - ] - or {} - ) - ) - ) + """ + Implement an agent-based interaction for complex query processing. + This endpoint supports multi-turn conversations and can handle complex queries + by breaking them down into sub-tasks. It uses the same filtering capabilities + as the search and RAG endpoints for retrieving relevant information. + + The agent's behavior can be customized using the rag_generation_config and + task_prompt_override parameters. + """ + allowed_groups = set(auth_user.group_ids) + vector_search_settings.filters = { + "$or": [ + {"user_id": str(auth_user.id)}, + {"group_ids": {"$overlap": list(allowed_groups)}}, + ], + "$and": vector_search_settings.filters, + } + print("filters = ", vector_search_settings) response = await self.engine.arag_agent( - messages=request.messages, - vector_search_settings=VectorSearchSettings( - **(request.vector_search_settings or {}) - ), - kg_search_settings=KGSearchSettings( - **(request.kg_search_settings or {}) - ), - rag_generation_config=GenerationConfig( - **(request.rag_generation_config or {}) - ), - task_prompt_override=request.task_prompt_override, - include_title_if_available=request.include_title_if_available, + messages=messages, + vector_search_settings=vector_search_settings, + kg_search_settings=kg_search_settings, + rag_generation_config=rag_generation_config, + task_prompt_override=task_prompt_override, + include_title_if_available=include_title_if_available, user=auth_user, ) - if ( - request.rag_generation_config - and request.rag_generation_config.get("stream", False) - ): + if rag_generation_config.stream: async def stream_generator(): async for chunk in response: @@ -165,21 +619,3 @@ async def stream_generator(): ) else: return response - - @self.router.post("/evaluate") - @self.base_endpoint - async def evaluate_app( - request: R2REvalRequest, - auth_user=( - Depends(self.engine.providers.auth.auth_wrapper) - if self.engine.providers.auth - else None - ), - ): - results = await self.engine.aevaluate( - query=request.query, - context=request.context, - completion=request.completion, - user=auth_user, - ) - return results diff --git a/r2r/main/api/routes/retrieval/requests.py b/r2r/main/api/routes/retrieval/requests.py deleted file mode 100644 index 87d321977..000000000 --- a/r2r/main/api/routes/retrieval/requests.py +++ /dev/null @@ -1,35 +0,0 @@ -from typing import Optional - -from pydantic import BaseModel - -from r2r.base import Message - - -class R2RSearchRequest(BaseModel): - query: str - vector_search_settings: Optional[dict] = None - kg_search_settings: Optional[dict] = None - - -class R2RRAGRequest(BaseModel): - query: str - vector_search_settings: Optional[dict] = None - kg_search_settings: Optional[dict] = None - rag_generation_config: Optional[dict] = None - task_prompt_override: Optional[str] = None - include_title_if_available: Optional[bool] = True - - -class R2REvalRequest(BaseModel): - query: str - context: str - completion: str - - -class R2RAgentRequest(BaseModel): - messages: list[Message] - vector_search_settings: Optional[dict] = None - kg_search_settings: Optional[dict] = None - rag_generation_config: Optional[dict] = None - task_prompt_override: Optional[str] = None - include_title_if_available: Optional[bool] = True diff --git a/r2r/main/app.py b/r2r/main/app.py index 12d5d04b4..ec9d4c479 100644 --- a/r2r/main/app.py +++ b/r2r/main/app.py @@ -1,10 +1,13 @@ +from typing import TYPE_CHECKING + from fastapi import FastAPI -from .engine import R2REngine +if TYPE_CHECKING: + from .engine import R2REngine class R2RApp: - def __init__(self, engine: R2REngine): + def __init__(self, engine: "R2REngine"): self.engine = engine self._setup_routes() self._apply_cors() @@ -17,6 +20,7 @@ def serve(self, host: str = "0.0.0.0", port: int = 8000): def _setup_routes(self): from .api.routes.auth import base as auth_base from .api.routes.ingestion import base as ingestion_base + from .api.routes.kg import base as kg_base from .api.routes.management import base as management_base from .api.routes.retrieval import base as retrieval_base @@ -34,11 +38,14 @@ def _setup_routes(self): ) auth_router = auth_base.AuthRouter.build_router(self.engine) + kg_router = kg_base.KGRouter.build_router(self.engine) + # Include routers in the app self.app.include_router(ingestion_router, prefix="/v1") self.app.include_router(management_router, prefix="/v1") self.app.include_router(retrieval_router, prefix="/v1") self.app.include_router(auth_router, prefix="/v1") + self.app.include_router(kg_router, prefix="/v1") @self.app.router.get("/v1/openapi_spec") async def openapi_spec(): diff --git a/r2r/main/app_entry.py b/r2r/main/app_entry.py index e18eaff1c..9c312108d 100644 --- a/r2r/main/app_entry.py +++ b/r2r/main/app_entry.py @@ -5,8 +5,8 @@ from fastapi import FastAPI -from r2r import R2RBuilder, R2RConfig -from r2r.main.execution import R2RExecutionWrapper +from .assembly import R2RBuilder, R2RConfig +from .execution import R2RExecutionWrapper logger = logging.getLogger(__name__) current_file_path = os.path.dirname(__file__) diff --git a/r2r/main/assembly/__init__.py b/r2r/main/assembly/__init__.py index e69de29bb..9fda7f8d4 100644 --- a/r2r/main/assembly/__init__.py +++ b/r2r/main/assembly/__init__.py @@ -0,0 +1,23 @@ +from .builder import R2RBuilder +from .config import R2RConfig +from .factory import ( + R2RAgentFactory, + R2RPipeFactory, + R2RPipelineFactory, + R2RProviderFactory, +) +from .factory_extensions import R2RPipeFactoryWithMultiSearch + +__all__ = [ + # Builder + "R2RBuilder", + # Config + "R2RConfig", + # Factory + "R2RProviderFactory", + "R2RPipeFactory", + "R2RPipelineFactory", + "R2RAgentFactory", + # Factory Extensions + "R2RPipeFactoryWithMultiSearch", +] diff --git a/r2r/main/assembly/builder.py b/r2r/main/assembly/builder.py index 981e336bb..9b34a0a0c 100644 --- a/r2r/main/assembly/builder.py +++ b/r2r/main/assembly/builder.py @@ -1,7 +1,7 @@ import os from typing import Optional, Type -from r2r.agents import R2RRAGAgent +from r2r.agent import R2RRAGAgent from r2r.base import ( AsyncPipe, AuthProvider, @@ -9,13 +9,12 @@ CryptoProvider, DatabaseProvider, EmbeddingProvider, - EvalProvider, KGProvider, PromptProvider, ) from r2r.pipelines import ( - EvalPipeline, IngestionPipeline, + KGEnrichmentPipeline, RAGPipeline, SearchPipeline, ) @@ -37,20 +36,14 @@ class R2RBuilder: config_root = os.path.join( current_file_path, "..", "..", "examples", "configs" ) - CONFIG_OPTIONS = { - "default": None, - "local_llm": os.path.join(config_root, "local_llm.toml"), - "local_llm_rerank": os.path.join(config_root, "local_llm_rerank.toml"), - "neo4j_kg": os.path.join(config_root, "neo4j_kg.toml"), - "neo4j_kg_no_vector_postgres": os.path.join( - config_root, "neo4j_kg_no_vector_postgres.toml" - ), - "local_llm_neo4j_kg": os.path.join( - config_root, "local_llm_neo4j_kg.toml" - ), - "postgres_logging": os.path.join(config_root, "postgres_logging.toml"), - "auth": os.path.join(config_root, "auth.toml"), - } + + CONFIG_OPTIONS = {} + for file in os.listdir(config_root): + if file.endswith(".toml"): + CONFIG_OPTIONS[file.removesuffix(".toml")] = os.path.join( + config_root, file + ) + CONFIG_OPTIONS["default"] = None @staticmethod def _get_config(config_name): @@ -79,7 +72,6 @@ def __init__( self.auth_provider_override: Optional[AuthProvider] = None self.database_provider_override: Optional[DatabaseProvider] = None self.embedding_provider_override: Optional[EmbeddingProvider] = None - self.eval_provider_override: Optional[EvalProvider] = None self.llm_provider_override: Optional[CompletionProvider] = None self.prompt_provider_override: Optional[PromptProvider] = None self.kg_provider_override: Optional[KGProvider] = None @@ -92,17 +84,19 @@ def __init__( self.vector_search_pipe_override: Optional[AsyncPipe] = None self.rag_pipe_override: Optional[AsyncPipe] = None self.streaming_rag_pipe_override: Optional[AsyncPipe] = None - self.eval_pipe_override: Optional[AsyncPipe] = None self.kg_pipe_override: Optional[AsyncPipe] = None self.kg_storage_pipe_override: Optional[AsyncPipe] = None self.kg_search_pipe_override: Optional[AsyncPipe] = None + self.kg_node_extraction_pipe_override: Optional[AsyncPipe] = None + self.kg_node_description_pipe_override: Optional[AsyncPipe] = None + self.kg_clustering_pipe_override: Optional[AsyncPipe] = None # Pipeline overrides self.ingestion_pipeline: Optional[IngestionPipeline] = None self.search_pipeline: Optional[SearchPipeline] = None self.rag_pipeline: Optional[RAGPipeline] = None self.streaming_rag_pipeline: Optional[RAGPipeline] = None - self.eval_pipeline: Optional[EvalPipeline] = None + self.kg_pipeline: Optional[KGEnrichmentPipeline] = None # Agent overrides self.assistant_factory_override: Optional[R2RAgentFactory] = None @@ -137,10 +131,6 @@ def with_embedding_provider(self, provider: EmbeddingProvider): self.embedding_provider_override = provider return self - def with_eval_provider(self, provider: EvalProvider): - self.eval_provider_override = provider - return self - def with_llm_provider(self, provider: CompletionProvider): self.llm_provider_override = provider return self @@ -182,10 +172,6 @@ def with_streaming_rag_pipe(self, pipe: AsyncPipe): self.streaming_rag_pipe_override = pipe return self - def with_eval_pipe(self, pipe: AsyncPipe): - self.eval_pipe_override = pipe - return self - def with_kg_pipe(self, pipe: AsyncPipe): self.kg_pipe_override = pipe return self @@ -198,6 +184,18 @@ def with_kg_search_pipe(self, pipe: AsyncPipe): self.kg_search_pipe_override = pipe return self + def with_kg_node_extraction_pipe(self, pipe: AsyncPipe): + self.kg_node_extraction_pipe_override = pipe + return self + + def with_kg_clustering_pipe(self, pipe: AsyncPipe): + self.kg_clustering_pipe_override = pipe + return self + + def with_kg_node_description_pipe(self, pipe: AsyncPipe): + self.kg_node_description_pipe_override = pipe + return self + # Pipeline override methods def with_ingestion_pipeline(self, pipeline: IngestionPipeline): self.ingestion_pipeline = pipeline @@ -215,8 +213,8 @@ def with_streaming_rag_pipeline(self, pipeline: RAGPipeline): self.streaming_rag_pipeline = pipeline return self - def with_eval_pipeline(self, pipeline: EvalPipeline): - self.eval_pipeline = pipeline + def with_kg_pipeline(self, pipeline: KGEnrichmentPipeline): + self.kg_pipeline = pipeline return self def with_assistant_factory(self, factory: R2RAgentFactory): @@ -236,7 +234,6 @@ def build(self, *args, **kwargs) -> R2R: auth_provider_override=self.auth_provider_override, database_provider_override=self.database_provider_override, embedding_provider_override=self.embedding_provider_override, - eval_provider_override=self.eval_provider_override, llm_provider_override=self.llm_provider_override, prompt_provider_override=self.prompt_provider_override, kg_provider_override=self.kg_provider_override, @@ -244,7 +241,6 @@ def build(self, *args, **kwargs) -> R2R: *args, **kwargs, ) - pipes = pipe_factory(self.config, providers).create_pipes( parsing_pipe_override=self.parsing_pipe_override, embedding_pipe_override=self.embedding_pipe_override, @@ -252,10 +248,12 @@ def build(self, *args, **kwargs) -> R2R: vector_search_pipe_override=self.vector_search_pipe_override, rag_pipe_override=self.rag_pipe_override, streaming_rag_pipe_override=self.streaming_rag_pipe_override, - eval_pipe_override=self.eval_pipe_override, kg_pipe_override=self.kg_pipe_override, kg_storage_pipe_override=self.kg_storage_pipe_override, kg_search_pipe_override=self.kg_search_pipe_override, + kg_node_extraction_pipe=self.kg_node_extraction_pipe_override, + kg_node_description_pipe=self.kg_node_description_pipe_override, + kg_clustering_pipe=self.kg_clustering_pipe_override, *args, **kwargs, ) @@ -265,7 +263,7 @@ def build(self, *args, **kwargs) -> R2R: search_pipeline=self.search_pipeline, rag_pipeline=self.rag_pipeline, streaming_rag_pipeline=self.streaming_rag_pipeline, - eval_pipeline=self.eval_pipeline, + kg_pipeline=self.kg_pipeline, *args, **kwargs, ) diff --git a/r2r/main/assembly/config.py b/r2r/main/assembly/config.py index f8e413fb8..1f1408198 100644 --- a/r2r/main/assembly/config.py +++ b/r2r/main/assembly/config.py @@ -6,16 +6,14 @@ import toml from pydantic import BaseModel -from ...base.abstractions.agent import AgentConfig -from ...base.abstractions.document import DocumentType from ...base.abstractions.llm import GenerationConfig -from ...base.logging.kv_logger import LoggingConfig +from ...base.agent.agent import AgentConfig +from ...base.logging.run_logger import LoggingConfig from ...base.providers.auth import AuthConfig from ...base.providers.chunking import ChunkingConfig from ...base.providers.crypto import CryptoConfig -from ...base.providers.database import DatabaseConfig, ProviderConfig +from ...base.providers.database import DatabaseConfig from ...base.providers.embedding import EmbeddingConfig -from ...base.providers.eval import EvalConfig from ...base.providers.kg import KGConfig from ...base.providers.llm import CompletionConfig from ...base.providers.parsing import ParsingConfig @@ -35,7 +33,6 @@ class R2RConfig: "batch_size", "add_title_as_prefix", ], - "eval": ["llm"], "kg": [ "provider", "batch_size", @@ -55,7 +52,6 @@ class R2RConfig: crypto: CryptoConfig database: DatabaseConfig embedding: EmbeddingConfig - eval: EvalConfig kg: KGConfig logging: LoggingConfig parsing: ParsingConfig @@ -95,7 +91,6 @@ def __init__(self, config_data: dict[str, Any]): self.crypto = CryptoConfig.create(**self.crypto) self.database = DatabaseConfig.create(**self.database) self.embedding = EmbeddingConfig.create(**self.embedding) - self.eval = EvalConfig.create(**self.eval, llm=None) self.kg = KGConfig.create(**self.kg) self.logging = LoggingConfig.create(**self.logging) self.parsing = ParsingConfig.create(**self.parsing) @@ -107,8 +102,11 @@ def _validate_config_section( ): if section not in config_data: raise ValueError(f"Missing '{section}' section in config") - if not all(key in config_data[section] for key in keys): - raise ValueError(f"Missing required keys in '{section}' config") + missing_keys = [key for key in keys if key not in config_data[section]] + if missing_keys: + raise ValueError( + f"Missing required keys in '{section}' config: {', '.join(missing_keys)}" + ) @classmethod def from_toml(cls, config_path: str = None) -> "R2RConfig": diff --git a/r2r/main/assembly/factory.py b/r2r/main/assembly/factory.py index 49166147d..178c552ae 100644 --- a/r2r/main/assembly/factory.py +++ b/r2r/main/assembly/factory.py @@ -2,9 +2,8 @@ import os from typing import Any, Optional -from r2r.agents import R2RRAGAgent, R2RStreamingRAGAgent +from r2r.agent import R2RRAGAgent, R2RStreamingRAGAgent from r2r.base import ( - AgentConfig, AsyncPipe, AuthConfig, AuthProvider, @@ -18,17 +17,16 @@ DatabaseProvider, EmbeddingConfig, EmbeddingProvider, - EvalProvider, KGProvider, - KVLoggingSingleton, ParsingConfig, ParsingProvider, PromptConfig, PromptProvider, + RunLoggingSingleton, ) from r2r.pipelines import ( - EvalPipeline, IngestionPipeline, + KGEnrichmentPipeline, RAGPipeline, SearchPipeline, ) @@ -106,6 +104,7 @@ def create_parsing_provider( def create_chunking_provider( chunking_config: ChunkingConfig, *args, **kwargs ) -> ChunkingProvider: + chunking_config.validate() if chunking_config.provider == "r2r": from r2r.providers import R2RChunkingProvider @@ -183,30 +182,6 @@ def create_embedding_provider( return embedding_provider - @staticmethod - def create_eval_provider( - eval_config, prompt_provider, *args, **kwargs - ) -> Optional[EvalProvider]: - if eval_config.provider == "local": - from r2r.providers import LLMEvalProvider - - llm_provider = R2RProviderFactory.create_llm_provider( - eval_config.llm - ) - eval_provider = LLMEvalProvider( - eval_config, - llm_provider=llm_provider, - prompt_provider=prompt_provider, - ) - elif eval_config.provider is None: - eval_provider = None - else: - raise ValueError( - f"Eval provider {eval_config.provider} not supported." - ) - - return eval_provider - @staticmethod def create_llm_provider( llm_config: CompletionConfig, *args, **kwargs @@ -259,7 +234,6 @@ def create_kg_provider(kg_config, *args, **kwargs): def create_providers( self, embedding_provider_override: Optional[EmbeddingProvider] = None, - eval_provider_override: Optional[EvalProvider] = None, llm_provider_override: Optional[CompletionProvider] = None, prompt_provider_override: Optional[PromptProvider] = None, kg_provider_override: Optional[KGProvider] = None, @@ -282,12 +256,6 @@ def create_providers( self.config.embedding, *args, **kwargs ) ) - eval_provider = eval_provider_override or self.create_eval_provider( - self.config.eval, - prompt_provider=prompt_provider, - *args, - **kwargs, - ) llm_provider = llm_provider_override or self.create_llm_provider( self.config.completion, *args, **kwargs @@ -330,7 +298,6 @@ def create_providers( chunking=chunking_provider, database=database_provider, embedding=embedding_provider, - eval=eval_provider, llm=llm_provider, parsing=parsing_provider, prompt=prompt_provider, @@ -354,7 +321,9 @@ def create_pipes( vector_search_pipe_override: Optional[AsyncPipe] = None, rag_pipe_override: Optional[AsyncPipe] = None, streaming_rag_pipe_override: Optional[AsyncPipe] = None, - eval_pipe_override: Optional[AsyncPipe] = None, + kg_node_extraction_pipe: Optional[AsyncPipe] = None, + kg_node_description_pipe: Optional[AsyncPipe] = None, + kg_clustering_pipe: Optional[AsyncPipe] = None, chunking_pipe_override: Optional[AsyncPipe] = None, *args, **kwargs, @@ -382,26 +351,16 @@ def create_pipes( or self.create_rag_pipe(*args, **kwargs), streaming_rag_pipe=streaming_rag_pipe_override or self.create_rag_pipe(stream=True, *args, **kwargs), - eval_pipe=eval_pipe_override - or self.create_eval_pipe(*args, **kwargs), + kg_node_extraction_pipe=kg_node_extraction_pipe + or self.create_kg_node_extraction_pipe(*args, **kwargs), + kg_node_description_pipe=kg_node_description_pipe + or self.create_kg_node_description_pipe(*args, **kwargs), + kg_clustering_pipe=kg_clustering_pipe + or self.create_kg_clustering_pipe(*args, **kwargs), chunking_pipe=chunking_pipe_override or self.create_chunking_pipe(*args, **kwargs), ) - def create_parsing_pipe( - self, - excluded_parsers: Optional[list] = None, - override_parsers: Optional[list] = None, - *args, - **kwargs, - ) -> Any: - from r2r.pipes import ParsingPipe - - return ParsingPipe( - excluded_parsers=excluded_parsers or [], - override_parsers=override_parsers or [], - ) - def create_parsing_pipe(self, *args, **kwargs) -> Any: from r2r.pipes import ParsingPipe @@ -416,7 +375,6 @@ def create_embedding_pipe(self, *args, **kwargs) -> Any: if self.config.embedding.provider is None: return None - from r2r.base import RecursiveCharacterTextSplitter from r2r.pipes import EmbeddingPipe return EmbeddingPipe( @@ -448,9 +406,9 @@ def create_kg_pipe(self, *args, **kwargs) -> Any: if self.config.kg.provider is None: return None - from r2r.pipes import KGExtractionPipe + from r2r.pipes import KGTriplesExtractionPipe - return KGExtractionPipe( + return KGTriplesExtractionPipe( kg_provider=self.providers.kg, llm_provider=self.providers.llm, prompt_provider=self.providers.prompt, @@ -479,6 +437,7 @@ def create_kg_search_pipe(self, *args, **kwargs) -> Any: kg_provider=self.providers.kg, llm_provider=self.providers.llm, prompt_provider=self.providers.prompt, + embedding_provider=self.providers.embedding, ) def create_rag_pipe(self, stream: bool = False, *args, **kwargs) -> Any: @@ -497,10 +456,34 @@ def create_rag_pipe(self, stream: bool = False, *args, **kwargs) -> Any: prompt_provider=self.providers.prompt, ) - def create_eval_pipe(self, *args, **kwargs) -> Any: - from r2r.pipes import EvalPipe + def create_kg_node_extraction_pipe(self, *args, **kwargs) -> Any: + from r2r.pipes import KGNodeExtractionPipe - return EvalPipe(eval_provider=self.providers.eval) + return KGNodeExtractionPipe( + kg_provider=self.providers.kg, + llm_provider=self.providers.llm, + prompt_provider=self.providers.prompt, + ) + + def create_kg_node_description_pipe(self, *args, **kwargs) -> Any: + from r2r.pipes import KGNodeDescriptionPipe + + return KGNodeDescriptionPipe( + kg_provider=self.providers.kg, + llm_provider=self.providers.llm, + prompt_provider=self.providers.prompt, + embedding_provider=self.providers.embedding, + ) + + def create_kg_clustering_pipe(self, *args, **kwargs) -> Any: + from r2r.pipes import KGClusteringPipe + + return KGClusteringPipe( + kg_provider=self.providers.kg, + llm_provider=self.providers.llm, + prompt_provider=self.providers.prompt, + embedding_provider=self.providers.embedding, + ) class R2RPipelineFactory: @@ -576,10 +559,13 @@ def create_rag_pipeline( rag_pipeline.add_pipe(rag_pipe) return rag_pipeline - def create_eval_pipeline(self, *args, **kwargs) -> EvalPipeline: - eval_pipeline = EvalPipeline() - eval_pipeline.add_pipe(self.pipes.eval_pipe) - return eval_pipeline + def create_kg_pipeline(self, *args, **kwargs) -> KGEnrichmentPipeline: + kg_pipeline = KGEnrichmentPipeline() + kg_pipeline.add_pipe(self.pipes.kg_node_extraction_pipe) + kg_pipeline.add_pipe(self.pipes.kg_node_description_pipe) + kg_pipeline.add_pipe(self.pipes.kg_clustering_pipe) + + return kg_pipeline def create_pipelines( self, @@ -587,7 +573,7 @@ def create_pipelines( search_pipeline: Optional[SearchPipeline] = None, rag_pipeline: Optional[RAGPipeline] = None, streaming_rag_pipeline: Optional[RAGPipeline] = None, - eval_pipeline: Optional[EvalPipeline] = None, + kg_pipeline: Optional[KGEnrichmentPipeline] = None, *args, **kwargs, ) -> R2RPipelines: @@ -616,12 +602,12 @@ def create_pipelines( *args, **kwargs, ), - eval_pipeline=eval_pipeline - or self.create_eval_pipeline(*args, **kwargs), + kg_pipeline=kg_pipeline + or self.create_kg_pipeline(*args, **kwargs), ) def configure_logging(self): - KVLoggingSingleton.configure(self.config.logging) + RunLoggingSingleton.configure(self.config.logging) class R2RAgentFactory: diff --git a/r2r/main/assembly/factory_extensions.py b/r2r/main/assembly/factory_extensions.py index 56e82ef76..34aaa1b4f 100644 --- a/r2r/main/assembly/factory_extensions.py +++ b/r2r/main/assembly/factory_extensions.py @@ -1,7 +1,8 @@ -from r2r.main import R2RPipeFactory from r2r.pipes.retrieval.multi_search import MultiSearchPipe from r2r.pipes.retrieval.query_transform_pipe import QueryTransformPipe +from .factory import R2RPipeFactory + class R2RPipeFactoryWithMultiSearch(R2RPipeFactory): QUERY_GENERATION_TEMPLATE: dict = ( diff --git a/r2r/main/engine.py b/r2r/main/engine.py index 0eb457cd5..433c91ea0 100644 --- a/r2r/main/engine.py +++ b/r2r/main/engine.py @@ -1,33 +1,36 @@ -from typing import Optional +from typing import TYPE_CHECKING, Optional -from r2r.base import KVLoggingSingleton, RunManager +from r2r.base import RunLoggingSingleton, RunManager from r2r.base.abstractions.base import AsyncSyncMeta, syncable from .abstractions import R2RAgents, R2RPipelines, R2RProviders -from .assembly.config import R2RConfig from .services.auth_service import AuthService from .services.ingestion_service import IngestionService from .services.management_service import ManagementService +from .services.restructure_service import RestructureService from .services.retrieval_service import RetrievalService +if TYPE_CHECKING: + from .assembly.config import R2RConfig + class R2REngine(metaclass=AsyncSyncMeta): def __init__( self, - config: R2RConfig, + config: "R2RConfig", providers: R2RProviders, pipelines: R2RPipelines, agents: R2RAgents, run_manager: Optional[RunManager] = None, ): - logging_connection = KVLoggingSingleton() + logging_connection = RunLoggingSingleton() run_manager = run_manager or RunManager(logging_connection) self.config = config self.providers = providers self.pipelines = pipelines self.agents = agents - self.logging_connection = KVLoggingSingleton() + self.logging_connection = RunLoggingSingleton() self.run_manager = run_manager self.ingestion_service = IngestionService( @@ -38,6 +41,16 @@ def __init__( run_manager, logging_connection, ) + + self.kg_service = RestructureService( + config, + providers, + pipelines, + agents, + run_manager, + logging_connection, + ) + self.retrieval_service = RetrievalService( config, providers, @@ -80,6 +93,10 @@ async def aingest_files(self, *args, **kwargs): async def aupdate_files(self, *args, **kwargs): return await self.ingestion_service.update_files(*args, **kwargs) + @syncable + async def aenrich_graph(self, *args, **kwargs): + return await self.kg_service.enrich_graph(*args, **kwargs) + @syncable async def asearch(self, *args, **kwargs): return await self.retrieval_service.search(*args, **kwargs) @@ -189,3 +206,51 @@ async def aclean_expired_blacklisted_tokens(self, *args, **kwargs): return await self.auth_service.clean_expired_blacklisted_tokens( *args, **kwargs ) + + @syncable + async def acreate_group(self, *args, **kwargs): + return await self.management_service.acreate_group(*args, **kwargs) + + @syncable + async def aget_group(self, *args, **kwargs): + return await self.management_service.aget_group(*args, **kwargs) + + @syncable + async def aupdate_group(self, *args, **kwargs): + return await self.management_service.aupdate_group(*args, **kwargs) + + @syncable + async def adelete_group(self, *args, **kwargs): + return await self.management_service.adelete_group(*args, **kwargs) + + @syncable + async def alist_groups(self, *args, **kwargs): + return await self.management_service.alist_groups(*args, **kwargs) + + @syncable + async def aadd_user_to_group(self, *args, **kwargs): + return await self.management_service.aadd_user_to_group( + *args, **kwargs + ) + + @syncable + async def aremove_user_from_group(self, *args, **kwargs): + return await self.management_service.aremove_user_from_group( + *args, **kwargs + ) + + @syncable + async def aget_users_in_group(self, *args, **kwargs): + return await self.management_service.aget_users_in_group( + *args, **kwargs + ) + + @syncable + async def aget_groups_for_user(self, *args, **kwargs): + return await self.management_service.aget_groups_for_user( + *args, **kwargs + ) + + @syncable + async def agroups_overview(self, *args, **kwargs): + return await self.management_service.agroups_overview(*args, **kwargs) diff --git a/r2r/main/execution.py b/r2r/main/execution.py index e95e92819..9a0685c19 100644 --- a/r2r/main/execution.py +++ b/r2r/main/execution.py @@ -12,11 +12,12 @@ from r2r.base import ( AnalysisTypes, - FilterCriteria, + GenerationConfig, KGSearchSettings, + LogFilterCriteria, + VectorDBFilterValue, VectorSearchSettings, ) -from r2r.base.abstractions.llm import GenerationConfig from .api.client import R2RClient from .assembly.builder import R2RBuilder @@ -169,7 +170,9 @@ def spinner(): document_ids=document_ids, metadatas=metadatas, versions=versions, - )["results"] + ) + print("results = ", results) + results["results"] else: results = self.app.ingest_files( files=files, @@ -222,23 +225,31 @@ def search( self, query: str, use_vector_search: bool = True, - search_filters: Optional[dict] = None, + filters: Optional[dict[str, VectorDBFilterValue]] = None, search_limit: int = 10, do_hybrid_search: bool = False, use_kg_search: bool = False, kg_search_generation_config: Optional[dict] = None, + kg_search_type: str = "global", + kg_search_level: Optional[int] = None, + entity_types: list = [], + relationships: list = [], ): if self.client_mode: return self.client.search( query, VectorSearchSettings( use_vector_search=use_vector_search, - search_filters=search_filters or {}, + filters=filters or {}, search_limit=search_limit, do_hybrid_search=do_hybrid_search, ), KGSearchSettings( use_kg_search=use_kg_search, + kg_search_type=kg_search_type, + kg_search_level=kg_search_level, + entity_types=entity_types, + relationships=relationships, kg_search_generation_config=GenerationConfig( **(kg_search_generation_config or {}) ), @@ -249,7 +260,7 @@ def search( query, VectorSearchSettings( use_vector_search=use_vector_search, - search_filters=search_filters or {}, + filters=filters or {}, search_limit=search_limit, do_hybrid_search=do_hybrid_search, ), @@ -258,6 +269,10 @@ def search( kg_search_generation_config=GenerationConfig( **(kg_search_generation_config or {}) ), + kg_search_type=kg_search_type, + kg_search_level=kg_search_level, + entity_types=entity_types, + relationships=relationships, ), ) @@ -265,7 +280,7 @@ def rag( self, query: str, use_vector_search: bool = True, - search_filters: Optional[dict] = None, + filters: Optional[dict[str, VectorDBFilterValue]] = None, search_limit: int = 10, do_hybrid_search: bool = False, use_kg_search: bool = False, @@ -278,7 +293,7 @@ def rag( query, vector_search_settings=VectorSearchSettings( use_vector_search=use_vector_search, - search_filters=search_filters or {}, + filters=filters or {}, search_limit=search_limit, do_hybrid_search=do_hybrid_search, ), @@ -303,7 +318,7 @@ def rag( query, vector_search_settings=VectorSearchSettings( use_vector_search=use_vector_search, - search_filters=search_filters or {}, + filters=filters or {}, search_limit=search_limit, do_hybrid_search=do_hybrid_search, ), @@ -344,34 +359,36 @@ def sync_generator(): def documents_overview( self, document_ids: Optional[list[str]] = None, - user_ids: Optional[list[str]] = None, ): if self.client_mode: - return self.client.documents_overview(document_ids, user_ids)[ - "results" - ] + return self.client.documents_overview(document_ids)["results"] + else: + return self.app.documents_overview(document_ids) + + def enrich_graph(self): + if self.client_mode: + return self.client.enrich_graph() else: - return self.app.documents_overview(document_ids, user_ids) + return self.app.enrich_graph() def delete( self, - keys: list[str], - values: list[str], + filters: Optional[dict[str, VectorDBFilterValue]] = None, ): if self.client_mode: - return self.client.delete(keys, values)["results"] + return self.client.delete(filters)["results"] else: - return self.app.delete(keys, values) + return self.app.delete(filters) def logs( self, - log_type_filter: Optional[str] = None, + run_type_filter: Optional[str] = None, max_runs: int = 100, ): if self.client_mode: - return self.client.logs(log_type_filter, max_runs)["results"] + return self.client.logs(run_type_filter, max_runs)["results"] else: - return self.app.logs(log_type_filter, max_runs) + return self.app.logs(run_type_filter, max_runs) def document_chunks(self, document_id: str): doc_uuid = uuid.UUID(document_id) @@ -403,7 +420,7 @@ def analytics( analysis_types=analysis_types, )["results"] - filter_criteria = FilterCriteria(filters=filters) + filter_criteria = LogFilterCriteria(filters=filters) analysis_types_obj = AnalysisTypes(analysis_types=analysis_types) return self.app.analytics( filter_criteria=filter_criteria, analysis_types=analysis_types_obj diff --git a/r2r/main/services/__init__.py b/r2r/main/services/__init__.py index f1b33c38f..8fb32f0fb 100644 --- a/r2r/main/services/__init__.py +++ b/r2r/main/services/__init__.py @@ -1,6 +1,7 @@ from .auth_service import AuthService from .ingestion_service import IngestionService from .management_service import ManagementService +from .restructure_service import RestructureService from .retrieval_service import RetrievalService __all__ = [ @@ -8,4 +9,5 @@ "IngestionService", "ManagementService", "RetrievalService", + "RestructureService", ] diff --git a/r2r/main/services/auth_service.py b/r2r/main/services/auth_service.py index 8dbb8a47c..721be4b9a 100644 --- a/r2r/main/services/auth_service.py +++ b/r2r/main/services/auth_service.py @@ -1,15 +1,9 @@ import uuid from datetime import datetime -from typing import Any - -from r2r.base import ( - KVLoggingSingleton, - R2RException, - RunManager, - Token, - User, - UserCreate, -) +from typing import Optional + +from r2r.base import R2RException, RunLoggingSingleton, RunManager, Token +from r2r.base.api.models.auth.responses import UserResponse from r2r.telemetry.telemetry_decorator import telemetry_event from ..abstractions import R2RAgents, R2RPipelines, R2RProviders @@ -25,7 +19,7 @@ def __init__( pipelines: R2RPipelines, agents: R2RAgents, run_manager: RunManager, - logging_connection: KVLoggingSingleton, + logging_connection: RunLoggingSingleton, ): super().__init__( config, @@ -37,8 +31,8 @@ def __init__( ) @telemetry_event("RegisterUser") - async def register(self, user: UserCreate) -> User: - return self.providers.auth.register(user) + async def register(self, email: str, password: str) -> UserResponse: + return self.providers.auth.register(email, password) @telemetry_event("VerifyEmail") async def verify_email(self, verification_code: str) -> bool: @@ -60,14 +54,14 @@ async def verify_email(self, verification_code: str) -> bool: self.providers.database.relational.remove_verification_code( verification_code ) - return True + return {"message": f"User account {user_id} verified successfully."} @telemetry_event("Login") async def login(self, email: str, password: str) -> dict[str, Token]: return self.providers.auth.login(email, password) @telemetry_event("GetCurrentUser") - async def user(self, token: str) -> User: + async def user(self, token: str) -> UserResponse: token_data = self.providers.auth.decode_token(token) user = self.providers.database.relational.get_user_by_email( token_data.email @@ -88,7 +82,7 @@ async def refresh_access_token( @telemetry_event("ChangePassword") async def change_password( - self, user: User, current_password: str, new_password: str + self, user: UserResponse, current_password: str, new_password: str ) -> dict[str, str]: if not user: raise R2RException(status_code=404, message="User not found") @@ -113,7 +107,7 @@ async def logout(self, token: str) -> dict[str, str]: return self.providers.auth.logout(token) @telemetry_event("GetUserProfile") - async def get_user_profile(self, user_id: uuid.UUID) -> User: + async def get_user_profile(self, user_id: uuid.UUID) -> UserResponse: user = self.providers.database.relational.get_user_by_id(user_id) if not user: raise R2RException(status_code=404, message="User not found") @@ -121,28 +115,45 @@ async def get_user_profile(self, user_id: uuid.UUID) -> User: @telemetry_event("UpdateUserProfile") async def update_user( - self, user_id: uuid.UUID, user_data: dict[str, Any] - ) -> User: + self, + user_id: uuid.UUID, + email: Optional[str] = None, + name: Optional[str] = None, + bio: Optional[str] = None, + profile_picture: Optional[str] = None, + ) -> UserResponse: user = self.providers.database.relational.get_user_by_id(user_id) if not user: raise R2RException(status_code=404, message="User not found") - for key, value in user_data.items(): - setattr(user, key, value) + if email: + setattr(user, "email", email) + if name: + setattr(user, "name", name) + if bio: + setattr(user, "bio", bio) + if profile_picture: + setattr(user, "profile_picture", profile_picture) return self.providers.database.relational.update_user(user) @telemetry_event("DeleteUserAccount") async def delete_user( - self, user_id: uuid.UUID, password: str + self, + user_id: uuid.UUID, + password: Optional[str] = None, + is_superuser: bool = False, ) -> dict[str, str]: user = self.providers.database.relational.get_user_by_id(user_id) if not user: raise R2RException(status_code=404, message="User not found") - if not self.providers.auth.crypto_provider.verify_password( - password, user.hashed_password + if not ( + is_superuser + or self.providers.auth.crypto_provider.verify_password( + password, user.hashed_password + ) ): raise R2RException(status_code=400, message="Incorrect password") self.providers.database.relational.delete_user(user_id) - return {"message": "User account deleted successfully"} + return {"message": f"User account {user_id} deleted successfully."} @telemetry_event("CleanExpiredBlacklistedTokens") async def clean_expired_blacklisted_tokens( diff --git a/r2r/main/services/base.py b/r2r/main/services/base.py index 4cb74babd..7089f76b9 100644 --- a/r2r/main/services/base.py +++ b/r2r/main/services/base.py @@ -1,6 +1,6 @@ from abc import ABC -from r2r.base import KVLoggingSingleton, RunManager +from r2r.base import RunLoggingSingleton, RunManager from ..abstractions import R2RAgents, R2RPipelines, R2RProviders from ..assembly.config import R2RConfig @@ -14,7 +14,7 @@ def __init__( pipelines: R2RPipelines, agents: R2RAgents, run_manager: RunManager, - logging_connection: KVLoggingSingleton, + logging_connection: RunLoggingSingleton, ): self.config = config self.providers = providers diff --git a/r2r/main/services/ingestion_service.py b/r2r/main/services/ingestion_service.py index 511e74a9c..da58d8b5a 100644 --- a/r2r/main/services/ingestion_service.py +++ b/r2r/main/services/ingestion_service.py @@ -1,33 +1,28 @@ -import json import logging import uuid -import warnings from collections import defaultdict from datetime import datetime from typing import Any, Optional -from fastapi import Form, UploadFile +from fastapi import UploadFile from r2r.base import ( Document, DocumentInfo, DocumentType, - KVLoggingSingleton, R2RDocumentProcessingError, R2RException, + RunLoggingSingleton, RunManager, - User, generate_id_from_label, increment_version, to_async_generator, ) +from r2r.base.api.models import IngestionResponse from r2r.telemetry.telemetry_decorator import telemetry_event +from ...base.api.models.auth.responses import UserResponse from ..abstractions import R2RAgents, R2RPipelines, R2RProviders -from ..api.routes.ingestion.requests import ( - R2RIngestFilesRequest, - R2RUpdateFilesRequest, -) from ..assembly.config import R2RConfig from .base import Service @@ -43,7 +38,7 @@ def __init__( pipelines: R2RPipelines, agents: R2RAgents, run_manager: RunManager, - logging_connection: KVLoggingSingleton, + logging_connection: RunLoggingSingleton, ): super().__init__( config, @@ -55,7 +50,11 @@ def __init__( ) def _file_to_document( - self, file: UploadFile, document_id: uuid.UUID, metadata: dict + self, + file: UploadFile, + user: UserResponse, + document_id: uuid.UUID, + metadata: dict, ) -> Document: file_extension = file.filename.split(".")[-1].lower() if file_extension.upper() not in DocumentType.__members__: @@ -69,6 +68,8 @@ def _file_to_document( return Document( id=document_id, + group_ids=metadata.get("group_ids", []), + user_id=user.id, type=DocumentType[file_extension.upper()], data=file.file.read(), metadata=metadata, @@ -79,7 +80,6 @@ async def ingest_documents( self, documents: list[Document], versions: Optional[list[str]] = None, - user: Optional[User] = None, *args: Any, **kwargs: Any, ): @@ -88,16 +88,29 @@ async def ingest_documents( status_code=400, message="No documents provided for ingestion." ) + chunking_provider = kwargs.get("chunking_provider") + if chunking_provider is None: + logger.info("No chunking provider specified. Using default.") + else: + logger.info( + f"Using custom chunking provider: {type(chunking_provider).__name__}" + ) + document_infos = [] skipped_documents = [] processed_documents = {} duplicate_documents = defaultdict(list) - user_ids = [str(user.id)] if user else [] + + if not all(doc.id for doc in documents): + raise R2RException( + status_code=400, message="All documents must have an ID." + ) + user_id = documents[0].user_id existing_documents = ( ( self.providers.database.relational.get_documents_overview( - filter_user_ids=user_ids + filter_user_ids=[user_id] ) ) if self.providers.database @@ -105,22 +118,12 @@ async def ingest_documents( ) existing_document_info = { - doc_info.document_id: doc_info for doc_info in existing_documents + doc_info.id: doc_info for doc_info in existing_documents } for iteration, document in enumerate(documents): version = versions[iteration] if versions else "v0" - # Check if user ID has already been provided, and if it matches the authenticated user - user_id = document.metadata.get("user_id", None) - if user: - if user_id and user_id != str(user.id): - raise R2RException( - status_code=403, - message="User ID in metadata does not match authenticated user.", - ) - document.metadata["user_id"] = str(user.id) - # Check for duplicates within the current batch if document.id in processed_documents: duplicate_documents[document.id].append( @@ -142,29 +145,30 @@ async def ingest_documents( message=f"Document with ID {document.id} was already successfully processed.", ) skipped_documents.append( - ( - document.id, - document.metadata.get("title", None) - or str(document.id), - ) + { + "id": document.id, + "title": document.metadata.get("title", "N/A"), + } ) continue now = datetime.now() document_info_metadata = document.metadata.copy() - title = document_info_metadata.pop("title", str(document.id)) - user_id = document_info_metadata.pop("user_id", None) + title = document_info_metadata.pop("title", "N/A") + document_infos.append( DocumentInfo( - document_id=document.id, - version=version, - size_in_bytes=len(document.data), + id=document.id, + user_id=document.user_id, + group_ids=document.group_ids, + type=document.type, metadata=document_info_metadata, title=title, - user_id=user_id, + version=version, + size_in_bytes=len(document.data), + status="processing", created_at=now, updated_at=now, - status="processing", # Set initial status to `processing` ) ) @@ -199,34 +203,42 @@ async def ingest_documents( doc for doc in documents if doc.id - not in [skipped[0] for skipped in skipped_documents] + not in [skipped["id"] for skipped in skipped_documents] ], ), versions=[info.version for info in document_infos], run_manager=self.run_manager, - user=user, *args, **kwargs, ) + + # enrich using graphrag + # get triples from the graph + + # self.graph_rag = True + # if self.graph_rag: + + # graphrag_results = await self.pipelines.kg_cluster_pipeline.run( + # input = to_async_generator() + # ) + return await self._process_ingestion_results( ingestion_results, document_infos, skipped_documents, - processed_documents, - user=user, ) @telemetry_event("IngestFiles") async def ingest_files( self, files: list[UploadFile], + user: UserResponse, metadatas: Optional[list[dict]] = None, document_ids: Optional[list[uuid.UUID]] = None, versions: Optional[list[str]] = None, - user: Optional[User] = None, *args: Any, **kwargs: Any, - ): + ) -> IngestionResponse: if not files: raise R2RException( status_code=400, message="No files provided for ingestion." @@ -242,22 +254,27 @@ async def ingest_files( document_metadata = metadatas[iteration] if metadatas else {} - id_label = str(file.filename.split("/")[-1]) - # Make user-level ids unique - if user: - id_label += str(user.id) + id_label = f'{file.filename.split("/")[-1]}-{user.id}' + document_id = ( document_ids[iteration] if document_ids else generate_id_from_label(id_label) ) + print("user.id = ", user.id) + print("document_id = ", document_id) + document = self._file_to_document( - file, document_id, document_metadata + file, user, document_id, document_metadata ) documents.append(document) return await self.ingest_documents( - documents, versions, *args, **kwargs, user=user + documents, + versions, + user=user, + *args, + **kwargs, ) finally: @@ -269,11 +286,12 @@ async def update_files( self, files: list[UploadFile], document_ids: list[uuid.UUID], + user: UserResponse, metadatas: Optional[list[dict]] = None, - user: Optional[User] = None, *args: Any, **kwargs: Any, - ): + ) -> IngestionResponse: + print("UpdateFiles") if not files: raise R2RException( status_code=400, message="No files provided for update." @@ -283,7 +301,6 @@ async def update_files( status_code=501, message="Database provider is not available for updating documents.", ) - try: if len(document_ids) != len(files): raise R2RException( @@ -293,9 +310,7 @@ async def update_files( documents_overview = ( self.providers.database.relational.get_documents_overview( - filter_document_ids=[ - str(doc_id) for doc_id in document_ids - ] + filter_document_ids=document_ids ) ) @@ -317,15 +332,6 @@ async def update_files( message=f"Document with id {doc_id} not found.", ) - user_id = doc_info.metadata.get("user_id", None) - if user: - if user_id and user_id != str(user.id): - raise R2RException( - status_code=403, - message="User ID in metadata does not match authenticated user.", - ) - doc_info.metadata["user_id"] = str(user.id) - new_version = increment_version(doc_info.version) new_versions.append(new_version) @@ -338,25 +344,21 @@ async def update_files( ) document = self._file_to_document( - file, doc_id, updated_metadata + file, user, doc_id, updated_metadata ) documents.append(document) ingestion_results = await self.ingest_documents( - documents, versions=new_versions, user=user, *args, **kwargs + documents, versions=new_versions, *args, **kwargs ) for doc_id, old_version in zip( document_ids, [doc_info.version for doc_info in documents_overview], ): - keys = ["document_id", "version"] - values = [str(doc_id), old_version] - if user: - keys.append("user_id") - values.append(str(user.id)) - - self.providers.database.vector.delete_by_metadata(keys, values) + self.providers.database.vector.delete( + filters={"document_id": {"$eq": doc_id}} + ) self.providers.database.relational.delete_from_documents_overview( doc_id, old_version ) @@ -371,11 +373,9 @@ async def _process_ingestion_results( self, ingestion_results: dict, document_infos: list[DocumentInfo], - skipped_documents: list[tuple[str, str]], - processed_documents: dict, - user: Optional[User] = None, + skipped_documents: list[dict[str, str]], ): - skipped_ids = [ele[0] for ele in skipped_documents] + skipped_ids = [ele["id"] for ele in skipped_documents] failed_ids = [] successful_ids = [] @@ -396,10 +396,10 @@ async def _process_ingestion_results( documents_to_upsert = [] for document_info in document_infos: - if document_info.document_id not in skipped_ids: - if document_info.document_id in failed_ids: + if document_info.id not in skipped_ids: + if document_info.id in failed_ids: document_info.status = "failure" - elif document_info.document_id in successful_ids: + elif document_info.id in successful_ids: document_info.status = "success" documents_to_upsert.append(document_info) @@ -407,147 +407,19 @@ async def _process_ingestion_results( self.providers.database.relational.upsert_documents_overview( documents_to_upsert ) - + # TODO - modify ingestion service so that at end we write out number of vectors produced or the error message + # THEN, return updated document infos here results = { "processed_documents": [ - f"Document '{processed_documents[document_id]}' processed successfully." - for document_id in successful_ids + document + for document in document_infos + if document.id in successful_ids ], "failed_documents": [ - f"Document '{processed_documents[document_id]}': {results[document_id]}" + {"document_id": document_id, "result": results[document_id]} for document_id in failed_ids ], - "skipped_documents": [ - f"Document '{filename}' skipped since it already exists." - for _, filename in skipped_documents - ], + "skipped_documents": skipped_ids, } - # TODO - Clean up logging for document parse results - if run_ids := list(self.run_manager.run_info.keys()): - run_id = run_ids[0] - for key in results: - if key in ["processed_documents", "failed_documents"]: - for value in results[key]: - await self.logging_connection.log( - log_id=run_id, - key="document_parse_result", - value=value, - user_id=str(user.id) if user else None, - ) - - if not user: - # TODO: add in link to migration guide - warnings.warn( - "Logs excluding user ids are deprecated and will be removed in version 0.3.0. Please follow the migration guide here.", - DeprecationWarning, - stacklevel=2, - ) return results - - @staticmethod - def parse_ingest_files_form_data( - metadatas: Optional[str] = Form(None), - document_ids: str = Form(None), - versions: Optional[str] = Form(None), - chunking_config_override: Optional[str] = Form(None), - ) -> R2RIngestFilesRequest: - try: - parsed_metadatas = ( - json.loads(metadatas) - if metadatas and metadatas != "null" - else None - ) - if parsed_metadatas is not None and not isinstance( - parsed_metadatas, list - ): - raise ValueError("metadatas must be a list of dictionaries") - - parsed_document_ids = ( - json.loads(document_ids) - if document_ids and document_ids != "null" - else None - ) - if parsed_document_ids is not None: - parsed_document_ids = [ - uuid.UUID(doc_id) for doc_id in parsed_document_ids - ] - - parsed_versions = ( - json.loads(versions) - if versions and versions != "null" - else None - ) - chunking_config_override = ( - json.loads(chunking_config_override) - if chunking_config_override - and chunking_config_override != "null" - else None - ) - request_data = { - "metadatas": parsed_metadatas, - "document_ids": parsed_document_ids, - "versions": parsed_versions, - "chunking_config_override": chunking_config_override, - } - return R2RIngestFilesRequest(**request_data) - except json.JSONDecodeError as e: - raise R2RException( - status_code=400, message=f"Invalid JSON in form data: {e}" - ) - except ValueError as e: - raise R2RException(status_code=400, message=str(e)) - except Exception as e: - raise R2RException( - status_code=400, message=f"Error processing form data: {e}" - ) - - @staticmethod - def parse_update_files_form_data( - metadatas: Optional[str] = Form(None), - document_ids: str = Form(...), - chunking_config_override: Optional[str] = Form(None), - ) -> R2RUpdateFilesRequest: - try: - parsed_metadatas = ( - json.loads(metadatas) - if metadatas and metadatas != "null" - else None - ) - if parsed_metadatas is not None and not isinstance( - parsed_metadatas, list - ): - raise ValueError("metadatas must be a list of dictionaries") - - if not document_ids or document_ids == "null": - raise ValueError("document_ids is required and cannot be null") - - parsed_document_ids = json.loads(document_ids) - if not isinstance(parsed_document_ids, list): - raise ValueError("document_ids must be a list") - parsed_document_ids = [ - uuid.UUID(doc_id) for doc_id in parsed_document_ids - ] - chunking_config_override = ( - json.loads(chunking_config_override) - if chunking_config_override - and chunking_config_override != "null" - else None - ) - - request_data = { - "metadatas": parsed_metadatas, - "document_ids": parsed_document_ids, - "chunking_config_override": chunking_config_override, - } - return R2RUpdateFilesRequest(**request_data) - except json.JSONDecodeError as e: - raise R2RException( - status_code=400, message=f"Invalid JSON in form data: {e}" - ) - except ValueError as e: - raise R2RException(status_code=400, message=str(e)) - except Exception as e: - raise R2RException( - status_code=400, message=f"Error processing form data: {e}" - ) diff --git a/r2r/main/services/management_service.py b/r2r/main/services/management_service.py index 57d8a2b71..4ff8f4101 100644 --- a/r2r/main/services/management_service.py +++ b/r2r/main/services/management_service.py @@ -2,15 +2,16 @@ import logging import uuid from collections import defaultdict -from typing import Any, Dict, List, Optional, Tuple, Union +from typing import Any, Dict, List, Optional, Tuple from r2r.base import ( AnalysisTypes, - FilterCriteria, - KVLoggingSingleton, + LogFilterCriteria, LogProcessor, R2RException, + RunLoggingSingleton, RunManager, + VectorDBFilterValue, ) from r2r.telemetry.telemetry_decorator import telemetry_event @@ -29,7 +30,7 @@ def __init__( pipelines: R2RPipelines, agents: R2RAgents, run_manager: RunManager, - logging_connection: KVLoggingSingleton, + logging_connection: RunLoggingSingleton, ): super().__init__( config, @@ -54,20 +55,16 @@ async def update_prompt( @telemetry_event("Logs") async def alogs( - self, - log_type_filter: Optional[str] = None, - max_runs_requested: int = 100, - *args: Any, - **kwargs: Any, + self, run_type_filter: Optional[str] = None, max_runs: int = 100 ): if self.logging_connection is None: raise R2RException( status_code=404, message="Logging provider not found." ) - run_info = await self.logging_connection.get_run_info( - limit=max_runs_requested, - log_type_filter=log_type_filter, + run_info = await self.logging_connection.get_info_logs( + limit=max_runs, + run_type_filter=run_type_filter, ) run_ids = [run.run_id for run in run_info] if len(run_ids) == 0: @@ -79,7 +76,7 @@ async def alogs( for run in run_info: run_logs = [ - log for log in logs if log["log_id"] == str(run.run_id) + log for log in logs if log["run_id"] == str(run.run_id) ] entries = [ { @@ -94,7 +91,7 @@ async def alogs( log_entry = { "run_id": run.run_id, - "run_type": run.log_type, + "run_type": run.run_type, "entries": entries, } @@ -117,12 +114,12 @@ async def alogs( @telemetry_event("Analytics") async def aanalytics( self, - filter_criteria: FilterCriteria, + filter_criteria: LogFilterCriteria, analysis_types: AnalysisTypes, *args, **kwargs, ): - run_info = await self.logging_connection.get_run_info(limit=100) + run_info = await self.logging_connection.get_info_logs(limit=100) run_ids = [info.run_id for info in run_info] if not run_ids: @@ -211,8 +208,8 @@ async def ascore_completion( self, message_id: uuid.UUID, score: float = 0.0, - log_type_filter: str = None, - max_runs_requested: int = 100, + run_type_filter: str = None, + max_runs: int = 100, *args: Any, **kwargs: Any, ): @@ -222,9 +219,9 @@ async def ascore_completion( status_code=404, message="Logging provider not found." ) - run_info = await self.logging_connection.get_run_info( - limit=max_runs_requested, - log_type_filter=log_type_filter, + run_info = await self.logging_connection.get_info_logs( + limit=max_runs, + run_type_filter=run_type_filter, ) run_ids = [run.run_id for run in run_info] @@ -242,8 +239,8 @@ async def ascore_completion( if completion_dict.get("message_id") == str(message_id): bounded_score = round(min(max(score, -1.00), 1.00), 2) - updated = await KVLoggingSingleton.score_completion( - log["log_id"], message_id, bounded_score + updated = await RunLoggingSingleton.score_completion( + log["run_id"], message_id, bounded_score ) if not updated: logger.error( @@ -269,42 +266,53 @@ async def ausers_overview( @telemetry_event("Delete") async def delete( self, - keys: list[str], - values: list[Union[bool, int, str]], + filters: dict[str, VectorDBFilterValue], *args, **kwargs, ): - metadata = ", ".join( - f"{key}={value}" for key, value in zip(keys, values) - ) - values = [str(value) for value in values] - logger.info(f"Deleting entries with metadata: {metadata}") - ids = self.providers.database.vector.delete_by_metadata(keys, values) - if not ids: + """ + Takes a list of filters like + "{key: {operator: value}, key: {operator: value}, ...}" + and deletes entries that match the filters. + + Then, deletes the corresponding entries from the documents overview table. + + NOTE: This method is not atomic and may result in orphaned entries in the documents overview table. + NOTE: This method assumes that filters delete entire contents of any touched documents. + """ + logger.info(f"Deleting entries with filters: {filters}") + results = self.providers.database.vector.delete(filters) + if not results: raise R2RException( status_code=404, message="No entries found for deletion." ) - for id in ids: + + document_ids_to_purge = { + doc_id + for doc_id in [ + result.get("document_id", None) for result in results.values() + ] + if doc_id + } + for document_id in document_ids_to_purge: self.providers.database.relational.delete_from_documents_overview( - id + document_id ) - return f"Documents {ids} deleted successfully." + return results @telemetry_event("DocumentsOverview") async def adocuments_overview( self, - document_ids: Optional[list[uuid.UUID]] = None, user_ids: Optional[list[uuid.UUID]] = None, + group_ids: Optional[list[uuid.UUID]] = None, + document_ids: Optional[list[uuid.UUID]] = None, *args: Any, **kwargs: Any, ): return self.providers.database.relational.get_documents_overview( - filter_document_ids=( - [str(ele) for ele in document_ids] if document_ids else None - ), - filter_user_ids=( - [str(ele) for ele in user_ids] if user_ids else None - ), + filter_document_ids=document_ids, + filter_user_ids=user_ids, + filter_group_ids=group_ids, ) @telemetry_event("DocumentChunks") @@ -314,9 +322,7 @@ async def document_chunks( *args, **kwargs, ): - return self.providers.database.vector.get_document_chunks( - str(document_id) - ) + return self.providers.database.vector.get_document_chunks(document_id) @telemetry_event("UsersOverview") async def users_overview( @@ -371,6 +377,43 @@ async def inspect_knowledge_graph( message=f"An error occurred while fetching relationships: {str(e)}", ) + @telemetry_event("AssignDocumentToGroup") + async def aassign_document_to_group( + self, document_id: str, group_id: uuid.UUID + ): + + success = self.providers.database.vector.assign_document_to_group( + document_id, group_id + ) + if success: + return {"message": "Document assigned to group successfully"} + else: + raise R2RException( + status_code=404, + message="Document not found or assignment failed", + ) + + @telemetry_event("RemoveDocumentFromGroup") + async def aremove_document_from_group( + self, document_id: str, group_id: uuid.UUID + ): + success = self.providers.database.vector.remove_document_from_group( + document_id, group_id + ) + if success: + return {"message": "Document removed from group successfully"} + else: + raise R2RException( + status_code=404, message="Document not found or removal failed" + ) + + @telemetry_event("GetDocumentGroups") + async def aget_document_groups(self, document_id: str): + group_ids = self.providers.database.vector.get_document_groups( + document_id + ) + return {"group_ids": [str(group_id) for group_id in group_ids]} + def process_relationships( self, relationships: List[Tuple[str, str, str]] ) -> Tuple[Dict[str, List[str]], Dict[str, Dict[str, List[str]]]]: @@ -456,3 +499,74 @@ async def app_settings( name: prompt.dict() for name, prompt in prompts.items() }, } + + @telemetry_event("CreateGroup") + async def acreate_group( + self, name: str, description: str = "" + ) -> uuid.UUID: + return self.providers.database.relational.create_group( + name, description + ) + + @telemetry_event("GetGroup") + async def aget_group(self, group_id: uuid.UUID) -> Optional[dict]: + return self.providers.database.relational.get_group(group_id) + + @telemetry_event("UpdateGroup") + async def aupdate_group( + self, group_id: uuid.UUID, name: str = None, description: str = None + ) -> bool: + return self.providers.database.relational.update_group( + group_id, name, description + ) + + @telemetry_event("DeleteGroup") + async def adelete_group(self, group_id: uuid.UUID) -> bool: + return self.providers.database.relational.delete_group(group_id) + + @telemetry_event("ListGroups") + async def alist_groups( + self, offset: int = 0, limit: int = 100 + ) -> list[dict]: + return self.providers.database.relational.list_groups( + offset=offset, limit=limit + ) + + @telemetry_event("AddUserToGroup") + async def aadd_user_to_group( + self, user_id: uuid.UUID, group_id: uuid.UUID + ) -> bool: + return self.providers.database.relational.add_user_to_group( + user_id, group_id + ) + + @telemetry_event("RemoveUserFromGroup") + async def aremove_user_from_group( + self, user_id: uuid.UUID, group_id: uuid.UUID + ) -> bool: + return self.providers.database.relational.remove_user_from_group( + user_id, group_id + ) + + @telemetry_event("GetUsersInGroup") + async def aget_users_in_group( + self, group_id: uuid.UUID, offset: int = 0, limit: int = 100 + ) -> list[dict]: + return self.providers.database.relational.get_users_in_group( + group_id, offset, limit + ) + + @telemetry_event("GetGroupsForUser") + async def aget_groups_for_user(self, user_id: uuid.UUID) -> list[dict]: + return self.providers.database.relational.get_groups_for_user(user_id) + + @telemetry_event("GroupsOverview") + async def agroups_overview( + self, + group_ids: Optional[list[uuid.UUID]] = None, + *args, + **kwargs, + ): + return self.providers.database.relational.get_groups_overview( + [str(ele) for ele in group_ids] if group_ids else None + ) diff --git a/r2r/main/services/restructure_service.py b/r2r/main/services/restructure_service.py new file mode 100644 index 000000000..1162ab222 --- /dev/null +++ b/r2r/main/services/restructure_service.py @@ -0,0 +1,94 @@ +import logging +from typing import Any, Dict, List + +from r2r.base import Document, R2RException, RunLoggingSingleton, RunManager + +from ..abstractions import R2RAgents, R2RPipelines, R2RProviders +from ..assembly.config import R2RConfig +from .base import Service + +logger = logging.getLogger(__name__) + + +class RestructureService(Service): + def __init__( + self, + config: R2RConfig, + providers: R2RProviders, + pipelines: R2RPipelines, + agents: R2RAgents, + run_manager: RunManager, + logging_connection: RunLoggingSingleton, + ): + + super().__init__( + config, + providers, + pipelines, + agents, + run_manager, + logging_connection, + ) + + async def enrich_graph( + self, documents: List[Document] = None + ) -> Dict[str, Any]: + """ + Perform graph enrichment on the given documents. + + Args: + documents (List[Document]): List of documents to enrich. + + Returns: + Dict[str, Any]: Results of the graph enrichment process. + """ + try: + # Assuming there's a graph enrichment pipeline + enrichment_results = await self.pipelines.kg_pipeline.run( + input=[], + run_manager=self.run_manager, + ) + + return enrichment_results + + except Exception as e: + logger.error(f"Error during graph enrichment: {str(e)}") + raise R2RException( + status_code=500, message=f"Graph enrichment failed: {str(e)}" + ) + + async def query_graph(self, query: str) -> Dict[str, Any]: + """ + Query the knowledge graph. + + Args: + query (str): The query to run against the knowledge graph. + + Returns: + Dict[str, Any]: Results of the graph query. + """ + try: + results = self.providers.database.graph.query(query) + return {"results": results} + except Exception as e: + logger.error(f"Error querying graph: {str(e)}") + raise R2RException( + status_code=500, message=f"Graph query failed: {str(e)}" + ) + + async def get_graph_statistics(self) -> Dict[str, Any]: + """ + Get statistics about the knowledge graph. + + Returns: + Dict[str, Any]: Statistics about the knowledge graph. + """ + try: + stats = self.providers.database.graph.get_statistics() + return stats + except Exception as e: + logger.error(f"Error getting graph statistics: {str(e)}") + raise R2RException( + status_code=500, + message=f"Failed to retrieve graph statistics: {str(e)}", + ) diff --git a/r2r/main/services/retrieval_service.py b/r2r/main/services/retrieval_service.py index 84d80996d..ca75d9c27 100644 --- a/r2r/main/services/retrieval_service.py +++ b/r2r/main/services/retrieval_service.py @@ -8,18 +8,18 @@ CompletionRecord, GenerationConfig, KGSearchSettings, - KVLoggingSingleton, Message, MessageType, R2RException, + RunLoggingSingleton, RunManager, - User, VectorSearchSettings, generate_id_from_label, manage_run, to_async_generator, ) -from r2r.pipes import EvalPipe +from r2r.base.api.models import RAGResponse, SearchResponse +from r2r.base.api.models.auth.responses import UserResponse from r2r.telemetry.telemetry_decorator import telemetry_event from ..abstractions import R2RAgents, R2RPipelines, R2RProviders @@ -37,7 +37,7 @@ def __init__( pipelines: R2RPipelines, agents: R2RAgents, run_manager: RunManager, - logging_connection: KVLoggingSingleton, + logging_connection: RunLoggingSingleton, ): super().__init__( config, @@ -54,10 +54,10 @@ async def search( query: str, vector_search_settings: VectorSearchSettings = VectorSearchSettings(), kg_search_settings: KGSearchSettings = KGSearchSettings(), - user: Optional[User] = None, + user: Optional[UserResponse] = None, *args, **kwargs, - ): + ) -> SearchResponse: async with manage_run(self.run_manager, "search_app") as run_id: t0 = time.time() @@ -80,18 +80,15 @@ async def search( ) # TODO - Remove these transforms once we have a better way to handle this - for filter, value in vector_search_settings.search_filters.items(): + for filter, value in vector_search_settings.filters.items(): if isinstance(value, uuid.UUID): - vector_search_settings.search_filters[filter] = str(value) - if user and not user.is_superuser: - vector_search_settings.search_filters["user_id"] = str(user.id) + vector_search_settings.filters[filter] = str(value) results = await self.pipelines.search_pipeline.run( input=to_async_generator([query]), vector_search_settings=vector_search_settings, kg_search_settings=kg_search_settings, run_manager=self.run_manager, - user=user, *args, **kwargs, ) @@ -100,10 +97,9 @@ async def search( latency = f"{t1 - t0:.2f}" await self.logging_connection.log( - log_id=run_id, + run_id=run_id, key="search_latency", value=latency, - is_info_log=False, ) return results.dict() @@ -115,26 +111,19 @@ async def rag( rag_generation_config: GenerationConfig, vector_search_settings: VectorSearchSettings = VectorSearchSettings(), kg_search_settings: KGSearchSettings = KGSearchSettings(), - user: Optional[User] = None, + user: Optional[UserResponse] = None, *args, **kwargs, - ): + ) -> RAGResponse: async with manage_run(self.run_manager, "rag_app") as run_id: try: # TODO - Remove these transforms once we have a better way to handle this for ( filter, value, - ) in vector_search_settings.search_filters.items(): + ) in vector_search_settings.filters.items(): if isinstance(value, uuid.UUID): - vector_search_settings.search_filters[filter] = str( - value - ) - - if user and not user.is_superuser: - vector_search_settings.search_filters["user_id"] = str( - user.id - ) + vector_search_settings.filters[filter] = str(value) completion_start_time = datetime.now() message_id = generate_id_from_label( @@ -161,13 +150,6 @@ async def rag( **kwargs, ) - await self.logging_connection.log( - log_id=run_id, - key="run_type", - value="rag", - is_info_log=True, - ) - results = await self.pipelines.rag_pipeline.run( input=to_async_generator([query]), run_manager=self.run_manager, @@ -200,10 +182,9 @@ async def rag( completion_record.completion_end_time = datetime.now() await self.logging_connection.log( - log_id=run_id, + run_id=run_id, key="completion_record", value=completion_record.to_json(), - is_info_log=False, ) # unpack the first result @@ -243,7 +224,6 @@ async def stream_response(): kg_search_settings=kg_search_settings, rag_generation_config=rag_generation_config, completion_record=completion_record, - user=user, *args, **kwargs, ): @@ -258,7 +238,7 @@ async def agent( rag_generation_config: GenerationConfig, vector_search_settings: VectorSearchSettings = VectorSearchSettings(), kg_search_settings: KGSearchSettings = KGSearchSettings(), - user: Optional[User] = None, + user: Optional[UserResponse] = None, task_prompt_override: Optional[str] = None, include_title_if_available: Optional[bool] = False, *args, @@ -272,26 +252,18 @@ async def agent( for ( filter, value, - ) in vector_search_settings.search_filters.items(): + ) in vector_search_settings.filters.items(): if isinstance(value, uuid.UUID): - vector_search_settings.search_filters[filter] = str( - value - ) - - if user and not user.is_superuser: - vector_search_settings.search_filters["user_id"] = str( - user.id - ) + vector_search_settings.filters[filter] = str(value) if rag_generation_config.stream: t1 = time.time() latency = f"{t1 - t0:.2f}" await self.logging_connection.log( - log_id=run_id, + run_id=run_id, key="rag_agent_generation_latency", value=latency, - is_info_log=False, ) async def stream_response(): @@ -305,7 +277,6 @@ async def stream_response(): kg_search_settings=kg_search_settings, rag_generation_config=rag_generation_config, include_title_if_available=include_title_if_available, - user=user, *args, **kwargs, ): @@ -320,7 +291,6 @@ async def stream_response(): kg_search_settings=kg_search_settings, rag_generation_config=rag_generation_config, include_title_if_available=include_title_if_available, - user=user, *args, **kwargs, ) @@ -328,10 +298,9 @@ async def stream_response(): latency = f"{t1 - t0:.2f}" await self.logging_connection.log( - log_id=run_id, + run_id=run_id, key="rag_agent_generation_latency", value=latency, - is_info_log=False, ) return results @@ -345,27 +314,3 @@ async def stream_response(): raise R2RException( status_code=500, message="Internal Server Error" ) - - @telemetry_event("Evaluate") - async def evaluate( - self, - query: str, - context: str, - completion: str, - eval_generation_config: Optional[GenerationConfig], - user: Optional[User] = None, - *args, - **kwargs, - ): - eval_payload = EvalPipe.EvalPayload( - query=query, - context=context, - completion=completion, - ) - return await self.eval_pipeline.run( - input=to_async_generator([eval_payload]), - run_manager=self.run_manager, - eval_generation_config=eval_generation_config, - *args, - **kwargs, - ) diff --git a/r2r/parsers/__init__.py b/r2r/parsers/__init__.py index 102a0110c..228f7085f 100644 --- a/r2r/parsers/__init__.py +++ b/r2r/parsers/__init__.py @@ -1,17 +1,9 @@ -from .media.audio_parser import AudioParser -from .media.docx_parser import DOCXParser -from .media.img_parser import ImageParser -from .media.movie_parser import MovieParser -from .media.pdf_parser import PDFParser, PDFParserMarker, PDFParserUnstructured -from .media.ppt_parser import PPTParser -from .structured.csv_parser import CSVParser, CSVParserAdvanced -from .structured.json_parser import JSONParser -from .structured.xlsx_parser import XLSXParser, XLSXParserAdvanced -from .text.html_parser import HTMLParser -from .text.md_parser import MDParser -from .text.text_parser import TextParser +from .media import * +from .structured import * +from .text import * __all__ = [ + # Media parsers "AudioParser", "DOCXParser", "ImageParser", @@ -20,12 +12,14 @@ "PDFParserUnstructured", "PDFParserMarker", "PPTParser", - "MDParser", - "HTMLParser", - "TextParser", + # Structured parsers "CSVParser", "CSVParserAdvanced", "JSONParser", "XLSXParser", "XLSXParserAdvanced", + # Text parsers + "MDParser", + "HTMLParser", + "TextParser", ] diff --git a/r2r/parsers/media/__init__.py b/r2r/parsers/media/__init__.py index e69de29bb..81a227459 100644 --- a/r2r/parsers/media/__init__.py +++ b/r2r/parsers/media/__init__.py @@ -0,0 +1,17 @@ +from .audio_parser import AudioParser +from .docx_parser import DOCXParser +from .img_parser import ImageParser +from .movie_parser import MovieParser +from .pdf_parser import PDFParser, PDFParserMarker, PDFParserUnstructured +from .ppt_parser import PPTParser + +__all__ = [ + "AudioParser", + "DOCXParser", + "ImageParser", + "MovieParser", + "PDFParser", + "PDFParserUnstructured", + "PDFParserMarker", + "PPTParser", +] diff --git a/r2r/parsers/media/openai_helpers.py b/r2r/parsers/media/openai_helpers.py index 707dadda0..583a685e9 100644 --- a/r2r/parsers/media/openai_helpers.py +++ b/r2r/parsers/media/openai_helpers.py @@ -55,4 +55,4 @@ def process_audio_with_openai( ) transcription = transcription_response.json() - return transcription["text"] + return transcription.text diff --git a/r2r/parsers/media/pdf_parser.py b/r2r/parsers/media/pdf_parser.py index 438019c5b..f50ac94fc 100644 --- a/r2r/parsers/media/pdf_parser.py +++ b/r2r/parsers/media/pdf_parser.py @@ -1,4 +1,5 @@ import asyncio +import logging import string import unicodedata from io import BytesIO @@ -7,6 +8,8 @@ from r2r.base.abstractions.document import DataType from r2r.base.parsers.base_parser import AsyncParser +logger = logging.getLogger(__name__) + class PDFParser(AsyncParser[DataType]): """A parser for PDF data.""" @@ -49,9 +52,7 @@ async def ingest(self, data: DataType) -> AsyncGenerator[str, None]: or "\u0E00" <= x <= "\u0E7F" # Thai or "\u3040" <= x <= "\u309F" # Japanese Hiragana or "\u30A0" <= x <= "\u30FF" # Katakana - or - # Other printable characters - x in string.printable + or x in string.printable ), page_text, ) @@ -113,8 +114,8 @@ def __init__(self): self.partition_pdf = partition_pdf except ImportError as e: - print("PDFParserUnstructured ImportError : ", e) - print( + logger.error("PDFParserUnstructured ImportError : ", e) + logger.error( """Please install missing modules using : pip install unstructured unstructured_pytesseract unstructured_inference pip install pdfplumber matplotlib pillow_heif toml diff --git a/r2r/parsers/structured/__init__.py b/r2r/parsers/structured/__init__.py index e69de29bb..a44b30662 100644 --- a/r2r/parsers/structured/__init__.py +++ b/r2r/parsers/structured/__init__.py @@ -0,0 +1,11 @@ +from .csv_parser import CSVParser, CSVParserAdvanced +from .json_parser import JSONParser +from .xlsx_parser import XLSXParser, XLSXParserAdvanced + +__all__ = [ + "CSVParser", + "CSVParserAdvanced", + "JSONParser", + "XLSXParser", + "XLSXParserAdvanced", +] diff --git a/r2r/parsers/structured/xlsx_parser.py b/r2r/parsers/structured/xlsx_parser.py index e4c4d659b..abd917541 100644 --- a/r2r/parsers/structured/xlsx_parser.py +++ b/r2r/parsers/structured/xlsx_parser.py @@ -50,7 +50,7 @@ def __init__(self): def connected_components(self, arr): g = self.nx.grid_2d_graph(len(arr), len(arr[0])) - empty_cell_indices = list(zip(*self.np.where(arr == None))) + empty_cell_indices = list(zip(*self.np.where(arr is None))) g.remove_nodes_from(empty_cell_indices) components = self.nx.connected_components(g) for component in components: @@ -80,7 +80,7 @@ async def ingest( if len(table) <= 1: continue - num_cols, num_rows = len(table[0]), len(table) + num_rows = len(table) num_rows_per_chunk = num_col_times_num_rows // num_rows headers = ", ".join(table[0]) # add header to each one diff --git a/r2r/parsers/text/__init__.py b/r2r/parsers/text/__init__.py index e69de29bb..0d88dcb31 100644 --- a/r2r/parsers/text/__init__.py +++ b/r2r/parsers/text/__init__.py @@ -0,0 +1,9 @@ +from .html_parser import HTMLParser +from .md_parser import MDParser +from .text_parser import TextParser + +__all__ = [ + "MDParser", + "HTMLParser", + "TextParser", +] diff --git a/r2r/pipelines/__init__.py b/r2r/pipelines/__init__.py index ebe3a0c39..6bd7cc5ab 100644 --- a/r2r/pipelines/__init__.py +++ b/r2r/pipelines/__init__.py @@ -1,4 +1,4 @@ -from .eval_pipeline import EvalPipeline +from .graph_enrichment import KGEnrichmentPipeline from .ingestion_pipeline import IngestionPipeline from .rag_pipeline import RAGPipeline from .search_pipeline import SearchPipeline @@ -7,5 +7,5 @@ "IngestionPipeline", "SearchPipeline", "RAGPipeline", - "EvalPipeline", + "KGEnrichmentPipeline", ] diff --git a/r2r/pipelines/eval_pipeline.py b/r2r/pipelines/eval_pipeline.py deleted file mode 100644 index 60aa50d49..000000000 --- a/r2r/pipelines/eval_pipeline.py +++ /dev/null @@ -1,37 +0,0 @@ -import logging -from typing import Any, Optional - -from r2r.base.logging.run_manager import RunManager -from r2r.base.pipeline.base_pipeline import AsyncPipeline -from r2r.base.pipes.base_pipe import AsyncPipe, AsyncState - -logger = logging.getLogger(__name__) - - -class EvalPipeline(AsyncPipeline): - """A pipeline for evaluation.""" - - pipeline_type: str = "eval" - - async def run( - self, - input: Any, - state: Optional[AsyncState] = None, - stream: bool = False, - run_manager: Optional[RunManager] = None, - *args: Any, - **kwargs: Any, - ): - return await super().run( - input, state, stream, run_manager, *args, **kwargs - ) - - def add_pipe( - self, - pipe: AsyncPipe, - add_upstream_outputs: Optional[list[dict[str, str]]] = None, - *args, - **kwargs, - ) -> None: - logger.debug(f"Adding pipe {pipe.config.name} to the EvalPipeline") - return super().add_pipe(pipe, add_upstream_outputs, *args, **kwargs) diff --git a/r2r/pipelines/graph_enrichment.py b/r2r/pipelines/graph_enrichment.py new file mode 100644 index 000000000..49d98dd78 --- /dev/null +++ b/r2r/pipelines/graph_enrichment.py @@ -0,0 +1,33 @@ +import logging +from typing import Optional + +from ..base.logging.run_logger import RunLoggingSingleton +from ..base.logging.run_manager import RunManager +from ..base.pipeline.base_pipeline import AsyncPipeline +from ..base.pipes.base_pipe import AsyncPipe + +logger = logging.getLogger(__name__) + + +class KGEnrichmentPipeline(AsyncPipeline): + """A pipeline for enhancing the graph with communities, connnected components etc.""" + + pipeline_type: str = "other" + + def __init__( + self, + pipe_logger: Optional[RunLoggingSingleton] = None, + run_manager: Optional[RunManager] = None, + ): + super().__init__(pipe_logger, run_manager) + + def add_pipe( + self, + pipe: AsyncPipe, + *args, + **kwargs, + ) -> None: + logger.debug( + f"Adding pipe {pipe.config.name} to the KGEnrichmentPipeline" + ) + super().add_pipe(pipe, *args, **kwargs) diff --git a/r2r/pipelines/ingestion_pipeline.py b/r2r/pipelines/ingestion_pipeline.py index 1b9f3eb25..5a1fe42e7 100644 --- a/r2r/pipelines/ingestion_pipeline.py +++ b/r2r/pipelines/ingestion_pipeline.py @@ -3,8 +3,8 @@ from asyncio import Queue from typing import Any, Optional -from r2r.base import User -from r2r.base.logging.kv_logger import KVLoggingSingleton +from r2r.base.api.models.auth.responses import UserResponse +from r2r.base.logging.run_logger import RunLoggingSingleton from r2r.base.logging.run_manager import RunManager, manage_run from r2r.base.pipeline.base_pipeline import AsyncPipeline, dequeue_requests from r2r.base.pipes.base_pipe import AsyncPipe, AsyncState @@ -16,11 +16,9 @@ class IngestionPipeline(AsyncPipeline): """A pipeline for ingestion.""" - pipeline_type: str = "ingestion" - def __init__( self, - pipe_logger: Optional[KVLoggingSingleton] = None, + pipe_logger: Optional[RunLoggingSingleton] = None, run_manager: Optional[RunManager] = None, ): super().__init__(pipe_logger, run_manager) @@ -34,21 +32,13 @@ async def run( state: Optional[AsyncState] = None, stream: bool = False, run_manager: Optional[RunManager] = None, - log_run_info: bool = True, chunking_config_override: Optional[ChunkingProvider] = None, - user: Optional[User] = None, + user: Optional[UserResponse] = None, *args: Any, **kwargs: Any, ) -> None: self.state = state or AsyncState() - async with manage_run(run_manager, self.pipeline_type): - if log_run_info: - await run_manager.log_run_info( - key="pipeline_type", - value=self.pipeline_type, - is_info_log=True, - user=user, - ) + async with manage_run(run_manager): if self.parsing_pipe is None: raise ValueError( "parsing_pipe must be set before running the ingestion pipeline" @@ -107,7 +97,6 @@ async def process_documents(): state, stream, run_manager, - log_run_info=False, *args, **kwargs, ) @@ -121,7 +110,6 @@ async def process_documents(): state, stream, run_manager, - log_run_info=False, *args, **kwargs, ) diff --git a/r2r/pipelines/rag_pipeline.py b/r2r/pipelines/rag_pipeline.py index ff054910f..c67c7da2a 100644 --- a/r2r/pipelines/rag_pipeline.py +++ b/r2r/pipelines/rag_pipeline.py @@ -2,10 +2,10 @@ import logging from typing import Any, Optional -from ..base import User from ..base.abstractions.llm import GenerationConfig from ..base.abstractions.search import KGSearchSettings, VectorSearchSettings -from ..base.logging.kv_logger import KVLoggingSingleton +from ..base.api.models.auth.responses import UserResponse +from ..base.logging.run_logger import RunLoggingSingleton from ..base.logging.run_manager import RunManager, manage_run from ..base.pipeline.base_pipeline import AsyncPipeline from ..base.pipes.base_pipe import AsyncPipe, AsyncState @@ -17,11 +17,9 @@ class RAGPipeline(AsyncPipeline): """A pipeline for RAG.""" - pipeline_type: str = "rag" - def __init__( self, - pipe_logger: Optional[KVLoggingSingleton] = None, + pipe_logger: Optional[RunLoggingSingleton] = None, run_manager: Optional[RunManager] = None, ): super().__init__(pipe_logger, run_manager) @@ -33,24 +31,15 @@ async def run( input: Any, state: Optional[AsyncState] = None, run_manager: Optional[RunManager] = None, - log_run_info=True, vector_search_settings: VectorSearchSettings = VectorSearchSettings(), kg_search_settings: KGSearchSettings = KGSearchSettings(), rag_generation_config: GenerationConfig = GenerationConfig(), - user: Optional[User] = None, + user: Optional[UserResponse] = None, *args: Any, **kwargs: Any, ): self.state = state or AsyncState() - async with manage_run(run_manager, self.pipeline_type): - if log_run_info: - await run_manager.log_run_info( - key="pipeline_type", - value=self.pipeline_type, - is_info_log=True, - user=user, - ) - + async with manage_run(run_manager): if not self._search_pipeline: raise ValueError( "`_search_pipeline` must be set before running the RAG pipeline" @@ -65,7 +54,6 @@ async def multi_query_generator(input): state=state, stream=False, run_manager=run_manager, - log_run_info=False, vector_search_settings=vector_search_settings, kg_search_settings=kg_search_settings, *args, @@ -82,7 +70,6 @@ async def multi_query_generator(input): state=state, stream=rag_generation_config.stream, run_manager=run_manager, - log_run_info=False, rag_generation_config=rag_generation_config, *args, **kwargs, diff --git a/r2r/pipelines/search_pipeline.py b/r2r/pipelines/search_pipeline.py index 62eccf921..9bccbbc8d 100644 --- a/r2r/pipelines/search_pipeline.py +++ b/r2r/pipelines/search_pipeline.py @@ -3,13 +3,13 @@ from asyncio import Queue from typing import Any, Optional -from ..base import User from ..base.abstractions.search import ( AggregateSearchResult, KGSearchSettings, VectorSearchSettings, ) -from ..base.logging.kv_logger import KVLoggingSingleton +from ..base.api.models.auth.responses import UserResponse +from ..base.logging.run_logger import RunLoggingSingleton from ..base.logging.run_manager import RunManager, manage_run from ..base.pipeline.base_pipeline import AsyncPipeline, dequeue_requests from ..base.pipes.base_pipe import AsyncPipe, AsyncState @@ -20,11 +20,9 @@ class SearchPipeline(AsyncPipeline): """A pipeline for search.""" - pipeline_type: str = "search" - def __init__( self, - pipe_logger: Optional[KVLoggingSingleton] = None, + pipe_logger: Optional[RunLoggingSingleton] = None, run_manager: Optional[RunManager] = None, ): super().__init__(pipe_logger, run_manager) @@ -38,10 +36,9 @@ async def run( state: Optional[AsyncState] = None, stream: bool = False, run_manager: Optional[RunManager] = None, - log_run_info: bool = True, vector_search_settings: VectorSearchSettings = VectorSearchSettings(), kg_search_settings: KGSearchSettings = KGSearchSettings(), - user: Optional[User] = None, + user: Optional[UserResponse] = None, *args: Any, **kwargs: Any, ): @@ -55,15 +52,7 @@ async def run( and kg_search_settings.use_kg_search ) run_manager = run_manager or self.run_manager - async with manage_run(run_manager, self.pipeline_type): - if log_run_info: - await run_manager.log_run_info( - key="pipeline_type", - value=self.pipeline_type, - is_info_log=True, - user=user, - ) - + async with manage_run(run_manager): vector_search_queue = Queue() kg_queue = Queue() @@ -88,7 +77,6 @@ async def enqueue_requests(): state, stream, run_manager, - log_run_info=False, vector_search_settings=vector_search_settings, *args, **kwargs, @@ -102,7 +90,6 @@ async def enqueue_requests(): state, stream, run_manager, - log_run_info=False, kg_search_settings=kg_search_settings, *args, **kwargs, diff --git a/r2r/pipes/__init__.py b/r2r/pipes/__init__.py index 32230166d..10f5cfaf1 100644 --- a/r2r/pipes/__init__.py +++ b/r2r/pipes/__init__.py @@ -1,11 +1,12 @@ from .abstractions.search_pipe import SearchPipe from .ingestion.chunking_pipe import ChunkingPipe from .ingestion.embedding_pipe import EmbeddingPipe -from .ingestion.kg_extraction_pipe import KGExtractionPipe -from .ingestion.kg_storage_pipe import KGStoragePipe from .ingestion.parsing_pipe import ParsingPipe from .ingestion.vector_storage_pipe import VectorStoragePipe -from .other.eval_pipe import EvalPipe +from .kg.clustering import KGClusteringPipe +from .kg.extraction import KGExtractionPipe +from .kg.node_extraction import KGNodeDescriptionPipe, KGNodeExtractionPipe +from .kg.storage import KGStoragePipe from .other.web_search_pipe import WebSearchPipe from .retrieval.kg_search_search_pipe import KGSearchSearchPipe from .retrieval.multi_search import MultiSearchPipe @@ -17,8 +18,9 @@ __all__ = [ "SearchPipe", "EmbeddingPipe", - "EvalPipe", "KGExtractionPipe", + "KGNodeExtractionPipe", + "KGNodeDescriptionPipe", "ParsingPipe", "ChunkingPipe", "QueryTransformPipe", @@ -29,5 +31,6 @@ "WebSearchPipe", "KGSearchSearchPipe", "KGStoragePipe", + "KGClusteringPipe", "MultiSearchPipe", ] diff --git a/r2r/pipes/abstractions/generator_pipe.py b/r2r/pipes/abstractions/generator_pipe.py index d90738425..1237948e9 100644 --- a/r2r/pipes/abstractions/generator_pipe.py +++ b/r2r/pipes/abstractions/generator_pipe.py @@ -5,9 +5,9 @@ from r2r.base import ( AsyncState, CompletionProvider, - KVLoggingSingleton, PipeType, PromptProvider, + RunLoggingSingleton, ) from r2r.base.abstractions.llm import GenerationConfig from r2r.base.pipes.base_pipe import AsyncPipe @@ -25,7 +25,7 @@ def __init__( prompt_provider: PromptProvider, type: PipeType = PipeType.GENERATOR, config: Optional[Config] = None, - pipe_logger: Optional[KVLoggingSingleton] = None, + pipe_logger: Optional[RunLoggingSingleton] = None, *args, **kwargs, ): diff --git a/r2r/pipes/abstractions/search_pipe.py b/r2r/pipes/abstractions/search_pipe.py index bb0303e0e..2f6d2d8c0 100644 --- a/r2r/pipes/abstractions/search_pipe.py +++ b/r2r/pipes/abstractions/search_pipe.py @@ -6,8 +6,8 @@ from r2r.base import ( AsyncPipe, AsyncState, - KVLoggingSingleton, PipeType, + RunLoggingSingleton, VectorSearchResult, ) @@ -17,7 +17,7 @@ class SearchPipe(AsyncPipe): class SearchConfig(AsyncPipe.PipeConfig): name: str = "default_vector_search" - search_filters: dict = {} + filters: dict = {} search_limit: int = 10 class Input(AsyncPipe.Input): @@ -25,7 +25,7 @@ class Input(AsyncPipe.Input): def __init__( self, - pipe_logger: Optional[KVLoggingSingleton] = None, + pipe_logger: Optional[RunLoggingSingleton] = None, type: PipeType = PipeType.SEARCH, config: Optional[AsyncPipe.PipeConfig] = None, *args, diff --git a/r2r/pipes/ingestion/chunking_pipe.py b/r2r/pipes/ingestion/chunking_pipe.py index 67dec7422..291a6ad0e 100644 --- a/r2r/pipes/ingestion/chunking_pipe.py +++ b/r2r/pipes/ingestion/chunking_pipe.py @@ -1,30 +1,30 @@ -import asyncio from typing import Any, AsyncGenerator, Optional, Union from r2r.base import ( AsyncState, + ChunkingConfig, ChunkingProvider, - Extraction, - Fragment, - FragmentType, - KVLoggingSingleton, + DocumentExtraction, + DocumentFragment, PipeType, R2RDocumentProcessingError, + RunLoggingSingleton, generate_id_from_label, ) from r2r.base.pipes.base_pipe import AsyncPipe +from r2r.providers import R2RChunkingProvider class ChunkingPipe(AsyncPipe): class Input(AsyncPipe.Input): message: AsyncGenerator[ - Union[Extraction, R2RDocumentProcessingError], None + Union[DocumentExtraction, R2RDocumentProcessingError], None ] def __init__( self, chunking_provider: ChunkingProvider, - pipe_logger: Optional[KVLoggingSingleton] = None, + pipe_logger: Optional[RunLoggingSingleton] = None, type: PipeType = PipeType.INGESTOR, config: Optional[AsyncPipe.PipeConfig] = None, *args, @@ -38,17 +38,25 @@ def __init__( *args, **kwargs, ) - self.chunking_provider = chunking_provider + self.default_chunking_provider = ( + chunking_provider or R2RChunkingProvider(ChunkingConfig()) + ) async def _run_logic( self, input: Input, state: AsyncState, run_id: Any, - chunking_config_override: Optional[ChunkingProvider] = None, *args: Any, **kwargs: Any, - ) -> AsyncGenerator[Union[R2RDocumentProcessingError, Fragment], None]: + ) -> AsyncGenerator[ + Union[R2RDocumentProcessingError, DocumentFragment], None + ]: + + chunking_provider = kwargs.get( + "chunking_provider", self.default_chunking_provider + ) + async for item in input.message: if isinstance(item, R2RDocumentProcessingError): yield item @@ -56,14 +64,15 @@ async def _run_logic( try: iteration = 0 - async for chunk in self.chunking_provider.chunk(item.data): - yield Fragment( + async for chunk in chunking_provider.chunk(item.data): + yield DocumentFragment( id=generate_id_from_label(f"{item.id}-{iteration}"), - type=FragmentType.TEXT, - data=chunk, - metadata=item.metadata, extraction_id=item.id, document_id=item.document_id, + user_id=item.user_id, + group_ids=item.group_ids, + data=chunk, + metadata=item.metadata, ) iteration += 1 except Exception as e: diff --git a/r2r/pipes/ingestion/embedding_pipe.py b/r2r/pipes/ingestion/embedding_pipe.py index 5da987242..19890091f 100644 --- a/r2r/pipes/ingestion/embedding_pipe.py +++ b/r2r/pipes/ingestion/embedding_pipe.py @@ -1,14 +1,13 @@ -import asyncio import logging from typing import Any, AsyncGenerator, Optional, Union from r2r.base import ( AsyncState, + DocumentFragment, EmbeddingProvider, - Fragment, - KVLoggingSingleton, PipeType, R2RDocumentProcessingError, + RunLoggingSingleton, Vector, VectorEntry, ) @@ -24,14 +23,14 @@ class EmbeddingPipe(AsyncPipe): class Input(AsyncPipe.Input): message: AsyncGenerator[ - Union[Fragment, R2RDocumentProcessingError], None + Union[DocumentFragment, R2RDocumentProcessingError], None ] def __init__( self, embedding_provider: EmbeddingProvider, embedding_batch_size: int = 1, - pipe_logger: Optional[KVLoggingSingleton] = None, + pipe_logger: Optional[RunLoggingSingleton] = None, type: PipeType = PipeType.INGESTOR, config: Optional[AsyncPipe.PipeConfig] = None, *args, @@ -46,24 +45,26 @@ def __init__( self.embedding_provider = embedding_provider self.embedding_batch_size = embedding_batch_size - async def embed(self, fragments: list[Fragment]) -> list[float]: + async def embed(self, fragments: list[DocumentFragment]) -> list[float]: return await self.embedding_provider.async_get_embeddings( [fragment.data for fragment in fragments], EmbeddingProvider.PipeStage.BASE, ) async def _process_batch( - self, fragment_batch: list[Fragment] + self, fragment_batch: list[DocumentFragment] ) -> list[VectorEntry]: vectors = await self.embed(fragment_batch) return [ VectorEntry( - id=fragment.id, + fragment_id=fragment.id, + extraction_id=fragment.extraction_id, + document_id=fragment.document_id, + user_id=fragment.user_id, + group_ids=fragment.group_ids, vector=Vector(data=raw_vector), + text=fragment.data, metadata={ - "document_id": fragment.document_id, - "extraction_id": fragment.extraction_id, - "text": fragment.data, **fragment.metadata, }, ) diff --git a/r2r/pipes/ingestion/kg_extraction_pipe.py b/r2r/pipes/ingestion/kg_extraction_pipe.py index 2d4536fc4..d36f6694a 100644 --- a/r2r/pipes/ingestion/kg_extraction_pipe.py +++ b/r2r/pipes/ingestion/kg_extraction_pipe.py @@ -7,14 +7,15 @@ AsyncState, ChunkingProvider, CompletionProvider, - Extraction, - Fragment, - KGExtraction, + DocumentExtraction, KGProvider, - KVLoggingSingleton, PipeType, PromptProvider, R2RDocumentProcessingError, + RunLoggingSingleton, +) +from r2r.base.abstractions.graph import ( + KGExtraction, extract_entities, extract_triples, ) @@ -29,14 +30,14 @@ class ClientError(Exception): pass -class KGExtractionPipe(AsyncPipe): +class KGTriplesExtractionPipe(AsyncPipe): """ Extracts knowledge graph information from document extractions. """ class Input(AsyncPipe.Input): message: AsyncGenerator[ - Union[Extraction, R2RDocumentProcessingError], None + Union[DocumentExtraction, R2RDocumentProcessingError], None ] def __init__( @@ -46,7 +47,7 @@ def __init__( prompt_provider: PromptProvider, chunking_provider: ChunkingProvider, kg_batch_size: int = 1, - pipe_logger: Optional[KVLoggingSingleton] = None, + pipe_logger: Optional[RunLoggingSingleton] = None, type: PipeType = PipeType.INGESTOR, config: Optional[AsyncPipe.PipeConfig] = None, *args, diff --git a/r2r/pipes/ingestion/parsing_pipe.py b/r2r/pipes/ingestion/parsing_pipe.py index 37b0ca590..e8fc3ff21 100644 --- a/r2r/pipes/ingestion/parsing_pipe.py +++ b/r2r/pipes/ingestion/parsing_pipe.py @@ -2,27 +2,24 @@ This module contains the `DocumentParsingPipe` class, which is responsible for parsing incoming documents into plaintext. """ -import asyncio import logging -import time import uuid from typing import AsyncGenerator, Optional, Union -from r2r import parsers from r2r.base import ( AsyncState, Document, - DocumentType, - Extraction, - ExtractionType, - KVLoggingSingleton, + DocumentExtraction, ParsingProvider, PipeType, + RunLoggingSingleton, generate_id_from_label, ) from r2r.base.abstractions.exception import R2RDocumentProcessingError from r2r.base.pipes.base_pipe import AsyncPipe +logger = logging.getLogger(__name__) + class ParsingPipe(AsyncPipe): class Input(AsyncPipe.Input): @@ -31,7 +28,7 @@ class Input(AsyncPipe.Input): def __init__( self, parsing_provider: ParsingProvider, - pipe_logger: Optional[KVLoggingSingleton] = None, + pipe_logger: Optional[RunLoggingSingleton] = None, type: PipeType = PipeType.INGESTOR, config: Optional[AsyncPipe.PipeConfig] = None, *args, @@ -52,7 +49,9 @@ async def _parse( document: Document, run_id: uuid.UUID, version: str, - ) -> AsyncGenerator[Union[R2RDocumentProcessingError, Extraction], None]: + ) -> AsyncGenerator[ + Union[R2RDocumentProcessingError, DocumentExtraction], None + ]: try: async for extraction in self.parsing_provider.parse(document): extraction_id = generate_id_from_label( @@ -74,8 +73,9 @@ async def _run_logic( versions: Optional[list[str]] = None, *args, **kwargs, - ) -> AsyncGenerator[Extraction, None]: + ) -> AsyncGenerator[DocumentExtraction, None]: async for document in input.message: version = versions[0] if versions else "v0" async for result in self._parse(document, run_id, version): + logger.info(f"Parsing pipe result for document, {document.id}") yield result diff --git a/r2r/pipes/ingestion/vector_storage_pipe.py b/r2r/pipes/ingestion/vector_storage_pipe.py index 639808b90..06b3a9984 100644 --- a/r2r/pipes/ingestion/vector_storage_pipe.py +++ b/r2r/pipes/ingestion/vector_storage_pipe.py @@ -6,8 +6,8 @@ from r2r.base import ( AsyncState, DatabaseProvider, - KVLoggingSingleton, PipeType, + RunLoggingSingleton, VectorEntry, ) from r2r.base.pipes.base_pipe import AsyncPipe @@ -22,13 +22,12 @@ class Input(AsyncPipe.Input): message: AsyncGenerator[ Union[R2RDocumentProcessingError, VectorEntry], None ] - do_upsert: bool = True def __init__( self, database_provider: DatabaseProvider, storage_batch_size: int = 128, - pipe_logger: Optional[KVLoggingSingleton] = None, + pipe_logger: Optional[RunLoggingSingleton] = None, type: PipeType = PipeType.INGESTOR, config: Optional[AsyncPipe.PipeConfig] = None, *args, @@ -50,17 +49,13 @@ def __init__( async def store( self, vector_entries: list[VectorEntry], - do_upsert: bool = True, ) -> None: """ Stores a batch of vector entries in the database. """ try: - if do_upsert: - self.database_provider.vector.upsert_entries(vector_entries) - else: - self.database_provider.vector.copy_entries(vector_entries) + self.database_provider.vector.upsert_entries(vector_entries) except Exception as e: error_message = ( f"Failed to store vector entries in the database: {e}" @@ -91,20 +86,17 @@ async def _run_logic( yield (msg.document_id, msg) continue - document_id = msg.metadata.get("document_id", None) - if not document_id: - raise ValueError("Document ID not found in the metadata.") - if document_id not in document_counts: - document_counts[document_id] = 1 + if msg.document_id not in document_counts: + document_counts[msg.document_id] = 1 else: - document_counts[document_id] += 1 + document_counts[msg.document_id] += 1 vector_batch.append(msg) if len(vector_batch) >= self.storage_batch_size: # Schedule the storage task batch_tasks.append( asyncio.create_task( - self.store(vector_batch.copy(), input.do_upsert), + self.store(vector_batch.copy()), name=f"vector-store-{self.config.name}", ) ) @@ -113,7 +105,7 @@ async def _run_logic( if vector_batch: # Process any remaining vectors batch_tasks.append( asyncio.create_task( - self.store(vector_batch.copy(), input.do_upsert), + self.store(vector_batch.copy()), name=f"vector-store-{self.config.name}", ) ) diff --git a/r2r/pipes/kg/clustering.py b/r2r/pipes/kg/clustering.py new file mode 100644 index 000000000..0fa51e905 --- /dev/null +++ b/r2r/pipes/kg/clustering.py @@ -0,0 +1,282 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module for clustering entities and triples into communities using hierarchical Leiden algorithm.""" + +import asyncio +import logging +import uuid +from typing import Any, AsyncGenerator, Optional + +import networkx as nx +from graspologic.partition import hierarchical_leiden + +from r2r.base import ( + AsyncPipe, + AsyncState, + Community, + CompletionProvider, + EmbeddingProvider, + GenerationConfig, + KGProvider, + PipeType, + PromptProvider, + RunLoggingSingleton, + Triple, +) + +logger = logging.getLogger(__name__) + + +class KGClusteringPipe(AsyncPipe): + """ + Clusters entities and triples into communities within the knowledge graph using hierarchical Leiden algorithm. + """ + + def __init__( + self, + kg_provider: KGProvider, + llm_provider: CompletionProvider, + prompt_provider: PromptProvider, + embedding_provider: EmbeddingProvider, + cluster_batch_size: int = 100, + max_cluster_size: int = 10, + use_lcc: bool = True, + pipe_logger: Optional[RunLoggingSingleton] = None, + type: PipeType = PipeType.OTHER, + config: Optional[AsyncPipe.PipeConfig] = None, + *args, + **kwargs, + ): + """ + Initializes the KG clustering pipe with necessary components and configurations. + """ + super().__init__( + pipe_logger=pipe_logger, + type=type, + config=config or AsyncPipe.PipeConfig(name="kg_cluster_pipe"), + ) + self.kg_provider = kg_provider + self.llm_provider = llm_provider + self.cluster_batch_size = cluster_batch_size + self.max_cluster_size = max_cluster_size + self.use_lcc = use_lcc + self.prompt_provider = prompt_provider + self.embedding_provider = embedding_provider + + def _compute_leiden_communities( + self, + graph: nx.Graph, + seed: int = 0xDEADBEEF, + ) -> dict[int, dict[str, int]]: + """Compute Leiden communities.""" + community_mapping = hierarchical_leiden( + graph, max_cluster_size=self.max_cluster_size, random_seed=seed + ) + results: dict[int, dict[str, int]] = {} + for partition in community_mapping: + results[partition.level] = results.get(partition.level, {}) + results[partition.level][partition.node] = partition.cluster + + return results + + async def cluster_kg(self, triples: list[Triple]) -> list[Community]: + """ + Clusters the knowledge graph triples into communities using hierarchical Leiden algorithm. + """ + + # for record in data: + # source = EntityNode( + # name=record["source_id"], + # label=record["source_type"], + # properties=remove_empty_values(record["source_properties"]), + # ) + # target = EntityNode( + # name=record["target_id"], + # label=record["target_type"], + # properties=remove_empty_values(record["target_properties"]), + # ) + # rel = Relation( + # source_id=record["source_id"], + # target_id=record["target_id"], + # label=record["type"], + # ) + # triples.append([source, rel, target]) + # return triples + + G = nx.Graph() + for triple in triples: + G.add_edge( + triple.subject, + triple.object, + weight=triple.weight, + description=triple.description, + predicate=triple.predicate, + id=f"{triple.subject}->{triple.predicate}->{triple.object}", + ) + + hierarchical_communities = self._compute_leiden_communities(G) + + community_details = {} + + for level, level_communities in hierarchical_communities.items(): + for node, cluster in level_communities.items(): + if f"{level}_{cluster}" not in community_details: + community_details[f"{level}_{cluster}"] = Community( + id=f"{level}_{cluster}", + level=str(level), + entity_ids=[], + relationship_ids=[], + short_id=f"{level}.{cluster}", + title=f"Community {level}.{cluster}", + attributes={ + "name": f"Community {level}.{cluster}", + "community_report": None, + }, + ) + + community_details[f"{level}_{cluster}"].entity_ids.append(node) + for neighbor in G.neighbors(node): + edge_info = G.get_edge_data(node, neighbor) + logger.info(f"Node: {node}") + logger.info(f"Neighbor: {neighbor}") + logger.info(f"Edge info: {edge_info}") + if edge_info and edge_info.get("id"): + community_details[ + f"{level}_{cluster}" + ].relationship_ids.append(edge_info.get("id")) + + async def async_iterate_dict(dictionary): + for key, value in dictionary.items(): + yield key, value + + async def process_community(community_key, community): + input_text = """ + + Entities: + {entities} + + Relationships: + {relationships} + + """ + + entities_info = self.kg_provider.get_entities(community.entity_ids) + entities_info = "\n".join( + [ + f"{entity.name}, {entity.description}" + for entity in entities_info + ] + ) + + relationships_info = self.kg_provider.get_triples( + community.relationship_ids + ) + relationships_info = "\n".join( + [ + f"{relationship.subject}, {relationship.object}, {relationship.predicate}, {relationship.description}" + for relationship in relationships_info + ] + ) + + input_text = input_text.format( + entities=entities_info, relationships=relationships_info + ) + + description = await self.llm_provider.aget_completion( + messages=self.prompt_provider._get_message_payload( + task_prompt_name="graphrag_community_reports", + task_inputs={ + "input_text": input_text, + }, + ), + generation_config=GenerationConfig( + model="gpt-4o-mini", + ), + ) + + description = description.choices[0].message.content + + logger.info(f"Community description: {description}") + + community.summary = description + + summary_embedding = ( + await self.embedding_provider.async_get_embedding( + community.summary + ) + ) + community.summary_embedding = summary_embedding + self.kg_provider.upsert_communities([community]) + return community + + tasks = [] + async for community_key, community in async_iterate_dict( + community_details + ): + tasks.append( + asyncio.create_task( + process_community(community_key, community) + ) + ) + + for completed_task in asyncio.as_completed(tasks): + yield await completed_task + + async def _process_batch(self, triples: list[Triple]) -> list[Community]: + """ + Processes a batch of triples and returns the resulting communities. + """ + return await self.cluster_kg(triples) + + async def _run_logic( + self, + input: AsyncPipe.Input, + state: AsyncState, + run_id: uuid.UUID, + *args: Any, + **kwargs: Any, + ) -> AsyncGenerator[Community, None]: + """ + Executes the KG clustering pipe: clustering entities and triples into communities. + """ + # batch_tasks = [] + # triple_batch = [] + + # async for triple in input.message: + # triple_batch.append(triple) + # if len(triple_batch) >= self.cluster_batch_size: + # batch_tasks.append(self._process_batch(triple_batch.copy())) + # triple_batch.clear() + + # if triple_batch: # Process any remaining triples + # batch_tasks.append(self._process_batch(triple_batch)) + + # for task in asyncio.as_completed(batch_tasks): + # communities = await task + # for community in communities: + # yield community + + # store all inputs + + all_nodes = [] + async for node in input.message: + all_nodes.append(node) + + triples = self.kg_provider.get_triples() + # create a networkx graph + + async for community in self.cluster_kg(triples): + yield community + + # then finally create vector indexes for communities + self.kg_provider.create_vector_index("__ENTITY__", "name_embedding") + self.kg_provider.create_vector_index( + "__ENTITY__", "description_embedding" + ) + + self.kg_provider.create_vector_index("__RELATIONSHIP__", "description") + + self.kg_provider.create_vector_index( + "__Community__", "summary_embedding" + ) diff --git a/r2r/pipes/kg/extraction.py b/r2r/pipes/kg/extraction.py new file mode 100644 index 000000000..ac00ab75c --- /dev/null +++ b/r2r/pipes/kg/extraction.py @@ -0,0 +1,227 @@ +import asyncio +import json +import logging +import re +import uuid +from typing import Any, AsyncGenerator, Optional, Union + +from r2r.base import ( + AsyncState, + ChunkingProvider, + CompletionProvider, + DocumentExtraction, + DocumentFragment, + Entity, + KGExtraction, + KGProvider, + PipeType, + PromptProvider, + R2RDocumentProcessingError, + RunLoggingSingleton, + Triple, + extract_entities, + extract_triples, +) +from r2r.base.pipes.base_pipe import AsyncPipe + +logger = logging.getLogger(__name__) + + +class ClientError(Exception): + """Base class for client connection errors.""" + + pass + + +class KGExtractionPipe(AsyncPipe): + """ + Extracts knowledge graph information from document extractions. + """ + + class Input(AsyncPipe.Input): + message: AsyncGenerator[ + Union[DocumentExtraction, R2RDocumentProcessingError], None + ] + + def __init__( + self, + kg_provider: KGProvider, + llm_provider: CompletionProvider, + prompt_provider: PromptProvider, + chunking_provider: ChunkingProvider, + kg_batch_size: int = 1, + graph_rag: bool = True, + id_prefix: str = "demo", + pipe_logger: Optional[RunLoggingSingleton] = None, + type: PipeType = PipeType.INGESTOR, + config: Optional[AsyncPipe.PipeConfig] = None, + *args, + **kwargs, + ): + super().__init__( + pipe_logger=pipe_logger, + type=type, + config=config + or AsyncPipe.PipeConfig(name="default_kg_extraction_pipe"), + ) + self.kg_provider = kg_provider + self.prompt_provider = prompt_provider + self.llm_provider = llm_provider + self.chunking_provider = chunking_provider + self.kg_batch_size = kg_batch_size + self.id_prefix = id_prefix + self.pipe_run_info = None + self.graph_rag = graph_rag + + def map_to_str(self, fragment: DocumentFragment) -> str: + # convert fragment to dict object + fragment = json.loads(json.dumps(fragment)) + return fragment + + async def extract_kg( + self, + fragment: DocumentFragment, + retries: int = 3, + delay: int = 2, + ) -> KGExtraction: + """ + Extracts NER triples from a fragment with retries. + """ + + task_inputs = {"input": fragment.data} + if self.graph_rag: + task_inputs["max_knowledge_triplets"] = 100 + + messages = self.prompt_provider._get_message_payload( + task_prompt_name=self.kg_provider.config.kg_extraction_prompt, + task_inputs=task_inputs, + ) + + for attempt in range(retries): + + try: + response = await self.llm_provider.aget_completion( + messages, self.kg_provider.config.kg_extraction_config + ) + + kg_extraction = response.choices[0].message.content + + if self.graph_rag: + + entity_pattern = ( + r'\("entity"\${4}([^$]+)\${4}([^$]+)\${4}([^$]+)\)' + ) + relationship_pattern = r'\("relationship"\${4}([^$]+)\${4}([^$]+)\${4}([^$]+)\${4}([^$]+)\${4}(\d+(?:\.\d+)?)\)' + + def parse_fn(response_str: str) -> Any: + entities = re.findall(entity_pattern, response_str) + relationships = re.findall( + relationship_pattern, response_str + ) + + entities_dict = {} + for entity in entities: + logger.info(f"Entity: {entity}") + entity_value = entity[0] + entity_category = entity[1] + entity_description = entity[2] + entities_dict[entity_value] = Entity( + category=entity_category, + description=entity_description, + name=entity_value, + document_ids=[str(fragment.document_id)], + text_unit_ids=[str(fragment.id)], + attributes={"fragment_text": fragment.data}, + ) + + relations_arr = [] + for relationship in relationships: + logger.info(f"Relationship: {relationship}") + subject = relationship[0] + object = relationship[1] + predicate = relationship[2] + description = relationship[3] + weight = float(relationship[4]) + + # check if subject and object are in entities_dict + relations_arr.append( + Triple( + id=str(uuid.uuid4()), + subject=subject, + predicate=predicate, + object=object, + description=description, + weight=weight, + document_ids=[str(fragment.document_id)], + text_unit_ids=[str(fragment.id)], + attributes={ + "fragment_text": fragment.data + }, + ) + ) + + return entities_dict, relations_arr + + entities, triples = parse_fn(kg_extraction) + return KGExtraction( + entities=list(entities.values()), triples=triples + ) + + else: + # Parsing JSON from the response + kg_json = ( + json.loads( + kg_extraction.split("```json")[1].split("```")[0] + ) + if "```json" in kg_extraction + else json.loads(kg_extraction) + ) + llm_payload = kg_json.get("entities_and_triples", {}) + + # Extract triples with detailed logging + entities = extract_entities(llm_payload) + triples = extract_triples(llm_payload, entities) + + # Create KG extraction object + return KGExtraction( + entities=entities.values(), triples=triples + ) + + except ( + ClientError, + json.JSONDecodeError, + KeyError, + IndexError, + ) as e: + logger.error(f"Error in extract_kg: {e}") + if attempt < retries - 1: + await asyncio.sleep(delay) + else: + logger.error(f"Failed after retries with {e}") + + # add metadata to entities and triples + + return KGExtraction(entities={}, triples=[]) + + async def _run_logic( + self, + input: Input, + state: AsyncState, + run_id: Any, + *args: Any, + **kwargs: Any, + ) -> AsyncGenerator[Union[KGExtraction, R2RDocumentProcessingError], None]: + + async def process_extraction(extraction): + return await self.extract_kg(extraction) + + extractions = [] + async for extraction in input.message: + extractions.append(extraction) + + kg_extractions = await asyncio.gather( + *[process_extraction(extraction) for extraction in extractions] + ) + + for kg_extraction in kg_extractions: + yield kg_extraction diff --git a/r2r/pipes/kg/node_extraction.py b/r2r/pipes/kg/node_extraction.py new file mode 100644 index 000000000..ffd8e7ce5 --- /dev/null +++ b/r2r/pipes/kg/node_extraction.py @@ -0,0 +1,234 @@ +# pipe to extract nodes/triples etc + +import asyncio +import logging +import uuid +from typing import Any, AsyncGenerator, Optional + +from r2r.base import ( + AsyncState, + CompletionProvider, + EmbeddingProvider, + KGProvider, + PipeType, + PromptProvider, + RunLoggingSingleton, +) +from r2r.base.abstractions.graph import Entity, Triple +from r2r.base.pipes.base_pipe import AsyncPipe +from r2r.base.providers.llm import GenerationConfig + +logger = logging.getLogger(__name__) + + +class KGNodeExtractionPipe(AsyncPipe): + """ + The pipe takes input a list of documents (optional) and extracts nodes and triples from them. + """ + + class Input(AsyncPipe.Input): + message: Any + + def __init__( + self, + kg_provider: KGProvider, + llm_provider: CompletionProvider, + prompt_provider: PromptProvider, + pipe_logger: Optional[RunLoggingSingleton] = None, + type: PipeType = PipeType.OTHER, + config: Optional[AsyncPipe.PipeConfig] = None, + *args, + **kwargs, + ): + super().__init__( + pipe_logger=pipe_logger, + type=type, + config=config + or AsyncPipe.PipeConfig(name="kg_node_extraction_pipe"), + ) + self.kg_provider = kg_provider + self.llm_provider = llm_provider + self.prompt_provider = prompt_provider + + async def _run_logic( + self, + input: Input, + state: AsyncState, + run_id: uuid.UUID, + *args, + **kwargs, + ) -> AsyncGenerator[Any, None]: + + nodes = self.kg_provider.get_entity_map() + + for node_value, node_info in nodes.items(): + for entity in node_info["entities"]: + yield entity, node_info[ + "triples" + ] # the entity and its associated triples + + +class KGNodeDescriptionPipe(AsyncPipe): + """ + The pipe takes input a list of nodes and extracts description from them. + """ + + class Input(AsyncPipe.Input): + message: AsyncGenerator[tuple[Entity, list[Triple]], None] + + def __init__( + self, + kg_provider: KGProvider, + llm_provider: CompletionProvider, + embedding_provider: EmbeddingProvider, + pipe_logger: Optional[RunLoggingSingleton] = None, + type: PipeType = PipeType.OTHER, + config: Optional[AsyncPipe.PipeConfig] = None, + *args, + **kwargs, + ): + super().__init__( + pipe_logger=pipe_logger, + type=type, + config=config + or AsyncPipe.PipeConfig(name="kg_node_description_pipe"), + ) + self.kg_provider = kg_provider + self.llm_provider = llm_provider + self.embedding_provider = embedding_provider + + async def _run_logic( + self, + input: Input, + state: AsyncState, + run_id: uuid.UUID, + *args: Any, + **kwargs: Any, + ) -> AsyncGenerator[Any, None]: + """ + Extracts description from the input. + """ + + # summarization_content = """ + + # You are given the following entity and its associated triples: + # Entity: {entity_info} + # Triples: {triples_txt} + # Your tasks: + + # Entity Description: + # Provide a concise description of the entity based on the given information and triples. + + # Entity Analysis: + # a) Determine if this entity represents a single concept or a combination of multiple entities. + # b) If it's a combination, list the separate entities that make up this composite entity. + # c) Map each separate entity to the relationship(s) it came from in the original triples. + # d) Suggest more appropriate names for each separate entity if applicable. + + # Formatted Output: + # For each entity (original or separate), provide the following formatted output: + # ("entity"$$$$$$$$$$$$$$$$) + + # Where: + # : The name of the entity (original or improved) + # : The type or category of the entity + # : A concise description of the entity + # : List of triples associated with this specific entity + + # Explanation: + # Briefly explain your reasoning for separating entities (if applicable) and any name changes you suggested. + + # Please ensure your response is clear, concise, and follows the requested format. + # """ + + summarization_content = """ + Provide a comprehensive yet concise summary of the given entity, incorporating its description and associated triples: + + Entity: {entity_info} + Description: {description} + Triples: {triples_txt} + + Your summary should: + 1. Clearly define the entity's core concept or purpose + 2. Highlight key relationships or attributes from the triples + 3. Integrate any relevant information from the existing description + 4. Maintain a neutral, factual tone + 5. Be approximately 2-3 sentences long + + Ensure the summary is coherent, informative, and captures the essence of the entity within the context of the provided information. + """ + + async def process_entity(entity, triples): + + # if embedding is present in the entity, just return it + # in the future disable this to override and recompute the descriptions for all entities + if entity.description_embedding and entity.name_embedding: + return entity + + entity_info = f"{entity.name}, {entity.description}" + triples_txt = "\n".join( + [ + f"{i+1}: {triple.subject}, {triple.object}, {triple.predicate} - Summary: {triple.description}" + for i, triple in enumerate(triples) + ] + ) + + messages = [ + { + "role": "user", + "content": summarization_content.format( + entity_info=entity_info, + description=entity.description, + triples_txt=triples_txt, + ), + } + ] + + out_entity = self.kg_provider.retrieve_cache( + "entities_with_description", f"{entity.name}_{entity.category}" + ) + if out_entity: + logger.info(f"Hit cache for entity {entity.name}") + else: + completion = await self.llm_provider.aget_completion( + messages, GenerationConfig(model="gpt-4o-mini") + ) + entity.description = completion.choices[0].message.content + + # embedding + description_embedding = ( + await self.embedding_provider.async_get_embeddings( + [entity.description] + ) + ) + entity.description_embedding = description_embedding[0] + + # name embedding + name_embedding = ( + await self.embedding_provider.async_get_embeddings( + [entity.name] + ) + ) + entity.name_embedding = name_embedding[0] + + out_entity = entity + + return out_entity + + tasks = [] + count = 0 + async for entity, triples in input.message: + tasks.append(asyncio.create_task(process_entity(entity, triples))) + count += 1 + if count == 4: + break + + processed_entities = await asyncio.gather(*tasks) + + # upsert to the database + self.kg_provider.upsert_entities( + processed_entities, with_embeddings=True + ) + + for entity in processed_entities: + yield entity diff --git a/r2r/pipes/ingestion/kg_storage_pipe.py b/r2r/pipes/kg/storage.py similarity index 65% rename from r2r/pipes/ingestion/kg_storage_pipe.py rename to r2r/pipes/kg/storage.py index 2d4605ca8..ab7e10e15 100644 --- a/r2r/pipes/ingestion/kg_storage_pipe.py +++ b/r2r/pipes/kg/storage.py @@ -7,12 +7,11 @@ AsyncState, EmbeddingProvider, KGExtraction, - KGProvider, - KVLoggingSingleton, PipeType, + RunLoggingSingleton, ) -from r2r.base.abstractions.llama_abstractions import EntityNode, Relation from r2r.base.pipes.base_pipe import AsyncPipe +from r2r.base.providers import KGProvider logger = logging.getLogger(__name__) @@ -26,7 +25,7 @@ def __init__( kg_provider: KGProvider, embedding_provider: Optional[EmbeddingProvider] = None, storage_batch_size: int = 1, - pipe_logger: Optional[KVLoggingSingleton] = None, + pipe_logger: Optional[RunLoggingSingleton] = None, type: PipeType = PipeType.INGESTOR, config: Optional[AsyncPipe.PipeConfig] = None, *args, @@ -58,37 +57,7 @@ async def store( Stores a batch of knowledge graph extractions in the graph database. """ try: - nodes = [] - relations = [] - for extraction in kg_extractions: - for entity in extraction.entities.values(): - embedding = None - if self.embedding_provider: - embedding = self.embedding_provider.get_embedding( - f"Entity:\n{entity.value}\nLabel:\n{entity.category}\nSubcategory:\n{entity.subcategory}" - ) - nodes.append( - EntityNode( - name=entity.value, - label=entity.category, - embedding=embedding, - properties=( - {"subcategory": entity.subcategory} - if entity.subcategory - else {} - ), - ) - ) - for triple in extraction.triples: - relations.append( - Relation( - source_id=triple.subject, - target_id=triple.object, - label=triple.predicate, - ) - ) - self.kg_provider.upsert_nodes(nodes) - self.kg_provider.upsert_relations(relations) + self.kg_provider.upsert_nodes_and_relationships(kg_extractions) except Exception as e: error_message = f"Failed to store knowledge graph extractions in the database: {e}" logger.error(error_message) diff --git a/r2r/pipes/other/eval_pipe.py b/r2r/pipes/other/eval_pipe.py deleted file mode 100644 index b1c603431..000000000 --- a/r2r/pipes/other/eval_pipe.py +++ /dev/null @@ -1,54 +0,0 @@ -import logging -import uuid -from typing import Any, AsyncGenerator, Optional - -from pydantic import BaseModel - -from r2r import AsyncState, EvalProvider, LLMChatCompletion, PipeType -from r2r.base.abstractions.llm import GenerationConfig -from r2r.base.pipes.base_pipe import AsyncPipe - -logger = logging.getLogger(__name__) - - -class EvalPipe(AsyncPipe): - class EvalPayload(BaseModel): - query: str - context: str - completion: str - - class Input(AsyncPipe.Input): - message: AsyncGenerator["EvalPipe.EvalPayload", None] - - def __init__( - self, - eval_provider: EvalProvider, - type: PipeType = PipeType.EVAL, - config: Optional[AsyncPipe.PipeConfig] = None, - *args, - **kwargs, - ): - self.eval_provider = eval_provider - super().__init__( - type=type, - config=config or AsyncPipe.PipeConfig(name="default_eval_pipe"), - *args, - **kwargs, - ) - - async def _run_logic( - self, - input: Input, - state: AsyncState, - run_id: uuid.UUID, - eval_generation_config: GenerationConfig, - *args: Any, - **kwargs: Any, - ) -> AsyncGenerator[LLMChatCompletion, None]: - async for item in input.message: - yield self.eval_provider.evaluate( - item.query, - item.context, - item.completion, - eval_generation_config, - ) diff --git a/r2r/pipes/other/web_search_pipe.py b/r2r/pipes/other/web_search_pipe.py index 92e3feee4..4ef1b47d1 100644 --- a/r2r/pipes/other/web_search_pipe.py +++ b/r2r/pipes/other/web_search_pipe.py @@ -55,12 +55,17 @@ async def search( for result in results: if result.get("snippet") is None: continue - result["text"] = result.pop("snippet") + result.text = result.pop("snippet") search_result = VectorSearchResult( - id=generate_id_from_label(str(result)), + fragment_id=generate_id_from_label(str(result)), + extraction_id=uuid.uuid4(), # Generate a new UUID for extraction_id + document_id=uuid.uuid4(), # Generate a new UUID for document_id + user_id=None, # Web search results don't have a user_id + group_ids=[], # Web search results don't belong to any group score=result.get( "score", 0 ), # TODO - Consider dynamically generating scores based on similarity + text=result.text, metadata=result, ) search_results.append(search_result) @@ -69,7 +74,7 @@ async def search( await self.enqueue_log( run_id=run_id, key="search_results", - value=json.dumps([ele.json() for ele in search_results]), + value=json.dumps([ele.dict() for ele in search_results]), ) async def _run_logic( diff --git a/r2r/pipes/retrieval/kg_search_search_pipe.py b/r2r/pipes/retrieval/kg_search_search_pipe.py index 0c9af7736..18aa77528 100644 --- a/r2r/pipes/retrieval/kg_search_search_pipe.py +++ b/r2r/pipes/retrieval/kg_search_search_pipe.py @@ -1,3 +1,5 @@ +import asyncio +import json import logging import uuid from typing import Any, Optional @@ -5,11 +7,12 @@ from r2r.base import ( AsyncState, CompletionProvider, + EmbeddingProvider, KGProvider, KGSearchSettings, - KVLoggingSingleton, PipeType, PromptProvider, + RunLoggingSingleton, ) from ..abstractions.generator_pipe import GeneratorPipe @@ -27,7 +30,8 @@ def __init__( kg_provider: KGProvider, llm_provider: CompletionProvider, prompt_provider: PromptProvider, - pipe_logger: Optional[KVLoggingSingleton] = None, + embedding_provider: EmbeddingProvider, + pipe_logger: Optional[RunLoggingSingleton] = None, type: PipeType = PipeType.INGESTOR, config: Optional[GeneratorPipe.PipeConfig] = None, *args, @@ -51,9 +55,81 @@ def __init__( self.kg_provider = kg_provider self.llm_provider = llm_provider self.prompt_provider = prompt_provider + self.embedding_provider = embedding_provider self.pipe_run_info = None - async def _run_logic( + def filter_responses(self, map_responses): + filtered_responses = [] + for response in map_responses: + try: + parsed_response = json.loads(response) + for item in parsed_response["points"]: + try: + if item["score"] > 0: + filtered_responses.append(item) + except KeyError: + # Skip this item if it doesn't have a 'score' key + logger.warning(f"Item in response missing 'score' key") + continue + except json.JSONDecodeError: + logger.warning( + f"Response is not valid JSON: {response[:100]}..." + ) + continue + except KeyError: + logger.warning( + f"Response is missing 'points' key: {response[:100]}..." + ) + continue + + filtered_responses = sorted( + filtered_responses, key=lambda x: x["score"], reverse=True + ) + + responses = "\n".join( + [ + response.get("description", "") + for response in filtered_responses + ] + ) + return responses + + async def local_search( + self, + input: GeneratorPipe.Input, + state: AsyncState, + run_id: uuid.UUID, + kg_search_settings: KGSearchSettings, + *args: Any, + **kwargs: Any, + ): + # search over communities and + # do 3 searches. One over entities, one over relationships, one over communities + + async for message in input.message: + query_embedding = ( + await self.embedding_provider.async_get_embedding(message) + ) + + all_search_results = [] + for search_type in [ + "__Entity__", + "__Relationship__", + "__Community__", + ]: + search_result = self.kg_provider.vector_query( + input, + search_type=search_type, + search_type_limits=kg_search_settings.local_search_limits[ + search_type + ], + query_embedding=query_embedding, + ) + all_search_results.append(search_result) + + yield message, all_search_results + + async def global_search( self, input: GeneratorPipe.Input, state: AsyncState, @@ -62,41 +138,95 @@ async def _run_logic( *args: Any, **kwargs: Any, ): + # map reduce async for message in input.message: + map_responses = [] + communities = self.kg_provider.get_communities( + level=kg_search_settings.kg_search_level + ) - if not kg_search_settings.entity_types: - messages = self.prompt_provider._get_message_payload( - task_prompt_name="kg_search", - task_inputs={"input": message}, + async def preprocess_communities(communities): + merged_report = "" + for community in communities: + community_report = community.summary + if ( + len(merged_report) + len(community_report) + > kg_search_settings.max_community_description_length + ): + yield merged_report.strip() + merged_report = "" + merged_report += community_report + "\n\n" + if merged_report: + yield merged_report.strip() + + async def process_community(merged_report): + output = await self.llm_provider.aget_completion( + messages=self.prompt_provider._get_message_payload( + task_prompt_name="graphrag_map_system_prompt", + task_inputs={ + "context_data": merged_report, + "input": message, + }, + ), + generation_config=kg_search_settings.kg_search_generation_config, ) - else: - messages = self.prompt_provider._get_message_payload( - task_prompt_name="kg_search_with_spec", + + return output.choices[0].message.content + + preprocessed_reports = [ + merged_report + async for merged_report in preprocess_communities(communities) + ] + + # Use asyncio.gather to process all preprocessed community reports concurrently + logger.info( + f"Processing {len(communities)} communities, {len(preprocessed_reports)} reports" + ) + + map_responses = await asyncio.gather( + *[process_community(report) for report in preprocessed_reports] + ) + # Filter only the relevant responses + filtered_responses = self.filter_responses(map_responses) + + # reducing the outputs + output = await self.llm_provider.aget_completion( + messages=self.prompt_provider._get_message_payload( + task_prompt_name="graphrag_reduce_system_prompt", task_inputs={ + "response_type": "multiple paragraphs", + "report_data": filtered_responses[:2048], "input": message, - "entity_types": str(kg_search_settings.entity_types), - "relations": str(kg_search_settings.relationships), }, - ) - - result = await self.llm_provider.aget_completion( - messages=messages, + ), generation_config=kg_search_settings.kg_search_generation_config, ) - extraction = result.choices[0].message.content - query = extraction.split("```cypher")[1].split("```")[0] - result = self.kg_provider.structured_query(query) - yield (query, result) + output = output.choices[0].message.content - await self.enqueue_log( - run_id=run_id, - key="kg_search_response", - value=extraction, - ) + yield message, [{"output": output}] - await self.enqueue_log( - run_id=run_id, - key="kg_search_execution_result", - value=result, - ) + async def _run_logic( + self, + input: GeneratorPipe.Input, + state: AsyncState, + run_id: uuid.UUID, + kg_search_settings: KGSearchSettings, + *args: Any, + **kwargs: Any, + ): + + logger.info("Performing global search") + kg_search_type = kg_search_settings.kg_search_type + + if kg_search_type == "local": + async for query, result in self.local_search( + input, state, run_id, kg_search_settings + ): + yield (query, result) + + else: + async for query, result in self.global_search( + input, state, run_id, kg_search_settings + ): + yield (query, result) diff --git a/r2r/pipes/retrieval/search_rag_pipe.py b/r2r/pipes/retrieval/search_rag_pipe.py index 3065a51c1..20ec6aee5 100644 --- a/r2r/pipes/retrieval/search_rag_pipe.py +++ b/r2r/pipes/retrieval/search_rag_pipe.py @@ -92,7 +92,7 @@ async def _collect_context( context += f"Vector Search Results({iteration}):\n" it = total_results + 1 for result in results.vector_search_results: - context += f"[{it}]: {result.metadata['text']}\n\n" + context += f"[{it}]: {result.text}\n\n" it += 1 total_results = ( it - 1 diff --git a/r2r/pipes/retrieval/streaming_rag_pipe.py b/r2r/pipes/retrieval/streaming_rag_pipe.py index 23b79bd83..686e9f758 100644 --- a/r2r/pipes/retrieval/streaming_rag_pipe.py +++ b/r2r/pipes/retrieval/streaming_rag_pipe.py @@ -65,9 +65,7 @@ async def _run_logic( if iteration >= 1: yield "," yield json.dumps(result.json()) - context += ( - f"{iteration + 1}:\n{result.metadata['text']}\n\n" - ) + context += f"{iteration + 1}:\n{result.text}\n\n" iteration += 1 yield f"" diff --git a/r2r/pipes/retrieval/vector_search_pipe.py b/r2r/pipes/retrieval/vector_search_pipe.py index d4ea3e211..d1c97ede6 100644 --- a/r2r/pipes/retrieval/vector_search_pipe.py +++ b/r2r/pipes/retrieval/vector_search_pipe.py @@ -49,9 +49,7 @@ async def search( await self.enqueue_log( run_id=run_id, key="search_query", value=message ) - search_filters = ( - vector_search_settings.search_filters or self.config.search_filters - ) + filters = vector_search_settings.filters or self.config.filters search_limit = ( vector_search_settings.search_limit or self.config.search_limit ) @@ -64,13 +62,13 @@ async def search( self.database_provider.vector.hybrid_search( query_vector=query_vector, query_text=message, - filters=search_filters, + filters=filters, limit=search_limit, ) if vector_search_settings.do_hybrid_search else self.database_provider.vector.search( query_vector=query_vector, - filters=search_filters, + filters=filters, limit=search_limit, ) ) @@ -85,9 +83,7 @@ async def search( title = result.metadata.get("title", None) if title: text = result.metadata.get("text", "") - result.metadata["text"] = ( - f"Document Title:{title}\n\nText:{text}" - ) + result.text = f"Document Title:{title}\n\nText:{text}" for result in reranked_results: result.metadata["associatedQuery"] = message diff --git a/r2r/providers/__init__.py b/r2r/providers/__init__.py index a8679dded..e1dcd0cec 100644 --- a/r2r/providers/__init__.py +++ b/r2r/providers/__init__.py @@ -7,27 +7,34 @@ OllamaEmbeddingProvider, OpenAIEmbeddingProvider, ) -from .eval import LLMEvalProvider from .kg import Neo4jKGProvider from .llm import LiteCompletionProvider, OpenAICompletionProvider from .parsing import R2RParsingProvider, UnstructuredParsingProvider from .prompts import R2RPromptProvider __all__ = [ + # Auth "R2RAuthProvider", + # Chunking + "R2RChunkingProvider", + "UnstructuredChunkingProvider", + # Crypto "BCryptProvider", "BCryptConfig", + # Database "PostgresDBProvider", + # Embeddings "LiteLLMEmbeddingProvider", "OllamaEmbeddingProvider", "OpenAIEmbeddingProvider", - "LLMEvalProvider", + # KG "Neo4jKGProvider", + # LLM "OpenAICompletionProvider", "LiteCompletionProvider", - "R2RPromptProvider", + # Parsing "R2RParsingProvider", "UnstructuredParsingProvider", - "R2RChunkingProvider", - "UnstructuredChunkingProvider", + # Prompts + "R2RPromptProvider", ] diff --git a/r2r/providers/auth/r2r_auth.py b/r2r/providers/auth/r2r_auth.py index f428e2ff6..59f93bf60 100644 --- a/r2r/providers/auth/r2r_auth.py +++ b/r2r/providers/auth/r2r_auth.py @@ -15,9 +15,8 @@ R2RException, Token, TokenData, - User, - UserCreate, ) +from r2r.base.api.models.auth.responses import UserResponse logger = logging.getLogger(__name__) oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") @@ -49,9 +48,7 @@ def __init__( ) try: user = self.register( - UserCreate( - email=self.admin_email, password=self.admin_password - ) + email=self.admin_email, password=self.admin_password ) self.db_provider.relational.mark_user_as_superuser(user.id) @@ -104,7 +101,7 @@ def decode_token(self, token: str) -> TokenData: except jwt.InvalidTokenError as e: raise R2RException(status_code=401, message="Invalid token") from e - def user(self, token: str = Depends(oauth2_scheme)) -> User: + def user(self, token: str = Depends(oauth2_scheme)) -> UserResponse: token_data = self.decode_token(token) user = self.db_provider.relational.get_user_by_email(token_data.email) if user is None: @@ -114,21 +111,21 @@ def user(self, token: str = Depends(oauth2_scheme)) -> User: return user def get_current_active_user( - self, current_user: User = Depends(user) - ) -> User: + self, current_user: UserResponse = Depends(user) + ) -> UserResponse: if not current_user.is_active: raise R2RException(status_code=400, message="Inactive user") return current_user - def register(self, user: UserCreate) -> Dict[str, str]: + def register(self, email: str, password: str) -> Dict[str, str]: # Check if user already exists - if self.db_provider.relational.get_user_by_email(user.email): + if self.db_provider.relational.get_user_by_email(email): raise R2RException( status_code=400, message="Email already registered" ) # Create new user - new_user = self.db_provider.relational.create_user(user) + new_user = self.db_provider.relational.create_user(email, password) if self.config.require_email_verification: # Generate verification code and send email @@ -205,7 +202,6 @@ def login(self, email: str, password: str) -> Dict[str, Token]: logger.warning(f"Unverified user attempted login: {email}") raise R2RException(status_code=401, message="Email not verified") - logger.info(f"Successful login for user: {email}") access_token = self.create_access_token(data={"sub": user.email}) refresh_token = self.create_refresh_token(data={"sub": user.email}) return { @@ -244,7 +240,7 @@ def refresh_access_token( } def change_password( - self, user: User, current_password: str, new_password: str + self, user: UserResponse, current_password: str, new_password: str ) -> Dict[str, str]: if not self.crypto_provider.verify_password( current_password, user.hashed_password diff --git a/r2r/providers/chunking/r2r_chunking.py b/r2r/providers/chunking/r2r_chunking.py index 53b442e55..1fc48b932 100644 --- a/r2r/providers/chunking/r2r_chunking.py +++ b/r2r/providers/chunking/r2r_chunking.py @@ -3,6 +3,7 @@ from r2r.base import ( ChunkingConfig, ChunkingProvider, + Method, RecursiveCharacterTextSplitter, TextSplitter, ) @@ -12,16 +13,36 @@ class R2RChunkingProvider(ChunkingProvider): def __init__(self, config: ChunkingConfig): super().__init__(config) self.text_splitter = self._initialize_text_splitter() + print( + f"R2RChunkingProvider initialized with config: {self.config}" + ) # Debug log def _initialize_text_splitter(self) -> TextSplitter: - if self.config.method == "recursive": + print( + f"Initializing text splitter with method: {self.config.method}" + ) # Debug log + if self.config.method == Method.RECURSIVE: return RecursiveCharacterTextSplitter( chunk_size=self.config.chunk_size, chunk_overlap=self.config.chunk_overlap, ) + elif self.config.method == Method.BASIC: + # Implement basic method + raise NotImplementedError("Basic method not implemented yet") + elif self.config.method == Method.BY_TITLE: + # Implement by_title method + raise NotImplementedError("By_title method not implemented yet") else: raise ValueError(f"Unsupported method type: {self.config.method}") + def validate(self) -> bool: + return self.config.chunk_size > 0 and self.config.chunk_overlap >= 0 + + def update_config(self, config_override: ChunkingConfig): + if self.config != config_override: + self.config = config_override + self.text_splitter = self._initialize_text_splitter() + async def chunk(self, parsed_document: Any) -> AsyncGenerator[Any, None]: if isinstance(parsed_document, str): chunks = self.text_splitter.create_documents([parsed_document]) @@ -33,3 +54,26 @@ async def chunk(self, parsed_document: Any) -> AsyncGenerator[Any, None]: yield ( chunk.page_content if hasattr(chunk, "page_content") else chunk ) + + async def chunk_with_override( + self, parsed_document: Any, config_override: ChunkingConfig + ) -> AsyncGenerator[Any, None]: + original_config = self.config + original_splitter = self.text_splitter + try: + self.update_config(config_override) + async for chunk in self.chunk(parsed_document): + yield chunk + finally: + self.config = original_config + self.text_splitter = original_splitter + + @classmethod + def with_override( + cls, + original_provider: "R2RChunkingProvider", + config_override: ChunkingConfig, + ) -> "R2RChunkingProvider": + new_config = ChunkingConfig(**original_provider.config.model_dump()) + new_config.update(config_override.model_dump(exclude_unset=True)) + return cls(new_config) diff --git a/r2r/providers/chunking/unstructured_chunking.py b/r2r/providers/chunking/unstructured_chunking.py index ca58913cf..908bfe066 100644 --- a/r2r/providers/chunking/unstructured_chunking.py +++ b/r2r/providers/chunking/unstructured_chunking.py @@ -1,4 +1,4 @@ -from typing import Any, AsyncGenerator +from typing import AsyncGenerator from r2r.base import ChunkingProvider diff --git a/r2r/providers/database/base.py b/r2r/providers/database/base.py new file mode 100644 index 000000000..78e719e88 --- /dev/null +++ b/r2r/providers/database/base.py @@ -0,0 +1,87 @@ +from typing import Any, Optional, Union + +from sqlalchemy import text + +from .vecs import Client + + +def execute_query( + vx: Client, + query: Union[str, text], + params: Optional[dict[str, Any]] = None, +): + with vx.Session() as sess: + if isinstance(query, str): + query = text(query) + result = sess.execute(query, params or {}) + sess.commit() + return result + + +class QueryBuilder: + def __init__(self, table_name: str): + self.table_name = table_name + self.conditions = [] + self.params = {} + self.select_fields = "*" + self.operation = "SELECT" + self.insert_data = None + self.limit_value = None + + def select(self, fields: list[str]): + self.select_fields = ", ".join(fields) + return self + + def insert(self, data: dict): + self.operation = "INSERT" + self.insert_data = data + return self + + def delete(self): + self.operation = "DELETE" + return self + + def where(self, condition: str, **kwargs): + self.conditions.append(condition) + self.params.update(kwargs) + return self + + def limit(self, value: int): + self.limit_value = value + return self + + def build(self): + if self.operation == "SELECT": + query = f"SELECT {self.select_fields} FROM {self.table_name}" + elif self.operation == "INSERT": + columns = ", ".join(self.insert_data.keys()) + values = ", ".join(f":{key}" for key in self.insert_data.keys()) + query = ( + f"INSERT INTO {self.table_name} ({columns}) VALUES ({values})" + ) + self.params.update(self.insert_data) + elif self.operation == "DELETE": + query = f"DELETE FROM {self.table_name}" + else: + raise ValueError(f"Unsupported operation: {self.operation}") + + if self.conditions: + query += " WHERE " + " AND ".join(self.conditions) + + if self.limit_value is not None and self.operation == "SELECT": + query += f" LIMIT {self.limit_value}" + + return query, self.params + + +class DatabaseMixin: + def _get_table_name(self, base_name: str) -> str: + raise NotImplementedError("Subclasses must implement this method") + + def execute_query( + self, query: Union[str, text], params: Optional[dict[str, Any]] = None + ): + raise NotImplementedError("Subclasses must implement this method") + + def create_table(self): + raise NotImplementedError("Subclasses must implement this method") diff --git a/r2r/providers/database/document.py b/r2r/providers/database/document.py new file mode 100644 index 000000000..38dae9536 --- /dev/null +++ b/r2r/providers/database/document.py @@ -0,0 +1,111 @@ +from typing import Optional +from uuid import UUID + +from r2r.base import DocumentInfo, DocumentStatus, DocumentType + +from .base import DatabaseMixin + + +class DocumentMixin(DatabaseMixin): + + def create_table(self): + query = f""" + CREATE TABLE IF NOT EXISTS {self._get_table_name('document_info')} ( + document_id UUID PRIMARY KEY, + group_ids UUID[], + user_id UUID, + type TEXT, + metadata JSONB, + title TEXT, + version TEXT, + size_in_bytes INT, + status TEXT DEFAULT 'processing', + created_at TIMESTAMPTZ DEFAULT NOW(), + updated_at TIMESTAMPTZ DEFAULT NOW() + ); + CREATE INDEX IF NOT EXISTS idx_group_ids_{self.collection_name} + ON {self._get_table_name('document_info')} USING GIN (group_ids); + """ + self.execute_query(query) + + def upsert_documents_overview( + self, documents_overview: list[DocumentInfo] + ) -> None: + for document_info in documents_overview: + query = f""" + INSERT INTO {self._get_table_name('document_info')} + (document_id, group_ids, user_id, type, metadata, title, version, size_in_bytes, status, created_at, updated_at) + VALUES (:document_id, :group_ids, :user_id, :type, :metadata, :title, :version, :size_in_bytes, :status, :created_at, :updated_at) + ON CONFLICT (document_id) DO UPDATE SET + group_ids = EXCLUDED.group_ids, + user_id = EXCLUDED.user_id, + type = EXCLUDED.type, + metadata = EXCLUDED.metadata, + title = EXCLUDED.title, + version = EXCLUDED.version, + size_in_bytes = EXCLUDED.size_in_bytes, + status = EXCLUDED.status, + updated_at = EXCLUDED.updated_at; + """ + self.execute_query(query, document_info.convert_to_db_entry()) + + def delete_from_documents_overview( + self, document_id: str, version: Optional[str] = None + ) -> None: + query = f""" + DELETE FROM {self._get_table_name('document_info')} + WHERE document_id = :document_id + """ + params = {"document_id": document_id} + + if version is not None: + query += " AND version = :version" + params["version"] = version + + self.execute_query(query, params) + + def get_documents_overview( + self, + filter_user_ids: Optional[list[UUID]] = None, + filter_document_ids: Optional[list[UUID]] = None, + filter_group_ids: Optional[list[UUID]] = None, + ): + conditions = [] + params = {} + + if filter_document_ids: + conditions.append("document_id = ANY(:document_ids)") + params["document_ids"] = filter_document_ids + + if filter_user_ids: + conditions.append("user_id = ANY(:user_ids)") + params["user_ids"] = filter_user_ids + + if filter_group_ids: + conditions.append("group_ids && :group_ids") + params["group_ids"] = filter_group_ids + + query = f""" + SELECT document_id, group_ids, user_id, type, metadata, title, version, size_in_bytes, status, created_at, updated_at + FROM {self._get_table_name('document_info')} + """ + if conditions: + query += " WHERE " + " AND ".join(conditions) + + results = self.execute_query(query, params).fetchall() + return [ + DocumentInfo( + id=row[0], + group_ids=row[1], + user_id=row[2], + type=DocumentType(row[3]), + metadata=row[4], + title=row[5], + version=row[6], + size_in_bytes=row[7], + status=DocumentStatus(row[8]), + created_at=row[9], + updated_at=row[10], + ) + for row in results + ] diff --git a/r2r/providers/database/group.py b/r2r/providers/database/group.py new file mode 100644 index 000000000..d3ef324ba --- /dev/null +++ b/r2r/providers/database/group.py @@ -0,0 +1,392 @@ +from datetime import datetime +from typing import Optional +from uuid import UUID + +from r2r.base import R2RException +from r2r.base.abstractions import DocumentInfo, DocumentStatus, DocumentType +from r2r.base.api.models.auth.responses import UserResponse +from r2r.base.api.models.management.responses import ( + GroupOverviewResponse, + GroupResponse, +) + +from .base import DatabaseMixin, QueryBuilder + + +class GroupMixin(DatabaseMixin): + def create_table(self) -> None: + print("creating group table = ", self._get_table_name("groups")) + query = f""" + CREATE TABLE IF NOT EXISTS {self._get_table_name('groups')} ( + group_id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), + name TEXT NOT NULL, + description TEXT, + created_at TIMESTAMPTZ DEFAULT NOW(), + updated_at TIMESTAMPTZ DEFAULT NOW() + ); + """ + self.execute_query(query) + + def group_exists(self, group_id: UUID) -> bool: + """Check if a group exists.""" + query = f""" + SELECT 1 FROM {self._get_table_name('groups')} + WHERE group_id = :group_id + """ + result = self.execute_query(query, {"group_id": group_id}).fetchone() + return bool(result) + + def create_group(self, name: str, description: str = "") -> GroupResponse: + current_time = datetime.utcnow() + query = f""" + INSERT INTO {self._get_table_name('groups')} (name, description, created_at, updated_at) + VALUES (:name, :description, :created_at, :updated_at) + RETURNING group_id, name, description, created_at, updated_at + """ + params = { + "name": name, + "description": description, + "created_at": current_time, + "updated_at": current_time, + } + result = self.execute_query(query, params).fetchone() + if not result: + raise R2RException( + status_code=500, message="Failed to create group" + ) + + return GroupResponse( + group_id=result[0], + name=result[1], + description=result[2], + created_at=result[3], + updated_at=result[4], + ) + + def get_group(self, group_id: UUID) -> GroupResponse: + """Get a group by its ID.""" + if not self.group_exists(group_id): + raise R2RException(status_code=404, message="Group not found") + + query = f""" + SELECT group_id, name, description, created_at, updated_at + FROM {self._get_table_name('groups')} + WHERE group_id = :group_id + """ + result = self.execute_query(query, {"group_id": group_id}).fetchone() + return GroupResponse( + group_id=result[0], + name=result[1], + description=result[2], + created_at=result[3], + updated_at=result[4], + ) + + def update_group( + self, group_id: UUID, name: str, description: str + ) -> GroupResponse: + """Update an existing group.""" + if not self.group_exists(group_id): + raise R2RException(status_code=404, message="Group not found") + + query = f""" + UPDATE {self._get_table_name('groups')} + SET name = :name, description = :description, updated_at = NOW() + WHERE group_id = :group_id + RETURNING group_id, name, description, created_at, updated_at + """ + result = self.execute_query( + query, + {"group_id": group_id, "name": name, "description": description}, + ).fetchone() + return GroupResponse( + group_id=result[0], + name=result[1], + description=result[2], + created_at=result[3], + updated_at=result[4], + ) + + def delete_group(self, group_id: UUID) -> None: + query = f""" + DELETE FROM {self._get_table_name('groups')} + WHERE group_id = :group_id + RETURNING group_id + """ + result = self.execute_query(query, {"group_id": group_id}).fetchone() + if not result: + raise R2RException(status_code=404, message="Group not found") + return None + + def list_groups( + self, offset: int = 0, limit: int = 100 + ) -> list[GroupResponse]: + """List groups with pagination.""" + query = f""" + SELECT group_id, name, description, created_at, updated_at + FROM {self._get_table_name('groups')} + ORDER BY name + OFFSET :offset + LIMIT :limit + """ + results = self.execute_query( + query, {"offset": offset, "limit": limit} + ).fetchall() + if not results: + return [] + return [ + GroupResponse( + group_id=row[0], + name=row[1], + description=row[2], + created_at=row[3], + updated_at=row[4], + ) + for row in results + ] + + def get_groups_by_ids(self, group_ids: list[UUID]) -> list[GroupResponse]: + query, params = ( + QueryBuilder(self._get_table_name("groups")) + .select( + ["group_id", "name", "description", "created_at", "updated_at"] + ) + .where("group_id = ANY(:group_ids)", group_ids=group_ids) + .build() + ) + results = self.execute_query(query, params).fetchall() + if len(results) != len(group_ids): + raise R2RException( + status_code=404, + message=f"These groups were not found: {set(group_ids) - set([row[0] for row in results])}", + ) + return [ + GroupResponse( + group_id=row[0], + name=row[1], + description=row[2], + created_at=row[3], + updated_at=row[4], + ) + for row in results + ] + + def add_user_to_group(self, user_id: UUID, group_id: UUID) -> bool: + """Add a user to a group.""" + if not self.group_exists(group_id): + raise R2RException(status_code=404, message="Group not found") + + query = f""" + UPDATE {self._get_table_name('users')} + SET group_ids = array_append(group_ids, :group_id) + WHERE user_id = :user_id AND NOT (:group_id = ANY(group_ids)) + RETURNING user_id + """ + result = self.execute_query( + query, {"user_id": user_id, "group_id": group_id} + ).fetchone() + return bool(result) + + def remove_user_from_group(self, user_id: UUID, group_id: UUID) -> None: + """Remove a user from a group.""" + if not self.group_exists(group_id): + raise R2RException(status_code=404, message="Group not found") + + query = f""" + UPDATE {self._get_table_name('users')} + SET group_ids = array_remove(group_ids, :group_id) + WHERE user_id = :user_id AND :group_id = ANY(group_ids) + RETURNING user_id + """ + result = self.execute_query( + query, {"user_id": user_id, "group_id": group_id} + ).fetchone() + if not result: + raise R2RException( + status_code=404, + message="User is not a member of the specified group", + ) + + def get_group_count(self) -> int: + query = f""" + SELECT COUNT(*) FROM {self._get_table_name('groups')} + """ + result = self.execute_query(query).fetchone() + return result[0] + + def get_users_in_group( + self, group_id: UUID, offset: int = 0, limit: int = 100 + ) -> list[UserResponse]: + """ + Get all users in a specific group with pagination. + + Args: + group_id (UUID): The ID of the group to get users from. + offset (int): The number of users to skip. + limit (int): The maximum number of users to return. + + Returns: + List[UserResponse]: A list of UserResponse objects representing the users in the group. + + Raises: + R2RException: If the group doesn't exist. + """ + if not self.group_exists(group_id): + raise R2RException(status_code=404, message="Group not found") + + query = f""" + SELECT u.user_id, u.email, u.is_active, u.is_superuser, u.created_at, u.updated_at, + u.is_verified, u.group_ids, u.name, u.bio, u.profile_picture + FROM {self._get_table_name('users')} u + WHERE :group_id = ANY(u.group_ids) + ORDER BY u.name + OFFSET :offset + LIMIT :limit + """ + results = self.execute_query( + query, {"group_id": group_id, "offset": offset, "limit": limit} + ).fetchall() + + return [ + UserResponse( + id=row[0], + email=row[1], + is_active=row[2], + is_superuser=row[3], + created_at=row[4], + updated_at=row[5], + is_verified=row[6], + group_ids=row[7], + name=row[8], + bio=row[9], + profile_picture=row[10], + hashed_password=None, + verification_code_expiry=None, + ) + for row in results + ] + + def get_documents_in_group( + self, group_id: UUID, offset: int = 0, limit: int = 100 + ) -> list[DocumentInfo]: + """ + Get all documents in a specific group with pagination. + + Args: + group_id (UUID): The ID of the group to get documents from. + offset (int): The number of documents to skip. + limit (int): The maximum number of documents to return. + + Returns: + List[DocumentInfo]: A list of DocumentInfo objects representing the documents in the group. + + Raises: + R2RException: If the group doesn't exist. + """ + if not self.group_exists(group_id): + raise R2RException(status_code=404, message="Group not found") + + query = f""" + SELECT d.document_id, d.group_ids, d.user_id, d.type, d.metadata, d.title, + d.version, d.size_in_bytes, d.status, d.created_at, d.updated_at + FROM {self._get_table_name('document_info')} d + WHERE :group_id = ANY(d.group_ids) + ORDER BY d.created_at DESC + OFFSET :offset + LIMIT :limit + """ + results = self.execute_query( + query, {"group_id": group_id, "offset": offset, "limit": limit} + ).fetchall() + + return [ + DocumentInfo( + id=row[0], + group_ids=row[1], + user_id=row[2], + type=DocumentType(row[3]), + metadata=row[4], + title=row[5], + version=row[6], + size_in_bytes=row[7], + status=DocumentStatus(row[8]), + created_at=row[9], + updated_at=row[10], + ) + for row in results + ] + + def get_groups_overview( + self, + group_ids: Optional[list[UUID]] = None, + offset: int = 0, + limit: int = 100, + ) -> list[GroupOverviewResponse]: + """Get an overview of groups, optionally filtered by group IDs, with pagination.""" + query = f""" + WITH group_overview AS ( + SELECT g.group_id, g.name, g.description, g.created_at, g.updated_at, + COUNT(DISTINCT u.user_id) AS user_count, + COUNT(DISTINCT d.document_id) AS document_count + FROM {self._get_table_name('groups')} g + LEFT JOIN {self._get_table_name('users')} u ON g.group_id = ANY(u.group_ids) + LEFT JOIN {self._get_table_name('document_info')} d ON g.group_id = ANY(d.group_ids) + """ + params = {"offset": offset, "limit": limit} + if group_ids: + query += " WHERE g.group_id = ANY(:group_ids)" + params["group_ids"] = group_ids + query += """ + GROUP BY g.group_id, g.name, g.description, g.created_at, g.updated_at + ) + SELECT * FROM group_overview + ORDER BY name + OFFSET :offset + LIMIT :limit + """ + + results = self.execute_query(query, params).fetchall() + if not results: + return [] + return [ + GroupOverviewResponse( + group_id=result[0], + name=result[1], + description=result[2], + created_at=result[3], + updated_at=result[4], + user_count=result[5], + document_count=result[6], + ) + for result in results + ] + + def get_groups_for_user( + self, user_id: UUID, offset: int = 0, limit: int = 100 + ) -> list[GroupResponse]: + query = f""" + SELECT g.group_id, g.name, g.description, g.created_at, g.updated_at + FROM {self._get_table_name('groups')} g + JOIN {self._get_table_name('users')} u ON g.group_id = ANY(u.group_ids) + WHERE u.user_id = :user_id + ORDER BY g.name + OFFSET :offset + LIMIT :limit + """ + results = self.execute_query( + query, {"user_id": user_id, "offset": offset, "limit": limit} + ).fetchall() + + if not results: + return [] + + return [ + GroupResponse( + group_id=row[0], + name=row[1], + description=row[2], + created_at=row[3], + updated_at=row[4], + ) + for row in results + ] diff --git a/r2r/providers/database/postgres.py b/r2r/providers/database/postgres.py index be7b373a8..290abaeca 100644 --- a/r2r/providers/database/postgres.py +++ b/r2r/providers/database/postgres.py @@ -1,1055 +1,22 @@ -import json import logging import os -import time -from datetime import datetime, timedelta -from typing import Literal, Optional, Union -from uuid import UUID - -from sqlalchemy import exc, text -from sqlalchemy.engine.url import make_url +from typing import Optional from r2r.base import ( CryptoProvider, DatabaseConfig, DatabaseProvider, - DocumentInfo, - RelationalDatabaseProvider, - User, - UserCreate, - VectorDatabaseProvider, - VectorEntry, - VectorSearchResult, - generate_id_from_label, + RelationalDBProvider, + VectorDBProvider, ) -from r2r.base.abstractions.user import UserStats -from .vecs import Client, Collection, create_client +from .relational import PostgresRelationalDBProvider +from .vecs import Client, create_client +from .vector import PostgresVectorDBProvider logger = logging.getLogger(__name__) -class PostgresVectorDBProvider(VectorDatabaseProvider): - def __init__(self, config: DatabaseConfig, *args, **kwargs): - super().__init__(config) - self.collection: Optional[Collection] = None - self.vx: Client = kwargs.get("vx", None) - if not self.vx: - raise ValueError( - "Please provide a valid `vx` client to the `PostgresVectorDBProvider`." - ) - self.collection_name = kwargs.get("collection_name", None) - if not self.collection_name: - raise ValueError( - "Please provide a valid `collection_name` to the `PostgresVectorDBProvider`." - ) - dimension = kwargs.get("dimension", None) - if not dimension: - raise ValueError( - "Please provide a valid `dimension` to the `PostgresVectorDBProvider`." - ) - - # Check if a complete Postgres URI is provided - postgres_uri = self.config.extra_fields.get( - "postgres_uri" - ) or os.getenv("POSTGRES_URI") - - if postgres_uri: - # Log loudly that Postgres URI is being used - logger.warning("=" * 50) - logger.warning( - "ATTENTION: Using provided Postgres URI for connection" - ) - logger.warning("=" * 50) - - # Validate and use the provided URI - try: - parsed_uri = make_url(postgres_uri) - if not all([parsed_uri.username, parsed_uri.database]): - raise ValueError( - "The provided Postgres URI is missing required components." - ) - DB_CONNECTION = postgres_uri - - # Log the sanitized URI (without password) - sanitized_uri = parsed_uri.set(password="*****") - logger.info(f"Connecting using URI: {sanitized_uri}") - except Exception as e: - raise ValueError(f"Invalid Postgres URI provided: {e}") - else: - # Fall back to existing logic for individual connection parameters - user = self.config.extra_fields.get("user", None) or os.getenv( - "POSTGRES_USER" - ) - password = self.config.extra_fields.get( - "password", None - ) or os.getenv("POSTGRES_PASSWORD") - host = self.config.extra_fields.get("host", None) or os.getenv( - "POSTGRES_HOST" - ) - port = self.config.extra_fields.get("port", None) or os.getenv( - "POSTGRES_PORT" - ) - db_name = self.config.extra_fields.get( - "db_name", None - ) or os.getenv("POSTGRES_DBNAME") - - if not all([user, password, host, db_name]): - raise ValueError( - "Error, please set the POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_HOST, POSTGRES_DBNAME environment variables or provide them in the config." - ) - - # Check if it's a Unix socket connection - if host.startswith("/") and not port: - DB_CONNECTION = ( - f"postgresql://{user}:{password}@/{db_name}?host={host}" - ) - logger.info("Using Unix socket connection") - else: - DB_CONNECTION = ( - f"postgresql://{user}:{password}@{host}:{port}/{db_name}" - ) - logger.info("Using TCP connection") - - # The rest of the initialization remains the same - try: - self.vx: Client = create_client(DB_CONNECTION) - except Exception as e: - raise ValueError( - f"Error {e} occurred while attempting to connect to the pgvector provider with {DB_CONNECTION}." - ) - - self.collection_name = self.config.extra_fields.get( - "vecs_collection" - ) or os.getenv("POSTGRES_VECS_COLLECTION") - if not self.collection_name: - raise ValueError( - "Error, please set a valid POSTGRES_VECS_COLLECTION environment variable or set a 'vecs_collection' in the 'database' settings of your `r2r.toml`." - ) - - self.collection: Optional[Collection] = None - self._initialize_vector_db(dimension) - self._create_hybrid_search_function() - logger.info( - f"Successfully initialized PGVectorDB with collection: {self.collection_name}" - ) - - def _initialize_vector_db(self, dimension: int) -> None: - self.collection = self.vx.get_or_create_collection( - name=self.collection_name, dimension=dimension - ) - - def _create_hybrid_search_function(self): - hybrid_search_function = f""" - CREATE OR REPLACE FUNCTION hybrid_search_{self.collection_name}( - query_text TEXT, - query_embedding VECTOR(512), - match_limit INT, - full_text_weight FLOAT = 1, - semantic_weight FLOAT = 1, - rrf_k INT = 50, - filter_condition JSONB = NULL - ) - RETURNS SETOF vecs."{self.collection_name}" - LANGUAGE sql - AS $$ - WITH full_text AS ( - SELECT - id, - ROW_NUMBER() OVER (ORDER BY ts_rank(to_tsvector('english', metadata->>'text'), websearch_to_tsquery(query_text)) DESC) AS rank_ix - FROM vecs."{self.collection_name}" - WHERE to_tsvector('english', metadata->>'text') @@ websearch_to_tsquery(query_text) - AND (filter_condition IS NULL OR (metadata @> filter_condition)) - ORDER BY rank_ix - LIMIT LEAST(match_limit, 30) * 2 - ), - semantic AS ( - SELECT - id, - ROW_NUMBER() OVER (ORDER BY vec <#> query_embedding) AS rank_ix - FROM vecs."{self.collection_name}" - WHERE filter_condition IS NULL OR (metadata @> filter_condition) - ORDER BY rank_ix - LIMIT LEAST(match_limit, 30) * 2 - ) - SELECT - vecs."{self.collection_name}".* - FROM - full_text - FULL OUTER JOIN semantic - ON full_text.id = semantic.id - JOIN vecs."{self.collection_name}" - ON vecs."{self.collection_name}".id = COALESCE(full_text.id, semantic.id) - ORDER BY - COALESCE(1.0 / (rrf_k + full_text.rank_ix), 0.0) * full_text_weight + - COALESCE(1.0 / (rrf_k + semantic.rank_ix), 0.0) * semantic_weight - DESC - LIMIT - LEAST(match_limit, 30); - $$; - """ - retry_attempts = 5 - for attempt in range(retry_attempts): - try: - with self.vx.Session() as sess: - # Acquire an advisory lock - sess.execute(text("SELECT pg_advisory_lock(123456789)")) - try: - sess.execute(text(hybrid_search_function)) - sess.commit() - finally: - # Release the advisory lock - sess.execute( - text("SELECT pg_advisory_unlock(123456789)") - ) - break # Break the loop if successful - except exc.InternalError as e: - if "tuple concurrently updated" in str(e): - time.sleep(2**attempt) # Exponential backoff - else: - raise # Re-raise the exception if it's not a concurrency issue - else: - raise RuntimeError( - "Failed to create hybrid search function after multiple attempts" - ) - - def copy(self, entry: VectorEntry, commit=True) -> None: - if self.collection is None: - raise ValueError( - "Please call `initialize_collection` before attempting to run `copy`." - ) - - serializeable_entry = entry.to_serializable() - - self.collection.copy( - records=[ - ( - serializeable_entry["id"], - serializeable_entry["vector"], - serializeable_entry["metadata"], - ) - ] - ) - - def copy_entries( - self, entries: list[VectorEntry], commit: bool = True - ) -> None: - if self.collection is None: - raise ValueError( - "Please call `initialize_collection` before attempting to run `copy_entries`." - ) - - self.collection.copy( - records=[ - ( - str(entry.id), - entry.vector.data, - entry.to_serializable()["metadata"], - ) - for entry in entries - ] - ) - - def upsert(self, entry: VectorEntry, commit=True) -> None: - if self.collection is None: - raise ValueError( - "Please call `initialize_collection` before attempting to run `upsert`." - ) - - self.collection.upsert( - records=[ - ( - str(entry.id), - entry.vector.data, - entry.to_serializable()["metadata"], - ) - ] - ) - - def upsert_entries( - self, entries: list[VectorEntry], commit: bool = True - ) -> None: - if self.collection is None: - raise ValueError( - "Please call `initialize_collection` before attempting to run `upsert_entries`." - ) - - self.collection.upsert( - records=[ - ( - str(entry.id), - entry.vector.data, - entry.to_serializable()["metadata"], - ) - for entry in entries - ] - ) - - def search( - self, - query_vector: list[float], - filters: dict[str, Union[bool, int, str]] = {}, - limit: int = 10, - *args, - **kwargs, - ) -> list[VectorSearchResult]: - if self.collection is None: - raise ValueError( - "Please call `initialize_collection` before attempting to run `search`." - ) - measure = kwargs.get("measure", "cosine_distance") - mapped_filters = { - key: {"$eq": value} for key, value in filters.items() - } - - return [ - VectorSearchResult(id=ele[0], score=float(1 - ele[1]), metadata=ele[2]) # type: ignore - for ele in self.collection.query( - data=query_vector, - limit=limit, - filters=mapped_filters, - measure=measure, - include_value=True, - include_metadata=True, - ) - ] - - def hybrid_search( - self, - query_text: str, - query_vector: list[float], - limit: int = 10, - filters: Optional[dict[str, Union[bool, int, str]]] = None, - full_text_weight: float = 1.0, - semantic_weight: float = 1.0, - rrf_k: int = 20, - *args, - **kwargs, - ) -> list[VectorSearchResult]: - if self.collection is None: - raise ValueError( - "Please call `initialize_collection` before attempting to run `hybrid_search`." - ) - - # Convert filters to a JSON-compatible format - filter_condition = None - if filters: - filter_condition = json.dumps(filters) - - query = text( - f""" - SELECT * FROM hybrid_search_{self.collection_name}( - cast(:query_text as TEXT), cast(:query_embedding as VECTOR), cast(:match_limit as INT), - cast(:full_text_weight as FLOAT), cast(:semantic_weight as FLOAT), cast(:rrf_k as INT), - cast(:filter_condition as JSONB) - ) - """ - ) - - params = { - "query_text": str(query_text), - "query_embedding": list(query_vector), - "match_limit": limit, - "full_text_weight": full_text_weight, - "semantic_weight": semantic_weight, - "rrf_k": rrf_k, - "filter_condition": filter_condition, - } - - with self.vx.Session() as session: - result = session.execute(query, params).fetchall() - return [ - VectorSearchResult(id=row[0], score=1.0, metadata=row[-1]) - for row in result - ] - - def create_index(self, index_type, column_name, index_options): - self.collection.create_index() - - def delete_by_metadata( - self, - metadata_fields: list[str], - metadata_values: list[Union[bool, int, str]], - logic: Literal["AND", "OR"] = "AND", - ) -> list[str]: - if logic == "OR": - raise ValueError( - "OR logic is still being tested before official support for `delete_by_metadata` in pgvector." - ) - if self.collection is None: - raise ValueError( - "Please call `initialize_collection` before attempting to run `delete_by_metadata`." - ) - - if len(metadata_fields) != len(metadata_values): - raise ValueError( - "The number of metadata fields must match the number of metadata values." - ) - - # Construct the filter - if logic == "AND": - filters = { - k: {"$eq": v} for k, v in zip(metadata_fields, metadata_values) - } - else: # OR logic - # TODO - Test 'or' logic and remove check above - filters = { - "$or": [ - {k: {"$eq": v}} - for k, v in zip(metadata_fields, metadata_values) - ] - } - return self.collection.delete(filters=filters) - - def get_metadatas( - self, - metadata_fields: list[str], - filter_field: Optional[str] = None, - filter_value: Optional[Union[bool, int, str]] = None, - ) -> list[dict]: - if self.collection is None: - raise ValueError( - "Please call `initialize_collection` before attempting to run `get_metadatas`." - ) - - results = {tuple(metadata_fields): {}} - for field in metadata_fields: - unique_values = self.collection.get_unique_metadata_values( - field=field, - filter_field=filter_field, - filter_value=filter_value, - ) - for value in unique_values: - if value not in results: - results[value] = {} - results[value][field] = value - - return [ - results[key] for key in results if key != tuple(metadata_fields) - ] - - def get_document_chunks(self, document_id: str) -> list[dict]: - if not self.collection: - raise ValueError("Collection is not initialized.") - - table_name = self.collection.table.name - query = text( - f""" - SELECT metadata - FROM vecs."{table_name}" - WHERE metadata->>'document_id' = :document_id - ORDER BY CAST(metadata->>'chunk_order' AS INTEGER) - """ - ) - - params = {"document_id": document_id} - - with self.vx.Session() as sess: - results = sess.execute(query, params).fetchall() - return [result[0] for result in results] - - -class PostgresRelationalDBProvider(RelationalDatabaseProvider): - def __init__( - self, - config: DatabaseConfig, - crypto_provider: Optional[CryptoProvider], - *args, - **kwargs, - ): - super().__init__(config) - self.vx: Client = kwargs.get("vx", None) - self.crypto_provider = crypto_provider - if not self.vx: - raise ValueError( - "Please provide a valid `vx` client to the `PostgresRelationalDBProvider`." - ) - self.collection_name = kwargs.get("collection_name", None) - if not self.collection_name: - raise ValueError( - "Please provide a valid `collection_name` to the `PostgresRelationalDBProvider`." - ) - self._initialize_relational_db() - - def _initialize_relational_db(self): - with self.vx.Session() as sess: - with sess.begin(): - try: - # Enable uuid-ossp extension - sess.execute( - text('CREATE EXTENSION IF NOT EXISTS "uuid-ossp";') - ) - except exc.ProgrammingError as e: - logger.error(f"Error enabling uuid-ossp extension: {e}") - raise - - # Create the table if it doesn't exist - create_table_query = f""" - CREATE TABLE IF NOT EXISTS document_info_{self.collection_name} ( - document_id UUID PRIMARY KEY, - title TEXT, - user_id UUID NULL, - version TEXT, - size_in_bytes INT, - created_at TIMESTAMPTZ DEFAULT NOW(), - updated_at TIMESTAMPTZ DEFAULT NOW(), - metadata JSONB, - status TEXT DEFAULT 'processing' - ); - """ - sess.execute(text(create_table_query)) - - # Create users table - query = f""" - CREATE TABLE IF NOT EXISTS users_{self.collection_name} ( - id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), - email TEXT UNIQUE NOT NULL, - hashed_password TEXT NOT NULL, - is_superuser BOOLEAN DEFAULT FALSE, - is_active BOOLEAN DEFAULT TRUE, - is_verified BOOLEAN DEFAULT FALSE, - verification_code TEXT, - verification_code_expiry TIMESTAMPTZ, - name TEXT, - bio TEXT, - profile_picture TEXT, - reset_token TEXT, - reset_token_expiry TIMESTAMPTZ, - created_at TIMESTAMPTZ DEFAULT NOW(), - updated_at TIMESTAMPTZ DEFAULT NOW() - ); - """ - sess.execute(text(query)) - - # Create blacklisted tokens table - query = f""" - CREATE TABLE IF NOT EXISTS blacklisted_tokens_{self.collection_name} ( - id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), - token TEXT NOT NULL, - blacklisted_at TIMESTAMPTZ DEFAULT NOW() - ); - CREATE INDEX IF NOT EXISTS idx_blacklisted_tokens_{self.collection_name}_token - ON blacklisted_tokens_{self.collection_name} (token); - CREATE INDEX IF NOT EXISTS idx_blacklisted_tokens_{self.collection_name}_blacklisted_at - ON blacklisted_tokens_{self.collection_name} (blacklisted_at); - """ - sess.execute(text(query)) - - sess.commit() - - def upsert_documents_overview( - self, documents_overview: list[DocumentInfo] - ) -> None: - for document_info in documents_overview: - db_entry = document_info.convert_to_db_entry() - - # Convert 'None' string to None type for user_id - if db_entry["user_id"] == "None": - db_entry["user_id"] = None - - query = text( - f""" - INSERT INTO document_info_{self.collection_name} (document_id, title, user_id, version, created_at, updated_at, size_in_bytes, metadata, status) - VALUES (:document_id, :title, :user_id, :version, :created_at, :updated_at, :size_in_bytes, :metadata, :status) - ON CONFLICT (document_id) DO UPDATE SET - title = EXCLUDED.title, - user_id = EXCLUDED.user_id, - version = EXCLUDED.version, - updated_at = EXCLUDED.updated_at, - size_in_bytes = EXCLUDED.size_in_bytes, - metadata = EXCLUDED.metadata, - status = EXCLUDED.status; - """ - ) - with self.vx.Session() as sess: - sess.execute(query, db_entry) - sess.commit() - - def delete_from_documents_overview( - self, document_id: str, version: Optional[str] = None - ) -> None: - query = f""" - DELETE FROM document_info_{self.collection_name} - WHERE document_id = :document_id - """ - params = {"document_id": document_id} - - if version is not None: - query += " AND version = :version" - params["version"] = version - - with self.vx.Session() as sess: - with sess.begin(): - sess.execute(text(query), params) - sess.commit() - - def get_documents_overview( - self, - filter_document_ids: Optional[list[str]] = None, - filter_user_ids: Optional[list[str]] = None, - ): - conditions = [] - params = {} - - if filter_document_ids: - placeholders = ", ".join( - f":doc_id_{i}" for i in range(len(filter_document_ids)) - ) - conditions.append(f"document_id IN ({placeholders})") - params.update( - { - f"doc_id_{i}": str(document_id) - for i, document_id in enumerate(filter_document_ids) - } - ) - if filter_user_ids: - placeholders = ", ".join( - f":user_id_{i}" for i in range(len(filter_user_ids)) - ) - conditions.append(f"user_id IN ({placeholders})") - params.update( - { - f"user_id_{i}": str(user_id) - for i, user_id in enumerate(filter_user_ids) - } - ) - - query = f""" - SELECT document_id, title, user_id, version, size_in_bytes, created_at, updated_at, metadata, status - FROM document_info_{self.collection_name} - """ - if conditions: - query += " WHERE " + " AND ".join(conditions) - - with self.vx.Session() as sess: - results = sess.execute(text(query), params).fetchall() - return [ - DocumentInfo( - document_id=row[0], - title=row[1], - user_id=row[2], - version=row[3], - size_in_bytes=row[4], - created_at=row[5], - updated_at=row[6], - metadata=row[7], - status=row[8], - ) - for row in results - ] - - # TODO - Deprecate this method - def get_users_overview(self, user_ids: Optional[list[str]] = None): - user_ids_condition = "" - params = {} - if user_ids: - user_ids_condition = "WHERE user_id IN :user_ids" - params["user_ids"] = tuple( - map(str, user_ids) - ) # Convert UUIDs to strings - - query = f""" - SELECT user_id, COUNT(document_id) AS num_files, SUM(size_in_bytes) AS total_size_in_bytes, ARRAY_AGG(document_id) AS document_ids - FROM document_info_{self.collection_name} - {user_ids_condition} - GROUP BY user_id - """ - - with self.vx.Session() as sess: - results = sess.execute(text(query), params).fetchall() - return [ - UserStats( - user_id=row[0], - num_files=row[1], - total_size_in_bytes=row[2], - document_ids=row[3], - ) - for row in results - if row[0] is not None - ] - - def create_user(self, user: UserCreate) -> User: - hashed_password = self.crypto_provider.get_password_hash(user.password) - query = text( - f""" - INSERT INTO users_{self.collection_name} - (email, id, hashed_password) - VALUES (:email, :id, :hashed_password) - RETURNING id, email, is_superuser, is_active, is_verified, created_at, updated_at - """ - ) - - with self.vx.Session() as sess: - result = sess.execute( - query, - { - "email": user.email, - "id": generate_id_from_label(user.email), - "hashed_password": hashed_password, - }, - ) - user_data = result.fetchone() - sess.commit() - - return User( - id=user_data[0], - email=user_data[1], - is_superuser=user_data[2], - is_active=user_data[3], - is_verified=user_data[4], - created_at=user_data[5], - updated_at=user_data[6], - hashed_password=hashed_password, - ) - - def get_user_by_email(self, email: str) -> Optional[User]: - query = text( - f""" - SELECT id, email, hashed_password, is_superuser, is_active, is_verified, created_at, updated_at - FROM users_{self.collection_name} - WHERE email = :email - """ - ) - - with self.vx.Session() as sess: - result = sess.execute(query, {"email": email}) - user_data = result.fetchone() - - if user_data: - return User( - id=user_data[0], - email=user_data[1], - # password="", # We don't return the hashed password - hashed_password=user_data[2], - is_superuser=user_data[3], - is_active=user_data[4], - is_verified=user_data[5], - created_at=user_data[6], - updated_at=user_data[7], - ) - return None - - def store_verification_code( - self, user_id: UUID, verification_code: str, expiry: datetime - ): - query = text( - f""" - UPDATE users_{self.collection_name} - SET verification_code = :code, verification_code_expiry = :expiry - WHERE id = :user_id - """ - ) - - with self.vx.Session() as sess: - sess.execute( - query, - { - "code": verification_code, - "expiry": expiry, - "user_id": user_id, - }, - ) - sess.commit() - - def get_user_id_by_verification_code( - self, verification_code: str - ) -> Optional[UUID]: - query = text( - f""" - SELECT id FROM users_{self.collection_name} - WHERE verification_code = :code AND verification_code_expiry > NOW() - """ - ) - - with self.vx.Session() as sess: - result = sess.execute(query, {"code": verification_code}) - user_data = result.fetchone() - - return user_data[0] if user_data else None - - def mark_user_as_verified(self, user_id: UUID): - query = text( - f""" - UPDATE users_{self.collection_name} - SET is_verified = TRUE, verification_code = NULL, verification_code_expiry = NULL - WHERE id = :user_id - """ - ) - - with self.vx.Session() as sess: - sess.execute(query, {"user_id": user_id}) - sess.commit() - - def mark_user_as_superuser(self, user_id: UUID): - query = text( - f""" - UPDATE users_{self.collection_name} - SET is_superuser = TRUE, is_verified = TRUE, verification_code = NULL, verification_code_expiry = NULL - WHERE id = :user_id - """ - ) - - with self.vx.Session() as sess: - sess.execute(query, {"user_id": user_id}) - sess.commit() - - def remove_verification_code(self, verification_code: str): - query = text( - f""" - UPDATE users_{self.collection_name} - SET verification_code = NULL, verification_code_expiry = NULL - WHERE verification_code = :code - """ - ) - - with self.vx.Session() as sess: - sess.execute(query, {"code": verification_code}) - sess.commit() - - def delete_user(self, user_id: UUID): - query = text( - f""" - DELETE FROM users_{self.collection_name} - WHERE id = :user_id - """ - ) - - with self.vx.Session() as sess: - sess.execute(query, {"user_id": user_id}) - sess.commit() - - def get_all_users(self) -> list[User]: - query = text( - f""" - SELECT id, email, is_superuser, is_active, is_verified, created_at, updated_at - FROM users_{self.collection_name} - """ - ) - - with self.vx.Session() as sess: - result = sess.execute(query) - users_data = result.fetchall() - - return [ - User( - id=user_data[0], - email=user_data[1], - hashed_password="null", - is_superuser=user_data[2], - is_active=user_data[3], - is_verified=user_data[4], - created_at=user_data[5], - updated_at=user_data[6], - ) - for user_data in users_data - ] - - def expire_verification_code(self, user_id): - query = text( - f""" - UPDATE users_{self.collection_name} - SET verification_code_expiry = NOW() - INTERVAL '365 day' - WHERE id = :user_id - """ - ) - with self.vx.Session() as sess: - sess.execute(query, {"user_id": user_id}) - sess.commit() - - def store_reset_token( - self, user_id: UUID, reset_token: str, expiry: datetime - ): - query = text( - f""" - UPDATE users_{self.collection_name} - SET reset_token = :token, reset_token_expiry = :expiry - WHERE id = :user_id - """ - ) - - with self.vx.Session() as sess: - sess.execute( - query, - { - "token": reset_token, - "expiry": expiry, - "user_id": user_id, - }, - ) - sess.commit() - - def get_user_id_by_reset_token(self, reset_token: str) -> Optional[UUID]: - query = text( - f""" - SELECT id FROM users_{self.collection_name} - WHERE reset_token = :token AND reset_token_expiry > NOW() - """ - ) - - with self.vx.Session() as sess: - result = sess.execute(query, {"token": reset_token}) - user_data = result.fetchone() - - return user_data[0] if user_data else None - - def remove_reset_token(self, user_id: UUID): - query = text( - f""" - UPDATE users_{self.collection_name} - SET reset_token = NULL, reset_token_expiry = NULL - WHERE id = :user_id - """ - ) - - with self.vx.Session() as sess: - sess.execute(query, {"user_id": user_id}) - sess.commit() - - def blacklist_token(self, token: str, current_time: datetime = None): - if current_time is None: - current_time = datetime.utcnow() - query = text( - f""" - INSERT INTO blacklisted_tokens_{self.collection_name} (token, blacklisted_at) - VALUES (:token, :blacklisted_at) - """ - ) - - with self.vx.Session() as sess: - sess.execute( - query, {"token": token, "blacklisted_at": current_time} - ) - sess.commit() - - def is_token_blacklisted(self, token: str) -> bool: - query = text( - f""" - SELECT EXISTS( - SELECT 1 FROM blacklisted_tokens_{self.collection_name} - WHERE token = :token - ) - """ - ) - - with self.vx.Session() as sess: - result = sess.execute(query, {"token": token}) - return result.scalar() - - def clean_expired_blacklisted_tokens( - self, - max_age_hours: int = 7 * 24, - current_time: Optional[datetime] = None, - ): - if current_time is None: - current_time = datetime.utcnow() - expiry_time = current_time - timedelta(hours=max_age_hours) - query = text( - f""" - DELETE FROM blacklisted_tokens_{self.collection_name} - WHERE blacklisted_at < :expiry_time - """ - ) - - with self.vx.Session() as sess: - sess.execute(query, {"expiry_time": expiry_time}) - sess.commit() - - # Modify existing methods to include new profile fields - - def get_user_by_id(self, user_id: UUID) -> Optional[User]: - query = text( - f""" - SELECT id, email, hashed_password, is_superuser, is_active, is_verified, - created_at, updated_at, name, profile_picture, bio - FROM users_{self.collection_name} - WHERE id = :user_id - """ - ) - - with self.vx.Session() as sess: - result = sess.execute(query, {"user_id": user_id}) - user_data = result.fetchone() - - if user_data: - return User( - id=user_data[0], - email=user_data[1], - hashed_password=user_data[2], - is_superuser=user_data[3], - is_active=user_data[4], - is_verified=user_data[5], - created_at=user_data[6], - updated_at=user_data[7], - name=user_data[8], - profile_picture=user_data[9], - bio=user_data[10], - ) - return None - - def update_user(self, user: User) -> User: - query = text( - f""" - UPDATE users_{self.collection_name} - SET email = :email, is_superuser = :is_superuser, is_active = :is_active, - is_verified = :is_verified, updated_at = NOW(), name = :name, - profile_picture = :profile_picture, bio = :bio - WHERE id = :user_id - RETURNING id, email, is_superuser, is_active, is_verified, created_at, - updated_at, name, profile_picture, bio - """ - ) - - with self.vx.Session() as sess: - result = sess.execute( - query, - { - "email": user.email, - "is_superuser": user.is_superuser, - "is_active": user.is_active, - "is_verified": user.is_verified, - "user_id": user.id, - "name": user.name, - "profile_picture": user.profile_picture, - "bio": user.bio, - }, - ) - updated_user_data = result.fetchone() - sess.commit() - - return User( - id=updated_user_data[0], - email=updated_user_data[1], - hashed_password="null", - is_superuser=updated_user_data[2], - is_active=updated_user_data[3], - is_verified=updated_user_data[4], - created_at=updated_user_data[5], - updated_at=updated_user_data[6], - name=updated_user_data[7], - profile_picture=updated_user_data[8], - bio=updated_user_data[9], - ) - - def update_user_password(self, user_id: UUID, new_hashed_password: str): - query = text( - f""" - UPDATE users_{self.collection_name} - SET hashed_password = :new_hashed_password, updated_at = NOW() - WHERE id = :user_id - """ - ) - - with self.vx.Session() as sess: - sess.execute( - query, - { - "user_id": user_id, - "new_hashed_password": new_hashed_password, - }, - ) - sess.commit() - - class PostgresDBProvider(DatabaseProvider): def __init__( self, @@ -1125,7 +92,7 @@ def __init__( self.crypto_provider = crypto_provider super().__init__(config) - def _initialize_vector_db(self) -> VectorDatabaseProvider: + def _initialize_vector_db(self) -> VectorDBProvider: return PostgresVectorDBProvider( self.config, vx=self.vx, @@ -1133,10 +100,11 @@ def _initialize_vector_db(self) -> VectorDatabaseProvider: dimension=self.vector_db_dimension, ) - def _initialize_relational_db(self) -> RelationalDatabaseProvider: - return PostgresRelationalDBProvider( + def _initialize_relational_db(self) -> RelationalDBProvider: + provider = PostgresRelationalDBProvider( self.config, vx=self.vx, crypto_provider=self.crypto_provider, collection_name=self.collection_name, ) + return provider diff --git a/r2r/providers/database/relational.py b/r2r/providers/database/relational.py new file mode 100644 index 000000000..0fb2769e3 --- /dev/null +++ b/r2r/providers/database/relational.py @@ -0,0 +1,47 @@ +import logging + +from sqlalchemy import exc, text + +from r2r.providers.database.base import DatabaseMixin, execute_query +from r2r.providers.database.document import DocumentMixin +from r2r.providers.database.group import GroupMixin +from r2r.providers.database.tokens import BlacklistedTokensMixin +from r2r.providers.database.user import UserMixin + +logger = logging.getLogger(__name__) + + +class PostgresRelationalDBProvider( + GroupMixin, UserMixin, BlacklistedTokensMixin, DocumentMixin +): + def __init__(self, config, vx, crypto_provider, collection_name): + self.config = config + self.vx = vx + self.crypto_provider = crypto_provider + self.collection_name = collection_name + self._initialize_relational_db() + + def _get_table_name(self, base_name: str) -> str: + return f"{base_name}_{self.collection_name}" + + def execute_query(self, query, params=None): + return execute_query(self.vx, query, params) + + def _initialize_relational_db(self): + with self.vx.Session() as sess: + with sess.begin(): + try: + sess.execute( + text('CREATE EXTENSION IF NOT EXISTS "uuid-ossp";') + ) + except exc.ProgrammingError as e: + logger.error(f"Error enabling uuid-ossp extension: {e}") + raise + + # Call create_table for each mixin + for base_class in self.__class__.__bases__: + print("base_class", base_class) + if issubclass(base_class, DatabaseMixin): + base_class.create_table(self) + + sess.commit() diff --git a/r2r/providers/database/tokens.py b/r2r/providers/database/tokens.py new file mode 100644 index 000000000..0149c263f --- /dev/null +++ b/r2r/providers/database/tokens.py @@ -0,0 +1,59 @@ +from datetime import datetime, timedelta +from typing import Optional + +from .base import DatabaseMixin, QueryBuilder + + +class BlacklistedTokensMixin(DatabaseMixin): + def create_table(self): + query = f""" + CREATE TABLE IF NOT EXISTS {self._get_table_name('blacklisted_tokens')} ( + id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), + token TEXT NOT NULL, + blacklisted_at TIMESTAMPTZ DEFAULT NOW() + ); + CREATE INDEX IF NOT EXISTS idx_blacklisted_tokens_{self.collection_name}_token + ON {self._get_table_name('blacklisted_tokens')} (token); + CREATE INDEX IF NOT EXISTS idx_blacklisted_tokens_{self.collection_name}_blacklisted_at + ON {self._get_table_name('blacklisted_tokens')} (blacklisted_at); + """ + self.execute_query(query) + + def blacklist_token(self, token: str, current_time: datetime = None): + if current_time is None: + current_time = datetime.utcnow() + + query, params = ( + QueryBuilder(self._get_table_name("blacklisted_tokens")) + .insert({"token": token, "blacklisted_at": current_time}) + .build() + ) + self.execute_query(query, params) + + def is_token_blacklisted(self, token: str) -> bool: + query, params = ( + QueryBuilder(self._get_table_name("blacklisted_tokens")) + .select(["1"]) + .where("token = :token", token=token) + .limit(1) + .build() + ) + result = self.execute_query(query, params) + return bool(result.fetchone()) + + def clean_expired_blacklisted_tokens( + self, + max_age_hours: int = 7 * 24, + current_time: Optional[datetime] = None, + ): + if current_time is None: + current_time = datetime.utcnow() + expiry_time = current_time - timedelta(hours=max_age_hours) + + query, params = ( + QueryBuilder(self._get_table_name("blacklisted_tokens")) + .delete() + .where("blacklisted_at < :expiry_time", expiry_time=expiry_time) + .build() + ) + self.execute_query(query, params) diff --git a/r2r/providers/database/user.py b/r2r/providers/database/user.py new file mode 100644 index 000000000..35b7f8c75 --- /dev/null +++ b/r2r/providers/database/user.py @@ -0,0 +1,432 @@ +from datetime import datetime +from typing import Optional +from uuid import UUID + +from sqlalchemy import text + +from r2r.base.abstractions import R2RException +from r2r.base.api.models.auth.responses import UserResponse +from r2r.base.utils import generate_id_from_label + +from .base import DatabaseMixin, QueryBuilder + + +class UserMixin(DatabaseMixin): + def create_table(self): + query = f""" + CREATE TABLE IF NOT EXISTS {self._get_table_name('users')} ( + user_id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), + email TEXT UNIQUE NOT NULL, + hashed_password TEXT NOT NULL, + is_superuser BOOLEAN DEFAULT FALSE, + is_active BOOLEAN DEFAULT TRUE, + is_verified BOOLEAN DEFAULT FALSE, + verification_code TEXT, + verification_code_expiry TIMESTAMPTZ, + name TEXT, + bio TEXT, + profile_picture TEXT, + reset_token TEXT, + reset_token_expiry TIMESTAMPTZ, + group_ids UUID[] NULL, + created_at TIMESTAMPTZ DEFAULT NOW(), + updated_at TIMESTAMPTZ DEFAULT NOW() + ); + """ + self.execute_query(query) + + def get_user_by_id(self, user_id: UUID) -> Optional[UserResponse]: + query, params = ( + QueryBuilder(self._get_table_name("users")) + .select( + [ + "user_id", + "email", + "hashed_password", + "is_superuser", + "is_active", + "is_verified", + "created_at", + "updated_at", + "name", + "profile_picture", + "bio", + "group_ids", + ] + ) + .where("user_id = :user_id", user_id=user_id) + .build() + ) + result = self.execute_query(query, params).fetchone() + return ( + UserResponse( + id=result[0], + email=result[1], + hashed_password=result[2], + is_superuser=result[3], + is_active=result[4], + is_verified=result[5], + created_at=result[6], + updated_at=result[7], + name=result[8], + profile_picture=result[9], + bio=result[10], + group_ids=result[11], + ) + if result + else None + ) + + def get_user_by_email(self, email: str) -> Optional[UserResponse]: + query, params = ( + QueryBuilder(self._get_table_name("users")) + .select( + [ + "user_id", + "email", + "hashed_password", + "is_superuser", + "is_active", + "is_verified", + "created_at", + "updated_at", + "name", + "profile_picture", + "bio", + "group_ids", + ] + ) + .where("email = :email", email=email) + .build() + ) + result = self.execute_query(query, params).fetchone() + return ( + UserResponse( + id=result[0], + email=result[1], + hashed_password=result[2], + is_superuser=result[3], + is_active=result[4], + is_verified=result[5], + created_at=result[6], + updated_at=result[7], + name=result[8], + profile_picture=result[9], + bio=result[10], + group_ids=result[11], + ) + if result + else None + ) + + def create_user(self, email: str, password: str) -> UserResponse: + if self.get_user_by_email(email): + raise R2RException( + status_code=400, message="User with this email already exists" + ) + + hashed_password = self.crypto_provider.get_password_hash(password) + query = f""" + INSERT INTO {self._get_table_name('users')} + (email, user_id, hashed_password, group_ids) + VALUES (:email, :user_id, :hashed_password, :group_ids) + RETURNING user_id, email, is_superuser, is_active, is_verified, created_at, updated_at, group_ids + """ + params = { + "email": email, + "user_id": generate_id_from_label(email), + "hashed_password": hashed_password, + "group_ids": [], + } + result = self.execute_query(query, params).fetchone() + if not result: + raise R2RException( + status_code=500, message="Failed to create user" + ) + + return UserResponse( + id=result[0], + email=result[1], + is_superuser=result[2], + is_active=result[3], + is_verified=result[4], + created_at=result[5], + updated_at=result[6], + group_ids=result[7], + hashed_password=hashed_password, + ) + + def update_user(self, user: UserResponse) -> UserResponse: + if not self.get_user_by_id(user.id): + raise R2RException(status_code=404, message="User not found") + + query = f""" + UPDATE {self._get_table_name('users')} + SET email = :email, is_superuser = :is_superuser, is_active = :is_active, + is_verified = :is_verified, updated_at = NOW(), name = :name, + profile_picture = :profile_picture, bio = :bio, group_ids = :group_ids + WHERE user_id = :id + RETURNING user_id, email, is_superuser, is_active, is_verified, created_at, + updated_at, name, profile_picture, bio, group_ids + """ + result = self.execute_query( + query, user.dict(exclude={"hashed_password"}) + ).fetchone() + if not result: + raise R2RException( + status_code=500, message="Failed to update user" + ) + return UserResponse( + id=result[0], + email=result[1], + is_superuser=result[2], + is_active=result[3], + is_verified=result[4], + created_at=result[5], + updated_at=result[6], + name=result[7], + profile_picture=result[8], + bio=result[9], + group_ids=result[10], + ) + + def delete_user(self, user_id: UUID): + query = f""" + DELETE FROM {self._get_table_name('users')} + WHERE user_id = :user_id + """ + result = self.execute_query(query, {"user_id": user_id}) + if result.rowcount == 0: + raise R2RException(status_code=404, message="User not found") + + def update_user_password(self, user_id: UUID, new_hashed_password: str): + query = f""" + UPDATE {self._get_table_name('users')} + SET hashed_password = :new_hashed_password, updated_at = NOW() + WHERE user_id = :user_id + """ + self.execute_query( + query, + {"user_id": user_id, "new_hashed_password": new_hashed_password}, + ) + + def get_all_users(self) -> list[UserResponse]: + query = f""" + SELECT user_id, email, is_superuser, is_active, is_verified, created_at, updated_at, group_ids + FROM {self._get_table_name('users')} + """ + results = self.execute_query(query).fetchall() + return [ + UserResponse( + id=row[0], + email=row[1], + hashed_password="null", + is_superuser=row[2], + is_active=row[3], + is_verified=row[4], + created_at=row[5], + updated_at=row[6], + group_ids=row[7], + ) + for row in results + ] + + def store_verification_code( + self, user_id: UUID, verification_code: str, expiry: datetime + ): + query = f""" + UPDATE {self._get_table_name('users')} + SET verification_code = :code, verification_code_expiry = :expiry + WHERE user_id = :user_id + """ + self.execute_query( + query, + {"code": verification_code, "expiry": expiry, "user_id": user_id}, + ) + + def verify_user(self, verification_code: str) -> None: + query = f""" + UPDATE {self._get_table_name('users')} + SET is_verified = TRUE, verification_code = NULL, verification_code_expiry = NULL + WHERE verification_code = :code AND verification_code_expiry > NOW() + RETURNING user_id + """ + result = self.execute_query( + query, {"code": verification_code} + ).fetchone() + if not result: + raise R2RException( + status_code=400, message="Invalid or expired verification code" + ) + return None + + def remove_verification_code(self, verification_code: str): + query = f""" + UPDATE {self._get_table_name('users')} + SET verification_code = NULL, verification_code_expiry = NULL + WHERE verification_code = :code + """ + self.execute_query(query, {"code": verification_code}) + + def expire_verification_code(self, user_id: UUID): + query = f""" + UPDATE {self._get_table_name('users')} + SET verification_code_expiry = NOW() - INTERVAL '1 day' + WHERE user_id = :user_id + """ + self.execute_query(query, {"user_id": user_id}) + + def store_reset_token( + self, user_id: UUID, reset_token: str, expiry: datetime + ): + query = f""" + UPDATE {self._get_table_name('users')} + SET reset_token = :token, reset_token_expiry = :expiry + WHERE user_id = :user_id + """ + self.execute_query( + query, {"token": reset_token, "expiry": expiry, "user_id": user_id} + ) + + def get_user_id_by_reset_token(self, reset_token: str) -> Optional[UUID]: + query = f""" + SELECT user_id FROM {self._get_table_name('users')} + WHERE reset_token = :token AND reset_token_expiry > NOW() + """ + result = self.execute_query(query, {"token": reset_token}).fetchone() + return result[0] if result else None + + def remove_reset_token(self, user_id: UUID): + query = f""" + UPDATE {self._get_table_name('users')} + SET reset_token = NULL, reset_token_expiry = NULL + WHERE user_id = :user_id + """ + self.execute_query(query, {"user_id": user_id}) + + def remove_user_from_all_groups(self, user_id: UUID): + query = f""" + UPDATE {self._get_table_name('users')} + SET group_ids = ARRAY[]::UUID[] + WHERE user_id = :user_id + """ + self.execute_query(query, {"user_id": user_id}) + + def add_user_to_group(self, user_id: UUID, group_id: UUID) -> None: + if not self.get_user_by_id(user_id): + raise R2RException(status_code=404, message="User not found") + + query = f""" + UPDATE {self._get_table_name('users')} + SET group_ids = array_append(group_ids, :group_id) + WHERE user_id = :user_id AND NOT (:group_id = ANY(group_ids)) + RETURNING user_id + """ + result = self.execute_query( + query, {"user_id": user_id, "group_id": group_id} + ).fetchone() + if not result: + raise R2RException( + status_code=400, message="User already in group" + ) + return None + + def remove_user_from_group(self, user_id: UUID, group_id: UUID) -> None: + if not self.get_user_by_id(user_id): + raise R2RException(status_code=404, message="User not found") + + query = f""" + UPDATE {self._get_table_name('users')} + SET group_ids = array_remove(group_ids, :group_id) + WHERE user_id = :user_id AND :group_id = ANY(group_ids) + RETURNING user_id + """ + result = self.execute_query( + query, {"user_id": user_id, "group_id": group_id} + ).fetchone() + if not result: + raise R2RException( + status_code=400, + message="User is not a member of the specified group", + ) + return None + + def mark_user_as_superuser(self, user_id: UUID): + query = text( + f""" + UPDATE users_{self.collection_name} + SET is_superuser = TRUE, is_verified = TRUE, verification_code = NULL, verification_code_expiry = NULL + WHERE user_id = :user_id + """ + ) + + with self.vx.Session() as sess: + sess.execute(query, {"user_id": user_id}) + sess.commit() + + def get_users_in_group( + self, group_id: UUID, offset: int = 0, limit: int = 100 + ) -> list[UserResponse]: + query = f""" + SELECT user_id, email, is_superuser, is_active, is_verified, created_at, updated_at, name, profile_picture, bio, group_ids + FROM {self._get_table_name('users')} + WHERE :group_id = ANY(group_ids) + ORDER BY email + OFFSET :offset + LIMIT :limit + """ + results = self.execute_query( + query, {"group_id": group_id, "offset": offset, "limit": limit} + ).fetchall() + return [ + UserResponse( + id=row[0], + email=row[1], + is_superuser=row[2], + is_active=row[3], + is_verified=row[4], + created_at=row[5], + updated_at=row[6], + name=row[7], + profile_picture=row[8], + bio=row[9], + group_ids=row[10], + ) + for row in results + ] + + def get_user_id_by_verification_code( + self, verification_code: str + ) -> Optional[UUID]: + query = text( + f""" + SELECT user_id FROM users_{self.collection_name} + WHERE verification_code = :code AND verification_code_expiry > NOW() + """ + ) + + with self.vx.Session() as sess: + result = sess.execute(query, {"code": verification_code}) + user_data = result.fetchone() + + if not user_data: + raise R2RException( + status_code=400, message="Invalid or expired verification code" + ) + return user_data[0] + + def mark_user_as_verified(self, user_id: UUID): + query = text( + f""" + UPDATE users_{self.collection_name} + SET is_verified = TRUE, verification_code = NULL, verification_code_expiry = NULL + WHERE user_id = :user_id + """ + ) + + with self.vx.Session() as sess: + result = sess.execute(query, {"user_id": user_id}) + sess.commit() + + if not result.rowcount: + raise R2RException(status_code=404, message="User not found") diff --git a/r2r/providers/database/vecs/adapter/__init__.py b/r2r/providers/database/vecs/adapter/__init__.py index 9cd9860de..f4532aeee 100644 --- a/r2r/providers/database/vecs/adapter/__init__.py +++ b/r2r/providers/database/vecs/adapter/__init__.py @@ -1,6 +1,6 @@ from .base import Adapter, AdapterContext, AdapterStep from .markdown import MarkdownChunker -from .noop import NoOp +from .noop import NoOp, Record from .text import ParagraphChunker, TextEmbedding, TextEmbeddingModel __all__ = [ @@ -8,6 +8,7 @@ "AdapterContext", "AdapterStep", "NoOp", + "Record", "ParagraphChunker", "TextEmbedding", "TextEmbeddingModel", diff --git a/r2r/providers/database/vecs/adapter/base.py b/r2r/providers/database/vecs/adapter/base.py index 7734e8020..6634f35a5 100644 --- a/r2r/providers/database/vecs/adapter/base.py +++ b/r2r/providers/database/vecs/adapter/base.py @@ -6,12 +6,28 @@ All public classes, enums, and functions are re-exported by `vecs.adapters` module. """ +import uuid from abc import ABC, abstractmethod from enum import Enum -from typing import Any, Dict, Generator, Iterable, Optional, Tuple +from typing import Any, Dict, Generator, Iterable, Optional, Tuple, Union from vecs.exc import ArgError +MetadataValues = Union[str, int, float, bool, list[str]] +Metadata = Dict[str, MetadataValues] +Numeric = Union[int, float, complex] + +Record = Tuple[ + uuid.UUID, + uuid.UUID, + uuid.UUID, + uuid.UUID, + list[uuid.UUID], + Iterable[Numeric], + str, + Metadata, +] + class AdapterContext(str, Enum): """ diff --git a/r2r/providers/database/vecs/adapter/noop.py b/r2r/providers/database/vecs/adapter/noop.py index b587a552e..26d35f28c 100644 --- a/r2r/providers/database/vecs/adapter/noop.py +++ b/r2r/providers/database/vecs/adapter/noop.py @@ -8,7 +8,7 @@ from typing import Any, Dict, Generator, Iterable, Optional, Tuple -from .base import AdapterContext, AdapterStep +from .base import AdapterContext, AdapterStep, Record class NoOp(AdapterStep): @@ -38,18 +38,27 @@ def exported_dimension(self) -> Optional[int]: def __call__( self, - records: Iterable[Tuple[str, Any, Optional[Dict]]], + records: Iterable[Record], adapter_context: AdapterContext, - ) -> Generator[Tuple[str, Any, Dict], None, None]: - """ - Yields the input records without any modification. - - Args: - records: Iterable of tuples each containing an id, a media and an optional dict. - adapter_context: Context of the adapter. - - Yields: - Tuple[str, Any, Dict]: The input record. - """ - for id, media, metadata in records: - yield (id, media, metadata or {}) + ) -> Generator[Record, None, None]: + for record in records: + ( + fragment_id, + extraction_id, + document_id, + user_id, + group_ids, + vec, + text, + metadata, + ) = record + yield ( + str(fragment_id), + str(extraction_id), + str(document_id), + str(user_id), + [str(gid) for gid in group_ids], + vec, + text, + metadata or {}, + ) diff --git a/r2r/providers/database/vecs/collection.py b/r2r/providers/database/vecs/collection.py index 580bef174..8bacee9c1 100644 --- a/r2r/providers/database/vecs/collection.py +++ b/r2r/providers/database/vecs/collection.py @@ -43,7 +43,7 @@ from sqlalchemy.dialects import postgresql from sqlalchemy.types import Float, UserDefinedType -from .adapter import Adapter, AdapterContext, NoOp +from .adapter import Adapter, AdapterContext, NoOp, Record from .exc import ( ArgError, CollectionAlreadyExists, @@ -57,12 +57,6 @@ from vecs.client import Client -MetadataValues = Union[str, int, float, bool, List[str]] -Metadata = Dict[str, MetadataValues] -Numeric = Union[int, float, complex] -Record = Tuple[str, Iterable[Numeric], Metadata] - - class IndexMethod(str, Enum): """ An enum representing the index methods available. @@ -208,6 +202,14 @@ class Collection: Note: Some methods of this class can raise exceptions from the `vecs.exc` module if errors occur. """ + COLUMN_VARS = [ + "fragment_id", + "extraction_id", + "document_id", + "user_id", + "group_ids", + ] + def __init__( self, name: str, @@ -231,7 +233,7 @@ def __init__( self.client = client self.name = name self.dimension = dimension - self.table = build_table(name, client.meta, dimension) + self.table = _build_table(name, client.meta, dimension) self._index: Optional[str] = None self.adapter = adapter or Adapter(steps=[NoOp(dimension=dimension)]) @@ -359,6 +361,27 @@ def _create(self): """ ) ) + + # Create trigger to update fts column + sess.execute( + text( + f""" + CREATE TRIGGER tsvector_update_{unique_string} BEFORE INSERT OR UPDATE + ON vecs."{self.table.name}" FOR EACH ROW EXECUTE FUNCTION + tsvector_update_trigger(fts, 'pg_catalog.english', text); + """ + ) + ) + + # Create index on fts column + sess.execute( + text( + f""" + CREATE INDEX ix_fts_{unique_string} ON vecs."{self.table.name}" USING GIN (fts); + """ + ) + ) + return self def _drop(self): @@ -377,124 +400,16 @@ def _drop(self): return self - def get_unique_metadata_values( - self, - field: str, - filter_field: Optional[str] = None, - filter_value: Optional[MetadataValues] = None, - ) -> List[MetadataValues]: - """ - Fetches all unique metadata values of a specific field, optionally filtered by another metadata field. - Args: - field (str): The metadata field for which to fetch unique values. - filter_field (Optional[str], optional): The metadata field to filter on. Defaults to None. - filter_value (Optional[MetadataValues], optional): The value to filter the metadata field with. Defaults to None. - Returns: - List[MetadataValues]: A list of unique metadata values for the specified field. - """ - with self.client.Session() as sess: - with sess.begin(): - stmt = select( - distinct(self.table.c.metadata[field].astext) - ).where(self.table.c.metadata[field] != None) - - if filter_field is not None and filter_value is not None: - stmt = stmt.where( - self.table.c.metadata[filter_field].astext - == str(filter_value) - ) - - result = sess.execute(stmt) - unique_values = result.scalars().all() - - return unique_values - - def copy( - self, - records: Iterable[Tuple[str, Any, Metadata]], - skip_adapter: bool = False, - ) -> None: - """ - Copies records into the collection. - - Args: - records (Iterable[Tuple[str, Any, Metadata]]): An iterable of content to copy. - Each record is a tuple where: - - the first element is a unique string identifier - - the second element is an iterable of numeric values or relevant input type for the - adapter assigned to the collection - - the third element is metadata associated with the vector - - skip_adapter (bool): Should the adapter be skipped while copying. i.e. if vectors are being - provided, rather than a media type that needs to be transformed - """ - import csv - import io - import json - import os - - pipeline = flu(records) - for record in pipeline: - with psycopg2.connect( - database=os.getenv("POSTGRES_DBNAME"), - user=os.getenv("POSTGRES_USER"), - password=os.getenv("POSTGRES_PASSWORD"), - host=os.getenv("POSTGRES_HOST"), - port=os.getenv("POSTGRES_PORT"), - ) as conn: - with conn.cursor() as cur: - f = io.StringIO() - id, vec, metadata = record - - writer = csv.writer(f, delimiter=",", quotechar='"') - writer.writerow( - [ - str(id), - [float(ele) for ele in vec], - json.dumps(metadata), - ] - ) - f.seek(0) - result = f.getvalue() - - writer_name = ( - f'vecs."{self.table.fullname.split(".")[-1]}"' - ) - g = io.StringIO(result) - cur.copy_expert( - f"COPY {writer_name}(id, vec, metadata) FROM STDIN WITH (FORMAT csv)", - g, - ) - conn.commit() - cur.close() - conn.close() - def upsert( self, - records: Iterable[Tuple[str, Any, Metadata]], + records: Iterable[Record], skip_adapter: bool = False, ) -> None: - """ - Inserts or updates *vectors* records in the collection. - - Args: - records (Iterable[Tuple[str, Any, Metadata]]): An iterable of content to upsert. - Each record is a tuple where: - - the first element is a unique string identifier - - the second element is an iterable of numeric values or relevant input type for the - adapter assigned to the collection - - the third element is metadata associated with the vector - - skip_adapter (bool): Should the adapter be skipped while upserting. i.e. if vectors are being - provided, rather than a media type that needs to be transformed - """ - chunk_size = 512 if skip_adapter: pipeline = flu(records).chunk(chunk_size) else: - # Construct a lazy pipeline of steps to transform and chunk user input pipeline = flu( self.adapter(records, AdapterContext("upsert")) ).chunk(chunk_size) @@ -502,37 +417,59 @@ def upsert( with self.client.Session() as sess: with sess.begin(): for chunk in pipeline: - stmt = postgresql.insert(self.table).values(chunk) + stmt = postgresql.insert(self.table).values( + [ + { + "fragment_id": record[0], + "extraction_id": record[1], + "document_id": record[2], + "user_id": record[3], + "group_ids": record[4], + "vec": record[5], + "text": record[6], + "metadata": record[7], + } + for record in chunk + ] + ) stmt = stmt.on_conflict_do_update( - index_elements=[self.table.c.id], + index_elements=[self.table.c.fragment_id], set_=dict( + extraction_id=stmt.excluded.extraction_id, + document_id=stmt.excluded.document_id, + user_id=stmt.excluded.user_id, + group_ids=stmt.excluded.group_ids, vec=stmt.excluded.vec, + text=stmt.excluded.text, metadata=stmt.excluded.metadata, ), ) sess.execute(stmt) return None - def fetch(self, ids: Iterable[str]) -> List[Record]: + def fetch(self, fragment_ids: Iterable[uuid.UUID]) -> List[Record]: """ - Fetches vectors from the collection by their identifiers. + Fetches vectors from the collection by their fragment identifiers. Args: - ids (Iterable[str]): An iterable of vector identifiers. + fragment_ids (Iterable[UUID]): An iterable of vector fragment identifiers. Returns: List[Record]: A list of the fetched vectors. + + Raises: + ArgError: If fragment_ids is not an iterable of UUIDs. """ - if isinstance(ids, str): - raise ArgError("ids must be a list of strings") + if isinstance(fragment_ids, (str, uuid.UUID)): + raise ArgError("fragment_ids must be an iterable of UUIDs") chunk_size = 12 records = [] with self.client.Session() as sess: with sess.begin(): - for id_chunk in flu(ids).chunk(chunk_size): + for id_chunk in flu(fragment_ids).chunk(chunk_size): stmt = select(self.table).where( - self.table.c.id.in_(id_chunk) + self.table.c.fragment_id.in_(id_chunk) ) chunk_records = sess.execute(stmt) records.extend(chunk_records) @@ -540,71 +477,82 @@ def fetch(self, ids: Iterable[str]) -> List[Record]: def delete( self, - ids: Optional[Iterable[str]] = None, + fragment_ids: Optional[Iterable[uuid.UUID]] = None, filters: Optional[Dict[str, Any]] = None, - ) -> List[str]: + ) -> Dict[str, Dict[str, str]]: """ - Deletes vectors from the collection by matching filters or ids. + Deletes vectors from the collection by matching filters or fragment_ids. Args: - ids (Iterable[str], optional): An iterable of vector identifiers. + fragment_ids (Optional[Iterable[UUID]], optional): An iterable of vector fragment identifiers. filters (Optional[Dict], optional): Filters to apply to the search. Defaults to None. Returns: - List[str]: A list of the document IDs of the deleted vectors. + Dict[str, Dict[str, str]]: A dictionary of deleted records, where the key is the fragment_id + and the value is a dictionary containing 'document_id', 'extraction_id', 'fragment_id', and 'text'. + + Raises: + ArgError: If neither fragment_ids nor filters are provided, or if both are provided. """ - if ids is None and filters is None: - raise ArgError("Either ids or filters must be provided.") + if fragment_ids is None and filters is None: + raise ArgError("Either fragment_ids or filters must be provided.") - if ids is not None and filters is not None: - raise ArgError("Either ids or filters must be provided, not both.") + if fragment_ids is not None and filters is not None: + raise ArgError( + "Either fragment_ids or filters must be provided, not both." + ) - if isinstance(ids, str): - raise ArgError("ids must be a list of strings") + if isinstance(fragment_ids, (str, uuid.UUID)): + raise ArgError("fragment_ids must be an iterable of UUIDs") - ids = ids or [] - filters = filters or {} - del_document_ids = set([]) + deleted_records = {} with self.client.Session() as sess: with sess.begin(): - if ids: - for id_chunk in flu(ids).chunk(12): - stmt = select(self.table.c.metadata).where( - self.table.c.id.in_(id_chunk) - ) - results = sess.execute(stmt).fetchall() - for result in results: - metadata_json = result[0] - document_id = metadata_json.get("document_id") - if document_id: - del_document_ids.add(document_id) - + if fragment_ids: + for id_chunk in flu(fragment_ids).chunk(12): delete_stmt = ( delete(self.table) - .where(self.table.c.id.in_(id_chunk)) - .returning(self.table.c.id) + .where(self.table.c.fragment_id.in_(id_chunk)) + .returning( + self.table.c.fragment_id, + self.table.c.document_id, + self.table.c.extraction_id, + self.table.c.text, + ) ) - sess.execute(delete_stmt) + result = sess.execute(delete_stmt) + for row in result: + fragment_id = str(row[0]) + deleted_records[fragment_id] = { + "fragment_id": fragment_id, + "document_id": str(row[1]), + "extraction_id": str(row[2]), + "text": row[3], + } if filters: - meta_filter = build_filters(self.table.c.metadata, filters) - stmt = select(self.table.c.metadata).where(meta_filter) - results = sess.execute(stmt).fetchall() - for result in results: - metadata_json = result[0] - document_id = metadata_json.get("document_id") - if document_id: - del_document_ids.add(document_id) - + meta_filter = self._build_complex_filters(filters) delete_stmt = ( delete(self.table) .where(meta_filter) - .returning(self.table.c.id) + .returning( + self.table.c.fragment_id, + self.table.c.document_id, + self.table.c.extraction_id, + self.table.c.text, + ) ) - sess.execute(delete_stmt) - - return list(del_document_ids) + result = sess.execute(delete_stmt) + for row in result: + fragment_id = str(row[0]) + deleted_records[fragment_id] = { + "fragment_id": fragment_id, + "document_id": str(row[1]), + "extraction_id": str(row[2]), + "text": row[3], + } + return deleted_records def __getitem__(self, items): """ @@ -627,58 +575,44 @@ def __getitem__(self, items): def query( self, - data: Union[Iterable[Numeric], Any], + vector: list[float], + filters: Dict[str, Any] = {}, + imeasure: IndexMeasure = IndexMeasure.cosine_distance, limit: int = 10, - filters: Optional[Dict] = None, - measure: Union[IndexMeasure, str] = IndexMeasure.cosine_distance, include_value: bool = False, include_metadata: bool = False, *, probes: Optional[int] = None, ef_search: Optional[int] = None, - skip_adapter: bool = False, ) -> Union[List[Record], List[str]]: """ - Executes a similarity search in the collection. - - The return type is dependent on arguments *include_value* and *include_metadata* + Executes a similarity search in the collection based on the new query structure. Args: - data (Any): The vector to use as the query. + vector (list[float]): The query vector. + filters (Dict[str, Any], optional): Metadata filters to apply. Defaults to {}. + imeasure (IndexMeasure, optional): The distance measure to use. Defaults to IndexMeasure.cosine_distance. limit (int, optional): The maximum number of results to return. Defaults to 10. - filters (Optional[Dict], optional): Filters to apply to the search. Defaults to None. - measure (Union[IndexMeasure, str], optional): The distance measure to use for the search. Defaults to 'cosine_distance'. include_value (bool, optional): Whether to include the distance value in the results. Defaults to False. include_metadata (bool, optional): Whether to include the metadata in the results. Defaults to False. - probes (Optional[Int], optional): Number of ivfflat index lists to query. Higher increases accuracy but decreases speed - ef_search (Optional[Int], optional): Size of the dynamic candidate list for HNSW index search. Higher increases accuracy but decreases speed - skip_adapter (bool, optional): When True, skips any associated adapter and queries using a literal vector provided to *data* + probes (Optional[int], optional): Number of ivfflat index lists to query. + ef_search (Optional[int], optional): Size of the dynamic candidate list for HNSW index search. Returns: Union[List[Record], List[str]]: The result of the similarity search. - """ + Raises: + ArgError: If the limit is greater than 1000 or if an invalid distance measure is provided. + """ if probes is None: probes = 10 if ef_search is None: ef_search = 40 - if not isinstance(probes, int): - raise ArgError("probes must be an integer") - - if probes < 1: - raise ArgError("probes must be >= 1") - if limit > 1000: raise ArgError("limit must be <= 1000") - # ValueError on bad input - try: - imeasure = IndexMeasure(measure) - except ValueError: - raise ArgError("Invalid index measure") - if not self.is_indexed_for_measure(imeasure): warnings.warn( UserWarning( @@ -686,34 +620,20 @@ def query( ) ) - if skip_adapter: - adapted_query = [("", data, {})] - else: - # Adapt the query using the pipeline - adapted_query = [ - x - for x in self.adapter( - records=[("", data, {})], - adapter_context=AdapterContext("query"), - ) - ] - - if len(adapted_query) != 1: - raise ArgError( - "Failed to produce exactly one query vector from input" - ) - - _, vec, _ = adapted_query[0] - distance_lambda = INDEX_MEASURE_TO_SQLA_ACC.get(imeasure) if distance_lambda is None: - # unreachable - raise ArgError("invalid distance_measure") # pragma: no cover - - distance_clause = distance_lambda(self.table.c.vec)(vec) - - cols = [self.table.c.id] - + raise ArgError("invalid distance_measure") + + distance_clause = distance_lambda(self.table.c.vec)(vector) + + cols = [ + self.table.c.fragment_id, + self.table.c.extraction_id, + self.table.c.document_id, + self.table.c.user_id, + self.table.c.group_ids, + self.table.c.text, + ] if include_value: cols.append(distance_clause) @@ -721,17 +641,14 @@ def query( cols.append(self.table.c.metadata) stmt = select(*cols) - if filters: - stmt = stmt.filter( - build_filters(self.table.c.metadata, filters) # type: ignore - ) + + stmt = stmt.filter(self._build_complex_filters(filters)) stmt = stmt.order_by(distance_clause) stmt = stmt.limit(limit) with self.client.Session() as sess: with sess.begin(): - # index ignored if greater than n_lists sess.execute( text("set local ivfflat.probes = :probes").bindparams( probes=probes @@ -747,6 +664,94 @@ def query( return [str(x) for x in sess.scalars(stmt).fetchall()] return sess.execute(stmt).fetchall() or [] + def _build_complex_filters(self, filters: Dict[str, Any]): + """ + Builds complex filters for SQL query based on the new filter structure. + + Args: + filters (Dict[str, Any]): The dictionary specifying filter conditions. + + Returns: + The filter clause for the SQL query. + """ + + def parse_condition(key, condition): + if key in self.COLUMN_VARS: + # Handle column-based filters + column = getattr(self.table.c, key) + if isinstance(condition, dict): + op = list(condition.keys())[0] + value = condition[op] + if op == "$eq": + return column == value + elif op == "$ne": + return column != value + elif op == "$in": + return column.in_(value) + elif op == "$nin": + return ~column.in_(value) + elif op == "$overlap": + return column.overlap(value) + else: + raise FilterError( + f"Unsupported operator for column {key}: {op}" + ) + else: + return column == condition + else: + if isinstance(condition, dict): + op = list(condition.keys())[0] + value = condition[op] + if op == "$eq": + return self.table.c.metadata[key].astext == str(value) + elif op == "$ne": + return self.table.c.metadata[key].astext != str(value) + elif op == "$gt": + return ( + cast(self.table.c.metadata[key].astext, Float) + > value + ) + elif op == "$gte": + return ( + cast(self.table.c.metadata[key].astext, Float) + >= value + ) + elif op == "$lt": + return ( + cast(self.table.c.metadata[key].astext, Float) + < value + ) + elif op == "$lte": + return ( + cast(self.table.c.metadata[key].astext, Float) + <= value + ) + elif op == "$in": + return self.table.c.metadata[key].astext.in_( + [str(v) for v in value] + ) + elif op == "$nin": + return ~self.table.c.metadata[key].astext.in_( + [str(v) for v in value] + ) + else: + raise FilterError(f"Unsupported operator: {op}") + else: + return self.table.c.metadata[key].astext == str(condition) + + def parse_filter(filter_dict): + conditions = [] + for key, value in filter_dict.items(): + if key == "$and": + conditions.append(and_(*[parse_filter(f) for f in value])) + elif key == "$or": + conditions.append(or_(*[parse_filter(f) for f in value])) + else: + conditions.append(parse_condition(key, value)) + return and_(*conditions) + + return parse_filter(filters) + @classmethod def _list_collections(cls, client: "Client") -> List["Collection"]: """ @@ -1009,101 +1014,7 @@ def create_index( return None -def build_filters(json_col: Column, filters: Dict): - """ - Builds filters for SQL query based on provided dictionary. - - Args: - json_col (Column): The column in the database table. - filters (Dict): The dictionary specifying filter conditions. - - Raises: - FilterError: If filter conditions are not correctly formatted. - - Returns: - The filter clause for the SQL query. - """ - if not isinstance(filters, dict): - raise FilterError("filters must be a dict") - - filter_clauses = [] - - for key, value in filters.items(): - if not isinstance(key, str): - raise FilterError("*filters* keys must be strings") - - if isinstance(value, dict): - if len(value) > 1: - raise FilterError("only one operator permitted per key") - for operator, clause in value.items(): - if operator not in ( - "$eq", - "$ne", - "$lt", - "$lte", - "$gt", - "$gte", - "$in", - ): - raise FilterError("unknown operator") - - if operator == "$eq" and not hasattr(clause, "__len__"): - contains_value = cast({key: clause}, postgresql.JSONB) - filter_clauses.append(json_col.op("@>")(contains_value)) - elif operator == "$in": - if not isinstance(clause, list): - raise FilterError( - "argument to $in filter must be a list" - ) - for elem in clause: - if not isinstance(elem, (int, str, float)): - raise FilterError( - "argument to $in filter must be a list of scalars" - ) - contains_value = [ - cast(elem, postgresql.JSONB) for elem in clause - ] - filter_clauses.append( - json_col.op("->")(key).in_(contains_value) - ) - else: - matches_value = cast(clause, postgresql.JSONB) - if operator == "$eq": - filter_clauses.append( - json_col.op("->")(key) == matches_value - ) - elif operator == "$ne": - filter_clauses.append( - json_col.op("->")(key) != matches_value - ) - elif operator == "$lt": - filter_clauses.append( - json_col.op("->")(key) < matches_value - ) - elif operator == "$lte": - filter_clauses.append( - json_col.op("->")(key) <= matches_value - ) - elif operator == "$gt": - filter_clauses.append( - json_col.op("->")(key) > matches_value - ) - elif operator == "$gte": - filter_clauses.append( - json_col.op("->")(key) >= matches_value - ) - else: - raise Unreachable() - else: - raise FilterError("Filter value must be a dict with an operator") - - if len(filter_clauses) == 1: - return filter_clauses[0] - else: - return and_(*filter_clauses) - - -def build_table(name: str, meta: MetaData, dimension: int) -> Table: +def _build_table(name: str, meta: MetaData, dimension: int) -> Table: """ PRIVATE @@ -1120,13 +1031,28 @@ def build_table(name: str, meta: MetaData, dimension: int) -> Table: return Table( name, meta, - Column("id", String, primary_key=True), + Column("fragment_id", postgresql.UUID, primary_key=True), + Column("extraction_id", postgresql.UUID, nullable=False), + Column("document_id", postgresql.UUID, nullable=False), + Column("user_id", postgresql.UUID, nullable=False), + Column( + "group_ids", postgresql.ARRAY(postgresql.UUID), server_default="{}" + ), Column("vec", Vector(dimension), nullable=False), + Column( + "text", postgresql.TEXT, nullable=True + ), # New standalone text column Column( "metadata", postgresql.JSONB, server_default=text("'{}'::jsonb"), nullable=False, ), + Column( + "fts", + postgresql.TSVECTOR, + server_default=text("to_tsvector('english', '')"), + nullable=False, + ), # New FTS column extend_existing=True, ) diff --git a/r2r/providers/database/vector.py b/r2r/providers/database/vector.py new file mode 100644 index 000000000..c8523a159 --- /dev/null +++ b/r2r/providers/database/vector.py @@ -0,0 +1,430 @@ +import json +import logging +import os +import time +from typing import Any, Optional + +from sqlalchemy import exc, text +from sqlalchemy.engine.url import make_url + +from r2r.base import ( + DatabaseConfig, + VectorDBProvider, + VectorEntry, + VectorSearchResult, + generate_id_from_label, +) + +from .vecs import Client, Collection, create_client + +logger = logging.getLogger(__name__) + + +class PostgresVectorDBProvider(VectorDBProvider): + def __init__(self, config: DatabaseConfig, *args, **kwargs): + super().__init__(config) + self.collection: Optional[Collection] = None + self.vx: Client = kwargs.get("vx", None) + if not self.vx: + raise ValueError( + "Please provide a valid `vx` client to the `PostgresVectorDBProvider`." + ) + self.collection_name = kwargs.get("collection_name", None) + if not self.collection_name: + raise ValueError( + "Please provide a valid `collection_name` to the `PostgresVectorDBProvider`." + ) + dimension = kwargs.get("dimension", None) + if not dimension: + raise ValueError( + "Please provide a valid `dimension` to the `PostgresVectorDBProvider`." + ) + + # Check if a complete Postgres URI is provided + postgres_uri = self.config.extra_fields.get( + "postgres_uri" + ) or os.getenv("POSTGRES_URI") + + if postgres_uri: + # Log loudly that Postgres URI is being used + logger.warning("=" * 50) + logger.warning( + "ATTENTION: Using provided Postgres URI for connection" + ) + logger.warning("=" * 50) + + # Validate and use the provided URI + try: + parsed_uri = make_url(postgres_uri) + if not all([parsed_uri.username, parsed_uri.database]): + raise ValueError( + "The provided Postgres URI is missing required components." + ) + DB_CONNECTION = postgres_uri + + # Log the sanitized URI (without password) + sanitized_uri = parsed_uri.set(password="*****") + logger.info(f"Connecting using URI: {sanitized_uri}") + except Exception as e: + raise ValueError(f"Invalid Postgres URI provided: {e}") + else: + # Fall back to existing logic for individual connection parameters + user = self.config.extra_fields.get("user", None) or os.getenv( + "POSTGRES_USER" + ) + password = self.config.extra_fields.get( + "password", None + ) or os.getenv("POSTGRES_PASSWORD") + host = self.config.extra_fields.get("host", None) or os.getenv( + "POSTGRES_HOST" + ) + port = self.config.extra_fields.get("port", None) or os.getenv( + "POSTGRES_PORT" + ) + db_name = self.config.extra_fields.get( + "db_name", None + ) or os.getenv("POSTGRES_DBNAME") + + if not all([user, password, host, db_name]): + raise ValueError( + "Error, please set the POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_HOST, POSTGRES_DBNAME environment variables or provide them in the config." + ) + + # Check if it's a Unix socket connection + if host.startswith("/") and not port: + DB_CONNECTION = ( + f"postgresql://{user}:{password}@/{db_name}?host={host}" + ) + logger.info("Using Unix socket connection") + else: + DB_CONNECTION = ( + f"postgresql://{user}:{password}@{host}:{port}/{db_name}" + ) + logger.info("Using TCP connection") + + # The rest of the initialization remains the same + try: + self.vx: Client = create_client(DB_CONNECTION) + except Exception as e: + raise ValueError( + f"Error {e} occurred while attempting to connect to the pgvector provider with {DB_CONNECTION}." + ) + + self.collection_name = self.config.extra_fields.get( + "vecs_collection" + ) or os.getenv("POSTGRES_VECS_COLLECTION") + if not self.collection_name: + raise ValueError( + "Error, please set a valid POSTGRES_VECS_COLLECTION environment variable or set a 'vecs_collection' in the 'database' settings of your `r2r.toml`." + ) + + self.collection: Optional[Collection] = None + self._initialize_vector_db(dimension) + self._create_hybrid_search_function() + logger.info( + f"Successfully initialized PGVectorDB with collection: {self.collection_name}" + ) + + def _initialize_vector_db(self, dimension: int) -> None: + self.collection = self.vx.get_or_create_collection( + name=self.collection_name, dimension=dimension + ) + + def _create_hybrid_search_function(self): + hybrid_search_function = f""" + CREATE OR REPLACE FUNCTION hybrid_search_{self.collection_name}( + query_text TEXT, + query_embedding VECTOR(512), + match_limit INT, + full_text_weight FLOAT = 1, + semantic_weight FLOAT = 1, + rrf_k INT = 50, + filter_condition JSONB = NULL + ) + RETURNS TABLE( + fragment_id UUID, + extraction_id UUID, + document_id UUID, + user_id UUID, + group_ids UUID[], + vec VECTOR(512), + text TEXT, + metadata JSONB, + rrf_score FLOAT, + semantic_score FLOAT, + full_text_score FLOAT, + rank_semantic INT, + rank_full_text INT + ) + LANGUAGE sql + AS $$ + WITH full_text AS ( + SELECT + fragment_id, + ts_rank_cd(to_tsvector('english', text), websearch_to_tsquery('english', query_text), 1 | 2 | 4 | 8 | 16 | 32 | 64) * 10000 AS full_text_score, + ROW_NUMBER() OVER (ORDER BY ts_rank_cd(to_tsvector('english', text), websearch_to_tsquery('english', query_text), 1 | 2 | 4 | 8 | 16 | 32 | 64) DESC) AS rank_ix + FROM vecs."{self.collection_name}" + WHERE to_tsvector('english', text) @@ websearch_to_tsquery('english', query_text) + AND (filter_condition IS NULL OR (metadata @> filter_condition)) + ORDER BY rank_ix + LIMIT LEAST(match_limit, 30) * 2 + ), + semantic AS ( + SELECT + fragment_id, + 1 - (vec <=> query_embedding) AS semantic_score, + ROW_NUMBER() OVER (ORDER BY (vec <=> query_embedding)) AS rank_ix + FROM vecs."{self.collection_name}" + WHERE filter_condition IS NULL OR (metadata @> filter_condition) + ORDER BY rank_ix + LIMIT LEAST(match_limit, 30) * 2 + ) + SELECT + vecs."{self.collection_name}".fragment_id, + vecs."{self.collection_name}".extraction_id, + vecs."{self.collection_name}".document_id, + vecs."{self.collection_name}".user_id, + vecs."{self.collection_name}".group_ids, + vecs."{self.collection_name}".vec, + vecs."{self.collection_name}".text, + vecs."{self.collection_name}".metadata, + (COALESCE(1.0 / (rrf_k + full_text.rank_ix), 0.0) * full_text_weight + + COALESCE(1.0 / (rrf_k + semantic.rank_ix), 0.0) * semantic_weight) AS rrf_score, + COALESCE(semantic.semantic_score, 0) AS semantic_score, + COALESCE(full_text.full_text_score, 0) AS full_text_score, + semantic.rank_ix AS rank_semantic, + full_text.rank_ix AS rank_full_text + FROM + full_text + FULL OUTER JOIN semantic + ON full_text.fragment_id = semantic.fragment_id + JOIN vecs."{self.collection_name}" + ON vecs."{self.collection_name}".fragment_id = COALESCE(full_text.fragment_id, semantic.fragment_id) + ORDER BY + rrf_score DESC + LIMIT + LEAST(match_limit, 30); + $$; + """ + retry_attempts = 5 + for attempt in range(retry_attempts): + try: + with self.vx.Session() as sess: + # Acquire an advisory lock + sess.execute(text("SELECT pg_advisory_lock(123456789)")) + try: + sess.execute(text(hybrid_search_function)) + sess.commit() + finally: + # Release the advisory lock + sess.execute( + text("SELECT pg_advisory_unlock(123456789)") + ) + break # Break the loop if successful + except exc.InternalError as e: + if "tuple concurrently updated" in str(e): + time.sleep(2**attempt) # Exponential backoff + else: + raise # Re-raise the exception if it's not a concurrency issue + else: + raise RuntimeError( + "Failed to create hybrid search function after multiple attempts" + ) + + def upsert(self, entry: VectorEntry) -> None: + if self.collection is None: + raise ValueError( + "Please call `initialize_collection` before attempting to run `upsert`." + ) + + self.collection.upsert( + records=[ + ( + entry.fragment_id, + entry.extraction_id, + entry.document_id, + entry.user_id, + entry.group_ids, + entry.vector.data, + entry.text, + entry.metadata, + ) + ] + ) + + def upsert_entries(self, entries: list[VectorEntry]) -> None: + if self.collection is None: + raise ValueError( + "Please call `initialize_collection` before attempting to run `upsert_entries`." + ) + + self.collection.upsert( + records=[ + ( + entry.fragment_id, + entry.extraction_id, + entry.document_id, + entry.user_id, + entry.group_ids, + entry.vector.data, + entry.text, + entry.metadata, + ) + for entry in entries + ] + ) + + def get_document_groups(self, document_id: str) -> list[str]: + query = text( + f""" + SELECT group_ids + FROM document_info_{self.collection_name} + WHERE document_id = :document_id + """ + ) + with self.vx.Session() as sess: + result = sess.execute(query, {"document_id": document_id}) + group_ids = result.scalar() + return [str(group_id) for group_id in (group_ids or [])] + + def search( + self, + query_vector: list[float], + filters: dict[str, Any] = {}, + limit: int = 10, + measure: str = "cosine_distance", + *args, + **kwargs, + ) -> list[VectorSearchResult]: + if self.collection is None: + raise ValueError( + "Please call `initialize_collection` before attempting to run `search`." + ) + results = self.collection.query( + vector=query_vector, + filters=filters, + limit=limit, + imeasure=measure, + include_value=True, + include_metadata=True, + ) + return [ + VectorSearchResult( + fragment_id=result[0], + extraction_id=result[1], + document_id=result[2], + user_id=result[3], + group_ids=result[4], + text=result[5], + score=1 - float(result[6]), + metadata=result[7], + ) + for result in results + ] + + def hybrid_search( + self, + query_text: str, + query_vector: list[float], + limit: int = 10, + filters: dict[str, Any] = {}, + full_text_weight: float = 1.0, + semantic_weight: float = 1.0, + rrf_k: int = 20, + *args, + **kwargs, + ) -> list[VectorSearchResult]: + if self.collection is None: + raise ValueError( + "Please call `initialize_collection` before attempting to run `hybrid_search`." + ) + + # Convert filters to a JSON-compatible format + filter_condition = json.dumps(filters) if filters else None + + query = text( + f""" + SELECT * FROM hybrid_search_{self.collection_name}( + cast(:query_text as TEXT), cast(:query_embedding as VECTOR), cast(:match_limit as INT), + cast(:full_text_weight as FLOAT), cast(:semantic_weight as FLOAT), cast(:rrf_k as INT), + cast(:filter_condition as JSONB) + ) + """ + ) + + params = { + "query_text": str(query_text), + "query_embedding": list(query_vector), + "match_limit": limit, + "full_text_weight": full_text_weight, + "semantic_weight": semantic_weight, + "rrf_k": rrf_k, + "filter_condition": filter_condition, + } + + with self.vx.Session() as session: + results = session.execute(query, params).fetchall() + return [ + VectorSearchResult( + fragment_id=result[0], + extraction_id=result[1], + document_id=result[2], + user_id=result[3], + group_ids=result[4], + text=result[6], + metadata={ + **result[7], + "semantic_score": result[9], + "semantic_rank": result[11], + "full_text_score": result[10], + "full_text_rank": result[12], + }, + score=result[8], + ) + for result in results + ] + + def create_index(self, index_type, column_name, index_options): + self.collection.create_index() + + def delete( + self, + filters: dict[str, Any], + ) -> list[str]: + if self.collection is None: + raise ValueError( + "Please call `initialize_collection` before attempting to run `delete`." + ) + + return self.collection.delete(filters=filters) + + def get_document_chunks(self, document_id: str) -> list[dict]: + if not self.collection: + raise ValueError("Collection is not initialized.") + + table_name = self.collection.table.name + query = text( + f""" + SELECT fragment_id, extraction_id, document_id, user_id, group_ids, text, metadata + FROM vecs."{table_name}" + WHERE document_id = :document_id + ORDER BY CAST(metadata->>'chunk_order' AS INTEGER) + """ + ) + + params = {"document_id": document_id} + + with self.vx.Session() as sess: + results = sess.execute(query, params).fetchall() + return [ + { + "fragment_id": result[0], + "extraction_id": result[1], + "document_id": result[2], + "user_id": result[3], + "group_ids": result[4], + "text": result[5], + "metadata": result[6], + } + for result in results + ] diff --git a/r2r/providers/eval/__init__.py b/r2r/providers/eval/__init__.py deleted file mode 100644 index 92848b358..000000000 --- a/r2r/providers/eval/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -from .r2r_llm_eval import LLMEvalProvider - -__all__ = ["LLMEvalProvider"] diff --git a/r2r/providers/eval/r2r_llm_eval.py b/r2r/providers/eval/r2r_llm_eval.py deleted file mode 100644 index 4deae34d8..000000000 --- a/r2r/providers/eval/r2r_llm_eval.py +++ /dev/null @@ -1,84 +0,0 @@ -from fractions import Fraction -from typing import Union - -from r2r import CompletionProvider, EvalConfig, EvalProvider, PromptProvider -from r2r.base.abstractions.llm import GenerationConfig - - -class LLMEvalProvider(EvalProvider): - def __init__( - self, - config: EvalConfig, - llm_provider: CompletionProvider, - prompt_provider: PromptProvider, - ): - super().__init__(config) - - self.llm_provider = llm_provider - self.prompt_provider = prompt_provider - - def _calc_query_context_relevancy(self, query: str, context: str) -> float: - system_prompt = self.prompt_provider.get_prompt("default_system") - eval_prompt = self.prompt_provider.get_prompt( - "rag_context_eval", {"query": query, "context": context} - ) - response = self.llm_provider.get_completion( - self.prompt_provider._get_message_payload( - system_prompt, eval_prompt - ), - self.eval_generation_config, - ) - response_text = response.choices[0].message.content - fraction = ( - response_text - # Get the fraction in the returned tuple - .split(",")[-1][:-1] - # Remove any quotes and spaces - .replace("'", "") - .replace('"', "") - .strip() - ) - return float(Fraction(fraction)) - - def _calc_answer_grounding( - self, query: str, context: str, answer: str - ) -> float: - system_prompt = self.prompt_provider.get_prompt("default_system") - eval_prompt = self.prompt_provider.get_prompt( - "rag_answer_eval", - {"query": query, "context": context, "answer": answer}, - ) - response = self.llm_provider.get_completion( - self.prompt_provider._get_message_payload( - system_prompt, eval_prompt - ), - self.eval_generation_config, - ) - response_text = response.choices[0].message.content - fraction = ( - response_text - # Get the fraction in the returned tuple - .split(",")[-1][:-1] - # Remove any quotes and spaces - .replace("'", "") - .replace('"', "") - .strip() - ) - return float(Fraction(fraction)) - - def _evaluate( - self, - query: str, - context: str, - answer: str, - eval_generation_config: GenerationConfig, - ) -> dict[str, dict[str, Union[str, float]]]: - self.eval_generation_config = eval_generation_config - query_context_relevancy = self._calc_query_context_relevancy( - query, context - ) - answer_grounding = self._calc_answer_grounding(query, context, answer) - return { - "query_context_relevancy": query_context_relevancy, - "answer_grounding": answer_grounding, - } diff --git a/r2r/providers/kg/neo4j.py b/r2r/providers/kg/neo4j.py deleted file mode 100644 index 01e0f0681..000000000 --- a/r2r/providers/kg/neo4j.py +++ /dev/null @@ -1,989 +0,0 @@ -# abstractions are taken from LlamaIndex -# Neo4jKGProvider is almost entirely taken from LlamaIndex Neo4jPropertyGraphStore -# https://github.com/run-llama/llama_index -import json -import os -from typing import Any, Dict, List, Optional, Tuple - -from r2r.base import ( - EntityType, - KGConfig, - KGProvider, - PromptProvider, - format_entity_types, - format_relations, -) -from r2r.base.abstractions.llama_abstractions import ( - LIST_LIMIT, - ChunkNode, - EntityNode, - LabelledNode, - PropertyGraphStore, - Relation, - Triplet, - VectorStoreQuery, - clean_string_values, - value_sanitize, -) - - -def remove_empty_values(input_dict): - """ - Remove entries with empty values from the dictionary. - - Parameters: - input_dict (dict): The dictionary from which empty values need to be removed. - - Returns: - dict: A new dictionary with all empty values removed. - """ - # Create a new dictionary excluding empty values - return {key: value for key, value in input_dict.items() if value} - - -BASE_ENTITY_LABEL = "__Entity__" -EXCLUDED_LABELS = ["_Bloom_Perspective_", "_Bloom_Scene_"] -EXCLUDED_RELS = ["_Bloom_HAS_SCENE_"] -EXHAUSTIVE_SEARCH_LIMIT = 10000 -# Threshold for returning all available prop values in graph schema -DISTINCT_VALUE_LIMIT = 10 - -node_properties_query = """ -CALL apoc.meta.data() -YIELD label, other, elementType, type, property -WHERE NOT type = "RELATIONSHIP" AND elementType = "node" - AND NOT label IN $EXCLUDED_LABELS -WITH label AS nodeLabels, collect({property:property, type:type}) AS properties -RETURN {labels: nodeLabels, properties: properties} AS output - -""" - -rel_properties_query = """ -CALL apoc.meta.data() -YIELD label, other, elementType, type, property -WHERE NOT type = "RELATIONSHIP" AND elementType = "relationship" - AND NOT label in $EXCLUDED_LABELS -WITH label AS nodeLabels, collect({property:property, type:type}) AS properties -RETURN {type: nodeLabels, properties: properties} AS output -""" - -rel_query = """ -CALL apoc.meta.data() -YIELD label, other, elementType, type, property -WHERE type = "RELATIONSHIP" AND elementType = "node" -UNWIND other AS other_node -WITH * WHERE NOT label IN $EXCLUDED_LABELS - AND NOT other_node IN $EXCLUDED_LABELS -RETURN {start: label, type: property, end: toString(other_node)} AS output -""" - - -class Neo4jKGProvider(PropertyGraphStore, KGProvider): - r""" - Neo4j Property Graph Store. - - This class implements a Neo4j property graph store. - - If you are using local Neo4j instead of aura, here's a helpful - command for launching the docker container: - - ```bash - docker run \ - -p 7474:7474 -p 7687:7687 \ - -v $PWD/data:/data -v $PWD/plugins:/plugins \ - --name neo4j-apoc \ - -e NEO4J_apoc_export_file_enabled=true \ - -e NEO4J_apoc_import_file_enabled=true \ - -e NEO4J_apoc_import_file_use__neo4j__config=true \ - -e NEO4JLABS_PLUGINS=\\[\"apoc\"\\] \ - neo4j:latest - ``` - - Args: - username (str): The username for the Neo4j database. - password (str): The password for the Neo4j database. - url (str): The URL for the Neo4j database. - database (Optional[str]): The name of the database to connect to. Defaults to "neo4j". - - Examples: - `pip install llama-index-graph-stores-neo4j` - - ```python - from llama_index.core.indices.property_graph import PropertyGraphIndex - from llama_index.graph_stores.neo4j import Neo4jKGProvider - - # Create a Neo4jKGProvider instance - graph_store = Neo4jKGProvider( - username="neo4j", - password="neo4j", - url="bolt://localhost:7687", - database="neo4j" - ) - - # create the index - index = PropertyGraphIndex.from_documents( - documents, - property_graph_store=graph_store, - ) - ``` - """ - - supports_structured_queries: bool = True - supports_vector_queries: bool = True - - def __init__( - self, - config: KGConfig, - refresh_schema: bool = True, - sanitize_query_output: bool = True, - enhanced_schema: bool = False, - *args: Any, - **kwargs: Any, - ) -> None: - if config.provider != "neo4j": - raise ValueError( - "Neo4jKGProvider must be initialized with config with `neo4j` provider." - ) - - try: - import neo4j - except ImportError: - raise ImportError("Please install neo4j: pip install neo4j") - - username = config.extra_fields.get("user", None) or os.getenv( - "NEO4J_USER" - ) - password = config.extra_fields.get("password", None) or os.getenv( - "NEO4J_PASSWORD" - ) - url = config.extra_fields.get("url", None) or os.getenv("NEO4J_URL") - database = config.extra_fields.get("database", None) or os.getenv( - "NEO4J_DATABASE", "neo4j" - ) - - if not username or not password or not url: - raise ValueError( - "Neo4j configuration values are missing. Please set NEO4J_USER, NEO4J_PASSWORD, and NEO4J_URL environment variables." - ) - - self.sanitize_query_output = sanitize_query_output - self.enhcnaced_schema = enhanced_schema - self._driver = neo4j.GraphDatabase.driver( - url, auth=(username, password), **kwargs - ) - self._async_driver = neo4j.AsyncGraphDatabase.driver( - url, - auth=(username, password), - **kwargs, - ) - self._database = database - self.structured_schema = {} - if refresh_schema: - self.refresh_schema() - self.neo4j = neo4j - self.config = config - - @property - def client(self): - return self._driver - - def refresh_schema(self) -> None: - """Refresh the schema.""" - node_query_results = self.structured_query( - node_properties_query, - param_map={ - "EXCLUDED_LABELS": [*EXCLUDED_LABELS, BASE_ENTITY_LABEL] - }, - ) - node_properties = ( - [el["output"] for el in node_query_results] - if node_query_results - else [] - ) - - rels_query_result = self.structured_query( - rel_properties_query, param_map={"EXCLUDED_LABELS": EXCLUDED_RELS} - ) - rel_properties = ( - [el["output"] for el in rels_query_result] - if rels_query_result - else [] - ) - - rel_objs_query_result = self.structured_query( - rel_query, - param_map={ - "EXCLUDED_LABELS": [*EXCLUDED_LABELS, BASE_ENTITY_LABEL] - }, - ) - relationships = ( - [el["output"] for el in rel_objs_query_result] - if rel_objs_query_result - else [] - ) - - # Get constraints & indexes - try: - constraint = self.structured_query("SHOW CONSTRAINTS") - index = self.structured_query( - "CALL apoc.schema.nodes() YIELD label, properties, type, size, " - "valuesSelectivity WHERE type = 'RANGE' RETURN *, " - "size * valuesSelectivity as distinctValues" - ) - except ( - self.neo4j.exceptions.ClientError - ): # Read-only user might not have access to schema information - constraint = [] - index = [] - - self.structured_schema = { - "node_props": { - el["labels"]: el["properties"] for el in node_properties - }, - "rel_props": { - el["type"]: el["properties"] for el in rel_properties - }, - "relationships": relationships, - "metadata": {"constraint": constraint, "index": index}, - } - schema_counts = self.structured_query( - "CALL apoc.meta.graphSample() YIELD nodes, relationships " - "RETURN nodes, [rel in relationships | {name:apoc.any.property" - "(rel, 'type'), count: apoc.any.property(rel, 'count')}]" - " AS relationships" - ) - # Update node info - for node in schema_counts[0].get("nodes", []): - # Skip bloom labels - if node["name"] in EXCLUDED_LABELS: - continue - node_props = self.structured_schema["node_props"].get(node["name"]) - if not node_props: # The node has no properties - continue - enhanced_cypher = self._enhanced_schema_cypher( - node["name"], - node_props, - node["count"] < EXHAUSTIVE_SEARCH_LIMIT, - ) - enhanced_info = self.structured_query(enhanced_cypher)[0]["output"] - for prop in node_props: - if prop["property"] in enhanced_info: - prop.update(enhanced_info[prop["property"]]) - # Update rel info - for rel in schema_counts[0].get("relationships", []): - # Skip bloom labels - if rel["name"] in EXCLUDED_RELS: - continue - rel_props = self.structured_schema["rel_props"].get(rel["name"]) - if not rel_props: # The rel has no properties - continue - enhanced_cypher = self._enhanced_schema_cypher( - rel["name"], - rel_props, - rel["count"] < EXHAUSTIVE_SEARCH_LIMIT, - is_relationship=True, - ) - try: - enhanced_info = self.structured_query(enhanced_cypher)[0][ - "output" - ] - for prop in rel_props: - if prop["property"] in enhanced_info: - prop.update(enhanced_info[prop["property"]]) - except self.neo4j.exceptions.ClientError: - # Sometimes the types are not consistent in the db - pass - - def upsert_nodes(self, nodes: List[LabelledNode]) -> None: - # Lists to hold separated types - entity_dicts: List[dict] = [] - chunk_dicts: List[dict] = [] - - # Sort by type - for item in nodes: - if isinstance(item, EntityNode): - entity_dicts.append({**item.dict(), "id": item.id}) - elif isinstance(item, ChunkNode): - chunk_dicts.append({**item.dict(), "id": item.id}) - else: - # Log that we do not support these types of nodes - # Or raise an error? - pass - - if chunk_dicts: - self.structured_query( - """ - UNWIND $data AS row - MERGE (c:Chunk {id: row.id}) - SET c.text = row.text - WITH c, row - SET c += row.properties - WITH c, row.embedding AS embedding - WHERE embedding IS NOT NULL - CALL db.create.setNodeVectorProperty(c, 'embedding', embedding) - RETURN count(*) - """, - param_map={"data": chunk_dicts}, - ) - - if entity_dicts: - self.structured_query( - """ - UNWIND $data AS row - MERGE (e:`__Entity__` {id: row.id}) - SET e += apoc.map.clean(row.properties, [], []) - SET e.name = row.name - WITH e, row - CALL apoc.create.addLabels(e, [row.label]) - YIELD node - WITH e, row - CALL { - WITH e, row - WITH e, row - WHERE row.embedding IS NOT NULL - CALL db.create.setNodeVectorProperty(e, 'embedding', row.embedding) - RETURN count(*) AS count - } - WITH e, row WHERE row.properties.triplet_source_id IS NOT NULL - MERGE (c:Chunk {id: row.properties.triplet_source_id}) - MERGE (e)<-[:MENTIONS]-(c) - """, - param_map={"data": entity_dicts}, - ) - - def upsert_relations(self, relations: List[Relation]) -> None: - """Add relations.""" - params = [r.dict() for r in relations] - - self.structured_query( - """ - UNWIND $data AS row - MERGE (source {id: row.source_id}) - MERGE (target {id: row.target_id}) - WITH source, target, row - CALL apoc.merge.relationship(source, row.label, {}, row.properties, target) YIELD rel - RETURN count(*) - """, - param_map={"data": params}, - ) - - def get( - self, - properties: Optional[dict] = None, - ids: Optional[List[str]] = None, - ) -> List[LabelledNode]: - """Get nodes.""" - cypher_statement = "MATCH (e) " - - params = {} - if properties or ids: - cypher_statement += "WHERE " - - if ids: - cypher_statement += "e.id in $ids " - params["ids"] = ids - - if properties: - prop_list = [] - for i, prop in enumerate(properties): - prop_list.append(f"e.`{prop}` = $property_{i}") - params[f"property_{i}"] = properties[prop] - cypher_statement += " AND ".join(prop_list) - - return_statement = """ - WITH e - RETURN e.id AS name, - [l in labels(e) WHERE l <> '__Entity__' | l][0] AS type, - e{.* , embedding: Null, id: Null} AS properties - """ - cypher_statement += return_statement - - response = self.structured_query(cypher_statement, param_map=params) - response = response if response else [] - - nodes = [] - for record in response: - # text indicates a chunk node - # none on the type indicates an implicit node, likely a chunk node - if "text" in record["properties"] or record["type"] is None: - text = record["properties"].pop("text", "") - nodes.append( - ChunkNode( - id_=record["name"], - text=text, - properties=remove_empty_values(record["properties"]), - ) - ) - else: - nodes.append( - EntityNode( - name=record["name"], - label=record["type"], - properties=remove_empty_values(record["properties"]), - ) - ) - - return nodes - - def get_triplets( - self, - entity_names: Optional[List[str]] = None, - relation_names: Optional[List[str]] = None, - properties: Optional[dict] = None, - ids: Optional[List[str]] = None, - ) -> List[Triplet]: - # TODO: handle ids of chunk nodes - cypher_statement = "MATCH (e:`__Entity__`) " - - params = {} - if entity_names or properties or ids: - cypher_statement += "WHERE " - - if entity_names: - cypher_statement += "e.name in $entity_names " - params["entity_names"] = entity_names - - if ids: - cypher_statement += "e.id in $ids " - params["ids"] = ids - - if properties: - prop_list = [] - for i, prop in enumerate(properties): - prop_list.append(f"e.`{prop}` = $property_{i}") - params[f"property_{i}"] = properties[prop] - cypher_statement += " AND ".join(prop_list) - - return_statement = f""" - WITH e - CALL {{ - WITH e - MATCH (e)-[r{':`' + '`|`'.join(relation_names) + '`' if relation_names else ''}]->(t) - RETURN e.name AS source_id, [l in labels(e) WHERE l <> '__Entity__' | l][0] AS source_type, - e{{.* , embedding: Null, name: Null}} AS source_properties, - type(r) AS type, - t.name AS target_id, [l in labels(t) WHERE l <> '__Entity__' | l][0] AS target_type, - t{{.* , embedding: Null, name: Null}} AS target_properties - UNION ALL - WITH e - MATCH (e)<-[r{':`' + '`|`'.join(relation_names) + '`' if relation_names else ''}]-(t) - RETURN t.name AS source_id, [l in labels(t) WHERE l <> '__Entity__' | l][0] AS source_type, - e{{.* , embedding: Null, name: Null}} AS source_properties, - type(r) AS type, - e.name AS target_id, [l in labels(e) WHERE l <> '__Entity__' | l][0] AS target_type, - t{{.* , embedding: Null, name: Null}} AS target_properties - }} - RETURN source_id, source_type, type, target_id, target_type, source_properties, target_properties""" - cypher_statement += return_statement - - data = self.structured_query(cypher_statement, param_map=params) - data = data if data else [] - - triples = [] - for record in data: - source = EntityNode( - name=record["source_id"], - label=record["source_type"], - properties=remove_empty_values(record["source_properties"]), - ) - target = EntityNode( - name=record["target_id"], - label=record["target_type"], - properties=remove_empty_values(record["target_properties"]), - ) - rel = Relation( - source_id=record["source_id"], - target_id=record["target_id"], - label=record["type"], - ) - triples.append([source, rel, target]) - return triples - - def get_rel_map( - self, - graph_nodes: List[LabelledNode], - depth: int = 2, - limit: int = 30, - ignore_rels: Optional[List[str]] = None, - ) -> List[Triplet]: - """Get depth-aware rel map.""" - triples = [] - - ids = [node.id for node in graph_nodes] - # Needs some optimization - response = self.structured_query( - f""" - MATCH (e:`__Entity__`) - WHERE e.id in $ids - MATCH p=(e)-[r*1..{depth}]-(other) - WHERE ALL(rel in relationships(p) WHERE type(rel) <> 'MENTIONS') - UNWIND relationships(p) AS rel - WITH distinct rel - WITH startNode(rel) AS source, - type(rel) AS type, - endNode(rel) AS endNode - RETURN source.id AS source_id, [l in labels(source) WHERE l <> '__Entity__' | l][0] AS source_type, - source{{.* , embedding: Null, id: Null}} AS source_properties, - type, - endNode.id AS target_id, [l in labels(endNode) WHERE l <> '__Entity__' | l][0] AS target_type, - endNode{{.* , embedding: Null, id: Null}} AS target_properties - LIMIT toInteger($limit) - """, - param_map={"ids": ids, "limit": limit}, - ) - response = response if response else [] - - ignore_rels = ignore_rels or [] - for record in response: - if record["type"] in ignore_rels: - continue - - source = EntityNode( - name=record["source_id"], - label=record["source_type"], - properties=remove_empty_values(record["source_properties"]), - ) - target = EntityNode( - name=record["target_id"], - label=record["target_type"], - properties=remove_empty_values(record["target_properties"]), - ) - rel = Relation( - source_id=record["source_id"], - target_id=record["target_id"], - label=record["type"], - ) - triples.append([source, rel, target]) - - return triples - - def structured_query( - self, query: str, param_map: Optional[Dict[str, Any]] = None - ) -> Any: - param_map = param_map or {} - - with self._driver.session(database=self._database) as session: - result = session.run(query, param_map) - full_result = [d.data() for d in result] - - if self.sanitize_query_output: - return value_sanitize(full_result) - - return full_result - - def vector_query( - self, query: VectorStoreQuery, **kwargs: Any - ) -> Tuple[List[LabelledNode], List[float]]: - """Query the graph store with a vector store query.""" - data = self.structured_query( - """MATCH (e:`__Entity__`) - WHERE e.embedding IS NOT NULL AND size(e.embedding) = $dimension - WITH e, vector.similarity.cosine(e.embedding, $embedding) AS score - ORDER BY score DESC LIMIT toInteger($limit) - RETURN e.id AS name, - [l in labels(e) WHERE l <> '__Entity__' | l][0] AS type, - e{.* , embedding: Null, name: Null, id: Null} AS properties, - score""", - param_map={ - "embedding": query.query_embedding, - "dimension": len(query.query_embedding), - "limit": query.similarity_top_k, - }, - ) - data = data if data else [] - - nodes = [] - scores = [] - for record in data: - node = EntityNode( - name=record["name"], - label=record["type"], - properties=remove_empty_values(record["properties"]), - ) - nodes.append(node) - scores.append(record["score"]) - - return (nodes, scores) - - def delete( - self, - entity_names: Optional[List[str]] = None, - relation_names: Optional[List[str]] = None, - properties: Optional[dict] = None, - ids: Optional[List[str]] = None, - ) -> None: - """Delete matching data.""" - if entity_names: - self.structured_query( - "MATCH (n) WHERE n.name IN $entity_names DETACH DELETE n", - param_map={"entity_names": entity_names}, - ) - - if ids: - self.structured_query( - "MATCH (n) WHERE n.id IN $ids DETACH DELETE n", - param_map={"ids": ids}, - ) - - if relation_names: - for rel in relation_names: - self.structured_query(f"MATCH ()-[r:`{rel}`]->() DELETE r") - - if properties: - cypher = "MATCH (e) WHERE " - prop_list = [] - params = {} - for i, prop in enumerate(properties): - prop_list.append(f"e.`{prop}` = $property_{i}") - params[f"property_{i}"] = properties[prop] - cypher += " AND ".join(prop_list) - self.structured_query( - cypher + " DETACH DELETE e", param_map=params - ) - - def _enhanced_schema_cypher( - self, - label_or_type: str, - properties: List[Dict[str, Any]], - exhaustive: bool, - is_relationship: bool = False, - ) -> str: - if is_relationship: - match_clause = f"MATCH ()-[n:`{label_or_type}`]->()" - else: - match_clause = f"MATCH (n:`{label_or_type}`)" - - with_clauses = [] - return_clauses = [] - output_dict = {} - if exhaustive: - for prop in properties: - prop_name = prop["property"] - prop_type = prop["type"] - if prop_type == "STRING": - with_clauses.append( - f"collect(distinct substring(toString(n.`{prop_name}`), 0, 50)) " - f"AS `{prop_name}_values`" - ) - return_clauses.append( - f"values:`{prop_name}_values`[..{DISTINCT_VALUE_LIMIT}]," - f" distinct_count: size(`{prop_name}_values`)" - ) - elif prop_type in [ - "INTEGER", - "FLOAT", - "DATE", - "DATE_TIME", - "LOCAL_DATE_TIME", - ]: - with_clauses.append( - f"min(n.`{prop_name}`) AS `{prop_name}_min`" - ) - with_clauses.append( - f"max(n.`{prop_name}`) AS `{prop_name}_max`" - ) - with_clauses.append( - f"count(distinct n.`{prop_name}`) AS `{prop_name}_distinct`" - ) - return_clauses.append( - f"min: toString(`{prop_name}_min`), " - f"max: toString(`{prop_name}_max`), " - f"distinct_count: `{prop_name}_distinct`" - ) - elif prop_type == "LIST": - with_clauses.append( - f"min(size(n.`{prop_name}`)) AS `{prop_name}_size_min`, " - f"max(size(n.`{prop_name}`)) AS `{prop_name}_size_max`" - ) - return_clauses.append( - f"min_size: `{prop_name}_size_min`, " - f"max_size: `{prop_name}_size_max`" - ) - elif prop_type in ["BOOLEAN", "POINT", "DURATION"]: - continue - output_dict[prop_name] = "{" + return_clauses.pop() + "}" - else: - # Just sample 5 random nodes - match_clause += " WITH n LIMIT 5" - for prop in properties: - prop_name = prop["property"] - prop_type = prop["type"] - - # Check if indexed property, we can still do exhaustive - prop_index = [ - el - for el in self.structured_schema["metadata"]["index"] - if el["label"] == label_or_type - and el["properties"] == [prop_name] - and el["type"] == "RANGE" - ] - if prop_type == "STRING": - if ( - prop_index - and prop_index[0].get("size") > 0 - and prop_index[0].get("distinctValues") - <= DISTINCT_VALUE_LIMIT - ): - distinct_values = self.query( - f"CALL apoc.schema.properties.distinct(" - f"'{label_or_type}', '{prop_name}') YIELD value" - )[0]["value"] - return_clauses.append( - f"values: {distinct_values}," - f" distinct_count: {len(distinct_values)}" - ) - else: - with_clauses.append( - f"collect(distinct substring(n.`{prop_name}`, 0, 50)) " - f"AS `{prop_name}_values`" - ) - return_clauses.append(f"values: `{prop_name}_values`") - elif prop_type in [ - "INTEGER", - "FLOAT", - "DATE", - "DATE_TIME", - "LOCAL_DATE_TIME", - ]: - if not prop_index: - with_clauses.append( - f"collect(distinct toString(n.`{prop_name}`)) " - f"AS `{prop_name}_values`" - ) - return_clauses.append(f"values: `{prop_name}_values`") - else: - with_clauses.append( - f"min(n.`{prop_name}`) AS `{prop_name}_min`" - ) - with_clauses.append( - f"max(n.`{prop_name}`) AS `{prop_name}_max`" - ) - with_clauses.append( - f"count(distinct n.`{prop_name}`) AS `{prop_name}_distinct`" - ) - return_clauses.append( - f"min: toString(`{prop_name}_min`), " - f"max: toString(`{prop_name}_max`), " - f"distinct_count: `{prop_name}_distinct`" - ) - - elif prop_type == "LIST": - with_clauses.append( - f"min(size(n.`{prop_name}`)) AS `{prop_name}_size_min`, " - f"max(size(n.`{prop_name}`)) AS `{prop_name}_size_max`" - ) - return_clauses.append( - f"min_size: `{prop_name}_size_min`, " - f"max_size: `{prop_name}_size_max`" - ) - elif prop_type in ["BOOLEAN", "POINT", "DURATION"]: - continue - - output_dict[prop_name] = "{" + return_clauses.pop() + "}" - - with_clause = "WITH " + ",\n ".join(with_clauses) - return_clause = ( - "RETURN {" - + ", ".join(f"`{k}`: {v}" for k, v in output_dict.items()) - + "} AS output" - ) - - # Combine all parts of the Cypher query - return f"{match_clause}\n{with_clause}\n{return_clause}" - - def get_schema(self, refresh: bool = False) -> Any: - if refresh: - self.refresh_schema() - - return self.structured_schema - - def get_schema_str(self, refresh: bool = False) -> str: - schema = self.get_schema(refresh=refresh) - - formatted_node_props = [] - formatted_rel_props = [] - - if self.enhcnaced_schema: - # Enhanced formatting for nodes - for node_type, properties in schema["node_props"].items(): - formatted_node_props.append(f"- **{node_type}**") - for prop in properties: - example = "" - if prop["type"] == "STRING" and prop.get("values"): - if ( - prop.get("distinct_count", 11) - > DISTINCT_VALUE_LIMIT - ): - example = ( - f'Example: "{clean_string_values(prop["values"][0])}"' - if prop["values"] - else "" - ) - else: # If less than 10 possible values return all - example = ( - ( - "Available options: " - f'{[clean_string_values(el) for el in prop["values"]]}' - ) - if prop["values"] - else "" - ) - - elif prop["type"] in [ - "INTEGER", - "FLOAT", - "DATE", - "DATE_TIME", - "LOCAL_DATE_TIME", - ]: - if prop.get("min") is not None: - example = f'Min: {prop["min"]}, Max: {prop["max"]}' - else: - example = ( - f'Example: "{prop["values"][0]}"' - if prop.get("values") - else "" - ) - elif prop["type"] == "LIST": - # Skip embeddings - if ( - not prop.get("min_size") - or prop["min_size"] > LIST_LIMIT - ): - continue - example = f'Min Size: {prop["min_size"]}, Max Size: {prop["max_size"]}' - formatted_node_props.append( - f" - `{prop['property']}`: {prop['type']} {example}" - ) - - # Enhanced formatting for relationships - for rel_type, properties in schema["rel_props"].items(): - formatted_rel_props.append(f"- **{rel_type}**") - for prop in properties: - example = "" - if prop["type"] == "STRING": - if ( - prop.get("distinct_count", 11) - > DISTINCT_VALUE_LIMIT - ): - example = ( - f'Example: "{clean_string_values(prop["values"][0])}"' - if prop.get("values") - else "" - ) - else: # If less than 10 possible values return all - example = ( - ( - "Available options: " - f'{[clean_string_values(el) for el in prop["values"]]}' - ) - if prop.get("values") - else "" - ) - elif prop["type"] in [ - "INTEGER", - "FLOAT", - "DATE", - "DATE_TIME", - "LOCAL_DATE_TIME", - ]: - if prop.get("min"): # If we have min/max - example = ( - f'Min: {prop["min"]}, Max: {prop["max"]}' - ) - else: # return a single value - example = ( - f'Example: "{prop["values"][0]}"' - if prop.get("values") - else "" - ) - elif prop["type"] == "LIST": - # Skip embeddings - if prop["min_size"] > LIST_LIMIT: - continue - example = f'Min Size: {prop["min_size"]}, Max Size: {prop["max_size"]}' - formatted_rel_props.append( - f" - `{prop['property']}: {prop['type']}` {example}" - ) - else: - # Format node properties - for label, props in schema["node_props"].items(): - props_str = ", ".join( - [f"{prop['property']}: {prop['type']}" for prop in props] - ) - formatted_node_props.append(f"{label} {{{props_str}}}") - - # Format relationship properties using structured_schema - for type, props in schema["rel_props"].items(): - props_str = ", ".join( - [f"{prop['property']}: {prop['type']}" for prop in props] - ) - formatted_rel_props.append(f"{type} {{{props_str}}}") - - # Format relationships - formatted_rels = [ - f"(:{el['start']})-[:{el['type']}]->(:{el['end']})" - for el in schema["relationships"] - ] - - return "\n".join( - [ - "Node properties:", - "\n".join(formatted_node_props), - "Relationship properties:", - "\n".join(formatted_rel_props), - "The relationships:", - "\n".join(formatted_rels), - ] - ) - - def update_extraction_prompt( - self, - prompt_provider: PromptProvider, - entity_types: list[EntityType], - relations: list[Relation], - ): - # Fetch the kg extraction prompt with blank entity types and relations - # Note - Assumes that for given prompt there is a `_with_spec` that can have entities + relations specified - few_shot_ner_kg_extraction_with_spec = prompt_provider.get_prompt( - f"{self.config.kg_extraction_prompt}_with_spec" - ) - - # Format the prompt to include the desired entity types and relations - few_shot_ner_kg_extraction = ( - few_shot_ner_kg_extraction_with_spec.replace( - "{entity_types}", format_entity_types(entity_types) - ).replace("{relations}", format_relations(relations)) - ) - - # Update the "few_shot_ner_kg_extraction" prompt used in downstream KG construction - prompt_provider.update_prompt( - self.config.kg_extraction_prompt, - json.dumps(few_shot_ner_kg_extraction, ensure_ascii=False), - ) - - def update_kg_search_prompt( - self, - prompt_provider: PromptProvider, - entity_types: list[EntityType], - relations: list[Relation], - ): - # Fetch the kg extraction prompt with blank entity types and relations - # Note - Assumes that for given prompt there is a `_with_spec` that can have entities + relations specified - few_shot_ner_kg_extraction_with_spec = prompt_provider.get_prompt( - f"{self.config.kg_search_prompt}_with_spec" - ) - - # Format the prompt to include the desired entity types and relations - few_shot_ner_kg_extraction = ( - few_shot_ner_kg_extraction_with_spec.replace( - "{entity_types}", - format_entity_types(entity_types, ignore_subcats=True), - ).replace("{relations}", format_relations(relations)) - ) - - # Update the "few_shot_ner_kg_extraction" prompt used in downstream KG construction - prompt_provider.update_prompt( - self.config.kg_search_prompt, - json.dumps(few_shot_ner_kg_extraction, ensure_ascii=False), - ) diff --git a/r2r/providers/kg/neo4j/__init__.py b/r2r/providers/kg/neo4j/__init__.py new file mode 100644 index 000000000..cb10b1add --- /dev/null +++ b/r2r/providers/kg/neo4j/__init__.py @@ -0,0 +1 @@ +from .provider import Neo4jKGProvider diff --git a/r2r/providers/kg/neo4j/graph_queries.py b/r2r/providers/kg/neo4j/graph_queries.py new file mode 100644 index 000000000..4468ca9d3 --- /dev/null +++ b/r2r/providers/kg/neo4j/graph_queries.py @@ -0,0 +1,168 @@ +UNIQUE_CONSTRAINTS = [ + # "create constraint chunk_id if not exists for (c:__Chunk__) require c.id is unique;", + # "create constraint document_id if not exists for (d:__Document__) require d.id is unique;", + # "create constraint entity_id if not exists for (c:__Community__) require c.community is unique;", + # "create constraint entity_id if not exists for (e:__Entity__) require e.id is unique;", + # "create constraint entity_title if not exists for (e:__Entity__) require e.name is unique;", + # "create constraint entity_title if not exists for (e:__Covariate__) require e.title is unique;", + # "create constraint related_id if not exists for ()-[rel:RELATED]->() require rel.id is unique;" +] + +GET_CHUNKS_QUERY = """ +MATCH (c:__Chunk__) +RETURN c +""" + +# class DocumentFragment(BaseModel): +# """A fragment extracted from a document.""" + +# id: uuid.UUID +# type: FragmentType +# data: DataType +# metadata: dict +# document_id: uuid.UUID +# extraction_id: uuid.UUID + + +PUT_CHUNKS_QUERY = """ +MERGE (c:__Chunk__ {id:value.id}) +SET c += value {.type, .data, .metadata, .document_id, .extraction_id} +MERGE (d:__Document__ {id:value.document_id}) +MERGE (n)-[:PART_OF_DOCUMENT]->(d) +""" + +# searching by entity_name +GET_ENTITIES_QUERY = """ +MATCH (e:__Entity__) +WHERE size($entity_ids) = 0 OR e.name IN $entity_ids +RETURN e +""" + +PUT_ENTITIES_QUERY = """ +WITH value, apoc.text.capitalize(value.category) AS upperCamelCategory +MERGE (e:__Entity__ {name: value.name}) +ON CREATE SET e:__Entity__ +ON MATCH SET e:__Entity__ +WITH e, upperCamelCategory, value +CALL apoc.create.addLabels(e, [upperCamelCategory]) YIELD node +SET node.description = CASE + WHEN node.description IS NULL THEN value.description + ELSE node.description + '\n\n' + value.description +END, +node.rank = CASE + WHEN node.rank IS NULL THEN value.rank + ELSE CASE WHEN value.rank > node.rank THEN value.rank ELSE node.rank END +END, +node.attributes = CASE + WHEN node.attributes IS NULL THEN value.attributes + ELSE node.attributes + '\n\n' + value.attributes +END +WITH node as e, value +UNWIND value.text_unit_ids AS text_unit +MATCH (c:__Chunk__ {id:text_unit}) +MERGE (e)-[:APPEARS_IN_CHUNK]->(c) +WITH e, value +UNWIND value.document_ids AS document_id +MATCH (d:__Document__ {id:document_id}) +MERGE (e)-[:APPEARS_IN_DOCUMENT]->(d) +WITH e, value +UNWIND value.community_ids AS community_id +MATCH (comm:__Community__ {community:community_id}) +MERGE (e)-[:BELONGS_TO_COMMUNITY]->(comm) +""" + +# use this after PUT_ENTITIES_QUERY when you have embeddings. +PUT_ENTITIES_EMBEDDINGS_QUERY = """ +MATCH (e:__Entity__ {name: value.name}) +SET e += value {.description} +WITH e, value +CALL db.create.setNodeVectorProperty(e, "name_embedding", value.name_embedding) +CALL db.create.setNodeVectorProperty(e, "description_embedding", value.description_embedding) +""" + +## get triples by subject and object +GET_TRIPLES_QUERY = """ + MATCH (e1)-[rel]->(e2) + RETURN e1, rel, e2 +""" + +GET_TRIPLES_BY_SUBJECT_AND_OBJECT_QUERY = """ +UNWIND $triples AS triple + MATCH (e1:__Entity__)-[rel]->(e2:__Entity__) + WHERE e1.name = triple.subject + AND e2.name = triple.object + AND type(rel) = triple.predicate + RETURN e1, rel, e2 +""" + +PUT_TRIPLES_QUERY = """ +WITH value, apoc.text.capitalize(value.predicate) AS upperCamelPredicate +MATCH (source:__Entity__ {name: value.subject}) +MATCH (target:__Entity__ {name: value.object}) +WITH source, target, value, upperCamelPredicate +CALL apoc.merge.relationship(source, upperCamelPredicate, {}, {}, target) YIELD rel +SET rel.weight = CASE + WHEN rel.weight IS NULL THEN value.weight + ELSE CASE WHEN value.weight > rel.weight THEN value.weight ELSE rel.weight END +END, +rel.description = CASE + WHEN rel.description IS NULL THEN value.description + ELSE rel.description + '\n\n' + value.description +END, +rel.attributes = CASE + WHEN rel.attributes IS NULL THEN value.attributes + ELSE rel.attributes + '\n\n' + value.attributes +END, +rel.text_unit_ids = CASE + WHEN rel.text_unit_ids IS NULL THEN value.text_unit_ids + ELSE rel.text_unit_ids + value.text_unit_ids +END, +rel.document_ids = CASE + WHEN rel.document_ids IS NULL THEN value.document_ids + ELSE rel.document_ids + value.document_ids +END +WITH rel, value +RETURN count(*) as createdRels +""" + +GET_COMMUNITIES_QUERY = """ +MATCH (c:__Community__) +where $level = -1 OR c.level = $level +RETURN c +""" + +PUT_COMMUNITIES_QUERY = """ +MERGE (c:__Community__ {community:value.id}) +SET c += value {.level, .rank, .summary} +WITH c, value +CALL db.create.setNodeVectorProperty(c, "summary_embedding", value.summary_embedding) +RETURN count(*) as createdCommunities +""" + +GET_COMMUNITIES_REPORT_QUERY = """ +MATCH (c:__Community__) +RETURN c +""" + +PUT_COMMUNITIES_REPORT_QUERY = """ +MERGE (c:__Community__ {community:value.community}) +SET c += value {.level, .title, .rank, .rank_explanation, .full_content, .summary} +WITH c, value +UNWIND range(0, size(value.findings)-1) AS finding_idx +WITH c, value, finding_idx, value.findings[finding_idx] as finding +MERGE (c)-[:HAS_FINDING]->(f:Finding {id:finding_idx}) +SET f += finding +""" + +GET_COVARIATES_QUERY = """ +MATCH (c:__Covariate__ {id:value.id}) +RETURN c +""" + +PUT_COVARIATES_QUERY = """ +MERGE (c:__Covariate__ {id:value.id}) +SET c += apoc.map.clean(value, ["text_unit_id", "document_ids", "n_tokens"], [NULL, ""]) +WITH c, value +MATCH (ch:__Chunk__ {id: value.text_unit_id}) +MERGE (ch)-[:HAS_COVARIATE]->(c) +""" diff --git a/r2r/providers/kg/neo4j/provider.py b/r2r/providers/kg/neo4j/provider.py new file mode 100644 index 000000000..a8b89769c --- /dev/null +++ b/r2r/providers/kg/neo4j/provider.py @@ -0,0 +1,405 @@ +import json +import os +import time +import uuid +from datetime import date, datetime +from decimal import Decimal +from typing import Any, Dict, List, Optional + +from r2r.base import ( + KGConfig, + KGProvider, + format_entity_types, + format_relations, +) +from r2r.base.abstractions.document import DocumentFragment +from r2r.base.abstractions.graph import ( + Community, + Entity, + KGExtraction, + RelationshipType, + Triple, +) + +from .graph_queries import ( + GET_CHUNKS_QUERY, + GET_COMMUNITIES_QUERY, + GET_COMMUNITIES_REPORT_QUERY, + GET_COVARIATES_QUERY, + GET_ENTITIES_QUERY, + GET_TRIPLES_BY_SUBJECT_AND_OBJECT_QUERY, + GET_TRIPLES_QUERY, + PUT_CHUNKS_QUERY, + PUT_COMMUNITIES_QUERY, + PUT_COMMUNITIES_REPORT_QUERY, + PUT_COVARIATES_QUERY, + PUT_ENTITIES_EMBEDDINGS_QUERY, + PUT_ENTITIES_QUERY, + PUT_TRIPLES_QUERY, + UNIQUE_CONSTRAINTS, +) + + +class Neo4jKGProvider(KGProvider): + + def __init__(self, config: KGConfig, *args: Any, **kwargs: Any) -> None: + + try: + import neo4j + except ImportError: + raise ImportError("Please install neo4j: pip install neo4j") + + username = config.extra_fields.get("user", None) or os.getenv( + "NEO4J_USER" + ) + password = config.extra_fields.get("password", None) or os.getenv( + "NEO4J_PASSWORD" + ) + url = config.extra_fields.get("url", None) or os.getenv("NEO4J_URL") + database = config.extra_fields.get("database", None) or os.getenv( + "NEO4J_DATABASE", "neo4j" + ) + + if not username or not password or not url: + raise ValueError( + "Neo4j configuration values are missing. Please set NEO4J_USER, NEO4J_PASSWORD, and NEO4J_URL environment variables." + ) + + self._driver = neo4j.GraphDatabase.driver( + url, auth=(username, password), **kwargs + ) + self._async_driver = neo4j.AsyncGraphDatabase.driver( + url, + auth=(username, password), + **kwargs, + ) + self._database = database + self.structured_schema = {} + self.config = config + + self.create_constraints() + + super().__init__(config, *args, **kwargs) + + @property + def client(self): + return self._driver + + def create_constraints(self): + for statement in UNIQUE_CONSTRAINTS: + self._driver.execute_query(statement) + + def structured_query(self, query: str, param_map: Dict[str, Any] = {}): + return self._driver.execute_query(query, parameters_=param_map) + + def convert_to_neo4j_compatible(self, value): + if isinstance(value, (str, int, float, bool)): + return value + elif isinstance(value, (datetime, date)): + return value.isoformat() + elif isinstance(value, uuid.UUID): + return str(value) + elif isinstance(value, Decimal): + return float(value) + elif isinstance(value, list): + return value + elif isinstance(value, dict): + return json.dumps(value) + else: + return str(value) + + def convert_model_list_to_neo4j_compatible(self, model_list): + return [ + { + k: self.convert_to_neo4j_compatible(v) + for k, v in item.dict().items() + } + for item in model_list + ] + + def get_entity_map( + self, entity_names: list[str] | None = None + ) -> dict[str, list[Any]]: + entities = self.get(entity_names) + triples = self.get_triples(entity_names) + entity_map = {} + for entity in entities: + if entity.name not in entity_map: + entity_map[entity.name] = {"entities": [], "triples": []} + entity_map[entity.name]["entities"].append(entity) + + for triple in triples: + if triple.subject in entity_map: + entity_map[triple.subject]["triples"].append(triple) + if triple.object in entity_map: + entity_map[triple.object]["triples"].append(triple) + return entity_map + + def batched_import(self, statement, df, batch_size=1000): + """ + Import a dataframe into Neo4j using a batched approach. + Parameters: statement is the Cypher query to execute, df is the dataframe to import, and batch_size is the number of rows to import in each batch. + """ + total = len(df) + start_s = time.time() + for start in range(0, total, batch_size): + batch = df[start : min(start + batch_size, total)] + batch = self.convert_model_list_to_neo4j_compatible(batch) + result = self._driver.execute_query( + "UNWIND $rows AS value " + statement, + rows=batch, + database_=self._database, + ) + print(result.summary.counters) + print(f"{total} rows in { time.time() - start_s} s.") + return total + + def get_chunks( + self, chunk_ids: List[str] = None + ) -> List[DocumentFragment]: + """ + Get chunks from the graph. + """ + return self.structured_query(GET_CHUNKS_QUERY, chunk_ids) + + def upsert_chunks(self, chunks: List[DocumentFragment]): + """ + Upsert chunks into the graph. + """ + return self.batched_import(PUT_CHUNKS_QUERY, chunks) + + # create constraints, idempotent operation + + def upsert_entities( + self, entities: List[Entity], with_embeddings: bool = False + ): + """ + Upsert entities into the graph. + """ + if with_embeddings: + return self.batched_import(PUT_ENTITIES_EMBEDDINGS_QUERY, entities) + else: + return self.batched_import(PUT_ENTITIES_QUERY, entities) + + def upsert_triples(self, triples: List[Triple]): + """ + Upsert relations into the graph. + """ + return self.batched_import(PUT_TRIPLES_QUERY, triples) + + def upsert_communities(self, communities: List[Community]): + """ + Upsert communities into the graph. + """ + self.batched_import(PUT_COMMUNITIES_QUERY, communities) + + def get_entities(self, entity_ids: List[str] = []) -> List[Entity]: + """ + Get entities from the graph. + """ + neo4j_records = self.structured_query( + GET_ENTITIES_QUERY, {"entity_ids": entity_ids} + ) + entities = [ + Entity( + category=", ".join(list(record["e"]._labels)[1:]), + **record["e"]._properties, + ) + for record in neo4j_records.records + ] + return entities + + def upsert_nodes_and_relationships( + self, kg_extractions: list[KGExtraction] + ) -> None: + + all_entities = [] + all_relationships = [] + for extraction in kg_extractions: + all_entities.extend(extraction.entities) + all_relationships.extend(extraction.triples) + + nodes_upserted = self.upsert_entities(all_entities) + relationships_upserted = self.upsert_triples(all_relationships) + + return nodes_upserted, relationships_upserted + + def get(self, entity_name: str = None) -> Entity: + """ + Get entities from the graph. + """ + if entity_name is None: + return self.get_entities() + else: + return self.get_entities(entity_ids=[entity_name]) + + def get_triples(self, triple_ids: list[str] | None = None) -> list[Triple]: + """ + Get triples from the graph. + """ + + if triple_ids is None: + neo4j_records = self.structured_query(GET_TRIPLES_QUERY) + else: + triple_ids = [triple_id.split("->") for triple_id in triple_ids] + triple_ids = [ + { + "subject": triple_id[0], + "predicate": triple_id[1], + "object": triple_id[2], + } + for triple_id in triple_ids + ] + neo4j_records = self.structured_query( + GET_TRIPLES_BY_SUBJECT_AND_OBJECT_QUERY, + {"triples": triple_ids}, + ) + + triples = [ + Triple( + subject=record["e1"]._properties["name"], + predicate=record["rel"].type, + object=record["e2"]._properties["name"], + **record["rel"]._properties, + ) + for record in neo4j_records.records + ] + return triples + + def update_extraction_prompt( + self, + prompt_provider: Any, + entity_types: list[Any], + relations: list[RelationshipType], + ) -> None: + pass + + def update_kg_search_prompt( + self, + prompt_provider: Any, + entity_types: list[Any], + relations: list[RelationshipType], + ) -> None: + pass + + def get_communities(self, level: int = -1) -> List[Community]: + """ + Get communities from the graph. + """ + neo4j_records = self.structured_query( + GET_COMMUNITIES_QUERY, {"level": level} + ) + communities = [ + Community(**record["c"]._properties) + for record in neo4j_records.records + ] + return communities + + def delete_all_nodes(self): + self._driver.execute_query("MATCH (a)-[r]->(b) DELETE a, r, b") + self._driver.execute_query("MATCH (a) DELETE a") + + def delete( + self, + entity_names: Optional[List[str]] = None, + relation_names: Optional[List[str]] = None, + properties: Optional[dict] = None, + ids: Optional[List[str]] = None, + ) -> None: + pass + + def get_rel_map( + self, + graph_nodes: Any, + depth: int = 2, + limit: int = 30, + ignore_rels: Optional[List[str]] = None, + ) -> List[Triple]: + pass + + def client(self): + return self._driver + + def create_vector_index(self, node_type: str, node_property: str) -> None: + + query = f""" + CREATE VECTOR INDEX `{node_type}_{node_property}` IF NOT EXISTS + + FOR (n:{node_type}) ON n.{node_property} + OPTIONS {{indexConfig: {{`vector.similarity_function`: 'cosine', `vector.dimensions`:{self.embedding_provider.config.base_dimension}}}}}""" + + self.structured_query(query) + + def get_rel_map( + self, + graph_nodes: Any, + depth: int = 2, + limit: int = 30, + ignore_rels: Optional[List[str]] = None, + ) -> List[Triple]: + pass + + def get_schema(self, refresh: bool = False) -> str: + return super().get_schema(refresh) + + def retrieve_cache(self, cache_type: str, cache_id: str) -> bool: + return False + + def vector_query(self, query, **kwargs: Any) -> Dict[str, Any]: + + query_embedding = kwargs.get("query_embedding", None) + search_type = kwargs.get("search_type", "__Entity__") + embedding_type = kwargs.get("embedding_type", "description_embedding") + property_names = kwargs.get( + "property_names", ["name", "description", "summary"] + ) + limit = kwargs.get("limit", 10) + + if search_type == "__Relationship__": + + query = f""" + MATCH () - [e] -> () + WHERE e.{embedding_type} IS NOT NULL AND size(e.{embedding_type}) = $dimension + WITH e, vector.similarity.cosine(e.{embedding_type}, $embedding) AS score + ORDER BY score DESC LIMIT toInteger($limit) + RETURN e, score + """ + + query_params = { + "embedding": query_embedding, + "dimension": len(query_embedding), + "limit": limit, + } + + else: + query = f""" + MATCH (e:{search_type}) + WHERE e.{embedding_type} IS NOT NULL AND size(e.{embedding_type}) = $dimension + WITH e, vector.similarity.cosine(e.{embedding_type}, $embedding) AS score + ORDER BY score DESC LIMIT toInteger($limit) + RETURN e, score + """ + query_params = { + "embedding": query_embedding, + "dimension": len(query_embedding), + "limit": limit, + "search_type": search_type, + } + + neo4j_results = self.structured_query(query, query_params) + + # get the descriptions from the neo4j results + # descriptions = [record['e']._properties[property_name] for record in neo4j_results.records for property_name in property_names] + # return descriptions, scores + + ret = {} + for record in neo4j_results.records: + ret[record["e"]._properties["name"]] = {} + + for property_name in property_names: + if property_name in record["e"]._properties: + ret[record["e"]._properties["name"]][property_name] = ( + record["e"]._properties[property_name] + ) + + return ret diff --git a/r2r/providers/parsing/r2r_parsing.py b/r2r/providers/parsing/r2r_parsing.py index 056091675..273e6606d 100644 --- a/r2r/providers/parsing/r2r_parsing.py +++ b/r2r/providers/parsing/r2r_parsing.py @@ -5,9 +5,8 @@ from r2r import parsers from r2r.base import ( Document, + DocumentExtraction, DocumentType, - Extraction, - ExtractionType, ParsingConfig, ParsingProvider, R2RDocumentProcessingError, @@ -68,7 +67,7 @@ def _initialize_parsers(self): async def parse( self, document: Document - ) -> AsyncGenerator[Extraction, None]: + ) -> AsyncGenerator[DocumentExtraction, None]: if document.type not in self.parsers: yield R2RDocumentProcessingError( document_id=document.id, @@ -78,24 +77,17 @@ async def parse( parser = self.parsers[document.type] texts = parser.ingest(document.data) - extraction_type = ExtractionType.TXT t0 = time.time() - if document.type in self.IMAGE_TYPES: - extraction_type = ExtractionType.IMG - document.metadata["image_type"] = document.type.value - elif document.type == DocumentType.MP4: - extraction_type = ExtractionType.MOV - document.metadata["audio_type"] = document.type.value - iteration = 0 async for text in texts: - extraction = Extraction( + extraction = DocumentExtraction( id=generate_id_from_label(f"{document.id}-{iteration}"), + document_id=document.id, + user_id=document.user_id, + group_ids=document.group_ids, data=text, metadata=document.metadata, - document_id=document.id, - type=extraction_type, ) yield extraction iteration += 1 diff --git a/r2r/providers/parsing/unstructured_parsing.py b/r2r/providers/parsing/unstructured_parsing.py index df1ec403c..a6f911559 100644 --- a/r2r/providers/parsing/unstructured_parsing.py +++ b/r2r/providers/parsing/unstructured_parsing.py @@ -1,13 +1,12 @@ import logging import time from io import BytesIO -from typing import Any, AsyncGenerator +from typing import AsyncGenerator from r2r.base import ( Document, + DocumentExtraction, DocumentType, - Extraction, - ExtractionType, ParsingProvider, generate_id_from_label, ) @@ -33,7 +32,7 @@ def __init__(self, config): async def parse( self, document: Document - ) -> AsyncGenerator[Extraction, None]: + ) -> AsyncGenerator[DocumentExtraction, None]: data = document.data if isinstance(data, bytes): data = BytesIO(data) @@ -44,17 +43,13 @@ async def parse( elements = self.partition(file=data) for iteration, element in enumerate(elements): - extraction_type = ExtractionType.TXT - - # You might want to add logic here to determine if the element - # is an image, video, etc., and set the extraction_type accordingly - - extraction = Extraction( + extraction = DocumentExtraction( id=generate_id_from_label(f"{document.id}-{iteration}"), - data=element.text, # Convert element to string - metadata=document.metadata, document_id=document.id, - type=extraction_type, + user_id=document.user_id, + group_ids=document.group_ids, + data=element.text, + metadata=document.metadata, ) yield extraction diff --git a/r2r/providers/prompts/defaults.yaml b/r2r/providers/prompts/defaults.yaml new file mode 100644 index 000000000..e69de29bb diff --git a/r2r/providers/prompts/defaults/graphrag_community_reports.yaml b/r2r/providers/prompts/defaults/graphrag_community_reports.yaml new file mode 100644 index 000000000..9d57b92be --- /dev/null +++ b/r2r/providers/prompts/defaults/graphrag_community_reports.yaml @@ -0,0 +1,150 @@ +graphrag_community_reports: + template: | + You are an AI assistant that helps a human analyst to perform general information discovery. Information discovery is the process of identifying and assessing relevant information associated with certain entities (e.g., organizations and individuals) within a network. + + # Goal + Write a comprehensive report of a community, given a list of entities that belong to the community as well as their relationships and optional associated claims. The report will be used to inform decision-makers about information associated with the community and their potential impact. The content of this report includes an overview of the community's key entities, their legal compliance, technical capabilities, reputation, and noteworthy claims. + + # Report Structure + + The report should include the following sections: + + - TITLE: community's name that represents its key entities - title should be short but specific. When possible, include representative named entities in the title. + - SUMMARY: An executive summary of the community's overall structure, how its entities are related to each other, and significant information associated with its entities. + - IMPACT SEVERITY RATING: a float score between 0-10 that represents the severity of IMPACT posed by entities within the community. IMPACT is the scored importance of a community. + - RATING EXPLANATION: Give a single sentence explanation of the IMPACT severity rating. + - DETAILED FINDINGS: A list of 5-10 key insights about the community. Each insight should have a short summary followed by multiple paragraphs of explanatory text grounded according to the grounding rules below. Be comprehensive. + + Return output as a well-formed JSON-formatted string with the following format: + {{ + "title": , + "summary": , + "rating": , + "rating_explanation": , + "findings": [ + {{ + "summary":, + "explanation": + }}, + {{ + "summary":, + "explanation": + }} + ] + }} + + # Grounding Rules + + Points supported by data should list their data references as follows: + + "This is an example sentence supported by multiple data references [Data: (record ids); (record ids)]." + + Do not list more than 5 record ids in a single reference. Instead, list the top 5 most relevant record ids and add "+more" to indicate that there are more. + + For example: + "Person X is the owner of Company Y and subject to many allegations of wrongdoing [Data: Reports (1), Entities (5, 7); Relationships (23); Claims (7, 2, 34, 64, 46, +more)]." + + where 1, 5, 7, 23, 2, 34, 46, and 64 represent the id (not the index) of the relevant data record. + + Do not include information where the supporting evidence for it is not provided. + + + # Example Input + ----------- + Text: + + Entities + + id,entity,description + 5,VERDANT OASIS PLAZA,Verdant Oasis Plaza is the location of the Unity March + 6,HARMONY ASSEMBLY,Harmony Assembly is an organization that is holding a march at Verdant Oasis Plaza + + Relationships + + id,source,target,description + 37,VERDANT OASIS PLAZA,UNITY MARCH,Verdant Oasis Plaza is the location of the Unity March + 38,VERDANT OASIS PLAZA,HARMONY ASSEMBLY,Harmony Assembly is holding a march at Verdant Oasis Plaza + 39,VERDANT OASIS PLAZA,UNITY MARCH,The Unity March is taking place at Verdant Oasis Plaza + 40,VERDANT OASIS PLAZA,TRIBUNE SPOTLIGHT,Tribune Spotlight is reporting on the Unity march taking place at Verdant Oasis Plaza + 41,VERDANT OASIS PLAZA,BAILEY ASADI,Bailey Asadi is speaking at Verdant Oasis Plaza about the march + 43,HARMONY ASSEMBLY,UNITY MARCH,Harmony Assembly is organizing the Unity March + + Output: + {{ + "title": "Verdant Oasis Plaza and Unity March", + "summary": "The community revolves around the Verdant Oasis Plaza, which is the location of the Unity March. The plaza has relationships with the Harmony Assembly, Unity March, and Tribune Spotlight, all of which are associated with the march event.", + "rating": 5.0, + "rating_explanation": "The impact severity rating is moderate due to the potential for unrest or conflict during the Unity March.", + "findings": [ + {{ + "summary": "Verdant Oasis Plaza as the central location", + "explanation": "Verdant Oasis Plaza is the central entity in this community, serving as the location for the Unity March. This plaza is the common link between all other entities, suggesting its significance in the community. The plaza's association with the march could potentially lead to issues such as public disorder or conflict, depending on the nature of the march and the reactions it provokes. [Data: Entities (5), Relationships (37, 38, 39, 40, 41,+more)]" + }}, + {{ + "summary": "Harmony Assembly's role in the community", + "explanation": "Harmony Assembly is another key entity in this community, being the organizer of the march at Verdant Oasis Plaza. The nature of Harmony Assembly and its march could be a potential source of threat, depending on their objectives and the reactions they provoke. The relationship between Harmony Assembly and the plaza is crucial in understanding the dynamics of this community. [Data: Entities(6), Relationships (38, 43)]" + }}, + {{ + "summary": "Unity March as a significant event", + "explanation": "The Unity March is a significant event taking place at Verdant Oasis Plaza. This event is a key factor in the community's dynamics and could be a potential source of threat, depending on the nature of the march and the reactions it provokes. The relationship between the march and the plaza is crucial in understanding the dynamics of this community. [Data: Relationships (39)]" + }}, + {{ + "summary": "Role of Tribune Spotlight", + "explanation": "Tribune Spotlight is reporting on the Unity March taking place in Verdant Oasis Plaza. This suggests that the event has attracted media attention, which could amplify its impact on the community. The role of Tribune Spotlight could be significant in shaping public perception of the event and the entities involved. [Data: Relationships (40)]" + }} + ] + }} + + + # Real Data + + Use the following text for your answer. Do not make anything up in your answer. + + Text: + {input_text} + + The report should include the following sections: + + - TITLE: community's name that represents its key entities - title should be short but specific. When possible, include representative named entities in the title. + - SUMMARY: An executive summary of the community's overall structure, how its entities are related to each other, and significant information associated with its entities. + - IMPACT SEVERITY RATING: a float score between 0-10 that represents the severity of IMPACT posed by entities within the community. IMPACT is the scored importance of a community. + - RATING EXPLANATION: Give a single sentence explanation of the IMPACT severity rating. + - DETAILED FINDINGS: A list of 5-10 key insights about the community. Each insight should have a short summary followed by multiple paragraphs of explanatory text grounded according to the grounding rules below. Be comprehensive. + + Return output as a well-formed JSON-formatted string with the following format: + {{ + "title": , + "summary": , + "rating": , + "rating_explanation": , + "findings": [ + {{ + "summary":, + "explanation": + }}, + {{ + "summary":, + "explanation": + }} + ] + }} + + # Grounding Rules + + Points supported by data should list their data references as follows: + + "This is an example sentence supported by multiple data references [Data: (record ids); (record ids)]." + + Do not list more than 5 record ids in a single reference. Instead, list the top 5 most relevant record ids and add "+more" to indicate that there are more. + + For example: + "Person X is the owner of Company Y and subject to many allegations of wrongdoing [Data: Reports (1), Entities (5, 7); Relationships (23); Claims (7, 2, 34, 64, 46, +more)]." + + where 1, 5, 7, 23, 2, 34, 46, and 64 represent the id (not the index) of the relevant data record. + + Do not include information where the supporting evidence for it is not provided. + + Output:""" + + input_types: + input_text: str diff --git a/r2r/providers/prompts/defaults/graphrag_map_system_prompt.yaml b/r2r/providers/prompts/defaults/graphrag_map_system_prompt.yaml new file mode 100644 index 000000000..0e7c15bce --- /dev/null +++ b/r2r/providers/prompts/defaults/graphrag_map_system_prompt.yaml @@ -0,0 +1,55 @@ +graphrag_map_system_prompt: + template : | + ---Role--- + You are a helpful assistant responding to questions about data in the tables provided. + ---Goal--- + Generate a response consisting of a list of key points that responds to the user's question, summarizing all relevant information in the input data tables. + You should use the data provided in the data tables below as the primary context for generating the response. + If you don't know the answer or if the input data tables do not contain sufficient information to provide an answer, just say so. Do not make anything up. + Each key point in the response should have the following element: + - Description: A comprehensive description of the point. + - Importance Score: An integer score between 0-100 that indicates how important the point is in answering the user's question. An 'I don't know' type of response should have a score of 0. + The response should be JSON formatted as follows: + {{ + "points": [ + {{"description": "Description of point 1 [Data: Reports (report ids)]", "score": score_value}}, + {{"description": "Description of point 2 [Data: Reports (report ids)]", "score": score_value}} + ] + }} + The response shall preserve the original meaning and use of modal verbs such as "shall", "may" or "will". + Points supported by data should list the relevant reports as references as follows: + "This is an example sentence supported by data references [Data: Reports (report ids)]" + **Do not list more than 5 record ids in a single reference**. Instead, list the top 5 most relevant record ids and add "+more" to indicate that there are more. + For example: + "Person X is the owner of Company Y and subject to many allegations of wrongdoing [Data: Reports (2, 7, 64, 46, 34, +more)]. He is also CEO of company X [Data: Reports (1, 3)]" + where 1, 2, 3, 7, 34, 46, and 64 represent the id (not the index) of the relevant data report in the provided tables. + Do not include information where the supporting evidence for it is not provided. + ---Data tables--- + {context_data} + ---Goal--- + Generate a response consisting of a list of key points that responds to the user's question, summarizing all relevant information in the input data tables. + You should use the data provided in the data tables below as the primary context for generating the response. + If you don't know the answer or if the input data tables do not contain sufficient information to provide an answer, just say so. Do not make anything up. + Each key point in the response should have the following element: + - Description: A comprehensive description of the point. + - Importance Score: An integer score between 0-100 that indicates how important the point is in answering the user's question. An 'I don't know' type of response should have a score of 0. + The response shall preserve the original meaning and use of modal verbs such as "shall", "may" or "will". + Points supported by data should list the relevant reports as references as follows: + "This is an example sentence supported by data references [Data: Reports (report ids)]" + **Do not list more than 5 record ids in a single reference**. Instead, list the top 5 most relevant record ids and add "+more" to indicate that there are more. + For example: + "Person X is the owner of Company Y and subject to many allegations of wrongdoing [Data: Reports (2, 7, 64, 46, 34, +more)]. He is also CEO of company X [Data: Reports (1, 3)]" + where 1, 2, 3, 7, 34, 46, and 64 represent the id (not the index) of the relevant data report in the provided tables. + Do not include information where the supporting evidence for it is not provided. + The response should be JSON formatted as follows: + {{ + "points": [ + {{"description": "Description of point 1 [Data: Reports (report ids)]", "score": score_value}}, + {{"description": "Description of point 2 [Data: Reports (report ids)]", "score": score_value}} + ] + }} + ---Input--- + {input} + input_types: + context_data: str + input: str diff --git a/r2r/providers/prompts/defaults/graphrag_reduce_system_prompt.yaml b/r2r/providers/prompts/defaults/graphrag_reduce_system_prompt.yaml new file mode 100644 index 000000000..0be2815c7 --- /dev/null +++ b/r2r/providers/prompts/defaults/graphrag_reduce_system_prompt.yaml @@ -0,0 +1,43 @@ +graphrag_reduce_system_prompt: + template: | + ---Role--- + You are a helpful assistant responding to questions about a dataset by synthesizing perspectives from multiple analysts. + ---Goal--- + Generate a response of the target length and format that responds to the user's question, summarize all the reports from multiple analysts who focused on different parts of the dataset. + Note that the analysts' reports provided below are ranked in the **descending order of importance**. + If you don't know the answer or if the provided reports do not contain sufficient information to provide an answer, just say so. Do not make anything up. + The final response should remove all irrelevant information from the analysts' reports and merge the cleaned information into a comprehensive answer that provides explanations of all the key points and implications appropriate for the response length and format. + Add sections and commentary to the response as appropriate for the length and format. Style the response in markdown. + The response shall preserve the original meaning and use of modal verbs such as "shall", "may" or "will". + The response should also preserve all the data references previously included in the analysts' reports, but do not mention the roles of multiple analysts in the analysis process. + **Do not list more than 5 record ids in a single reference**. Instead, list the top 5 most relevant record ids and add "+more" to indicate that there are more. + + For example: + "Person X is the owner of Company Y and subject to many allegations of wrongdoing [Data: Reports (2, 7, 34, 46, 64, +more)]. He is also CEO of company X [Data: Reports (1, 3)]" + where 1, 2, 3, 7, 34, 46, and 64 represent the id (not the index) of the relevant data record. + Do not include information where the supporting evidence for it is not provided. + ---Target response length and format--- + {response_type} + ---Analyst Reports--- + {report_data} + ---Goal--- + Generate a response of the target length and format that responds to the user's question, summarize all the reports from multiple analysts who focused on different parts of the dataset. + Note that the analysts' reports provided below are ranked in the **descending order of importance**. + If you don't know the answer or if the provided reports do not contain sufficient information to provide an answer, just say so. Do not make anything up. + The final response should remove all irrelevant information from the analysts' reports and merge the cleaned information into a comprehensive answer that provides explanations of all the key points and implications appropriate for the response length and format. + The response shall preserve the original meaning and use of modal verbs such as "shall", "may" or "will". + The response should also preserve all the data references previously included in the analysts' reports, but do not mention the roles of multiple analysts in the analysis process. + **Do not list more than 5 record ids in a single reference**. Instead, list the top 5 most relevant record ids and add "+more" to indicate that there are more. + For example: + "Person X is the owner of Company Y and subject to many allegations of wrongdoing [Data: Reports (2, 7, 34, 46, 64, +more)]. He is also CEO of company X [Data: Reports (1, 3)]" + where 1, 2, 3, 7, 34, 46, and 64 represent the id (not the index) of the relevant data record. + Do not include information where the supporting evidence for it is not provided. + ---Target response length and format--- + {response_type} + Add sections and commentary to the response as appropriate for the length and format. Style the response in markdown. + -- Query -- + {input} + input_types: + response_type: str + report_data: str + input: str diff --git a/r2r/providers/prompts/defaults/graphrag_triplet_extraction_few_shot.yaml b/r2r/providers/prompts/defaults/graphrag_triplet_extraction_few_shot.yaml new file mode 100644 index 000000000..0a9b580a8 --- /dev/null +++ b/r2r/providers/prompts/defaults/graphrag_triplet_extraction_few_shot.yaml @@ -0,0 +1,36 @@ +graphrag_triplet_extraction_few_shot: + template: > + -Goal- + Given a text document, identify all entities and their entity types from the text and all relationships among the identified entities. + Given the text, extract up to {max_knowledge_triplets} entity-relation triplets. + -Steps- + 1. Identify all entities. For each identified entity, extract the following information: + - entity_name: Name of the entity, capitalized + - entity_type: Type of the entity + - entity_description: Comprehensive description of the entity's attributes and activities + Format each entity as ("entity"$$$$$$$$$$$$) + 2. From the entities identified in step 1, identify all pairs of (source_entity, target_entity) that are *clearly related* to each other. + For each pair of related entities, extract the following information: + - source_entity: name of the source entity, as identified in step 1 + - target_entity: name of the target entity, as identified in step 1 + - relation: relationship between source_entity and target_entity + - relationship_description: explanation as to why you think the source entity and the target entity are related to each other + - relationship_weight: a weight between 0 and 10 that represents the strength of the relationship between the source entity and the target entity + Format each relationship as ("relationship"$$$$$$$$$$$$$$$$$$$$) + 3. When finished, output. + -Real Data- + ###################### + text: {input} + ###################### + + Only extract entities of the given types + {entity_types} + + Only extract relations of the given types + {relation_types} + + input_types: + max_knowledge_triplets: int + input: str + entity_types: list[str] + relation_types: list[str] diff --git a/r2r/providers/prompts/defaults/graphrag_triplet_extraction_zero_shot.yaml b/r2r/providers/prompts/defaults/graphrag_triplet_extraction_zero_shot.yaml new file mode 100644 index 000000000..d2d11fb2c --- /dev/null +++ b/r2r/providers/prompts/defaults/graphrag_triplet_extraction_zero_shot.yaml @@ -0,0 +1,28 @@ +graphrag_triplet_extraction_zero_shot: + template: > + -Goal- + Given a text document, identify all entities and their entity types from the text and all relationships among the identified entities. + Given the text, extract up to {max_knowledge_triplets} entity-relation triplets. + -Steps- + 1. Identify all entities. For each identified entity, extract the following information: + - entity_name: Name of the entity, capitalized + - entity_type: Type of the entity + - entity_description: Comprehensive description of the entity's attributes and activities + Format each entity as ("entity"$$$$$$$$$$$$) + 2. From the entities identified in step 1, identify all pairs of (source_entity, target_entity) that are *clearly related* to each other. + For each pair of related entities, extract the following information: + - source_entity: name of the source entity, as identified in step 1 + - target_entity: name of the target entity, as identified in step 1 + - relation: relationship between source_entity and target_entity + - relationship_description: explanation as to why you think the source entity and the target entity are related to each other + - relationship_weight: a weight between 0 and 10 that represents the strength of the relationship between the source entity and the target entity + Format each relationship as ("relationship"$$$$$$$$$$$$$$$$$$$$) + 3. When finished, output. + -Real Data- + ###################### + text: {input} + ###################### + + input_types: + max_knowledge_triplets: int + input: str diff --git a/r2r/providers/prompts/defaults/rag_answer.yaml b/r2r/providers/prompts/defaults/rag_answer.yaml deleted file mode 100644 index dfaf7059c..000000000 --- a/r2r/providers/prompts/defaults/rag_answer.yaml +++ /dev/null @@ -1,52 +0,0 @@ -rag_answer_eval: - template: >+ - ### Instruction: - - - You are given a `query`, related `context` and an associated `answer`. Your task is to sequentially score each sentence in the given answer as either 1 or 0, based on whether or not the given sentence is relevant to the given query and supported in full by the given context. - - ### Example: - - #### Input: - - - Query: - - Why does Alice prefer spending her mornings in the garden? - - - Context: - - Alice loves to read books in her garden. She has a large collection of mystery novels. Every morning, she spends an hour reading while drinking her favorite tea. Her garden is filled with various flowers, and she especially loves the roses. On weekends, Alice's friend, Bob, often joins her for tea and they discuss the books they've read. - - - Answer: - - Alice enjoys her mornings in the garden because she loves to read there. She often listens to music while reading. - - ####### Response: - - - ([1,0], '1/2')### Input: - - Query: - - {query} - - - Context: - - {context} - - - Answer: - - {answer} - - - Response: - - input_types: - query: str - context: str - answer: str diff --git a/r2r/providers/prompts/defaults/rag_context.yaml b/r2r/providers/prompts/defaults/rag_context.yaml index 8e26a5979..376378452 100644 --- a/r2r/providers/prompts/defaults/rag_context.yaml +++ b/r2r/providers/prompts/defaults/rag_context.yaml @@ -1,4 +1,4 @@ -rag_context_eval: +rag_context: template: >+ ### Instruction: diff --git a/r2r/providers/prompts/r2r_prompts.py b/r2r/providers/prompts/r2r_prompts.py index fd976325b..896eb0c00 100644 --- a/r2r/providers/prompts/r2r_prompts.py +++ b/r2r/providers/prompts/r2r_prompts.py @@ -14,10 +14,10 @@ class R2RPromptProvider(PromptProvider): def __init__(self, config: PromptConfig = PromptConfig()): self.prompts: dict[str, Prompt] = {} - self._load_prompts_from_toml_directory(directory_path=config.file_path) + self._load_prompts_from_yaml_directory(directory_path=config.file_path) super().__init__(config) - def _load_prompts_from_toml_directory( + def _load_prompts_from_yaml_directory( self, directory_path: Optional[Path] = None ): if not directory_path: @@ -47,7 +47,7 @@ def _load_prompts_from_toml_directory( logger.error(error_msg) raise ValueError(error_msg) except KeyError as e: - error_msg = f"Missing key in TOML file {toml_file}: {e}" + error_msg = f"Missing key in TOML file {yaml_file}: {e}" logger.error(error_msg) raise ValueError(error_msg) diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/regression/expected_outputs/test_document_management.json b/tests/regression/expected_outputs/test_document_management.json new file mode 100644 index 000000000..39c49fd88 --- /dev/null +++ b/tests/regression/expected_outputs/test_document_management.json @@ -0,0 +1,1183 @@ +{ + "ingest_sample_files": { + "results": { + "processed_documents": [ + { + "id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "group_ids": [], + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "type": "html", + "metadata": {}, + "title": "pg_essay_1.html", + "version": "v0", + "size_in_bytes": 131503, + "status": "success", + "created_at": "2024-08-13T17:43:28.344768", + "updated_at": "2024-08-13T17:43:28.344768" + }, + { + "id": "716fea3a-826b-5b27-8e59-ffbd1a35455a", + "group_ids": [], + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "type": "txt", + "metadata": {}, + "title": "got.txt", + "version": "v0", + "size_in_bytes": 9491, + "status": "success", + "created_at": "2024-08-13T17:43:28.344841", + "updated_at": "2024-08-13T17:43:28.344841" + }, + { + "id": "52e12576-090f-59db-91f4-6d4b2e29ae6c", + "group_ids": [], + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "type": "mp3", + "metadata": {}, + "title": "sample.mp3", + "version": "v0", + "size_in_bytes": 121671, + "status": "success", + "created_at": "2024-08-13T17:43:28.344851", + "updated_at": "2024-08-13T17:43:28.344851" + }, + { + "id": "3e157b3a-8469-51db-90d9-52e7d896b49b", + "group_ids": [], + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "type": "pdf", + "metadata": {}, + "title": "uber_2021.pdf", + "version": "v0", + "size_in_bytes": 1880483, + "status": "success", + "created_at": "2024-08-13T17:43:28.344856", + "updated_at": "2024-08-13T17:43:28.344856" + }, + { + "id": "01d514a4-5cb1-5c86-be8c-0c5c312a02c9", + "group_ids": [], + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "type": "mp3", + "metadata": {}, + "title": "sample2.mp3", + "version": "v0", + "size_in_bytes": 72456, + "status": "success", + "created_at": "2024-08-13T17:43:28.344867", + "updated_at": "2024-08-13T17:43:28.344867" + }, + { + "id": "c3291abf-8a4e-5d9d-80fd-232ef6fd8526", + "group_ids": [], + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "type": "txt", + "metadata": {}, + "title": "aristotle_v2.txt", + "version": "v0", + "size_in_bytes": 7443, + "status": "success", + "created_at": "2024-08-13T17:43:28.344871", + "updated_at": "2024-08-13T17:43:28.344871" + }, + { + "id": "e797da22-8c5d-54e5-bed5-a55954cf6bf9", + "group_ids": [], + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "type": "html", + "metadata": {}, + "title": "pg_essay_4.html", + "version": "v0", + "size_in_bytes": 118113, + "status": "success", + "created_at": "2024-08-13T17:43:28.344874", + "updated_at": "2024-08-13T17:43:28.344874" + }, + { + "id": "7c1105fc-8f62-5a8f-ac81-fe88f3ec9e4c", + "group_ids": [], + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "type": "html", + "metadata": {}, + "title": "pg_essay_5.html", + "version": "v0", + "size_in_bytes": 123779, + "status": "success", + "created_at": "2024-08-13T17:43:28.344879", + "updated_at": "2024-08-13T17:43:28.344879" + }, + { + "id": "2f576170-c4f9-5141-a910-a0924f341de4", + "group_ids": [], + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "type": "pdf", + "metadata": {}, + "title": "lyft_2021.pdf", + "version": "v0", + "size_in_bytes": 1440303, + "status": "success", + "created_at": "2024-08-13T17:43:28.344884", + "updated_at": "2024-08-13T17:43:28.344884" + }, + { + "id": "30f950f0-c692-57c5-b6ec-ff78ccf5ccdc", + "group_ids": [], + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "type": "txt", + "metadata": {}, + "title": "test.txt", + "version": "v0", + "size_in_bytes": 20, + "status": "success", + "created_at": "2024-08-13T17:43:28.344889", + "updated_at": "2024-08-13T17:43:28.344889" + }, + { + "id": "57eec3df-cf68-5559-a80d-ae3fb55b9af1", + "group_ids": [], + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "type": "html", + "metadata": {}, + "title": "pg_essay_2.html", + "version": "v0", + "size_in_bytes": 125112, + "status": "success", + "created_at": "2024-08-13T17:43:28.344893", + "updated_at": "2024-08-13T17:43:28.344893" + }, + { + "id": "db02076e-989a-59cd-98d5-e24e15a0bd27", + "group_ids": [], + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "type": "txt", + "metadata": {}, + "title": "aristotle.txt", + "version": "v0", + "size_in_bytes": 73353, + "status": "success", + "created_at": "2024-08-13T17:43:28.344898", + "updated_at": "2024-08-13T17:43:28.344898" + }, + { + "id": "d421207a-d799-5806-8d67-46b2005b15d4", + "group_ids": [], + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "type": "txt", + "metadata": {}, + "title": "yc_companies.txt", + "version": "v0", + "size_in_bytes": 47209, + "status": "success", + "created_at": "2024-08-13T17:43:28.344901", + "updated_at": "2024-08-13T17:43:28.344901" + }, + { + "id": "451adbbd-e24e-5c9b-80a8-f424b6c7accb", + "group_ids": [], + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "type": "png", + "metadata": {}, + "title": "screen_shot.png", + "version": "v0", + "size_in_bytes": 791764, + "status": "success", + "created_at": "2024-08-13T17:43:28.344905", + "updated_at": "2024-08-13T17:43:28.344905" + }, + { + "id": "5b1bd54f-4d70-56b9-a017-a618bc75f94c", + "group_ids": [], + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "type": "html", + "metadata": {}, + "title": "pg_essay_3.html", + "version": "v0", + "size_in_bytes": 124915, + "status": "success", + "created_at": "2024-08-13T17:43:28.344908", + "updated_at": "2024-08-13T17:43:28.344908" + } + ], + "failed_documents": [], + "skipped_documents": [] + } + }, + "reingest_sample_file": { + "results": "All provided documents already exist. Use the `update_documents` endpoint instead to update these documents." + }, + "documents_overview": { + "results": [ + { + "id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "group_ids": [], + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "type": "html", + "metadata": {}, + "title": "pg_essay_1.html", + "version": "v0", + "size_in_bytes": 131503, + "status": "success", + "created_at": "2024-08-13T17:43:28.344768Z", + "updated_at": "2024-08-13T17:43:28.344768Z" + }, + { + "id": "716fea3a-826b-5b27-8e59-ffbd1a35455a", + "group_ids": [], + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "type": "txt", + "metadata": {}, + "title": "got.txt", + "version": "v0", + "size_in_bytes": 9491, + "status": "success", + "created_at": "2024-08-13T17:43:28.344841Z", + "updated_at": "2024-08-13T17:43:28.344841Z" + }, + { + "id": "52e12576-090f-59db-91f4-6d4b2e29ae6c", + "group_ids": [], + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "type": "mp3", + "metadata": {}, + "title": "sample.mp3", + "version": "v0", + "size_in_bytes": 121671, + "status": "success", + "created_at": "2024-08-13T17:43:28.344851Z", + "updated_at": "2024-08-13T17:43:28.344851Z" + }, + { + "id": "3e157b3a-8469-51db-90d9-52e7d896b49b", + "group_ids": [], + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "type": "pdf", + "metadata": {}, + "title": "uber_2021.pdf", + "version": "v0", + "size_in_bytes": 1880483, + "status": "success", + "created_at": "2024-08-13T17:43:28.344856Z", + "updated_at": "2024-08-13T17:43:28.344856Z" + }, + { + "id": "01d514a4-5cb1-5c86-be8c-0c5c312a02c9", + "group_ids": [], + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "type": "mp3", + "metadata": {}, + "title": "sample2.mp3", + "version": "v0", + "size_in_bytes": 72456, + "status": "success", + "created_at": "2024-08-13T17:43:28.344867Z", + "updated_at": "2024-08-13T17:43:28.344867Z" + }, + { + "id": "c3291abf-8a4e-5d9d-80fd-232ef6fd8526", + "group_ids": [], + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "type": "txt", + "metadata": {}, + "title": "aristotle_v2.txt", + "version": "v0", + "size_in_bytes": 7443, + "status": "success", + "created_at": "2024-08-13T17:43:28.344871Z", + "updated_at": "2024-08-13T17:43:28.344871Z" + }, + { + "id": "e797da22-8c5d-54e5-bed5-a55954cf6bf9", + "group_ids": [], + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "type": "html", + "metadata": {}, + "title": "pg_essay_4.html", + "version": "v0", + "size_in_bytes": 118113, + "status": "success", + "created_at": "2024-08-13T17:43:28.344874Z", + "updated_at": "2024-08-13T17:43:28.344874Z" + }, + { + "id": "7c1105fc-8f62-5a8f-ac81-fe88f3ec9e4c", + "group_ids": [], + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "type": "html", + "metadata": {}, + "title": "pg_essay_5.html", + "version": "v0", + "size_in_bytes": 123779, + "status": "success", + "created_at": "2024-08-13T17:43:28.344879Z", + "updated_at": "2024-08-13T17:43:28.344879Z" + }, + { + "id": "2f576170-c4f9-5141-a910-a0924f341de4", + "group_ids": [], + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "type": "pdf", + "metadata": {}, + "title": "lyft_2021.pdf", + "version": "v0", + "size_in_bytes": 1440303, + "status": "success", + "created_at": "2024-08-13T17:43:28.344884Z", + "updated_at": "2024-08-13T17:43:28.344884Z" + }, + { + "id": "30f950f0-c692-57c5-b6ec-ff78ccf5ccdc", + "group_ids": [], + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "type": "txt", + "metadata": {}, + "title": "test.txt", + "version": "v0", + "size_in_bytes": 20, + "status": "success", + "created_at": "2024-08-13T17:43:28.344889Z", + "updated_at": "2024-08-13T17:43:28.344889Z" + }, + { + "id": "57eec3df-cf68-5559-a80d-ae3fb55b9af1", + "group_ids": [], + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "type": "html", + "metadata": {}, + "title": "pg_essay_2.html", + "version": "v0", + "size_in_bytes": 125112, + "status": "success", + "created_at": "2024-08-13T17:43:28.344893Z", + "updated_at": "2024-08-13T17:43:28.344893Z" + }, + { + "id": "db02076e-989a-59cd-98d5-e24e15a0bd27", + "group_ids": [], + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "type": "txt", + "metadata": {}, + "title": "aristotle.txt", + "version": "v0", + "size_in_bytes": 73353, + "status": "success", + "created_at": "2024-08-13T17:43:28.344898Z", + "updated_at": "2024-08-13T17:43:28.344898Z" + }, + { + "id": "d421207a-d799-5806-8d67-46b2005b15d4", + "group_ids": [], + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "type": "txt", + "metadata": {}, + "title": "yc_companies.txt", + "version": "v0", + "size_in_bytes": 47209, + "status": "success", + "created_at": "2024-08-13T17:43:28.344901Z", + "updated_at": "2024-08-13T17:43:28.344901Z" + }, + { + "id": "451adbbd-e24e-5c9b-80a8-f424b6c7accb", + "group_ids": [], + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "type": "png", + "metadata": {}, + "title": "screen_shot.png", + "version": "v0", + "size_in_bytes": 791764, + "status": "success", + "created_at": "2024-08-13T17:43:28.344905Z", + "updated_at": "2024-08-13T17:43:28.344905Z" + }, + { + "id": "5b1bd54f-4d70-56b9-a017-a618bc75f94c", + "group_ids": [], + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "type": "html", + "metadata": {}, + "title": "pg_essay_3.html", + "version": "v0", + "size_in_bytes": 124915, + "status": "success", + "created_at": "2024-08-13T17:43:28.344908Z", + "updated_at": "2024-08-13T17:43:28.344908Z" + } + ] + }, + "document_chunks_test": { + "results": [ + { + "fragment_id": "cd85f762-5739-5f19-86d9-a4a9fe213e44", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "text": "A Project of One's Own", + "metadata": { + "text": "A Project of One's Own", + "title": "pg_essay_1.html" + } + }, + { + "fragment_id": "cd38c41d-a14a-52ba-8882-83eaafcbb163", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "text": "June 2021A few days ago, on the way home from school, my nine year old son\ntold me he couldn't wait to get home to write more of the story he\nwas working on. This made me as happy as anything I've heard him\nsay \u2014 not just because he was excited about his story, but because\nhe'd discovered this way of working. Working on a project of your\nown is as different from ordinary work as skating is from walking.", + "metadata": { + "text": "June 2021A few days ago, on the way home from school, my nine year old son\ntold me he couldn't wait to get home to write more of the story he\nwas working on. This made me as happy as anything I've heard him\nsay \u2014 not just because he was excited about his story, but because\nhe'd discovered this way of working. Working on a project of your\nown is as different from ordinary work as skating is from walking.", + "title": "pg_essay_1.html" + } + }, + { + "fragment_id": "fb968ad0-15ab-50b1-982c-08d1e1a1cbd9", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "text": "It's more fun, but also much more productive.What proportion of great work has been done by people who were\nskating in this sense? If not all of it, certainly a lot.There is something special about working on a project of your own.\nI wouldn't say exactly that you're happier. A better word would be\nexcited, or engaged. You're happy when things are going well, but\noften they aren't. When I'm writing an essay, most of the time I'm\nworried and puzzled: worried that the essay will turn out badly,", + "metadata": { + "text": "It's more fun, but also much more productive.What proportion of great work has been done by people who were\nskating in this sense? If not all of it, certainly a lot.There is something special about working on a project of your own.\nI wouldn't say exactly that you're happier. A better word would be\nexcited, or engaged. You're happy when things are going well, but\noften they aren't. When I'm writing an essay, most of the time I'm\nworried and puzzled: worried that the essay will turn out badly,", + "title": "pg_essay_1.html" + } + }, + { + "fragment_id": "263476d3-7650-52c9-99ad-ec9d5406c581", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "text": "and puzzled because I'm groping for some idea that I can't see\nclearly enough. Will I be able to pin it down with words? In the\nend I usually can, if I take long enough, but I'm never sure; the\nfirst few attempts often fail.You have moments of happiness when things work out, but they don't\nlast long, because then you're on to the next problem. So why do\nit at all? Because to the kind of people who like working this way,\nnothing else feels as right. You feel as if you're an animal in its", + "metadata": { + "text": "and puzzled because I'm groping for some idea that I can't see\nclearly enough. Will I be able to pin it down with words? In the\nend I usually can, if I take long enough, but I'm never sure; the\nfirst few attempts often fail.You have moments of happiness when things work out, but they don't\nlast long, because then you're on to the next problem. So why do\nit at all? Because to the kind of people who like working this way,\nnothing else feels as right. You feel as if you're an animal in its", + "title": "pg_essay_1.html" + } + }, + { + "fragment_id": "28c70d00-ee77-5e5e-9c0e-ff79332ffabb", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "text": "natural habitat, doing what you were meant to do \u2014 not always\nhappy, maybe, but awake and alive.Many kids experience the excitement of working on projects of their\nown. The hard part is making this converge with the work you do as\nan adult. And our customs make it harder. We treat \"playing\" and\n\"hobbies\" as qualitatively different from \"work\". It's not clear\nto a kid building a treehouse that there's a direct (though long)\nroute from that to architecture or engineering. And instead of", + "metadata": { + "text": "natural habitat, doing what you were meant to do \u2014 not always\nhappy, maybe, but awake and alive.Many kids experience the excitement of working on projects of their\nown. The hard part is making this converge with the work you do as\nan adult. And our customs make it harder. We treat \"playing\" and\n\"hobbies\" as qualitatively different from \"work\". It's not clear\nto a kid building a treehouse that there's a direct (though long)\nroute from that to architecture or engineering. And instead of", + "title": "pg_essay_1.html" + } + }, + { + "fragment_id": "67a4ddfc-d362-5b4b-afaf-5b3f53ec7ac5", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "text": "pointing out the route, we conceal it, by implicitly treating the\nstuff kids do as different from real work.\n[1]Instead of telling kids that their treehouses could be on the path\nto the work they do as adults, we tell them the path goes through\nschool. And unfortunately schoolwork tends to be very different from\nworking on projects of one's own. It's usually neither a project,\nnor one's own. So as school gets more serious, working on projects", + "metadata": { + "text": "pointing out the route, we conceal it, by implicitly treating the\nstuff kids do as different from real work.\n[1]Instead of telling kids that their treehouses could be on the path\nto the work they do as adults, we tell them the path goes through\nschool. And unfortunately schoolwork tends to be very different from\nworking on projects of one's own. It's usually neither a project,\nnor one's own. So as school gets more serious, working on projects", + "title": "pg_essay_1.html" + } + }, + { + "fragment_id": "001c1335-737c-5585-9ec1-441ee9c49348", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "text": "of one's own is something that survives, if at all, as a thin thread\noff to the side.It's a bit sad to think of all the high school kids turning their\nbacks on building treehouses and sitting in class dutifully learning\nabout Darwin or Newton to pass some exam, when the work that made\nDarwin and Newton famous was actually closer in spirit to building\ntreehouses than studying for exams.If I had to choose between my kids getting good grades and\nworking on ambitious projects of their own, I'd pick", + "metadata": { + "text": "of one's own is something that survives, if at all, as a thin thread\noff to the side.It's a bit sad to think of all the high school kids turning their\nbacks on building treehouses and sitting in class dutifully learning\nabout Darwin or Newton to pass some exam, when the work that made\nDarwin and Newton famous was actually closer in spirit to building\ntreehouses than studying for exams.If I had to choose between my kids getting good grades and\nworking on ambitious projects of their own, I'd pick", + "title": "pg_essay_1.html" + } + }, + { + "fragment_id": "c3759b2a-fbec-55db-b850-511d4730de7e", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "text": "techniques for preserving that excitement.\n[4]The team that made the original Macintosh were a great example of\nthis phenomenon. People like Burrell Smith and Andy Hertzfeld and\nBill Atkinson and Susan Kare were not just following orders. They\nwere not tennis balls hit by Steve Jobs, but rockets let loose by\nSteve Jobs. There was a lot of collaboration between them, but\nthey all seem to have individually felt the excitement of", + "metadata": { + "text": "techniques for preserving that excitement.\n[4]The team that made the original Macintosh were a great example of\nthis phenomenon. People like Burrell Smith and Andy Hertzfeld and\nBill Atkinson and Susan Kare were not just following orders. They\nwere not tennis balls hit by Steve Jobs, but rockets let loose by\nSteve Jobs. There was a lot of collaboration between them, but\nthey all seem to have individually felt the excitement of", + "title": "pg_essay_1.html" + } + }, + { + "fragment_id": "540d1c52-6dae-5fb4-b4ad-3d5bbd938abe", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "text": "the projects. And not because I'm an indulgent parent, but because\nI've been on the other end and I know which has more predictive\nvalue. When I was picking startups for Y Combinator, I didn't care\nabout applicants' grades. But if they'd worked on projects of their\nown, I wanted to hear all about those.\n[2]It may be inevitable that school is the way it is. I'm not saying\nwe have to redesign it (though I'm not saying we don't), just that\nwe should understand what it does to our attitudes to work \u2014 that", + "metadata": { + "text": "the projects. And not because I'm an indulgent parent, but because\nI've been on the other end and I know which has more predictive\nvalue. When I was picking startups for Y Combinator, I didn't care\nabout applicants' grades. But if they'd worked on projects of their\nown, I wanted to hear all about those.\n[2]It may be inevitable that school is the way it is. I'm not saying\nwe have to redesign it (though I'm not saying we don't), just that\nwe should understand what it does to our attitudes to work \u2014 that", + "title": "pg_essay_1.html" + } + }, + { + "fragment_id": "fee3d54e-dd02-5f46-9edc-ee4f5d7a70d4", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "text": "it steers us toward the dutiful plodding kind of work, often using\ncompetition as bait, and away from skating.There are occasionally times when schoolwork becomes a project of\none's own. Whenever I had to write a paper, that would become a\nproject of my own \u2014 except in English classes, ironically, because\nthe things one has to write in English classes are so\nbogus. And\nwhen I got to college and started taking CS classes, the programs\nI had to write became projects of my own. Whenever I was writing", + "metadata": { + "text": "it steers us toward the dutiful plodding kind of work, often using\ncompetition as bait, and away from skating.There are occasionally times when schoolwork becomes a project of\none's own. Whenever I had to write a paper, that would become a\nproject of my own \u2014 except in English classes, ironically, because\nthe things one has to write in English classes are so\nbogus. And\nwhen I got to college and started taking CS classes, the programs\nI had to write became projects of my own. Whenever I was writing", + "title": "pg_essay_1.html" + } + }, + { + "fragment_id": "05f02dc2-53ab-539b-9b4d-899eada47a3c", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "text": "or programming, I was usually skating, and that has been true ever\nsince.So where exactly is the edge of projects of one's own? That's an\ninteresting question, partly because the answer is so complicated,\nand partly because there's so much at stake. There turn out to be\ntwo senses in which work can be one's own: 1) that you're doing it\nvoluntarily, rather than merely because someone told you to, and\n2) that you're doing it by yourself.The edge of the former is quite sharp. People who care a lot about", + "metadata": { + "text": "or programming, I was usually skating, and that has been true ever\nsince.So where exactly is the edge of projects of one's own? That's an\ninteresting question, partly because the answer is so complicated,\nand partly because there's so much at stake. There turn out to be\ntwo senses in which work can be one's own: 1) that you're doing it\nvoluntarily, rather than merely because someone told you to, and\n2) that you're doing it by yourself.The edge of the former is quite sharp. People who care a lot about", + "title": "pg_essay_1.html" + } + }, + { + "fragment_id": "42b9d617-6d85-5ba4-a8a6-bb3489faf930", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "text": "their work are usually very sensitive to the difference between\npulling, and being pushed, and work tends to fall into one category\nor the other. But the test isn't simply whether you're told to do\nsomething. You can choose to do something you're told to do. Indeed,\nyou can own it far more thoroughly than the person who told you to\ndo it.For example, math homework is for most people something they're\ntold to do. But for my father, who was a mathematician, it wasn't.", + "metadata": { + "text": "their work are usually very sensitive to the difference between\npulling, and being pushed, and work tends to fall into one category\nor the other. But the test isn't simply whether you're told to do\nsomething. You can choose to do something you're told to do. Indeed,\nyou can own it far more thoroughly than the person who told you to\ndo it.For example, math homework is for most people something they're\ntold to do. But for my father, who was a mathematician, it wasn't.", + "title": "pg_essay_1.html" + } + }, + { + "fragment_id": "d9876b6c-42ab-5852-a98f-15032c7687c7", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "text": "Most of us think of the problems in a math book as a way to test\nor develop our knowledge of the material explained in each section.\nBut to my father the problems were the part that mattered, and the\ntext was merely a sort of annotation. Whenever he got a new math\nbook it was to him like being given a puzzle: here was a new set\nof problems to solve, and he'd immediately set about solving all\nof them.The other sense of a project being one's own \u2014 working on it by", + "metadata": { + "text": "Most of us think of the problems in a math book as a way to test\nor develop our knowledge of the material explained in each section.\nBut to my father the problems were the part that mattered, and the\ntext was merely a sort of annotation. Whenever he got a new math\nbook it was to him like being given a puzzle: here was a new set\nof problems to solve, and he'd immediately set about solving all\nof them.The other sense of a project being one's own \u2014 working on it by", + "title": "pg_essay_1.html" + } + }, + { + "fragment_id": "bec313c9-3fe3-5197-8792-078069a484e2", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "text": "oneself \u2014 has a much softer edge. It shades gradually into\ncollaboration. And interestingly, it shades into collaboration in\ntwo different ways. One way to collaborate is to share a single\nproject. For example, when two mathematicians collaborate on a proof\nthat takes shape in the course of a conversation between them. The\nother way is when multiple people work on separate projects of their\nown that fit together like a jigsaw puzzle. For example, when one", + "metadata": { + "text": "oneself \u2014 has a much softer edge. It shades gradually into\ncollaboration. And interestingly, it shades into collaboration in\ntwo different ways. One way to collaborate is to share a single\nproject. For example, when two mathematicians collaborate on a proof\nthat takes shape in the course of a conversation between them. The\nother way is when multiple people work on separate projects of their\nown that fit together like a jigsaw puzzle. For example, when one", + "title": "pg_essay_1.html" + } + }, + { + "fragment_id": "8626ebe9-8132-5222-ba90-eef6a380ea65", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "text": "person writes the text of a book and another does the graphic design.\n[3]These two paths into collaboration can of course be combined. But\nunder the right conditions, the excitement of working on a project\nof one's own can be preserved for quite a while before disintegrating\ninto the turbulent flow of work in a large organization. Indeed,\nthe history of successful organizations is partly the history of\ntechniques for preserving that excitement.", + "metadata": { + "text": "person writes the text of a book and another does the graphic design.\n[3]These two paths into collaboration can of course be combined. But\nunder the right conditions, the excitement of working on a project\nof one's own can be preserved for quite a while before disintegrating\ninto the turbulent flow of work in a large organization. Indeed,\nthe history of successful organizations is partly the history of\ntechniques for preserving that excitement.", + "title": "pg_essay_1.html" + } + }, + { + "fragment_id": "759018be-fcfc-5e53-bc2e-ce2e6e677d61", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "text": "working on a project of one's own.In Andy Hertzfeld's book on the Macintosh, he describes how they'd\ncome back into the office after dinner and work late into the night.\nPeople who've never experienced the thrill of working on a project\nthey're excited about can't distinguish this kind of working long\nhours from the kind that happens in sweatshops and boiler rooms,\nbut they're at opposite ends of the spectrum. That's why it's a\nmistake to insist dogmatically on \"work/life balance.\" Indeed, the", + "metadata": { + "text": "working on a project of one's own.In Andy Hertzfeld's book on the Macintosh, he describes how they'd\ncome back into the office after dinner and work late into the night.\nPeople who've never experienced the thrill of working on a project\nthey're excited about can't distinguish this kind of working long\nhours from the kind that happens in sweatshops and boiler rooms,\nbut they're at opposite ends of the spectrum. That's why it's a\nmistake to insist dogmatically on \"work/life balance.\" Indeed, the", + "title": "pg_essay_1.html" + } + }, + { + "fragment_id": "4f01bc15-500e-586f-97f0-a89b36248ea2", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "text": "mere expression \"work/life\" embodies a mistake: it assumes work and\nlife are distinct. For those to whom the word \"work\" automatically\nimplies the dutiful plodding kind, they are. But for the skaters,\nthe relationship between work and life would be better represented\nby a dash than a slash. I wouldn't want to work on anything that I didn't\nwant to take over my life.Of course, it's easier to achieve this level of motivation when\nyou're making something like the Macintosh. It's easy for something", + "metadata": { + "text": "mere expression \"work/life\" embodies a mistake: it assumes work and\nlife are distinct. For those to whom the word \"work\" automatically\nimplies the dutiful plodding kind, they are. But for the skaters,\nthe relationship between work and life would be better represented\nby a dash than a slash. I wouldn't want to work on anything that I didn't\nwant to take over my life.Of course, it's easier to achieve this level of motivation when\nyou're making something like the Macintosh. It's easy for something", + "title": "pg_essay_1.html" + } + }, + { + "fragment_id": "31e60d4e-e223-53ae-aa46-f30821fd7a92", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "text": "new to feel like a project of your own. That's one of the reasons\nfor the tendency programmers have to rewrite things that don't need\nrewriting, and to write their own versions of things that already\nexist. This sometimes alarms managers, and measured by total number\nof characters typed, it's rarely the optimal solution. But it's not\nalways driven simply by arrogance or cluelessness.\nWriting code from scratch is also much more rewarding \u2014 so much", + "metadata": { + "text": "new to feel like a project of your own. That's one of the reasons\nfor the tendency programmers have to rewrite things that don't need\nrewriting, and to write their own versions of things that already\nexist. This sometimes alarms managers, and measured by total number\nof characters typed, it's rarely the optimal solution. But it's not\nalways driven simply by arrogance or cluelessness.\nWriting code from scratch is also much more rewarding \u2014 so much", + "title": "pg_essay_1.html" + } + }, + { + "fragment_id": "194d9ee6-13f4-527a-ba02-595131ace02a", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "text": "more rewarding that a good programmer can end up net ahead, despite\nthe shocking waste of characters. Indeed, it may be one of the\nadvantages of capitalism that it encourages such rewriting. A company\nthat needs software to do something can't use the software already\nwritten to do it at another company, and thus has to write their\nown, which often turns out better.\n[5]The natural alignment between skating and solving new problems is\none of the reasons the payoffs from startups are so high. Not only", + "metadata": { + "text": "more rewarding that a good programmer can end up net ahead, despite\nthe shocking waste of characters. Indeed, it may be one of the\nadvantages of capitalism that it encourages such rewriting. A company\nthat needs software to do something can't use the software already\nwritten to do it at another company, and thus has to write their\nown, which often turns out better.\n[5]The natural alignment between skating and solving new problems is\none of the reasons the payoffs from startups are so high. Not only", + "title": "pg_essay_1.html" + } + }, + { + "fragment_id": "d3fee2f7-a7bd-523e-957e-427712013146", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "text": "is the market price of unsolved problems higher, you also get a\ndiscount on productivity when you work on them. In fact, you get a\ndouble increase in productivity: when you're doing a clean-sheet\ndesign, it's easier to recruit skaters, and they get to spend all\ntheir time skating.Steve Jobs knew a thing or two about skaters from having watched\nSteve Wozniak. If you can find the right people, you only have to\ntell them what to do at the highest level. They'll handle the", + "metadata": { + "text": "is the market price of unsolved problems higher, you also get a\ndiscount on productivity when you work on them. In fact, you get a\ndouble increase in productivity: when you're doing a clean-sheet\ndesign, it's easier to recruit skaters, and they get to spend all\ntheir time skating.Steve Jobs knew a thing or two about skaters from having watched\nSteve Wozniak. If you can find the right people, you only have to\ntell them what to do at the highest level. They'll handle the", + "title": "pg_essay_1.html" + } + }, + { + "fragment_id": "e78bb470-5e0e-5b05-9f76-b60b9e43e90d", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "text": "details. Indeed, they insist on it. For a project to feel like your\nown, you must have sufficient autonomy. You can't be working to\norder, or slowed down\nby bureaucracy.One way to ensure autonomy is not to have a boss at all. There are\ntwo ways to do that: to be the boss yourself, and to work on projects\noutside of work. Though they're at opposite ends of the scale\nfinancially, startups and open source projects have a lot in common,\nincluding the fact that they're often run by skaters. And indeed,", + "metadata": { + "text": "details. Indeed, they insist on it. For a project to feel like your\nown, you must have sufficient autonomy. You can't be working to\norder, or slowed down\nby bureaucracy.One way to ensure autonomy is not to have a boss at all. There are\ntwo ways to do that: to be the boss yourself, and to work on projects\noutside of work. Though they're at opposite ends of the scale\nfinancially, startups and open source projects have a lot in common,\nincluding the fact that they're often run by skaters. And indeed,", + "title": "pg_essay_1.html" + } + }, + { + "fragment_id": "abed8147-50aa-5c90-8f66-cdbfe02d068f", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "text": "there's a wormhole from one end of the scale to the other: one of\nthe best ways to discover\nstartup ideas is to work on a project\njust for fun.If your projects are the kind that make money, it's easy to work\non them. It's harder when they're not. And the hardest part, usually,\nis morale. That's where adults have it harder than kids. Kids just\nplunge in and build their treehouse without worrying about whether\nthey're wasting their time, or how it compares to other treehouses.", + "metadata": { + "text": "there's a wormhole from one end of the scale to the other: one of\nthe best ways to discover\nstartup ideas is to work on a project\njust for fun.If your projects are the kind that make money, it's easy to work\non them. It's harder when they're not. And the hardest part, usually,\nis morale. That's where adults have it harder than kids. Kids just\nplunge in and build their treehouse without worrying about whether\nthey're wasting their time, or how it compares to other treehouses.", + "title": "pg_essay_1.html" + } + }, + { + "fragment_id": "80fbb24a-999e-593f-93a2-f9c42b46c98b", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "text": "And frankly we could learn a lot from kids here. The high standards\nmost grownups have for \"real\" work do not always serve us well.The most important phase in a project of one's own is at the\nbeginning: when you go from thinking it might be cool to do x to\nactually doing x. And at that point high standards are not merely\nuseless but positively harmful. There are a few people who start\ntoo many new projects, but far more, I suspect, who are deterred", + "metadata": { + "text": "And frankly we could learn a lot from kids here. The high standards\nmost grownups have for \"real\" work do not always serve us well.The most important phase in a project of one's own is at the\nbeginning: when you go from thinking it might be cool to do x to\nactually doing x. And at that point high standards are not merely\nuseless but positively harmful. There are a few people who start\ntoo many new projects, but far more, I suspect, who are deterred", + "title": "pg_essay_1.html" + } + }, + { + "fragment_id": "5be9b626-b309-5502-941e-250efd5d23be", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "text": "by fear of failure from starting projects that would have succeeded\nif they had.But if we couldn't benefit as kids from the knowledge that our\ntreehouses were on the path to grownup projects, we can at least\nbenefit as grownups from knowing that our projects are on a path\nthat stretches back to treehouses. Remember that careless confidence\nyou had as a kid when starting something new? That would be a\npowerful thing to recapture.If it's harder as adults to retain that kind of confidence, we at", + "metadata": { + "text": "by fear of failure from starting projects that would have succeeded\nif they had.But if we couldn't benefit as kids from the knowledge that our\ntreehouses were on the path to grownup projects, we can at least\nbenefit as grownups from knowing that our projects are on a path\nthat stretches back to treehouses. Remember that careless confidence\nyou had as a kid when starting something new? That would be a\npowerful thing to recapture.If it's harder as adults to retain that kind of confidence, we at", + "title": "pg_essay_1.html" + } + }, + { + "fragment_id": "6139c5ce-049d-5f31-86b5-efd3a2be1e5d", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "text": "least tend to be more aware of what we're doing. Kids bounce, or\nare herded, from one kind of work to the next, barely realizing\nwhat's happening to them. Whereas we know more about different types\nof work and have more control over which we do. Ideally we can have\nthe best of both worlds: to be deliberate in choosing to work on\nprojects of our own, and carelessly confident in starting new ones.\nNotes[1]\n\"Hobby\" is a curious word. Now it means work that isn't real", + "metadata": { + "text": "least tend to be more aware of what we're doing. Kids bounce, or\nare herded, from one kind of work to the next, barely realizing\nwhat's happening to them. Whereas we know more about different types\nof work and have more control over which we do. Ideally we can have\nthe best of both worlds: to be deliberate in choosing to work on\nprojects of our own, and carelessly confident in starting new ones.\nNotes[1]\n\"Hobby\" is a curious word. Now it means work that isn't real", + "title": "pg_essay_1.html" + } + }, + { + "fragment_id": "d3027d33-3720-5a1e-8563-7249b05ac5c5", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "text": "work \u2014 work that one is not to be judged by \u2014 but originally it just\nmeant an obsession in a fairly general sense (even a political\nopinion, for example) that one metaphorically rode as a child rides\na hobby-horse. It's hard to say if its recent, narrower meaning is\na change for the better or the worse. For sure there are lots of\nfalse positives \u2014 lots of projects that end up being important but\nare dismissed initially as mere hobbies. But on the other hand, the", + "metadata": { + "text": "work \u2014 work that one is not to be judged by \u2014 but originally it just\nmeant an obsession in a fairly general sense (even a political\nopinion, for example) that one metaphorically rode as a child rides\na hobby-horse. It's hard to say if its recent, narrower meaning is\na change for the better or the worse. For sure there are lots of\nfalse positives \u2014 lots of projects that end up being important but\nare dismissed initially as mere hobbies. But on the other hand, the", + "title": "pg_essay_1.html" + } + }, + { + "fragment_id": "b6587cfc-01dc-5324-af32-08c059b099cd", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "text": "concept provides valuable cover for projects in the early, ugly\nduckling phase.[2]\nTiger parents, as parents so often do, are fighting the last\nwar. Grades mattered more in the old days when the route to success\nwas to acquire\ncredentials\nwhile ascending some predefined ladder.\nBut it's just as well that their tactics are focused on grades. How\nawful it would be if they invaded the territory of projects, and\nthereby gave their kids a distaste for this kind of work by forcing", + "metadata": { + "text": "concept provides valuable cover for projects in the early, ugly\nduckling phase.[2]\nTiger parents, as parents so often do, are fighting the last\nwar. Grades mattered more in the old days when the route to success\nwas to acquire\ncredentials\nwhile ascending some predefined ladder.\nBut it's just as well that their tactics are focused on grades. How\nawful it would be if they invaded the territory of projects, and\nthereby gave their kids a distaste for this kind of work by forcing", + "title": "pg_essay_1.html" + } + }, + { + "fragment_id": "57b17831-a919-5d01-b7c1-1077285ffd38", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "text": "them to do it. Grades are already a grim, fake world, and aren't\nharmed much by parental interference, but working on one's own\nprojects is a more delicate, private thing that could be damaged\nvery easily.[3]\nThe complicated, gradual edge between working on one's own\nprojects and collaborating with others is one reason there is so\nmuch disagreement about the idea of the \"lone genius.\" In practice\npeople collaborate (or not) in all kinds of different ways, but the", + "metadata": { + "text": "them to do it. Grades are already a grim, fake world, and aren't\nharmed much by parental interference, but working on one's own\nprojects is a more delicate, private thing that could be damaged\nvery easily.[3]\nThe complicated, gradual edge between working on one's own\nprojects and collaborating with others is one reason there is so\nmuch disagreement about the idea of the \"lone genius.\" In practice\npeople collaborate (or not) in all kinds of different ways, but the", + "title": "pg_essay_1.html" + } + }, + { + "fragment_id": "8e943dae-6cbf-543f-9092-16600569621c", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "text": "idea of the lone genius is definitely not a myth. There's a core\nof truth to it that goes with a certain way of working.[4]\nCollaboration is powerful too. The optimal organization would\ncombine collaboration and ownership in such a way as to do the least\ndamage to each. Interestingly, companies and university departments\napproach this ideal from opposite directions: companies insist on\ncollaboration, and occasionally also manage both to recruit skaters", + "metadata": { + "text": "idea of the lone genius is definitely not a myth. There's a core\nof truth to it that goes with a certain way of working.[4]\nCollaboration is powerful too. The optimal organization would\ncombine collaboration and ownership in such a way as to do the least\ndamage to each. Interestingly, companies and university departments\napproach this ideal from opposite directions: companies insist on\ncollaboration, and occasionally also manage both to recruit skaters", + "title": "pg_essay_1.html" + } + }, + { + "fragment_id": "8ad34f88-fe21-598e-b6d7-1d66224075c3", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "text": "and allow them to skate, and university departments insist on the\nability to do independent research (which is by custom treated as\nskating, whether it is or not), and the people they hire collaborate\nas much as they choose.[5]\nIf a company could design its software in such a way that the\nbest newly arrived programmers always got a clean sheet, it could\nhave a kind of eternal youth. That might not be impossible. If you\nhad a software backbone defining a game with sufficiently clear", + "metadata": { + "text": "and allow them to skate, and university departments insist on the\nability to do independent research (which is by custom treated as\nskating, whether it is or not), and the people they hire collaborate\nas much as they choose.[5]\nIf a company could design its software in such a way that the\nbest newly arrived programmers always got a clean sheet, it could\nhave a kind of eternal youth. That might not be impossible. If you\nhad a software backbone defining a game with sufficiently clear", + "title": "pg_essay_1.html" + } + }, + { + "fragment_id": "5127d109-8748-5615-92c1-082bd728df43", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "text": "rules, individual programmers could write their own players.\nThanks to Trevor Blackwell, Paul Buchheit, Andy Hertzfeld, Jessica\nLivingston, and Peter Norvig for reading drafts of this.", + "metadata": { + "text": "rules, individual programmers could write their own players.\nThanks to Trevor Blackwell, Paul Buchheit, Andy Hertzfeld, Jessica\nLivingston, and Peter Norvig for reading drafts of this.", + "title": "pg_essay_1.html" + } + } + ] + }, + "update_document_test": { + "results": { + "processed_documents": [ + { + "id": "db02076e-989a-59cd-98d5-e24e15a0bd27", + "group_ids": [], + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "type": "txt", + "metadata": {}, + "title": "aristotle_v2.txt", + "version": "v1", + "size_in_bytes": 7443, + "status": "success", + "created_at": "2024-08-13T17:47:20.150851", + "updated_at": "2024-08-13T17:47:20.150851" + } + ], + "failed_documents": [], + "skipped_documents": [] + } + }, + "delete_document_test": { + "results": { + "cd85f762-5739-5f19-86d9-a4a9fe213e44": { + "fragment_id": "cd85f762-5739-5f19-86d9-a4a9fe213e44", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "text": "A Project of One's Own" + }, + "cd38c41d-a14a-52ba-8882-83eaafcbb163": { + "fragment_id": "cd38c41d-a14a-52ba-8882-83eaafcbb163", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "text": "June 2021A few days ago, on the way home from school, my nine year old son\ntold me he couldn't wait to get home to write more of the story he\nwas working on. This made me as happy as anything I've heard him\nsay \u2014 not just because he was excited about his story, but because\nhe'd discovered this way of working. Working on a project of your\nown is as different from ordinary work as skating is from walking." + }, + "fb968ad0-15ab-50b1-982c-08d1e1a1cbd9": { + "fragment_id": "fb968ad0-15ab-50b1-982c-08d1e1a1cbd9", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "text": "It's more fun, but also much more productive.What proportion of great work has been done by people who were\nskating in this sense? If not all of it, certainly a lot.There is something special about working on a project of your own.\nI wouldn't say exactly that you're happier. A better word would be\nexcited, or engaged. You're happy when things are going well, but\noften they aren't. When I'm writing an essay, most of the time I'm\nworried and puzzled: worried that the essay will turn out badly," + }, + "263476d3-7650-52c9-99ad-ec9d5406c581": { + "fragment_id": "263476d3-7650-52c9-99ad-ec9d5406c581", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "text": "and puzzled because I'm groping for some idea that I can't see\nclearly enough. Will I be able to pin it down with words? In the\nend I usually can, if I take long enough, but I'm never sure; the\nfirst few attempts often fail.You have moments of happiness when things work out, but they don't\nlast long, because then you're on to the next problem. So why do\nit at all? Because to the kind of people who like working this way,\nnothing else feels as right. You feel as if you're an animal in its" + }, + "28c70d00-ee77-5e5e-9c0e-ff79332ffabb": { + "fragment_id": "28c70d00-ee77-5e5e-9c0e-ff79332ffabb", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "text": "natural habitat, doing what you were meant to do \u2014 not always\nhappy, maybe, but awake and alive.Many kids experience the excitement of working on projects of their\nown. The hard part is making this converge with the work you do as\nan adult. And our customs make it harder. We treat \"playing\" and\n\"hobbies\" as qualitatively different from \"work\". It's not clear\nto a kid building a treehouse that there's a direct (though long)\nroute from that to architecture or engineering. And instead of" + }, + "67a4ddfc-d362-5b4b-afaf-5b3f53ec7ac5": { + "fragment_id": "67a4ddfc-d362-5b4b-afaf-5b3f53ec7ac5", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "text": "pointing out the route, we conceal it, by implicitly treating the\nstuff kids do as different from real work.\n[1]Instead of telling kids that their treehouses could be on the path\nto the work they do as adults, we tell them the path goes through\nschool. And unfortunately schoolwork tends to be very different from\nworking on projects of one's own. It's usually neither a project,\nnor one's own. So as school gets more serious, working on projects" + }, + "001c1335-737c-5585-9ec1-441ee9c49348": { + "fragment_id": "001c1335-737c-5585-9ec1-441ee9c49348", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "text": "of one's own is something that survives, if at all, as a thin thread\noff to the side.It's a bit sad to think of all the high school kids turning their\nbacks on building treehouses and sitting in class dutifully learning\nabout Darwin or Newton to pass some exam, when the work that made\nDarwin and Newton famous was actually closer in spirit to building\ntreehouses than studying for exams.If I had to choose between my kids getting good grades and\nworking on ambitious projects of their own, I'd pick" + }, + "c3759b2a-fbec-55db-b850-511d4730de7e": { + "fragment_id": "c3759b2a-fbec-55db-b850-511d4730de7e", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "text": "techniques for preserving that excitement.\n[4]The team that made the original Macintosh were a great example of\nthis phenomenon. People like Burrell Smith and Andy Hertzfeld and\nBill Atkinson and Susan Kare were not just following orders. They\nwere not tennis balls hit by Steve Jobs, but rockets let loose by\nSteve Jobs. There was a lot of collaboration between them, but\nthey all seem to have individually felt the excitement of" + }, + "540d1c52-6dae-5fb4-b4ad-3d5bbd938abe": { + "fragment_id": "540d1c52-6dae-5fb4-b4ad-3d5bbd938abe", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "text": "the projects. And not because I'm an indulgent parent, but because\nI've been on the other end and I know which has more predictive\nvalue. When I was picking startups for Y Combinator, I didn't care\nabout applicants' grades. But if they'd worked on projects of their\nown, I wanted to hear all about those.\n[2]It may be inevitable that school is the way it is. I'm not saying\nwe have to redesign it (though I'm not saying we don't), just that\nwe should understand what it does to our attitudes to work \u2014 that" + }, + "fee3d54e-dd02-5f46-9edc-ee4f5d7a70d4": { + "fragment_id": "fee3d54e-dd02-5f46-9edc-ee4f5d7a70d4", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "text": "it steers us toward the dutiful plodding kind of work, often using\ncompetition as bait, and away from skating.There are occasionally times when schoolwork becomes a project of\none's own. Whenever I had to write a paper, that would become a\nproject of my own \u2014 except in English classes, ironically, because\nthe things one has to write in English classes are so\nbogus. And\nwhen I got to college and started taking CS classes, the programs\nI had to write became projects of my own. Whenever I was writing" + }, + "05f02dc2-53ab-539b-9b4d-899eada47a3c": { + "fragment_id": "05f02dc2-53ab-539b-9b4d-899eada47a3c", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "text": "or programming, I was usually skating, and that has been true ever\nsince.So where exactly is the edge of projects of one's own? That's an\ninteresting question, partly because the answer is so complicated,\nand partly because there's so much at stake. There turn out to be\ntwo senses in which work can be one's own: 1) that you're doing it\nvoluntarily, rather than merely because someone told you to, and\n2) that you're doing it by yourself.The edge of the former is quite sharp. People who care a lot about" + }, + "42b9d617-6d85-5ba4-a8a6-bb3489faf930": { + "fragment_id": "42b9d617-6d85-5ba4-a8a6-bb3489faf930", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "text": "their work are usually very sensitive to the difference between\npulling, and being pushed, and work tends to fall into one category\nor the other. But the test isn't simply whether you're told to do\nsomething. You can choose to do something you're told to do. Indeed,\nyou can own it far more thoroughly than the person who told you to\ndo it.For example, math homework is for most people something they're\ntold to do. But for my father, who was a mathematician, it wasn't." + }, + "d9876b6c-42ab-5852-a98f-15032c7687c7": { + "fragment_id": "d9876b6c-42ab-5852-a98f-15032c7687c7", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "text": "Most of us think of the problems in a math book as a way to test\nor develop our knowledge of the material explained in each section.\nBut to my father the problems were the part that mattered, and the\ntext was merely a sort of annotation. Whenever he got a new math\nbook it was to him like being given a puzzle: here was a new set\nof problems to solve, and he'd immediately set about solving all\nof them.The other sense of a project being one's own \u2014 working on it by" + }, + "bec313c9-3fe3-5197-8792-078069a484e2": { + "fragment_id": "bec313c9-3fe3-5197-8792-078069a484e2", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "text": "oneself \u2014 has a much softer edge. It shades gradually into\ncollaboration. And interestingly, it shades into collaboration in\ntwo different ways. One way to collaborate is to share a single\nproject. For example, when two mathematicians collaborate on a proof\nthat takes shape in the course of a conversation between them. The\nother way is when multiple people work on separate projects of their\nown that fit together like a jigsaw puzzle. For example, when one" + }, + "8626ebe9-8132-5222-ba90-eef6a380ea65": { + "fragment_id": "8626ebe9-8132-5222-ba90-eef6a380ea65", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "text": "person writes the text of a book and another does the graphic design.\n[3]These two paths into collaboration can of course be combined. But\nunder the right conditions, the excitement of working on a project\nof one's own can be preserved for quite a while before disintegrating\ninto the turbulent flow of work in a large organization. Indeed,\nthe history of successful organizations is partly the history of\ntechniques for preserving that excitement." + }, + "759018be-fcfc-5e53-bc2e-ce2e6e677d61": { + "fragment_id": "759018be-fcfc-5e53-bc2e-ce2e6e677d61", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "text": "working on a project of one's own.In Andy Hertzfeld's book on the Macintosh, he describes how they'd\ncome back into the office after dinner and work late into the night.\nPeople who've never experienced the thrill of working on a project\nthey're excited about can't distinguish this kind of working long\nhours from the kind that happens in sweatshops and boiler rooms,\nbut they're at opposite ends of the spectrum. That's why it's a\nmistake to insist dogmatically on \"work/life balance.\" Indeed, the" + }, + "4f01bc15-500e-586f-97f0-a89b36248ea2": { + "fragment_id": "4f01bc15-500e-586f-97f0-a89b36248ea2", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "text": "mere expression \"work/life\" embodies a mistake: it assumes work and\nlife are distinct. For those to whom the word \"work\" automatically\nimplies the dutiful plodding kind, they are. But for the skaters,\nthe relationship between work and life would be better represented\nby a dash than a slash. I wouldn't want to work on anything that I didn't\nwant to take over my life.Of course, it's easier to achieve this level of motivation when\nyou're making something like the Macintosh. It's easy for something" + }, + "31e60d4e-e223-53ae-aa46-f30821fd7a92": { + "fragment_id": "31e60d4e-e223-53ae-aa46-f30821fd7a92", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "text": "new to feel like a project of your own. That's one of the reasons\nfor the tendency programmers have to rewrite things that don't need\nrewriting, and to write their own versions of things that already\nexist. This sometimes alarms managers, and measured by total number\nof characters typed, it's rarely the optimal solution. But it's not\nalways driven simply by arrogance or cluelessness.\nWriting code from scratch is also much more rewarding \u2014 so much" + }, + "194d9ee6-13f4-527a-ba02-595131ace02a": { + "fragment_id": "194d9ee6-13f4-527a-ba02-595131ace02a", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "text": "more rewarding that a good programmer can end up net ahead, despite\nthe shocking waste of characters. Indeed, it may be one of the\nadvantages of capitalism that it encourages such rewriting. A company\nthat needs software to do something can't use the software already\nwritten to do it at another company, and thus has to write their\nown, which often turns out better.\n[5]The natural alignment between skating and solving new problems is\none of the reasons the payoffs from startups are so high. Not only" + }, + "d3fee2f7-a7bd-523e-957e-427712013146": { + "fragment_id": "d3fee2f7-a7bd-523e-957e-427712013146", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "text": "is the market price of unsolved problems higher, you also get a\ndiscount on productivity when you work on them. In fact, you get a\ndouble increase in productivity: when you're doing a clean-sheet\ndesign, it's easier to recruit skaters, and they get to spend all\ntheir time skating.Steve Jobs knew a thing or two about skaters from having watched\nSteve Wozniak. If you can find the right people, you only have to\ntell them what to do at the highest level. They'll handle the" + }, + "e78bb470-5e0e-5b05-9f76-b60b9e43e90d": { + "fragment_id": "e78bb470-5e0e-5b05-9f76-b60b9e43e90d", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "text": "details. Indeed, they insist on it. For a project to feel like your\nown, you must have sufficient autonomy. You can't be working to\norder, or slowed down\nby bureaucracy.One way to ensure autonomy is not to have a boss at all. There are\ntwo ways to do that: to be the boss yourself, and to work on projects\noutside of work. Though they're at opposite ends of the scale\nfinancially, startups and open source projects have a lot in common,\nincluding the fact that they're often run by skaters. And indeed," + }, + "abed8147-50aa-5c90-8f66-cdbfe02d068f": { + "fragment_id": "abed8147-50aa-5c90-8f66-cdbfe02d068f", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "text": "there's a wormhole from one end of the scale to the other: one of\nthe best ways to discover\nstartup ideas is to work on a project\njust for fun.If your projects are the kind that make money, it's easy to work\non them. It's harder when they're not. And the hardest part, usually,\nis morale. That's where adults have it harder than kids. Kids just\nplunge in and build their treehouse without worrying about whether\nthey're wasting their time, or how it compares to other treehouses." + }, + "80fbb24a-999e-593f-93a2-f9c42b46c98b": { + "fragment_id": "80fbb24a-999e-593f-93a2-f9c42b46c98b", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "text": "And frankly we could learn a lot from kids here. The high standards\nmost grownups have for \"real\" work do not always serve us well.The most important phase in a project of one's own is at the\nbeginning: when you go from thinking it might be cool to do x to\nactually doing x. And at that point high standards are not merely\nuseless but positively harmful. There are a few people who start\ntoo many new projects, but far more, I suspect, who are deterred" + }, + "5be9b626-b309-5502-941e-250efd5d23be": { + "fragment_id": "5be9b626-b309-5502-941e-250efd5d23be", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "text": "by fear of failure from starting projects that would have succeeded\nif they had.But if we couldn't benefit as kids from the knowledge that our\ntreehouses were on the path to grownup projects, we can at least\nbenefit as grownups from knowing that our projects are on a path\nthat stretches back to treehouses. Remember that careless confidence\nyou had as a kid when starting something new? That would be a\npowerful thing to recapture.If it's harder as adults to retain that kind of confidence, we at" + }, + "6139c5ce-049d-5f31-86b5-efd3a2be1e5d": { + "fragment_id": "6139c5ce-049d-5f31-86b5-efd3a2be1e5d", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "text": "least tend to be more aware of what we're doing. Kids bounce, or\nare herded, from one kind of work to the next, barely realizing\nwhat's happening to them. Whereas we know more about different types\nof work and have more control over which we do. Ideally we can have\nthe best of both worlds: to be deliberate in choosing to work on\nprojects of our own, and carelessly confident in starting new ones.\nNotes[1]\n\"Hobby\" is a curious word. Now it means work that isn't real" + }, + "d3027d33-3720-5a1e-8563-7249b05ac5c5": { + "fragment_id": "d3027d33-3720-5a1e-8563-7249b05ac5c5", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "text": "work \u2014 work that one is not to be judged by \u2014 but originally it just\nmeant an obsession in a fairly general sense (even a political\nopinion, for example) that one metaphorically rode as a child rides\na hobby-horse. It's hard to say if its recent, narrower meaning is\na change for the better or the worse. For sure there are lots of\nfalse positives \u2014 lots of projects that end up being important but\nare dismissed initially as mere hobbies. But on the other hand, the" + }, + "b6587cfc-01dc-5324-af32-08c059b099cd": { + "fragment_id": "b6587cfc-01dc-5324-af32-08c059b099cd", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "text": "concept provides valuable cover for projects in the early, ugly\nduckling phase.[2]\nTiger parents, as parents so often do, are fighting the last\nwar. Grades mattered more in the old days when the route to success\nwas to acquire\ncredentials\nwhile ascending some predefined ladder.\nBut it's just as well that their tactics are focused on grades. How\nawful it would be if they invaded the territory of projects, and\nthereby gave their kids a distaste for this kind of work by forcing" + }, + "57b17831-a919-5d01-b7c1-1077285ffd38": { + "fragment_id": "57b17831-a919-5d01-b7c1-1077285ffd38", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "text": "them to do it. Grades are already a grim, fake world, and aren't\nharmed much by parental interference, but working on one's own\nprojects is a more delicate, private thing that could be damaged\nvery easily.[3]\nThe complicated, gradual edge between working on one's own\nprojects and collaborating with others is one reason there is so\nmuch disagreement about the idea of the \"lone genius.\" In practice\npeople collaborate (or not) in all kinds of different ways, but the" + }, + "8e943dae-6cbf-543f-9092-16600569621c": { + "fragment_id": "8e943dae-6cbf-543f-9092-16600569621c", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "text": "idea of the lone genius is definitely not a myth. There's a core\nof truth to it that goes with a certain way of working.[4]\nCollaboration is powerful too. The optimal organization would\ncombine collaboration and ownership in such a way as to do the least\ndamage to each. Interestingly, companies and university departments\napproach this ideal from opposite directions: companies insist on\ncollaboration, and occasionally also manage both to recruit skaters" + }, + "8ad34f88-fe21-598e-b6d7-1d66224075c3": { + "fragment_id": "8ad34f88-fe21-598e-b6d7-1d66224075c3", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "text": "and allow them to skate, and university departments insist on the\nability to do independent research (which is by custom treated as\nskating, whether it is or not), and the people they hire collaborate\nas much as they choose.[5]\nIf a company could design its software in such a way that the\nbest newly arrived programmers always got a clean sheet, it could\nhave a kind of eternal youth. That might not be impossible. If you\nhad a software backbone defining a game with sufficiently clear" + }, + "5127d109-8748-5615-92c1-082bd728df43": { + "fragment_id": "5127d109-8748-5615-92c1-082bd728df43", + "document_id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "extraction_id": "36474213-c9fa-5fb7-b99e-c3720743da53", + "text": "rules, individual programmers could write their own players.\nThanks to Trevor Blackwell, Paul Buchheit, Andy Hertzfeld, Jessica\nLivingston, and Peter Norvig for reading drafts of this." + } + } + }, + "rerun_documents_overview_test": { + "results": [ + { + "id": "716fea3a-826b-5b27-8e59-ffbd1a35455a", + "group_ids": [], + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "type": "txt", + "metadata": {}, + "title": "got.txt", + "version": "v0", + "size_in_bytes": 9491, + "status": "success", + "created_at": "2024-08-13T17:43:28.344841Z", + "updated_at": "2024-08-13T17:43:28.344841Z" + }, + { + "id": "52e12576-090f-59db-91f4-6d4b2e29ae6c", + "group_ids": [], + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "type": "mp3", + "metadata": {}, + "title": "sample.mp3", + "version": "v0", + "size_in_bytes": 121671, + "status": "success", + "created_at": "2024-08-13T17:43:28.344851Z", + "updated_at": "2024-08-13T17:43:28.344851Z" + }, + { + "id": "3e157b3a-8469-51db-90d9-52e7d896b49b", + "group_ids": [], + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "type": "pdf", + "metadata": {}, + "title": "uber_2021.pdf", + "version": "v0", + "size_in_bytes": 1880483, + "status": "success", + "created_at": "2024-08-13T17:43:28.344856Z", + "updated_at": "2024-08-13T17:43:28.344856Z" + }, + { + "id": "01d514a4-5cb1-5c86-be8c-0c5c312a02c9", + "group_ids": [], + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "type": "mp3", + "metadata": {}, + "title": "sample2.mp3", + "version": "v0", + "size_in_bytes": 72456, + "status": "success", + "created_at": "2024-08-13T17:43:28.344867Z", + "updated_at": "2024-08-13T17:43:28.344867Z" + }, + { + "id": "c3291abf-8a4e-5d9d-80fd-232ef6fd8526", + "group_ids": [], + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "type": "txt", + "metadata": {}, + "title": "aristotle_v2.txt", + "version": "v0", + "size_in_bytes": 7443, + "status": "success", + "created_at": "2024-08-13T17:43:28.344871Z", + "updated_at": "2024-08-13T17:43:28.344871Z" + }, + { + "id": "e797da22-8c5d-54e5-bed5-a55954cf6bf9", + "group_ids": [], + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "type": "html", + "metadata": {}, + "title": "pg_essay_4.html", + "version": "v0", + "size_in_bytes": 118113, + "status": "success", + "created_at": "2024-08-13T17:43:28.344874Z", + "updated_at": "2024-08-13T17:43:28.344874Z" + }, + { + "id": "7c1105fc-8f62-5a8f-ac81-fe88f3ec9e4c", + "group_ids": [], + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "type": "html", + "metadata": {}, + "title": "pg_essay_5.html", + "version": "v0", + "size_in_bytes": 123779, + "status": "success", + "created_at": "2024-08-13T17:43:28.344879Z", + "updated_at": "2024-08-13T17:43:28.344879Z" + }, + { + "id": "2f576170-c4f9-5141-a910-a0924f341de4", + "group_ids": [], + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "type": "pdf", + "metadata": {}, + "title": "lyft_2021.pdf", + "version": "v0", + "size_in_bytes": 1440303, + "status": "success", + "created_at": "2024-08-13T17:43:28.344884Z", + "updated_at": "2024-08-13T17:43:28.344884Z" + }, + { + "id": "30f950f0-c692-57c5-b6ec-ff78ccf5ccdc", + "group_ids": [], + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "type": "txt", + "metadata": {}, + "title": "test.txt", + "version": "v0", + "size_in_bytes": 20, + "status": "success", + "created_at": "2024-08-13T17:43:28.344889Z", + "updated_at": "2024-08-13T17:43:28.344889Z" + }, + { + "id": "57eec3df-cf68-5559-a80d-ae3fb55b9af1", + "group_ids": [], + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "type": "html", + "metadata": {}, + "title": "pg_essay_2.html", + "version": "v0", + "size_in_bytes": 125112, + "status": "success", + "created_at": "2024-08-13T17:43:28.344893Z", + "updated_at": "2024-08-13T17:43:28.344893Z" + }, + { + "id": "d421207a-d799-5806-8d67-46b2005b15d4", + "group_ids": [], + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "type": "txt", + "metadata": {}, + "title": "yc_companies.txt", + "version": "v0", + "size_in_bytes": 47209, + "status": "success", + "created_at": "2024-08-13T17:43:28.344901Z", + "updated_at": "2024-08-13T17:43:28.344901Z" + }, + { + "id": "451adbbd-e24e-5c9b-80a8-f424b6c7accb", + "group_ids": [], + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "type": "png", + "metadata": {}, + "title": "screen_shot.png", + "version": "v0", + "size_in_bytes": 791764, + "status": "success", + "created_at": "2024-08-13T17:43:28.344905Z", + "updated_at": "2024-08-13T17:43:28.344905Z" + }, + { + "id": "5b1bd54f-4d70-56b9-a017-a618bc75f94c", + "group_ids": [], + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "type": "html", + "metadata": {}, + "title": "pg_essay_3.html", + "version": "v0", + "size_in_bytes": 124915, + "status": "success", + "created_at": "2024-08-13T17:43:28.344908Z", + "updated_at": "2024-08-13T17:43:28.344908Z" + }, + { + "id": "db02076e-989a-59cd-98d5-e24e15a0bd27", + "group_ids": [], + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "type": "txt", + "metadata": {}, + "title": "aristotle_v2.txt", + "version": "v1", + "size_in_bytes": 7443, + "status": "success", + "created_at": "2024-08-13T17:43:28.344898Z", + "updated_at": "2024-08-13T17:47:20.150851Z" + } + ] + }, + "rerun_document_chunks_test": { + "results": "No chunks found for the given document ID." + } +} diff --git a/tests/regression/expected_outputs/test_group_management.json b/tests/regression/expected_outputs/test_group_management.json new file mode 100644 index 000000000..079881405 --- /dev/null +++ b/tests/regression/expected_outputs/test_group_management.json @@ -0,0 +1,168 @@ +{ + "create_groups": { + "group_1": { + "results": { + "group_id": "3b24e22c-843d-4cd1-8183-6f244211542b", + "name": "Test Group 1 90248f87-cf4f-42ac-9f10-c68716e46ccb", + "description": "A test group for permissions", + "created_at": "2024-08-14T01:01:19.662617+00:00", + "updated_at": "2024-08-14T01:01:19.662617+00:00" + } + }, + "group_2": { + "results": { + "group_id": "3a2bfab3-5527-47a1-a901-a463e9b06971", + "name": "Test Group 2 99212e13-64dc-456a-93d3-3e2afc97f3be", + "description": "Another test group for permissions", + "created_at": "2024-08-14T01:01:19.803314+00:00", + "updated_at": "2024-08-14T01:01:19.803314+00:00" + } + } + }, + "add_users_to_groups": { + "user_1": { + "results": { + "email": "user1_62951675-cbc1-40dd-b005-3758adfc4c68@example.com", + "id": "a34207e5-9b1a-5fe3-8a02-9ff56464b112", + "group_ids": [], + "hashed_password": "$2b$12$tVPpwO.Tr5KR/gtWm1UPDuq6.pXY3rlO7YonLYR0XcwwJkhgVI96O", + "is_superuser": false, + "is_active": true, + "is_verified": false, + "verification_code_expiry": null, + "name": null, + "bio": null, + "profile_picture": null, + "created_at": "2024-08-14T01:01:20.181505Z", + "updated_at": "2024-08-14T01:01:20.181505Z" + } + }, + "user_2": { + "results": { + "email": "user2_16f40e51-174a-4b06-b308-1160b701cda7@example.com", + "id": "4404314d-12a1-5299-9f7a-adfac07a5a3b", + "group_ids": [], + "hashed_password": "$2b$12$oqVl4mg7sL6UfUO2ziz4suSSOOBwYJisag.E.pHNWxd0YMde57e0y", + "is_superuser": false, + "is_active": true, + "is_verified": false, + "verification_code_expiry": null, + "name": null, + "bio": null, + "profile_picture": null, + "created_at": "2024-08-14T01:01:20.651635Z", + "updated_at": "2024-08-14T01:01:20.651635Z" + } + } + }, + "group_based_document_access": { + "error": "An error ''PostgresVectorDBProvider' object has no attribute 'assign_document_to_group'' occurred during ingest_files_app" + }, + "admin_ingest_documents": { + "error": "An error ''PostgresVectorDBProvider' object has no attribute 'assign_document_to_group'' occurred during ingest_files_app" + }, + "user_ingest_and_search": { + "user_1_ingest": { + "results": { + "processed_documents": [ + { + "id": "55d7b67e-c717-5e89-a956-61580475199d", + "group_ids": [], + "user_id": "a34207e5-9b1a-5fe3-8a02-9ff56464b112", + "type": "txt", + "metadata": {}, + "title": "user1_document.txt", + "version": "v0", + "size_in_bytes": 15, + "status": "success", + "created_at": "2024-08-13T18:01:23.617547", + "updated_at": "2024-08-13T18:01:23.617547" + } + ], + "failed_documents": [], + "skipped_documents": [] + } + }, + "user_1_search": { + "results": { + "vector_search_results": [ + { + "fragment_id": "ced2d47c-524c-58d3-8cc3-0d474312fb00", + "extraction_id": "b4451d80-760d-5e0f-93bc-cc0a89b1630d", + "document_id": "55d7b67e-c717-5e89-a956-61580475199d", + "user_id": "a34207e5-9b1a-5fe3-8a02-9ff56464b112", + "group_ids": [], + "score": 0.577595285558281, + "text": "user1_document", + "metadata": { + "text": "user1_document", + "title": "user1_document.txt", + "associatedQuery": "document" + } + }, + { + "fragment_id": "2b30d8c0-d037-5ca7-9961-08e2a13a25cd", + "extraction_id": "eae05bf5-f732-53b3-80e5-a6e39d5a23d3", + "document_id": "653c933c-867d-5588-b6cd-54d9412a8ffa", + "user_id": "a34207e5-9b1a-5fe3-8a02-9ff56464b112", + "group_ids": [], + "score": 0.487762882211468, + "text": "user1_document_group", + "metadata": { + "text": "user1_document_group", + "title": "user1_document_group.txt", + "user_id": "a34207e5-9b1a-5fe3-8a02-9ff56464b112", + "associatedQuery": "document" + } + } + ], + "kg_search_results": [] + } + }, + "user_2_ingest": { + "results": { + "processed_documents": [ + { + "id": "6a7d57a8-0bab-55df-8674-a94b1ecd6492", + "group_ids": [], + "user_id": "4404314d-12a1-5299-9f7a-adfac07a5a3b", + "type": "txt", + "metadata": {}, + "title": "user2_document.txt", + "version": "v0", + "size_in_bytes": 15, + "status": "success", + "created_at": "2024-08-13T18:01:25.577549", + "updated_at": "2024-08-13T18:01:25.577549" + } + ], + "failed_documents": [], + "skipped_documents": [] + } + }, + "user_2_search": { + "results": { + "vector_search_results": [ + { + "fragment_id": "4f3e93df-099c-58a7-a5cf-c40ba5ae76c1", + "extraction_id": "838aa00a-2d5a-588c-9aa1-2553ae514024", + "document_id": "6a7d57a8-0bab-55df-8674-a94b1ecd6492", + "user_id": "4404314d-12a1-5299-9f7a-adfac07a5a3b", + "group_ids": [], + "score": 0.530904515656706, + "text": "user2_document", + "metadata": { + "text": "user2_document", + "title": "user2_document.txt", + "associatedQuery": "document" + } + } + ], + "kg_search_results": [] + } + } + }, + "cleanup": { + "status": "cleanup completed" + } +} diff --git a/tests/regression/expected_outputs/test_observability.json b/tests/regression/expected_outputs/test_observability.json new file mode 100644 index 000000000..9caa47047 --- /dev/null +++ b/tests/regression/expected_outputs/test_observability.json @@ -0,0 +1,381 @@ +{ + "users_overview": { + "results": [ + { + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "num_files": 15, + "total_size_in_bytes": 5067615, + "document_ids": [ + "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "716fea3a-826b-5b27-8e59-ffbd1a35455a", + "52e12576-090f-59db-91f4-6d4b2e29ae6c", + "3e157b3a-8469-51db-90d9-52e7d896b49b", + "01d514a4-5cb1-5c86-be8c-0c5c312a02c9", + "c3291abf-8a4e-5d9d-80fd-232ef6fd8526", + "e797da22-8c5d-54e5-bed5-a55954cf6bf9", + "7c1105fc-8f62-5a8f-ac81-fe88f3ec9e4c", + "2f576170-c4f9-5141-a910-a0924f341de4", + "30f950f0-c692-57c5-b6ec-ff78ccf5ccdc", + "57eec3df-cf68-5559-a80d-ae3fb55b9af1", + "db02076e-989a-59cd-98d5-e24e15a0bd27", + "d421207a-d799-5806-8d67-46b2005b15d4", + "451adbbd-e24e-5c9b-80a8-f424b6c7accb", + "5b1bd54f-4d70-56b9-a017-a618bc75f94c" + ] + } + ] + }, + "logs": { + "results": [ + { + "run_id": "ad9ece10-fe2f-49e4-835e-1b274dae8167", + "run_type": "UNSPECIFIED", + "entries": [], + "timestamp": "2024-08-14T00:26:03", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220" + }, + { + "run_id": "698aa5cd-dc80-478f-9bb4-ae92c5c344a1", + "run_type": "UNSPECIFIED", + "entries": [], + "timestamp": "2024-08-14T00:26:03", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220" + }, + { + "run_id": "1477b2aa-6ff1-4548-ba07-0a9fb889bf18", + "run_type": "UNSPECIFIED", + "entries": [], + "timestamp": "2024-08-14T00:26:03", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220" + }, + { + "run_id": "0291e48c-2884-46b9-ba95-0ac1515ed60b", + "run_type": "UNSPECIFIED", + "entries": [], + "timestamp": "2024-08-14T00:26:02", + "user_id": "f36f0a8a-9f12-5979-9416-1fbb7d28a80b" + }, + { + "run_id": "b6284a00-2285-44e8-9ed6-dc617b298948", + "run_type": "UNSPECIFIED", + "entries": [], + "timestamp": "2024-08-14T00:26:02", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220" + }, + { + "run_id": "3b57e745-0d33-463c-947a-cb88287e9584", + "run_type": "UNSPECIFIED", + "entries": [], + "timestamp": "2024-08-14T00:26:02", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220" + }, + { + "run_id": "95a75f58-dbcd-47cb-9883-c035aaf8ac48", + "run_type": "UNSPECIFIED", + "entries": [], + "timestamp": "2024-08-14T00:26:01", + "user_id": "f36f0a8a-9f12-5979-9416-1fbb7d28a80b" + }, + { + "run_id": "1032bdaa-324f-482b-ab80-5177a214e981", + "run_type": "UNSPECIFIED", + "entries": [], + "timestamp": "2024-08-14T00:26:01", + "user_id": "f36f0a8a-9f12-5979-9416-1fbb7d28a80b" + }, + { + "run_id": "bc78145e-70d3-47d7-b13c-890e4ea0d098", + "run_type": "UNSPECIFIED", + "entries": [], + "timestamp": "2024-08-14T00:26:01", + "user_id": "f36f0a8a-9f12-5979-9416-1fbb7d28a80b" + }, + { + "run_id": "02a6c397-b69f-4f53-836e-d9ef69dbec10", + "run_type": "UNSPECIFIED", + "entries": [], + "timestamp": "2024-08-14T00:25:59", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220" + }, + { + "run_id": "dfefe355-b78f-463a-ad0b-e4651f20f9f4", + "run_type": "UNSPECIFIED", + "entries": [], + "timestamp": "2024-08-14T00:25:55", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220" + }, + { + "run_id": "4fa823b5-f440-4f5a-88ca-434731fa45c9", + "run_type": "UNSPECIFIED", + "entries": [], + "timestamp": "2024-08-14T00:25:54", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220" + }, + { + "run_id": "c0cf5191-78f2-4e18-b5b7-2df62307fd23", + "run_type": "UNSPECIFIED", + "entries": [], + "timestamp": "2024-08-14T00:25:53", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220" + }, + { + "run_id": "d24c3c19-8354-418c-9b7a-d95cb624a235", + "run_type": "UNSPECIFIED", + "entries": [], + "timestamp": "2024-08-14T00:25:52", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220" + }, + { + "run_id": "4df1f53b-db11-4919-ae20-8f1d7d7eb6fb", + "run_type": "UNSPECIFIED", + "entries": [], + "timestamp": "2024-08-14T00:25:52", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220" + }, + { + "run_id": "1d2ec5de-df04-4ea9-9ef3-8a05e0f36fc9", + "run_type": "UNSPECIFIED", + "entries": [], + "timestamp": "2024-08-14T00:25:52", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220" + }, + { + "run_id": "f997102d-4d2a-4897-9b4a-0049d25a9ada", + "run_type": "UNSPECIFIED", + "entries": [], + "timestamp": "2024-08-14T00:25:10", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220" + }, + { + "run_id": "ee0dc7eb-c204-44b7-82a4-d07d59b67741", + "run_type": "UNSPECIFIED", + "entries": [], + "timestamp": "2024-08-14T00:24:58", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220" + }, + { + "run_id": "730e188e-6946-4a83-ad77-0861e94c1f29", + "run_type": "UNSPECIFIED", + "entries": [], + "timestamp": "2024-08-14T00:24:46", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220" + }, + { + "run_id": "b2c15b09-f69b-444a-bb7d-dc1939e7eba4", + "run_type": "UNSPECIFIED", + "entries": [], + "timestamp": "2024-08-14T00:23:57", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220" + }, + { + "run_id": "86c24884-a353-4298-8183-2037beb139aa", + "run_type": "UNSPECIFIED", + "entries": [], + "timestamp": "2024-08-14T00:23:57", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220" + }, + { + "run_id": "59ea5208-72e9-44f8-8cfe-fe4ce2423f7c", + "run_type": "UNSPECIFIED", + "entries": [], + "timestamp": "2024-08-14T00:23:57", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220" + }, + { + "run_id": "1272f2f6-56ef-411c-a4ce-9437e3bff5dc", + "run_type": "UNSPECIFIED", + "entries": [], + "timestamp": "2024-08-14T00:23:57", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220" + }, + { + "run_id": "19228cf4-34e4-4102-a6e1-2656c136af4b", + "run_type": "UNSPECIFIED", + "entries": [], + "timestamp": "2024-08-14T00:23:56", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220" + }, + { + "run_id": "bdcee52d-9726-4531-8a00-b31244563a9d", + "run_type": "UNSPECIFIED", + "entries": [], + "timestamp": "2024-08-14T00:23:56", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220" + }, + { + "run_id": "3d68fc91-b9a6-405f-b344-e9d825093e8e", + "run_type": "UNSPECIFIED", + "entries": [], + "timestamp": "2024-08-14T00:23:55", + "user_id": "4b17bfba-12b5-5c3a-98a7-fcaaab561791" + }, + { + "run_id": "d8689825-7f2f-4b70-8114-31fdae4e86fd", + "run_type": "UNSPECIFIED", + "entries": [], + "timestamp": "2024-08-14T00:23:55", + "user_id": "4b17bfba-12b5-5c3a-98a7-fcaaab561791" + }, + { + "run_id": "0f128c75-25c2-4754-8af9-88d7d63de866", + "run_type": "UNSPECIFIED", + "entries": [], + "timestamp": "2024-08-14T00:23:55", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220" + }, + { + "run_id": "5b61a591-a94a-4f9e-8233-0c82a4f3faa4", + "run_type": "UNSPECIFIED", + "entries": [], + "timestamp": "2024-08-14T00:23:55", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220" + }, + { + "run_id": "d8c3ccb0-0be0-4d59-b7f5-76d043eeb0bc", + "run_type": "UNSPECIFIED", + "entries": [], + "timestamp": "2024-08-14T00:23:54", + "user_id": "4b17bfba-12b5-5c3a-98a7-fcaaab561791" + }, + { + "run_id": "c84e61f9-1318-4fa0-b174-6a00f59727a9", + "run_type": "UNSPECIFIED", + "entries": [], + "timestamp": "2024-08-14T00:23:54", + "user_id": "4b17bfba-12b5-5c3a-98a7-fcaaab561791" + }, + { + "run_id": "3b05eccc-3bd4-4b0a-813d-60fdfbc06cad", + "run_type": "UNSPECIFIED", + "entries": [], + "timestamp": "2024-08-14T00:23:51", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220" + }, + { + "run_id": "e81699a2-b47b-4fdf-8d97-b6b48e394533", + "run_type": "UNSPECIFIED", + "entries": [], + "timestamp": "2024-08-14T00:23:47", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220" + }, + { + "run_id": "d41ad353-cd3d-4cbc-b141-010c499acebb", + "run_type": "UNSPECIFIED", + "entries": [], + "timestamp": "2024-08-14T00:23:45", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220" + }, + { + "run_id": "0129829c-55e9-4fee-b396-7e548c5ead4e", + "run_type": "UNSPECIFIED", + "entries": [], + "timestamp": "2024-08-14T00:23:45", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220" + }, + { + "run_id": "81704be9-5286-4373-9f84-839f1c25933e", + "run_type": "UNSPECIFIED", + "entries": [], + "timestamp": "2024-08-14T00:23:44", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220" + }, + { + "run_id": "d09b1ca5-a684-4a0b-9f56-f198d5bdf619", + "run_type": "UNSPECIFIED", + "entries": [], + "timestamp": "2024-08-14T00:23:44", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220" + }, + { + "run_id": "047b36d3-43b1-4239-b65a-07ec1265439a", + "run_type": "UNSPECIFIED", + "entries": [], + "timestamp": "2024-08-14T00:23:43", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220" + }, + { + "run_id": "979b9d23-4617-4754-b220-67936965b60d", + "run_type": "UNSPECIFIED", + "entries": [], + "timestamp": "2024-08-14T00:23:08", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220" + }, + { + "run_id": "4bfd3253-60c7-46d1-b309-fb7b816ce2ec", + "run_type": "UNSPECIFIED", + "entries": [], + "timestamp": "2024-08-14T00:22:28", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220" + }, + { + "run_id": "75434e64-bd07-4b2d-a11a-5c00adc6753e", + "run_type": "UNSPECIFIED", + "entries": [], + "timestamp": "2024-08-14T00:21:39", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220" + }, + { + "run_id": "523a1049-f5ad-4b95-bde4-d3c4a94927aa", + "run_type": "UNSPECIFIED", + "entries": [], + "timestamp": "2024-08-14T00:20:48", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220" + }, + { + "run_id": "0fd21ec5-f305-4e48-b75d-7ddb29534dce", + "run_type": "UNSPECIFIED", + "entries": [], + "timestamp": "2024-08-14T00:19:38", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220" + }, + { + "run_id": "ace1ffb9-4cd4-4029-8c8b-2e5b25b504a5", + "run_type": "UNSPECIFIED", + "entries": [], + "timestamp": "2024-08-14T00:19:38", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220" + }, + { + "run_id": "a926c1be-405e-44fd-ac6a-1e8a0cb92512", + "run_type": "UNSPECIFIED", + "entries": [], + "timestamp": "2024-08-14T00:19:38", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220" + }, + { + "run_id": "748191c0-5ae1-424b-8c19-1c35a5428e68", + "run_type": "UNSPECIFIED", + "entries": [], + "timestamp": "2024-08-14T00:16:07", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220" + } + ] + }, + "analytics": { + "results": { + "filtered_logs": { + "search_latencies": [ + { + "run_id": "c0cf5191-78f2-4e18-b5b7-2df62307fd23", + "key": "search_latency", + "value": "0.45", + "timestamp": "2024-08-14 00:25:53" + }, + { + "run_id": "d41ad353-cd3d-4cbc-b141-010c499acebb", + "key": "search_latency", + "value": "0.46", + "timestamp": "2024-08-14 00:23:45" + } + ] + }, + "search_latencies": { + "Mean": 0.455, + "Median": 0.455, + "Mode": null, + "Standard Deviation": 0.007, + "Variance": 0.0 + } + } + } +} diff --git a/tests/regression/expected_outputs/test_retrieval.json b/tests/regression/expected_outputs/test_retrieval.json new file mode 100644 index 000000000..4f4a7171c --- /dev/null +++ b/tests/regression/expected_outputs/test_retrieval.json @@ -0,0 +1,554 @@ +{ + "search": { + "results": { + "vector_search_results": [ + { + "fragment_id": "c68dc72e-fc23-5452-8f49-d7bd46088a96", + "extraction_id": "3f3d47f3-8baf-58eb-8bc2-0171fb1c6e09", + "document_id": "3e157b3a-8469-51db-90d9-52e7d896b49b", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "score": 0.23943702876567796, + "text": "Alternate Base Rate means, for any day, a rate per annum equal to the greatest of (i) the Prime Rate in effect on such day, (ii) the Federal Funds Effective Rate in effect on such day \nplus \u00bd of 1% and (iii) the sum of (a) the Adjusted LIBO Rate that would be payable onsuch day for a Eurodollar Borrowing with a one-month interest period", + "metadata": { + "text": "Alternate Base Rate means, for any day, a rate per annum equal to the greatest of (i) the Prime Rate in effect on such day, (ii) the Federal Funds Effective Rate in effect on such day \nplus \u00bd of 1% and (iii) the sum of (a) the Adjusted LIBO Rate that would be payable onsuch day for a Eurodollar Borrowing with a one-month interest period", + "title": "uber_2021.pdf", + "associatedQuery": "What is the capital of France?" + } + }, + { + "fragment_id": "f0b40c99-e200-507b-a4b9-e931e0b5f321", + "extraction_id": "0348ae71-bccb-58d1-8b5f-36810e46245a", + "document_id": "3e157b3a-8469-51db-90d9-52e7d896b49b", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "score": 0.22033508121967305, + "text": "s, could also restrict our future access to the capital markets.ITEM 1B. UNRESOLVED STAFF\n COMMENTSNot applicable.\nITEM 2. PROPERTIES\nAs\n of December 31, 2021, we leased and owned office facilities around the world totaling 10.6 million square feet, including 2.6 million square feet for ourcorporate headquarte\nrs in the San Francisco Bay Area, California.We", + "metadata": { + "text": "s, could also restrict our future access to the capital markets.ITEM 1B. UNRESOLVED STAFF\n COMMENTSNot applicable.\nITEM 2. PROPERTIES\nAs\n of December 31, 2021, we leased and owned office facilities around the world totaling 10.6 million square feet, including 2.6 million square feet for ourcorporate headquarte\nrs in the San Francisco Bay Area, California.We", + "title": "uber_2021.pdf", + "associatedQuery": "What is the capital of France?" + } + }, + { + "fragment_id": "967c4291-0629-55b6-9323-e2291de8730d", + "extraction_id": "7595cdf2-d1b0-5f13-b853-8ce6857ca5f5", + "document_id": "3e157b3a-8469-51db-90d9-52e7d896b49b", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "score": 0.21763332188129403, + "text": "RFR means, for any RFR Loan denominated in (a) British Pounds, SONIA and (b) Swiss Francs, SARON. \nRFR Borrowing means, as to any Borrowing, the RFR Loans comprising such Borrowing. \nRFR Business Day means, for any Loan denominated in (a) British Pounds, any day except for (i) a Saturday, (ii) a Sunday or (iii) a day on which banks are closed for general business in London and (b) Swiss Francs, any day except for (i) a Saturday, (ii) a Sunday or", + "metadata": { + "text": "RFR means, for any RFR Loan denominated in (a) British Pounds, SONIA and (b) Swiss Francs, SARON. \nRFR Borrowing means, as to any Borrowing, the RFR Loans comprising such Borrowing. \nRFR Business Day means, for any Loan denominated in (a) British Pounds, any day except for (i) a Saturday, (ii) a Sunday or (iii) a day on which banks are closed for general business in London and (b) Swiss Francs, any day except for (i) a Saturday, (ii) a Sunday or", + "title": "uber_2021.pdf", + "associatedQuery": "What is the capital of France?" + } + }, + { + "fragment_id": "188b7dd5-9554-53cb-9e68-b97e5ee71342", + "extraction_id": "7595cdf2-d1b0-5f13-b853-8ce6857ca5f5", + "document_id": "3e157b3a-8469-51db-90d9-52e7d896b49b", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "score": 0.21672844886779796, + "text": "RFR Interest Day has the meaning specified in the definition of Daily Simple RFR. \nRFR Loan means a Loan that bears interest at a rate based on the Adjusted Daily Simple RFR. For the avoidance of doubt, only Loans denominated in British Pounds and Swiss Francs shall bear interest at a rate based on the Adjusted Daily Simple RFR.", + "metadata": { + "text": "RFR Interest Day has the meaning specified in the definition of Daily Simple RFR. \nRFR Loan means a Loan that bears interest at a rate based on the Adjusted Daily Simple RFR. For the avoidance of doubt, only Loans denominated in British Pounds and Swiss Francs shall bear interest at a rate based on the Adjusted Daily Simple RFR.", + "title": "uber_2021.pdf", + "associatedQuery": "What is the capital of France?" + } + }, + { + "fragment_id": "8e88e5b1-9785-5b26-a296-15150737dc10", + "extraction_id": "dd07e341-17f4-5ff7-9985-3e4719a4e145", + "document_id": "2f576170-c4f9-5141-a910-a0924f341de4", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "score": 0.21409947956201303, + "text": "Restricted\n cash and cash equivalents consist primarily of amounts held in separate trust accounts and restricted bank accounts as collateral for insurance purposesand amounts pledged\n to secure certain letters of credit.Investments\nDebt Securities\nThe Companys accounting for its investme\nnts in debt securities is based on the legal form of the security, the Companys intended holding period for the security,and", + "metadata": { + "text": "Restricted\n cash and cash equivalents consist primarily of amounts held in separate trust accounts and restricted bank accounts as collateral for insurance purposesand amounts pledged\n to secure certain letters of credit.Investments\nDebt Securities\nThe Companys accounting for its investme\nnts in debt securities is based on the legal form of the security, the Companys intended holding period for the security,and", + "title": "lyft_2021.pdf", + "associatedQuery": "What is the capital of France?" + } + }, + { + "fragment_id": "cbc7d77c-ca2f-5e66-89c9-706588902653", + "extraction_id": "1b94a71e-a37d-5270-ba32-11b728014017", + "document_id": "3e157b3a-8469-51db-90d9-52e7d896b49b", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "score": 0.20865452782457905, + "text": "Fax: \n212-701-5165 (iv)\nif to MSSF, in its capacity as a Lender, to it at: Morgan Stanley Senior Funding, Inc.\n1 New York Plaza, 41st Floor\nNew York, New York, 10004\nAttention: Agency Team\nFax: (212) 507-6680\n(iv) if to any other Lender or any other Issuing Bank, to it at its address (or telecopy number) set forth in its Administrative\nQuestionnaire.\n112", + "metadata": { + "text": "Fax: \n212-701-5165 (iv)\nif to MSSF, in its capacity as a Lender, to it at: Morgan Stanley Senior Funding, Inc.\n1 New York Plaza, 41st Floor\nNew York, New York, 10004\nAttention: Agency Team\nFax: (212) 507-6680\n(iv) if to any other Lender or any other Issuing Bank, to it at its address (or telecopy number) set forth in its Administrative\nQuestionnaire.\n112", + "title": "uber_2021.pdf", + "associatedQuery": "What is the capital of France?" + } + }, + { + "fragment_id": "abb86b50-d271-57ef-a5a0-fafa06d4590b", + "extraction_id": "9dcfaa51-83d4-5119-9fab-c6591ca32cb0", + "document_id": "2f576170-c4f9-5141-a910-a0924f341de4", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "score": 0.20697565376758598, + "text": "24,757 24,757 Money market deposit accoun\nts162 162 Term deposits\n6,506 6,506 Certificates of deposit\n481,154 213 (3) 481,364 Commercial paper\n469,193 57 (10) 469,240 Corporate bonds\n184,560 67 (26) 184,601 Total restricted cash equivale\nnts and investments1,166,332 337 (39) 1,166,630 Total unrestricted and \nrestricted cash equivalents and investments$ 3,283,497 $ 668 $ (104) $ 3,284,061 _______________\n(1)", + "metadata": { + "text": "24,757 24,757 Money market deposit accoun\nts162 162 Term deposits\n6,506 6,506 Certificates of deposit\n481,154 213 (3) 481,364 Commercial paper\n469,193 57 (10) 469,240 Corporate bonds\n184,560 67 (26) 184,601 Total restricted cash equivale\nnts and investments1,166,332 337 (39) 1,166,630 Total unrestricted and \nrestricted cash equivalents and investments$ 3,283,497 $ 668 $ (104) $ 3,284,061 _______________\n(1)", + "title": "lyft_2021.pdf", + "associatedQuery": "What is the capital of France?" + } + }, + { + "fragment_id": "24dd1910-d09b-5af2-9608-542777d8cbca", + "extraction_id": "7b1e614f-bda0-5c9d-adc5-a8dd25658c4c", + "document_id": "2f576170-c4f9-5141-a910-a0924f341de4", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "score": 0.20446833968162503, + "text": "our future capital requirements;\nour ability to service our current and future debt, and counterparty risk with respect to our capped call transactions;\nour ability to make and successfully integrate acquisitions and investments or complete divestitures, joint ventures, partnerships or other strategic transactions;\nour tax liabilities, ability to use our net operating loss carryforwards and future changes in tax matters;Governance Risks and Risks related to Ownership o\nf our Capital Stock", + "metadata": { + "text": "our future capital requirements;\nour ability to service our current and future debt, and counterparty risk with respect to our capped call transactions;\nour ability to make and successfully integrate acquisitions and investments or complete divestitures, joint ventures, partnerships or other strategic transactions;\nour tax liabilities, ability to use our net operating loss carryforwards and future changes in tax matters;Governance Risks and Risks related to Ownership o\nf our Capital Stock", + "title": "lyft_2021.pdf", + "associatedQuery": "What is the capital of France?" + } + }, + { + "fragment_id": "aa169f74-9fdb-5f76-ae71-33230ef0291b", + "extraction_id": "efee52c0-afbf-522e-a82b-1cbe07df4a66", + "document_id": "3e157b3a-8469-51db-90d9-52e7d896b49b", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "score": 0.20252158030738998, + "text": "UK Financial Institution means any BRRD Undertaking (as such term is defined under the PRA Rulebook (as amended form time to time) promulgated by the United Kingdom Prudential Regulation Authority) or any person falling within IFPRU 11.6 of the FCA\nHandbook (as amended from time to time) promulgated by the United Kingdom Financial Conduct Authority, which includes certain credit\ninstitutions and investment firms, and certain affiliates of such credit institutions or investment firms.", + "metadata": { + "text": "UK Financial Institution means any BRRD Undertaking (as such term is defined under the PRA Rulebook (as amended form time to time) promulgated by the United Kingdom Prudential Regulation Authority) or any person falling within IFPRU 11.6 of the FCA\nHandbook (as amended from time to time) promulgated by the United Kingdom Financial Conduct Authority, which includes certain credit\ninstitutions and investment firms, and certain affiliates of such credit institutions or investment firms.", + "title": "uber_2021.pdf", + "associatedQuery": "What is the capital of France?" + } + }, + { + "fragment_id": "129a19b8-9164-52f1-990e-0af926045c59", + "extraction_id": "b4000f00-a84f-51bd-abf8-4b6eff9f6ada", + "document_id": "3e157b3a-8469-51db-90d9-52e7d896b49b", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "score": 0.20240467786788896, + "text": "l executive offices are located at 1515 3rd Street, San Francisco, California 94158, and our telephone number is (415) 612-8582.10", + "metadata": { + "text": "l executive offices are located at 1515 3rd Street, San Francisco, California 94158, and our telephone number is (415) 612-8582.10", + "title": "uber_2021.pdf", + "associatedQuery": "What is the capital of France?" + } + } + ], + "kg_search_results": [] + } + }, + "basic_rag": { + "results": { + "completion": { + "id": "chatcmpl-9vwee7AtlnR6nxgbSG60VOpb9bxtE", + "choices": [ + { + "finish_reason": "stop", + "index": 0, + "logprobs": null, + "message": { + "content": "Uber did not make a profit in 2020. Instead, it reported a net loss attributable to Uber Technologies, Inc. of $6,768 million [4], [5], [9].", + "refusal": null, + "role": "assistant", + "function_call": null, + "tool_calls": null + } + } + ], + "created": 1723597192, + "model": "gpt-4o-2024-05-13", + "object": "chat.completion", + "service_tier": null, + "system_fingerprint": "fp_3aa7262c27", + "usage": { + "completion_tokens": 40, + "prompt_tokens": 1483, + "total_tokens": 1523 + } + }, + "search_results": { + "vector_search_results": [ + { + "fragment_id": "13a12fc0-cbce-5e35-b179-d413c15179cb", + "extraction_id": "2b8ff2e9-c135-573d-bf8a-7a2db60a0a11", + "document_id": "3e157b3a-8469-51db-90d9-52e7d896b49b", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "score": 0.744923337991438, + "text": "Net\n loss attributable to Uber Technologies, Inc. was $496 million, a 93% improvement year-over-year, driven by a $1.6 billion pre-tax gain on the sale of ourATG\n Business to Aurora, a $1.6 billion pre-tax net benefit relating to Ubers equity investments, as well as reductions in our fixed cost structure and increasedvariable cost effi\nciencies. Net loss attributable to Uber Technologies, Inc. also included $1.2 billion of stock-based compensation expense.Adjusted", + "metadata": { + "text": "Net\n loss attributable to Uber Technologies, Inc. was $496 million, a 93% improvement year-over-year, driven by a $1.6 billion pre-tax gain on the sale of ourATG\n Business to Aurora, a $1.6 billion pre-tax net benefit relating to Ubers equity investments, as well as reductions in our fixed cost structure and increasedvariable cost effi\nciencies. Net loss attributable to Uber Technologies, Inc. also included $1.2 billion of stock-based compensation expense.Adjusted", + "title": "uber_2021.pdf", + "associatedQuery": "What was Uber's profit in 2020?" + } + }, + { + "fragment_id": "26fc1632-7d88-5107-91a6-db2ffda6d5eb", + "extraction_id": "bb7ea09e-04a8-5d9d-8133-9408ba51dc0b", + "document_id": "3e157b3a-8469-51db-90d9-52e7d896b49b", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "score": 0.671538352966309, + "text": "See the section titled Reconciliations of Non-GAAP Financial Measures for our definition and a reconciliation of net loss attributable toUber Technologies, Inc. to Adjusted EBITDA.\nYear Ended December 31,\n(In millions, except percentages)\n2020 2021 2020 to 2021 %Change\nAdjusted EBITDA\n$ (2,528) $ (774) 69 %2021 Compared to 2020\nAdjusted\n EBITDA loss improved $1.8 billion, or 69%, primarily attributable to a $525 million improvement in Delivery Adjusted EBITDA loss, a $427million", + "metadata": { + "text": "See the section titled Reconciliations of Non-GAAP Financial Measures for our definition and a reconciliation of net loss attributable toUber Technologies, Inc. to Adjusted EBITDA.\nYear Ended December 31,\n(In millions, except percentages)\n2020 2021 2020 to 2021 %Change\nAdjusted EBITDA\n$ (2,528) $ (774) 69 %2021 Compared to 2020\nAdjusted\n EBITDA loss improved $1.8 billion, or 69%, primarily attributable to a $525 million improvement in Delivery Adjusted EBITDA loss, a $427million", + "title": "uber_2021.pdf", + "associatedQuery": "What was Uber's profit in 2020?" + } + }, + { + "fragment_id": "fc79cf57-a508-5781-874e-afca763f2efd", + "extraction_id": "cdf49309-5eeb-58df-b62f-15a2fe7444db", + "document_id": "3e157b3a-8469-51db-90d9-52e7d896b49b", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "score": 0.667392492294312, + "text": "24 59 83 Other income (expense), net\n$ 722 $ (1,625) $ 3,292 During\n the year ended December 31, 2020, gain on business divestitures, net represented a $154 million gain on the sale of our Uber Eats India operationsto Zomato\n recognized in the first quarter of 2020 and a $77 million gain on the sale of our European Freight Business to sennder GmbH (Sennder) recognized inthe fourth quarter of 2020, pa", + "metadata": { + "text": "24 59 83 Other income (expense), net\n$ 722 $ (1,625) $ 3,292 During\n the year ended December 31, 2020, gain on business divestitures, net represented a $154 million gain on the sale of our Uber Eats India operationsto Zomato\n recognized in the first quarter of 2020 and a $77 million gain on the sale of our European Freight Business to sennder GmbH (Sennder) recognized inthe fourth quarter of 2020, pa", + "title": "uber_2021.pdf", + "associatedQuery": "What was Uber's profit in 2020?" + } + }, + { + "fragment_id": "8d585c42-a618-50e0-be1d-709f94978ace", + "extraction_id": "b314fcfb-f0d2-5344-8397-8904f96282c7", + "document_id": "3e157b3a-8469-51db-90d9-52e7d896b49b", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "score": 0.657597821045186, + "text": "The following table presents a reconciliation of net loss attributable to Uber Technologies, Inc., the most directly comparable GAAP financial measure, toAdjusted EBITDA for each of the periods ind\nicated:Year Ended December 31,\n(In millions)\n2020 2021 Adjusted EBITDA reconciliation:\nNet loss attributable to Ube\nr Technologies, Inc.$ (6,768) $ (496) Add (deduct):\nNet loss attributable to non\n-controlling interests, net of tax(20) (74) Provision for (benefit fro", + "metadata": { + "text": "The following table presents a reconciliation of net loss attributable to Uber Technologies, Inc., the most directly comparable GAAP financial measure, toAdjusted EBITDA for each of the periods ind\nicated:Year Ended December 31,\n(In millions)\n2020 2021 Adjusted EBITDA reconciliation:\nNet loss attributable to Ube\nr Technologies, Inc.$ (6,768) $ (496) Add (deduct):\nNet loss attributable to non\n-controlling interests, net of tax(20) (74) Provision for (benefit fro", + "title": "uber_2021.pdf", + "associatedQuery": "What was Uber's profit in 2020?" + } + }, + { + "fragment_id": "e11e0d27-9bb6-5db1-97ba-cbb7f082f4f7", + "extraction_id": "2b8ff2e9-c135-573d-bf8a-7a2db60a0a11", + "document_id": "3e157b3a-8469-51db-90d9-52e7d896b49b", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "score": 0.627140164375305, + "text": "Financial and Operational HighlightsYear Ended December 31,\nConstant Currency (In millions, except percentages)\n2020 2021 2020 to 2021 %Change\n2020 to 2021 % Change Monthly Active Platform Consumers \n(MAPCs) 93 118 27 %Trips \n5,025 6,368 27 %Gross Bookings \n$ 57,897 $ 90,415 56 %53 % Revenue\n$ 11,139 $ 17,455 57 %54 % Net loss attributable to Ube\nr Technologies, Inc. $ (6,768) $ (496) 93 %Mobility Adjusted EBITDA\n$ 1,169 $ 1,596 37 %Delivery Adjusted EBITDA\n$ (873) $ (348) 60 %Adjusted EBITDA", + "metadata": { + "text": "Financial and Operational HighlightsYear Ended December 31,\nConstant Currency (In millions, except percentages)\n2020 2021 2020 to 2021 %Change\n2020 to 2021 % Change Monthly Active Platform Consumers \n(MAPCs) 93 118 27 %Trips \n5,025 6,368 27 %Gross Bookings \n$ 57,897 $ 90,415 56 %53 % Revenue\n$ 11,139 $ 17,455 57 %54 % Net loss attributable to Ube\nr Technologies, Inc. $ (6,768) $ (496) 93 %Mobility Adjusted EBITDA\n$ 1,169 $ 1,596 37 %Delivery Adjusted EBITDA\n$ (873) $ (348) 60 %Adjusted EBITDA", + "title": "uber_2021.pdf", + "associatedQuery": "What was Uber's profit in 2020?" + } + }, + { + "fragment_id": "4cc24e78-c6c5-56a6-9a2c-c361a1172116", + "extraction_id": "2b6f0786-5dc4-5581-bb83-b63f1175111a", + "document_id": "3e157b3a-8469-51db-90d9-52e7d896b49b", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "score": 0.6232549323591561, + "text": "ments(34) (34) (37) Net loss including non-controlling interests\n(8,512) (6,788) (570) Less: net loss attributab\nle to non-controlling interests, net of tax(6) (20) (74) Net loss attributable to Uber Technologies, Inc.\n$ (8,506) $ (6,768) $ (496) Net loss per share attributable to Uber Technologies, Inc. co\nmmon stockholders:Basic\n$ (6.81) $ (3.86) $ (0.26) Diluted\n$ (6.81) $ (3.86) $ (0.29) Weighted-average shares used to compute net loss per shar\ne attributable to common stockholders:Basic", + "metadata": { + "text": "ments(34) (34) (37) Net loss including non-controlling interests\n(8,512) (6,788) (570) Less: net loss attributab\nle to non-controlling interests, net of tax(6) (20) (74) Net loss attributable to Uber Technologies, Inc.\n$ (8,506) $ (6,768) $ (496) Net loss per share attributable to Uber Technologies, Inc. co\nmmon stockholders:Basic\n$ (6.81) $ (3.86) $ (0.26) Diluted\n$ (6.81) $ (3.86) $ (0.29) Weighted-average shares used to compute net loss per shar\ne attributable to common stockholders:Basic", + "title": "uber_2021.pdf", + "associatedQuery": "What was Uber's profit in 2020?" + } + }, + { + "fragment_id": "3b9425c9-5147-5559-ac48-2d32a5f2fa50", + "extraction_id": "e0668732-8b42-53c5-a719-39f72634e380", + "document_id": "3e157b3a-8469-51db-90d9-52e7d896b49b", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "score": 0.62315821647644, + "text": "issued to new investors in close proximity to the time of our transaction with Zomato. The transaction resulted in a gain on disposal of $154 millionrecognized\n in other income (expense), net in the consolidated statements of operations during the first quarter of 2020. The income tax effect of the sale was notmaterial.\n The divestiture of Uber Eats India did not represent a strategic shift that would have had a major effect on our operations and financial results, andtherefore does not quali", + "metadata": { + "text": "issued to new investors in close proximity to the time of our transaction with Zomato. The transaction resulted in a gain on disposal of $154 millionrecognized\n in other income (expense), net in the consolidated statements of operations during the first quarter of 2020. The income tax effect of the sale was notmaterial.\n The divestiture of Uber Eats India did not represent a strategic shift that would have had a major effect on our operations and financial results, andtherefore does not quali", + "title": "uber_2021.pdf", + "associatedQuery": "What was Uber's profit in 2020?" + } + }, + { + "fragment_id": "7d297996-f186-5f08-aa4f-2ff30ad8cc6f", + "extraction_id": "eeadc634-c141-5748-98d0-4c89aa5404b1", + "document_id": "3e157b3a-8469-51db-90d9-52e7d896b49b", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "score": 0.6223304271698, + "text": "is presented in the following tables for the years ended December 31, 2019, 2020 and 2021, respectively (in millions):Year Ended December 31,\n2019\n2020 2021 Mobility revenue \n$ 10,707 $ 6,089 $ 6,953 Delivery revenue \n1,401 3,904 8,362 Freight revenue\n731 1,011 2,132 All Other revenue\n161 135 8 Total revenue\n$ 13,000 $ 11,139 $ 17,455 We\n offer subscription memberships to end-users including Uber One, Uber Pass, Rides Pass, and Eats Pass (Subscription). We recognize Subscriptionfees", + "metadata": { + "text": "is presented in the following tables for the years ended December 31, 2019, 2020 and 2021, respectively (in millions):Year Ended December 31,\n2019\n2020 2021 Mobility revenue \n$ 10,707 $ 6,089 $ 6,953 Delivery revenue \n1,401 3,904 8,362 Freight revenue\n731 1,011 2,132 All Other revenue\n161 135 8 Total revenue\n$ 13,000 $ 11,139 $ 17,455 We\n offer subscription memberships to end-users including Uber One, Uber Pass, Rides Pass, and Eats Pass (Subscription). We recognize Subscriptionfees", + "title": "uber_2021.pdf", + "associatedQuery": "What was Uber's profit in 2020?" + } + }, + { + "fragment_id": "5d2bb46e-d9ad-5cdc-9658-09e8e6f9bd4d", + "extraction_id": "2a3a3cef-bc9d-5c62-9691-14d892c521c9", + "document_id": "3e157b3a-8469-51db-90d9-52e7d896b49b", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "score": 0.6163432230744841, + "text": "(458) (483) Other income (expense), net\n(1,625) 3,292 Loss before income taxes and loss from equity me\nthod investments(6,946) (1,025) Provision for (benefit fro\nm) income taxes(192) (492) Loss from equity method invest\nments(34) (37) Net loss including non-controlling interests\n(6,788) (570) Less: net loss attributab\nle to non-controlling interests, net of tax(20) (74) Net loss attributable to Uber Technologies, Inc.\n$ (6,768) $ (496) 54", + "metadata": { + "text": "(458) (483) Other income (expense), net\n(1,625) 3,292 Loss before income taxes and loss from equity me\nthod investments(6,946) (1,025) Provision for (benefit fro\nm) income taxes(192) (492) Loss from equity method invest\nments(34) (37) Net loss including non-controlling interests\n(6,788) (570) Less: net loss attributab\nle to non-controlling interests, net of tax(20) (74) Net loss attributable to Uber Technologies, Inc.\n$ (6,768) $ (496) 54", + "title": "uber_2021.pdf", + "associatedQuery": "What was Uber's profit in 2020?" + } + }, + { + "fragment_id": "b89e13fa-4d7a-5b0a-87db-d51de1ce777f", + "extraction_id": "45650893-257d-5ae5-8a35-35edd54f7699", + "document_id": "3e157b3a-8469-51db-90d9-52e7d896b49b", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "score": 0.606526911258698, + "text": "UBER TECHNOLOGIES, INC.NOTES TO CONSOLIDATED \nFINANCIAL STATEMENTSNote 1 Description of Business and Summary of Significant Accounting Policies\nDescription of Business\nUber\n Technologies, Inc. (Uber, we, our, or us) was incorporated in Delaware in July 2010, and is headquartered in San Francisco, California. Uber isa\n technology platform that uses a massive network, leading technology, operational excellence and product expertise to power movement from point A to point B.Uber", + "metadata": { + "text": "UBER TECHNOLOGIES, INC.NOTES TO CONSOLIDATED \nFINANCIAL STATEMENTSNote 1 Description of Business and Summary of Significant Accounting Policies\nDescription of Business\nUber\n Technologies, Inc. (Uber, we, our, or us) was incorporated in Delaware in July 2010, and is headquartered in San Francisco, California. Uber isa\n technology platform that uses a massive network, leading technology, operational excellence and product expertise to power movement from point A to point B.Uber", + "title": "uber_2021.pdf", + "associatedQuery": "What was Uber's profit in 2020?" + } + } + ], + "kg_search_results": null + } + } + }, + "hybrid_rag": { + "results": { + "completion": { + "id": "chatcmpl-9vwegy0zTZ75kT3Y52UopJ7QYeFFi", + "choices": [ + { + "finish_reason": "stop", + "index": 0, + "logprobs": null, + "message": { + "content": "John Snow, referred to as Jon Snow in the context, is Ned Stark\u2019s bastard son. Since Catelyn is not his mother, he is not considered a proper member of the Stark family, which often makes him feel like an outsider. He is also a highly capable swordsman and thinker, known for his piercing observations [1].", + "refusal": null, + "role": "assistant", + "function_call": null, + "tool_calls": null + } + } + ], + "created": 1723597194, + "model": "gpt-4o-2024-05-13", + "object": "chat.completion", + "service_tier": null, + "system_fingerprint": "fp_3aa7262c27", + "usage": { + "completion_tokens": 68, + "prompt_tokens": 1147, + "total_tokens": 1215 + } + }, + "search_results": { + "vector_search_results": [ + { + "fragment_id": "378da9e2-4ba7-503f-b3a5-bbb0c3095f55", + "extraction_id": "866f85a0-b3d6-5fc5-9ca0-dbd2373eac58", + "document_id": "716fea3a-826b-5b27-8e59-ffbd1a35455a", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "score": 0.0476190476190476, + "text": "Jon Snow\nNed Stark\u2019s bastard son. Since Catelyn is not his mother, he is not a proper member of the Stark family, and he often feels himself an outsider. He is also a highly capable swordsman and thinker, with a knack for piercing observations.\nTyrion (The Imp) Lannister\nA small man with a giant intellect and sharp tongue. Tyrion does not pity himself but rather accepts his shortcomings as a little person and turns them to his advantage. He loves his family but recognizes their greed and ambition.", + "metadata": { + "text": "Jon Snow\nNed Stark\u2019s bastard son. Since Catelyn is not his mother, he is not a proper member of the Stark family, and he often feels himself an outsider. He is also a highly capable swordsman and thinker, with a knack for piercing observations.\nTyrion (The Imp) Lannister\nA small man with a giant intellect and sharp tongue. Tyrion does not pity himself but rather accepts his shortcomings as a little person and turns them to his advantage. He loves his family but recognizes their greed and ambition.", + "title": "got.txt", + "semantic_score": 0.289943260553881, + "semantic_rank": 1, + "full_text_score": 0.0, + "full_text_rank": null, + "associatedQuery": "Who is John Snow?" + } + }, + { + "fragment_id": "2a4f2509-a218-5919-b5b1-6018760d5c66", + "extraction_id": "866f85a0-b3d6-5fc5-9ca0-dbd2373eac58", + "document_id": "716fea3a-826b-5b27-8e59-ffbd1a35455a", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "score": 0.0454545454545455, + "text": "Maester Aemon\nThe chief man of learning at Castle Black. Despite his blind white eyes, Maester Aemon sees and speaks the truth in cryptic ways. Though few people realize it, Aemon is one of the few surviving members of the Targaryen family, but he has always put his vows to the Night\u2019s Watch ahead of any family loyalties.\nSamwell (Sam) Tarly", + "metadata": { + "text": "Maester Aemon\nThe chief man of learning at Castle Black. Despite his blind white eyes, Maester Aemon sees and speaks the truth in cryptic ways. Though few people realize it, Aemon is one of the few surviving members of the Targaryen family, but he has always put his vows to the Night\u2019s Watch ahead of any family loyalties.\nSamwell (Sam) Tarly", + "title": "got.txt", + "semantic_score": 0.285634236671582, + "semantic_rank": 2, + "full_text_score": 0.0, + "full_text_rank": null, + "associatedQuery": "Who is John Snow?" + } + }, + { + "fragment_id": "2acc7019-c9dc-5ff9-bcaa-6df98f2831d9", + "extraction_id": "866f85a0-b3d6-5fc5-9ca0-dbd2373eac58", + "document_id": "716fea3a-826b-5b27-8e59-ffbd1a35455a", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "score": 0.0434782608695652, + "text": "Samwell (Sam) Tarly\nA new recruit to the Night\u2019s Watch who is fat and cowardly but very smart. Sam loves to read and eat but hates to fight, and he quickly becomes one of Jon Snow\u2019s closest companions at the Wall.\nSer Allister Thorne\nCastle Black\u2019s resentful master-at-arms. He hard on the new recruits to the Night\u2019s Watch and seems to enjoy making them suffer, causing Jon to rebel against him. During Robert\u2019s rebellion against the former king, he was a Targaryen loyalist.\nIllyrio Mopatis", + "metadata": { + "text": "Samwell (Sam) Tarly\nA new recruit to the Night\u2019s Watch who is fat and cowardly but very smart. Sam loves to read and eat but hates to fight, and he quickly becomes one of Jon Snow\u2019s closest companions at the Wall.\nSer Allister Thorne\nCastle Black\u2019s resentful master-at-arms. He hard on the new recruits to the Night\u2019s Watch and seems to enjoy making them suffer, causing Jon to rebel against him. During Robert\u2019s rebellion against the former king, he was a Targaryen loyalist.\nIllyrio Mopatis", + "title": "got.txt", + "semantic_score": 0.264474719762802, + "semantic_rank": 3, + "full_text_score": 0.0, + "full_text_rank": null, + "associatedQuery": "Who is John Snow?" + } + }, + { + "fragment_id": "7f3f6e6f-9ec5-5ae0-8879-e89c5a892fcc", + "extraction_id": "866f85a0-b3d6-5fc5-9ca0-dbd2373eac58", + "document_id": "716fea3a-826b-5b27-8e59-ffbd1a35455a", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "score": 0.0416666666666667, + "text": "Ser Jorah Mormont\nAn exiled knight who serves unofficially as Daenerys\u2019s chief advisor. Though he was exiled by Ned Stark for selling slaves, he is intelligent, valiant, and a great fighter. He swears allegiance to Viserys as true king of Westeros, but he also feeds information about the Targaryens back to Varys.\nViserys Targaryen", + "metadata": { + "text": "Ser Jorah Mormont\nAn exiled knight who serves unofficially as Daenerys\u2019s chief advisor. Though he was exiled by Ned Stark for selling slaves, he is intelligent, valiant, and a great fighter. He swears allegiance to Viserys as true king of Westeros, but he also feeds information about the Targaryens back to Varys.\nViserys Targaryen", + "title": "got.txt", + "semantic_score": 0.259267091751099, + "semantic_rank": 4, + "full_text_score": 0.0, + "full_text_rank": null, + "associatedQuery": "Who is John Snow?" + } + }, + { + "fragment_id": "b732d643-eb13-5ed3-a31b-ae2ef7877428", + "extraction_id": "866f85a0-b3d6-5fc5-9ca0-dbd2373eac58", + "document_id": "716fea3a-826b-5b27-8e59-ffbd1a35455a", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "score": 0.04, + "text": "Daenerys Stormborn Targaryen\nThe Dothraki khaleesi (queen) and Targaryen princess. She and her brother are the only surviving members of the Targaryen family, and she grows from a frightened girl to a confident ruler, while still maintaining her kindness, over the course of the novel.\nJon Snow", + "metadata": { + "text": "Daenerys Stormborn Targaryen\nThe Dothraki khaleesi (queen) and Targaryen princess. She and her brother are the only surviving members of the Targaryen family, and she grows from a frightened girl to a confident ruler, while still maintaining her kindness, over the course of the novel.\nJon Snow", + "title": "got.txt", + "semantic_score": 0.253841363237027, + "semantic_rank": 5, + "full_text_score": 0.0, + "full_text_rank": null, + "associatedQuery": "Who is John Snow?" + } + }, + { + "fragment_id": "2252087b-54d3-5df8-9e0f-f3718e7f42e3", + "extraction_id": "866f85a0-b3d6-5fc5-9ca0-dbd2373eac58", + "document_id": "716fea3a-826b-5b27-8e59-ffbd1a35455a", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "score": 0.0384615384615385, + "text": "Robert Baratheon\nThe corpulent king of Westeros. He loves to fight, drink, and sleep with women, and he hates the duties of ruling. He and Ned are long-time friends, and he was engaged to Ned\u2019s sister until she died.\nSer Jorah Mormont", + "metadata": { + "text": "Robert Baratheon\nThe corpulent king of Westeros. He loves to fight, drink, and sleep with women, and he hates the duties of ruling. He and Ned are long-time friends, and he was engaged to Ned\u2019s sister until she died.\nSer Jorah Mormont", + "title": "got.txt", + "semantic_score": 0.23582898080349, + "semantic_rank": 6, + "full_text_score": 0.0, + "full_text_rank": null, + "associatedQuery": "Who is John Snow?" + } + }, + { + "fragment_id": "fe72ba41-30c1-5b96-b0ce-d6eebf137d38", + "extraction_id": "9caef060-01ee-51f0-a342-4852adb0ad43", + "document_id": "57eec3df-cf68-5559-a80d-ae3fb55b9af1", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "score": 0.037037037037037, + "text": "allowed them to work on problems they only half understood (they\nwere literally described as \"clowns\" by one eminent insider), and\ntheir impatience and competitiveness got them to the answer ahead\nof two other groups that would otherwise have found it within the\nnext year, if not the next several months.\n[2]The idea that there could be fierce nerds is an unfamiliar one not\njust to many normal people but even to some young nerds. Especially\nearly on, nerds spend so much of their time in ordinary social", + "metadata": { + "text": "allowed them to work on problems they only half understood (they\nwere literally described as \"clowns\" by one eminent insider), and\ntheir impatience and competitiveness got them to the answer ahead\nof two other groups that would otherwise have found it within the\nnext year, if not the next several months.\n[2]The idea that there could be fierce nerds is an unfamiliar one not\njust to many normal people but even to some young nerds. Especially\nearly on, nerds spend so much of their time in ordinary social", + "title": "pg_essay_2.html", + "semantic_score": 0.234802625620444, + "semantic_rank": 7, + "full_text_score": 0.0, + "full_text_rank": null, + "associatedQuery": "Who is John Snow?" + } + }, + { + "fragment_id": "d7ed83c7-0a72-5346-bca9-dc1cb0e956ea", + "extraction_id": "8ee4678a-1fa8-58a6-8d6f-ec88cf10a6dc", + "document_id": "5b1bd54f-4d70-56b9-a017-a618bc75f94c", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "score": 0.0357142857142857, + "text": "Structure of Scientific Revolutions, but I also recommend his\nCopernican Revolution, where you can see him at work developing the\nidea.[4]\nThis is one reason people with a touch of Asperger's may have\nan advantage in discovering new ideas. They're always flying on\ninstruments.[5]\nHall, Rupert. From Galileo to Newton. Collins, 1963. This\nbook is particularly good at getting into contemporaries' heads.Thanks to Trevor Blackwell, Patrick Collison, Suhail Doshi, Daniel", + "metadata": { + "text": "Structure of Scientific Revolutions, but I also recommend his\nCopernican Revolution, where you can see him at work developing the\nidea.[4]\nThis is one reason people with a touch of Asperger's may have\nan advantage in discovering new ideas. They're always flying on\ninstruments.[5]\nHall, Rupert. From Galileo to Newton. Collins, 1963. This\nbook is particularly good at getting into contemporaries' heads.Thanks to Trevor Blackwell, Patrick Collison, Suhail Doshi, Daniel", + "title": "pg_essay_3.html", + "semantic_score": 0.230954363942146, + "semantic_rank": 8, + "full_text_score": 0.0, + "full_text_rank": null, + "associatedQuery": "Who is John Snow?" + } + }, + { + "fragment_id": "0de20d43-9e29-5686-9033-3e184a60cf6a", + "extraction_id": "06e9714f-4805-5dc8-a72f-61ecd0241b49", + "document_id": "3e157b3a-8469-51db-90d9-52e7d896b49b", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "score": 0.0344827586206897, + "text": "to economic, social, weather, and regulatory conditions or other circumstances in each of these large metropolitan areas. Outbreaks of contagiousdiseases\n or other viruses, such as COVID-19, could lead to a sustained decline in the desirability of living, working and congregating in metropolitan areas inwhich we operate. Any short-term o\nr long-term shifts in the travel patterns of consumers away from metropolitan areas, due to health concerns regarding epidemicsor", + "metadata": { + "text": "to economic, social, weather, and regulatory conditions or other circumstances in each of these large metropolitan areas. Outbreaks of contagiousdiseases\n or other viruses, such as COVID-19, could lead to a sustained decline in the desirability of living, working and congregating in metropolitan areas inwhich we operate. Any short-term o\nr long-term shifts in the travel patterns of consumers away from metropolitan areas, due to health concerns regarding epidemicsor", + "title": "uber_2021.pdf", + "semantic_score": 0.22635568537448, + "semantic_rank": 9, + "full_text_score": 0.0, + "full_text_rank": null, + "associatedQuery": "Who is John Snow?" + } + }, + { + "fragment_id": "78e0fcac-92e2-571f-a5bd-54d8c6da69ee", + "extraction_id": "8ee4678a-1fa8-58a6-8d6f-ec88cf10a6dc", + "document_id": "5b1bd54f-4d70-56b9-a017-a618bc75f94c", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "score": 0.0333333333333333, + "text": "completely as soon as it was discovered \u2014 that whatever the church thought\nof the heliocentric model, astronomers must have been convinced as\nsoon as Copernicus proposed it. Far, in fact, from it. Copernicus\npublished the heliocentric model in 1532, but it wasn't till the\nmid seventeenth century that the balance of scientific opinion\nshifted in its favor.\n[5]Few understand how feeble new ideas look when they first appear.\nSo if you want to have new ideas yourself, one of the most valuable", + "metadata": { + "text": "completely as soon as it was discovered \u2014 that whatever the church thought\nof the heliocentric model, astronomers must have been convinced as\nsoon as Copernicus proposed it. Far, in fact, from it. Copernicus\npublished the heliocentric model in 1532, but it wasn't till the\nmid seventeenth century that the balance of scientific opinion\nshifted in its favor.\n[5]Few understand how feeble new ideas look when they first appear.\nSo if you want to have new ideas yourself, one of the most valuable", + "title": "pg_essay_3.html", + "semantic_score": 0.224857065098637, + "semantic_rank": 10, + "full_text_score": 0.0, + "full_text_rank": null, + "associatedQuery": "Who is John Snow?" + } + } + ], + "kg_search_results": null + } + } + }, + "streaming_rag": { + "results": { + "completion": { + "choices": [ + { + "message": { + "content": "\"{\\\"fragment_id\\\":\\\"14745860-73d2-5d40-81aa-9f7085c52d25\\\",\\\"extraction_id\\\":\\\"a1ba66bf-a034-5cc6-b88b-0df6f1c38dbc\\\",\\\"document_id\\\":\\\"2f576170-c4f9-5141-a910-a0924f341de4\\\",\\\"user_id\\\":\\\"2acb499e-8428-543b-bd85-0d9098718220\\\",\\\"group_ids\\\":[],\\\"score\\\":0.761440396308899,\\\"text\\\":\\\"Lyft, Inc.Consolidated Statements of Operations\\\\n(in thousands, except for per share data\\\\n) Year Ended December 31,\\\\n2021\\\\n2020 2019 Revenue\\\\n$ 3,208,323 $ 2,364,681 $ 3,615,960 Costs and expenses\\\\nCost of revenue\\\\n1,649,532 1,447,516 2,176,469 Operations and support\\\\n402,233 453,963 636,116 Research and development\\\\n911,946 909,126 1,505,640 Sales and marketing\\\\n411,406 416,331 814,122 General and administrative\\\\n915,638 946,127 1,186,093 Total costs and expenses\\\\n4,290,755 4,173,063 6,318,440 Loss from operations\\\",\\\"metadata\\\":{\\\"text\\\":\\\"Lyft, Inc.Consolidated Statements of Operations\\\\n(in thousands, except for per share data\\\\n) Year Ended December 31,\\\\n2021\\\\n2020 2019 Revenue\\\\n$ 3,208,323 $ 2,364,681 $ 3,615,960 Costs and expenses\\\\nCost of revenue\\\\n1,649,532 1,447,516 2,176,469 Operations and support\\\\n402,233 453,963 636,116 Research and development\\\\n911,946 909,126 1,505,640 Sales and marketing\\\\n411,406 416,331 814,122 General and administrative\\\\n915,638 946,127 1,186,093 Total costs and expenses\\\\n4,290,755 4,173,063 6,318,440 Loss from operations\\\",\\\"title\\\":\\\"lyft_2021.pdf\\\",\\\"associatedQuery\\\":\\\"What was Lyft's profit in 2020?\\\"}}\",\"{\\\"fragment_id\\\":\\\"14478ac4-8f43-5f09-bbe3-7b1ddfdece40\\\",\\\"extraction_id\\\":\\\"12cff898-f0fe-59b8-929b-00d3d56fd73d\\\",\\\"document_id\\\":\\\"2f576170-c4f9-5141-a910-a0924f341de4\\\",\\\"user_id\\\":\\\"2acb499e-8428-543b-bd85-0d9098718220\\\",\\\"group_ids\\\":[],\\\"score\\\":0.69296767157509,\\\"text\\\":\\\"was attributable to the divestiture of certain assets related to the Level 5 division and how much was attributable to the commercial agreements for theutilization\\\\n of Lyft rideshare and fleet data. For the year ended December 31, 2021, the Company recognized a $119.3 million pre-tax gain for the divestiture of certainassets\\\",\\\"metadata\\\":{\\\"text\\\":\\\"was attributable to the divestiture of certain assets related to the Level 5 division and how much was attributable to the commercial agreements for theutilization\\\\n of Lyft rideshare and fleet data. For the year ended December 31, 2021, the Company recognized a $119.3 million pre-tax gain for the divestiture of certainassets\\\",\\\"title\\\":\\\"lyft_2021.pdf\\\",\\\"associatedQuery\\\":\\\"What was Lyft's profit in 2020?\\\"}}\",\"{\\\"fragment_id\\\":\\\"1a76991f-fa85-59b2-b522-700d47b2d809\\\",\\\"extraction_id\\\":\\\"0773cd62-b39f-517f-b6f1-be788b38374d\\\",\\\"document_id\\\":\\\"2f576170-c4f9-5141-a910-a0924f341de4\\\",\\\"user_id\\\":\\\"2acb499e-8428-543b-bd85-0d9098718220\\\",\\\"group_ids\\\":[],\\\"score\\\":0.683727383613586,\\\"text\\\":\\\"Lyft, Inc.Consolidated Statements of Cash Flows\\\\n(in thousands)\\\\nYear Ended December 31,\\\\n2021\\\\n2020 2019 Cash flows from operating activities\\\\nNet loss\\\\n$ (1,009,359) $ (1,752,857) $ (2,602,241) Adjustments to reconcile net loss to net cash used in operating activities\\\\nDepreciation and amortization\\\\n139,347 157,353 108,429 Stock-based compensation\\\\n724,560 565,807 1,599,311 Amortization of premium on marketable securities\\\\n4,100 6,461 597 Accretion of discount on marketable securities\\\",\\\"metadata\\\":{\\\"text\\\":\\\"Lyft, Inc.Consolidated Statements of Cash Flows\\\\n(in thousands)\\\\nYear Ended December 31,\\\\n2021\\\\n2020 2019 Cash flows from operating activities\\\\nNet loss\\\\n$ (1,009,359) $ (1,752,857) $ (2,602,241) Adjustments to reconcile net loss to net cash used in operating activities\\\\nDepreciation and amortization\\\\n139,347 157,353 108,429 Stock-based compensation\\\\n724,560 565,807 1,599,311 Amortization of premium on marketable securities\\\\n4,100 6,461 597 Accretion of discount on marketable securities\\\",\\\"title\\\":\\\"lyft_2021.pdf\\\",\\\"associatedQuery\\\":\\\"What was Lyft's profit in 2020?\\\"}}\",\"{\\\"fragment_id\\\":\\\"bfc29c59-2925-5621-951a-645df5c892b2\\\",\\\"extraction_id\\\":\\\"94c562ae-c5cc-5622-b91c-34a0effcb6e1\\\",\\\"document_id\\\":\\\"2f576170-c4f9-5141-a910-a0924f341de4\\\",\\\"user_id\\\":\\\"2acb499e-8428-543b-bd85-0d9098718220\\\",\\\"group_ids\\\":[],\\\"score\\\":0.671545108304772,\\\"text\\\":\\\"Lyft, Inc.Consolidated Statements of Comprehensive Loss\\\\n(in thousands) \\\\nYear Ended December 31,\\\\n2021\\\\n2020 2019 Net loss\\\\n$ (1,009,359) $ (1,752,857) $ (2,602,241) Other comprehensive incom\\\\ne (loss)Foreign currency transla\\\\ntion adjustment(931) (2,187) 162 Unrealized gain (loss) on m\\\\narketable securities, net of taxes(1,107) (1,011) 2,430 Other comprehensive incom\\\\ne (loss)(2,038) (3,198) 2,592 Comprehensive loss\\\\n$ (1,011,397) $ (1,756,055) $ (2,599,649) The accompanying notes are\\\",\\\"metadata\\\":{\\\"text\\\":\\\"Lyft, Inc.Consolidated Statements of Comprehensive Loss\\\\n(in thousands) \\\\nYear Ended December 31,\\\\n2021\\\\n2020 2019 Net loss\\\\n$ (1,009,359) $ (1,752,857) $ (2,602,241) Other comprehensive incom\\\\ne (loss)Foreign currency transla\\\\ntion adjustment(931) (2,187) 162 Unrealized gain (loss) on m\\\\narketable securities, net of taxes(1,107) (1,011) 2,430 Other comprehensive incom\\\\ne (loss)(2,038) (3,198) 2,592 Comprehensive loss\\\\n$ (1,011,397) $ (1,756,055) $ (2,599,649) The accompanying notes are\\\",\\\"title\\\":\\\"lyft_2021.pdf\\\",\\\"associatedQuery\\\":\\\"What was Lyft's profit in 2020?\\\"}}\",\"{\\\"fragment_id\\\":\\\"dbd5427c-f5ef-5fa6-83ae-a4a8ddbb48c2\\\",\\\"extraction_id\\\":\\\"14b08757-0819-5105-af37-509686dd6d01\\\",\\\"document_id\\\":\\\"2f576170-c4f9-5141-a910-a0924f341de4\\\",\\\"user_id\\\":\\\"2acb499e-8428-543b-bd85-0d9098718220\\\",\\\"group_ids\\\":[],\\\"score\\\":0.6639652450074329,\\\"text\\\":\\\"Lyft, Inc.Consolidated Balance Sheets\\\\n(in thousands, except for share and per share da\\\\nta) December 31,\\\\n2021\\\\n2020 Assets\\\\nCurrent assets\\\\nCash and cash equivalents\\\\n$ 457,325 $ 319,734 Short-term investments\\\\n1,796,533 1,931,334 Prepaid expenses and other cur\\\\nrent assets522,212 343,070 Total current assets\\\\n2,776,070 2,594,138 Restricted cash and cash equ\\\\nivalents73,205 118,559 Restricted investments\\\\n1,044,855 1,101,712 Other investments\\\\n80,411 10,000 Property and equipment, net\\\",\\\"metadata\\\":{\\\"text\\\":\\\"Lyft, Inc.Consolidated Balance Sheets\\\\n(in thousands, except for share and per share da\\\\nta) December 31,\\\\n2021\\\\n2020 Assets\\\\nCurrent assets\\\\nCash and cash equivalents\\\\n$ 457,325 $ 319,734 Short-term investments\\\\n1,796,533 1,931,334 Prepaid expenses and other cur\\\\nrent assets522,212 343,070 Total current assets\\\\n2,776,070 2,594,138 Restricted cash and cash equ\\\\nivalents73,205 118,559 Restricted investments\\\\n1,044,855 1,101,712 Other investments\\\\n80,411 10,000 Property and equipment, net\\\",\\\"title\\\":\\\"lyft_2021.pdf\\\",\\\"associatedQuery\\\":\\\"What was Lyft's profit in 2020?\\\"}}\",\"{\\\"fragment_id\\\":\\\"ba4bdf94-9b0d-5548-b3b0-b28595c39b2a\\\",\\\"extraction_id\\\":\\\"12cff898-f0fe-59b8-929b-00d3d56fd73d\\\",\\\"document_id\\\":\\\"2f576170-c4f9-5141-a910-a0924f341de4\\\",\\\"user_id\\\":\\\"2acb499e-8428-543b-bd85-0d9098718220\\\",\\\"group_ids\\\":[],\\\"score\\\":0.657470505539123,\\\"text\\\":\\\"Lyft rideshare and fleet data. The Company will receive, in total, approximately $515 million in cash in connection with this transaction, with $165 million paid upfrontand\\\\n $350 million to be paid over a five-year period. As the transaction included multiple elements, management had to estimate how much of the arrangementconsideration\\\",\\\"metadata\\\":{\\\"text\\\":\\\"Lyft rideshare and fleet data. The Company will receive, in total, approximately $515 million in cash in connection with this transaction, with $165 million paid upfrontand\\\\n $350 million to be paid over a five-year period. As the transaction included multiple elements, management had to estimate how much of the arrangementconsideration\\\",\\\"title\\\":\\\"lyft_2021.pdf\\\",\\\"associatedQuery\\\":\\\"What was Lyft's profit in 2020?\\\"}}\",\"{\\\"fragment_id\\\":\\\"68519877-163f-545b-a96f-77e2595ef720\\\",\\\"extraction_id\\\":\\\"9e45b68a-e773-5903-a9e7-05f860a05cf5\\\",\\\"document_id\\\":\\\"2f576170-c4f9-5141-a910-a0924f341de4\\\",\\\"user_id\\\":\\\"2acb499e-8428-543b-bd85-0d9098718220\\\",\\\"group_ids\\\":[],\\\"score\\\":0.644272885067888,\\\"text\\\":\\\"Lyft, Inc.Notes to Consolidated Financial Statements\\\\n1. Description of Business and Basis of Presentation\\\\nOrganization and Description of Business\\\\nLyft,\\\\n Inc. (the Company or Lyft) is incorporated in Delaware with its headquarters in San Francisco, California. The Company operates multimodaltransportation\\\\n networks in the United States and Canada that offer access to a variety of transportation options through the Companys platform and mobile-basedapplications.\\\",\\\"metadata\\\":{\\\"text\\\":\\\"Lyft, Inc.Notes to Consolidated Financial Statements\\\\n1. Description of Business and Basis of Presentation\\\\nOrganization and Description of Business\\\\nLyft,\\\\n Inc. (the Company or Lyft) is incorporated in Delaware with its headquarters in San Francisco, California. The Company operates multimodaltransportation\\\\n networks in the United States and Canada that offer access to a variety of transportation options through the Companys platform and mobile-basedapplications.\\\",\\\"title\\\":\\\"lyft_2021.pdf\\\",\\\"associatedQuery\\\":\\\"What was Lyft's profit in 2020?\\\"}}\",\"{\\\"fragment_id\\\":\\\"05ddcc28-fd4b-5318-9224-6f2cd3d16c5c\\\",\\\"extraction_id\\\":\\\"7ce2fcae-d65b-5a4c-b45d-dcd87c4df38e\\\",\\\"document_id\\\":\\\"2f576170-c4f9-5141-a910-a0924f341de4\\\",\\\"user_id\\\":\\\"2acb499e-8428-543b-bd85-0d9098718220\\\",\\\"group_ids\\\":[],\\\"score\\\":0.642513496576135,\\\"text\\\":\\\"Lyft, Inc.Consolidated Statements of Cash Flows\\\\n(in thousands)\\\\nYear Ended December 31,\\\\n2021\\\\n2020 2019 Reconciliation of cash, cash equivalents and restricted cash and cash equivalents to the consolidated balance sheets\\\\nCash and cash equivalents\\\\n$ 457,325 $ 319,734 $ 358,319 Restricted cash and cash equivalents\\\\n73,205 118,559 204,976 Restricted cash, included in prepaid expenses and other current \\\\nassets663 192 1,170 Total cash, cash equivalents and restricted cash and cash equivalents\\\",\\\"metadata\\\":{\\\"text\\\":\\\"Lyft, Inc.Consolidated Statements of Cash Flows\\\\n(in thousands)\\\\nYear Ended December 31,\\\\n2021\\\\n2020 2019 Reconciliation of cash, cash equivalents and restricted cash and cash equivalents to the consolidated balance sheets\\\\nCash and cash equivalents\\\\n$ 457,325 $ 319,734 $ 358,319 Restricted cash and cash equivalents\\\\n73,205 118,559 204,976 Restricted cash, included in prepaid expenses and other current \\\\nassets663 192 1,170 Total cash, cash equivalents and restricted cash and cash equivalents\\\",\\\"title\\\":\\\"lyft_2021.pdf\\\",\\\"associatedQuery\\\":\\\"What was Lyft's profit in 2020?\\\"}}\",\"{\\\"fragment_id\\\":\\\"e89d60be-9148-52f1-8907-03187fdd2b65\\\",\\\"extraction_id\\\":\\\"ac9c9f74-c545-586e-8acf-5545cf0864d5\\\",\\\"document_id\\\":\\\"2f576170-c4f9-5141-a910-a0924f341de4\\\",\\\"user_id\\\":\\\"2acb499e-8428-543b-bd85-0d9098718220\\\",\\\"group_ids\\\":[],\\\"score\\\":0.633240878582001,\\\"text\\\":\\\"Lyft, Inc. for the fiscal year ended December 31, 2021 fully complies with the requirements of Section 13(a) or 15(d) of the Securities Exchange Act of 1934, asamended,\\\\n and that the information contained in such Annual Report on Form 10-K fairly presents, in all material respects, the financial condition and results of operationsof Lyft, Inc.\\\\nDate:\\\\nFebruary 28, 2022 By: /s/ Logan Green Name:\\\\nLogan Green Title:\\\\nChief Executive Officer (Principal Executive Officer)\\\\nI, Elaine\\\",\\\"metadata\\\":{\\\"text\\\":\\\"Lyft, Inc. for the fiscal year ended December 31, 2021 fully complies with the requirements of Section 13(a) or 15(d) of the Securities Exchange Act of 1934, asamended,\\\\n and that the information contained in such Annual Report on Form 10-K fairly presents, in all material respects, the financial condition and results of operationsof Lyft, Inc.\\\\nDate:\\\\nFebruary 28, 2022 By: /s/ Logan Green Name:\\\\nLogan Green Title:\\\\nChief Executive Officer (Principal Executive Officer)\\\\nI, Elaine\\\",\\\"title\\\":\\\"lyft_2021.pdf\\\",\\\"associatedQuery\\\":\\\"What was Lyft's profit in 2020?\\\"}}\",\"{\\\"fragment_id\\\":\\\"b230ec93-1003-5382-98e3-15505dc5bdba\\\",\\\"extraction_id\\\":\\\"9f117275-9d93-5b4a-97d8-bb270db8b94e\\\",\\\"document_id\\\":\\\"2f576170-c4f9-5141-a910-a0924f341de4\\\",\\\"user_id\\\":\\\"2acb499e-8428-543b-bd85-0d9098718220\\\",\\\"group_ids\\\":[],\\\"score\\\":0.621775843010894,\\\"text\\\":\\\"PART IItem 1. Business.\\\\nOur Mission\\\\nImprove peoples lives with \\\\nthe worlds best transportation.Overview\\\\nLyft,\\\\n Inc (the Company or Lyft) started a movement to revolutionize transportation. In 2012, we launched our peer-to-peer marketplace for on-demandridesharing\\\\n and have continued to pioneer innovations aligned with our mission. Today, Lyft is one of the largest multimodal transportation networks in the United Statesand Canada.\\\\nWe\\\",\\\"metadata\\\":{\\\"text\\\":\\\"PART IItem 1. Business.\\\\nOur Mission\\\\nImprove peoples lives with \\\\nthe worlds best transportation.Overview\\\\nLyft,\\\\n Inc (the Company or Lyft) started a movement to revolutionize transportation. In 2012, we launched our peer-to-peer marketplace for on-demandridesharing\\\\n and have continued to pioneer innovations aligned with our mission. Today, Lyft is one of the largest multimodal transportation networks in the United Statesand Canada.\\\\nWe\\\",\\\"title\\\":\\\"lyft_2021.pdf\\\",\\\"associatedQuery\\\":\\\"What was Lyft's profit in 2020?\\\"}}\"Lyft did not make a profit in 2020. Instead, the company reported a net loss of $1,752,857,000 for the year ended December 31, 2020 [3], [4]." + } + } + ] + } + } + } +} diff --git a/tests/regression/expected_outputs/test_user_management.json b/tests/regression/expected_outputs/test_user_management.json new file mode 100644 index 000000000..971498d6e --- /dev/null +++ b/tests/regression/expected_outputs/test_user_management.json @@ -0,0 +1,116 @@ +{ + "register_user": { + "results": { + "email": "test_72231655@example.com", + "id": "f36f0a8a-9f12-5979-9416-1fbb7d28a80b", + "group_ids": [], + "hashed_password": "$2b$12$uXTZiDl4gRWPueHa1IEC3OCVRsxZFUJjIgOkajwSFDKFzyRcL2ge.", + "is_superuser": false, + "is_active": true, + "is_verified": false, + "verification_code_expiry": null, + "name": null, + "bio": null, + "profile_picture": null, + "created_at": "2024-08-14T00:26:00.833888Z", + "updated_at": "2024-08-14T00:26:00.833888Z" + } + }, + "login_user": { + "results": { + "access_token": { + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ0ZXN0XzcyMjMxNjU1QGV4YW1wbGUuY29tIiwiZXhwIjoxNzIzNTk4NzYxLjE5OTA1NCwidG9rZW5fdHlwZSI6ImFjY2VzcyJ9.FN2W4wEKQA8X1OLYFVfjUUJ46f6FsZdCjShsYbiIX_o", + "token_type": "access" + }, + "refresh_token": { + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ0ZXN0XzcyMjMxNjU1QGV4YW1wbGUuY29tIiwiZXhwIjoxNzI0MTk5OTYxLCJ0b2tlbl90eXBlIjoicmVmcmVzaCJ9.ZvX9ASi6RZvKSn8O1t-ZDoJm_dgdtcch9EPT9RSvmtY", + "token_type": "refresh" + } + } + }, + "user_info": { + "results": { + "email": "test_72231655@example.com", + "id": "f36f0a8a-9f12-5979-9416-1fbb7d28a80b", + "group_ids": [], + "hashed_password": "$2b$12$uXTZiDl4gRWPueHa1IEC3OCVRsxZFUJjIgOkajwSFDKFzyRcL2ge.", + "is_superuser": false, + "is_active": true, + "is_verified": true, + "verification_code_expiry": null, + "name": null, + "bio": null, + "profile_picture": null, + "created_at": "2024-08-14T00:26:00.833888Z", + "updated_at": "2024-08-14T00:26:00.833888Z" + } + }, + "change_password": { + "results": { + "message": "Password changed successfully" + } + }, + "update_profile": { + "results": { + "email": "test_72231655@example.com", + "id": "f36f0a8a-9f12-5979-9416-1fbb7d28a80b", + "group_ids": [], + "hashed_password": "null", + "is_superuser": false, + "is_active": true, + "is_verified": true, + "verification_code_expiry": null, + "name": "John Doe", + "bio": "R2R enthusiast", + "profile_picture": null, + "created_at": "2024-08-14T00:26:00.833888Z", + "updated_at": "2024-08-14T00:26:01.991559Z" + } + }, + "refresh_token": { + "results": { + "access_token": { + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ0ZXN0XzcyMjMxNjU1QGV4YW1wbGUuY29tIiwiZXhwIjoxNzIzNTk4NzYyLjEzNDQ1NiwidG9rZW5fdHlwZSI6ImFjY2VzcyJ9.zaXBVSgktzEB1BWrg2W9rsjmTW_uw1tEqHJEJ5diPRs", + "token_type": "access" + }, + "refresh_token": { + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ0ZXN0XzcyMjMxNjU1QGV4YW1wbGUuY29tIiwiZXhwIjoxNzI0MTk5OTYyLCJ0b2tlbl90eXBlIjoicmVmcmVzaCJ9.09YDDLWNVPrWJAzFaXai3Kul5RJ7W8iNTKmkq-0y4n4", + "token_type": "refresh" + } + } + }, + "superuser_test": { + "results": [ + { + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "num_files": 15, + "total_size_in_bytes": 5067615, + "document_ids": [ + "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", + "716fea3a-826b-5b27-8e59-ffbd1a35455a", + "52e12576-090f-59db-91f4-6d4b2e29ae6c", + "3e157b3a-8469-51db-90d9-52e7d896b49b", + "01d514a4-5cb1-5c86-be8c-0c5c312a02c9", + "c3291abf-8a4e-5d9d-80fd-232ef6fd8526", + "e797da22-8c5d-54e5-bed5-a55954cf6bf9", + "7c1105fc-8f62-5a8f-ac81-fe88f3ec9e4c", + "2f576170-c4f9-5141-a910-a0924f341de4", + "30f950f0-c692-57c5-b6ec-ff78ccf5ccdc", + "57eec3df-cf68-5559-a80d-ae3fb55b9af1", + "db02076e-989a-59cd-98d5-e24e15a0bd27", + "d421207a-d799-5806-8d67-46b2005b15d4", + "451adbbd-e24e-5c9b-80a8-f424b6c7accb", + "5b1bd54f-4d70-56b9-a017-a618bc75f94c" + ] + } + ] + }, + "logout": { + "results": { + "message": "Logged out successfully" + } + }, + "delete_account": { + "results": "User account deleted successfully" + } +} diff --git a/tests/regression/runner.py b/tests/regression/runner.py new file mode 100644 index 000000000..7101177c7 --- /dev/null +++ b/tests/regression/runner.py @@ -0,0 +1,138 @@ +import argparse +import importlib +import os +from typing import List + +from colorama import Fore, Style, init +from test_cases.base import BaseTest, RegressionTest + +from r2r.main.api.client import R2RClient + + +class RegressionTestRunner: + def __init__( + self, + check_only: bool = False, + update_expected: bool = False, + base_url: str = "http://localhost:8000", + ): + self.client = R2RClient(base_url=base_url) + self.tests: List[BaseTest] = [] + self.test_order = [ + # "TestDocumentManagement", + # "TestRetrieval", + "TestUserManagement", + # "TestObservability", + # "TestGroupManagement", + ] + self.check_only = check_only + self.update_expected = update_expected + + if not check_only: + self.outputs_dir = os.path.join( + os.path.dirname(__file__), + ( + "expected_outputs" + if self.update_expected + else "observed_outputs" + ), + ) + os.makedirs(self.outputs_dir, exist_ok=True) + + def load_tests(self): + test_dir = os.path.join(os.path.dirname(__file__), "test_cases") + for class_name in self.test_order: + # Convert camel case to snake case + snake_case = "".join( + ["_" + c.lower() if c.isupper() else c for c in class_name] + ).lstrip("_") + filename = f"test_{snake_case[5:]}.py" # Remove "test_" prefix + if filename in os.listdir(test_dir): + module_name = f"tests.regression.test_cases.{filename[:-3]}" + module = importlib.import_module(module_name) + test_class = getattr(module, class_name) + self.tests.append(test_class(self.client)) + + def run_all(self) -> bool: + for test in self.tests: + print( + f"{Fore.CYAN}Running test suite: {test.__class__.__name__}{Style.RESET_ALL}" + ) + test.run_and_save_outputs(self.outputs_dir) + + return self.compare_all() if not self.update_expected else True + + def compare_all(self) -> bool: + all_passed = True + expected_outputs_dir = os.path.join( + os.path.dirname(__file__), "expected_outputs" + ) + observed_outputs_dir = os.path.join( + os.path.dirname(__file__), "observed_outputs" + ) + print( + f"\n{Fore.CYAN}Comparing results for test suites:{Style.RESET_ALL}" + ) + for test in self.tests: + if test.compare_outputs( + observed_outputs_dir, expected_outputs_dir + ): + print( + f"{Fore.GREEN}{test.__class__.__name__} ✓{Style.RESET_ALL}" + ) + else: + print( + f"{Fore.RED}{test.__class__.__name__} ✗{Style.RESET_ALL}" + ) + all_passed = False + return all_passed + + def update_all_expected_outputs(self): + for test in self.tests: + print( + f"{Fore.YELLOW}Updating expected output for test suite: {test.__class__.__name__}{Style.RESET_ALL}" + ) + test.update_expected_outputs(self.outputs_dir) + + +def main(): + parser = argparse.ArgumentParser(description="Run regression tests") + parser.add_argument( + "--check-only", + action="store_true", + help="Run in check mode (compare existing outputs without running tests)", + ) + parser.add_argument( + "--update-expected", + action="store_true", + help="Run in update mode (update expected outputs)", + ) + args = parser.parse_args() + + runner = RegressionTestRunner(args.check_only) + runner.load_tests() + + if args.check_only: + print(f"{Fore.CYAN}Running in check-only mode{Style.RESET_ALL}") + success = runner.compare_all() + elif runner.update_expected: + print(f"{Fore.YELLOW}Updating expected outputs{Style.RESET_ALL}") + runner.run_all() # Run tests to generate outputs + runner.update_all_expected_outputs() + if os.environ.get("CHECK_UPDATED_OUTPUTS", "").lower() != "true": + success = runner.compare_all() + else: + print(f"{Fore.CYAN}Running all tests{Style.RESET_ALL}") + success = runner.run_all() + + if success: + print(f"\n{Fore.GREEN}All tests passed successfully!{Style.RESET_ALL}") + else: + print( + f"\n{Fore.RED}Some tests failed. Please check the output above for details.{Style.RESET_ALL}" + ) + exit(1) + + +if __name__ == "__main__": + main() diff --git a/tests/regression/test_cases/base.py b/tests/regression/test_cases/base.py new file mode 100644 index 000000000..e4b0378b5 --- /dev/null +++ b/tests/regression/test_cases/base.py @@ -0,0 +1,273 @@ +import json +import os +import re +from typing import Any, Callable, Dict, Optional + +from colorama import Fore, Style, init +from deepdiff import DeepDiff + +from r2r.main.api.client import R2RClient + + +def _to_snake_case(name: str) -> str: + pattern = re.compile(r"(? bool: + result = self._run_test(client) + return self._compare_output(result, self.expected_output) + + def update_expected_output(self, client: R2RClient): + result = self._run_test(client) + self._save_expected_output(result) + + def _run_test(self, client: R2RClient) -> Dict[str, Any]: + return self.test_function(client) + + def _load_expected_output(self) -> Dict[str, Any]: + with open(self.expected_output_file, "r") as f: + return json.load(f) + + def _save_expected_output(self, output: Dict[str, Any]): + with open(self.expected_output_file, "w") as f: + json.dump(output, f, indent=2) + + def _compare_output( + self, actual: Dict[str, Any], expected: Dict[str, Any] + ) -> bool: + diff = self._custom_diff(expected, actual) + if diff: + print(f"\nTest {self.name} failed. Differences found:") + print(json.dumps(diff, indent=2)) + return False + return True + + def _custom_diff( + self, expected: Dict[str, Any], actual: Dict[str, Any] + ) -> Dict[str, Any]: + diff = {} + + expected_results = expected.get("results", {}) + actual_results = actual.get("results", {}) + + if "completion" in expected_results and "completion" in actual_results: + # Custom comparison for content field + expected_completion = self._get_completion_content( + expected_results + ) + actual_completion = self._get_completion_content(actual_results) + if ( + expected_completion + and actual_completion + and not self._fuzzy_content_match( + expected_completion, actual_completion + ) + ): + diff["content_mismatch"] = { + "expected": expected_completion, + "actual": actual_completion, + } + + # Use DeepDiff for the rest, ignoring specified fields + try: + deep_diff = DeepDiff( + expected_results, + actual_results, + ignore_order=True, + exclude_paths=self.exclude_paths, + ) + if deep_diff: + diff["other_differences"] = self._serialize_deep_diff( + deep_diff + ) + # Print the specific fields that are different + for change_type, changes in deep_diff.items(): + if change_type == "values_changed": + for path, change in changes.items(): + print(f"Field '{path}' changed:") + print(f" Expected: {change['old_value']}") + print(f" Actual: {change['new_value']}") + + except Exception as e: + diff["deepdiff_error"] = ( + f"Error in DeepDiff comparison: {str(e)}" + ) + return diff + elif ( + "completion" in expected_results or "completion" in actual_results + ): + diff["content_mismatch"] = { + "expected_results": expected_results, + "actual_results": actual_results, + } + else: + + deep_diff = DeepDiff( + expected_results, + actual_results, + ignore_order=True, + exclude_paths=self.exclude_paths, + ) + + if deep_diff: + diff["other_differences"] = self._serialize_deep_diff( + deep_diff + ) + # Print the specific fields that are different + for change_type, changes in deep_diff.items(): + if change_type == "values_changed": + for path, change in changes.items(): + print(f"Field '{path}' changed:") + print(f" Expected: {change['old_value']}") + print(f" Actual: {change['new_value']}") + + return self._serialize_deep_diff(deep_diff) + + return diff + + def _serialize_deep_diff(self, deep_diff): + if isinstance(deep_diff, dict): + serializable_diff = {} + for key, value in deep_diff.items(): + if isinstance(value, (dict, list)): + serializable_diff[key] = self._serialize_deep_diff(value) + elif isinstance(value, (int, float, str, bool, type(None))): + serializable_diff[key] = value + else: + serializable_diff[key] = str(value) + return serializable_diff + elif isinstance(deep_diff, list): + return [self._serialize_deep_diff(item) for item in deep_diff] + elif isinstance(deep_diff, (int, float, str, bool, type(None))): + return deep_diff + else: + return str(deep_diff) + + def _get_completion_content(self, data: Dict[str, Any]) -> Optional[str]: + try: + return data["completion"]["choices"][0]["message"]["content"] + except (KeyError, IndexError): + return None + + def _fuzzy_content_match( + self, expected: str, actual: str, threshold: float = 0.6 + ) -> bool: + expected_words = set(re.findall(r"\w+", expected.lower())) + actual_words = set(re.findall(r"\w+", actual.lower())) + common_words = expected_words.intersection(actual_words) + similarity = len(common_words) / max( + len(expected_words), len(actual_words) + ) + return similarity >= threshold + + +class BaseTest: + def __init__(self, client: R2RClient): + self.client = client + self.expected_outputs_file = os.path.join( + os.path.dirname(os.path.dirname(__file__)), + "expected_outputs", + f"{_to_snake_case(self.__class__.__name__)}.json", + ) + self.exclude_paths_map = {} + + def run_and_save_outputs(self, actual_outputs_dir: str): + actual_outputs = {} + for test_name, test_func in self.get_test_cases().items(): + snake_case_name = _to_snake_case(test_name) + print(f" Running test: {snake_case_name}") + result = test_func(self.client) + actual_outputs[snake_case_name] = result + + actual_outputs_file = os.path.join( + actual_outputs_dir, + f"{_to_snake_case(self.__class__.__name__)}.json", + ) + with open(actual_outputs_file, "w") as f: + json.dump(actual_outputs, f, indent=2) + + def compare_outputs( + self, observed_outputs_dir: str, expected_outputs_dir: str + ) -> bool: + all_passed = True + expected_outputs_file = os.path.join( + expected_outputs_dir, + f"{_to_snake_case(self.__class__.__name__)}.json", + ) + observed_outputs_file = os.path.join( + observed_outputs_dir, + f"{_to_snake_case(self.__class__.__name__)}.json", + ) + + with open(expected_outputs_file, "r") as f: + expected_outputs = json.load(f) + + with open(observed_outputs_file, "r") as f: + observed_outputs = json.load(f) + + for test_name in self.get_test_cases().keys(): + snake_case_name = _to_snake_case(test_name) + exclude_paths = self.exclude_paths_map.get(snake_case_name, []) + regression_test = RegressionTest( + test_name, + lambda x: x, + expected_outputs.get(snake_case_name, {}), + exclude_paths, + ) + if regression_test._compare_output( + observed_outputs.get(snake_case_name, {}), + expected_outputs.get(snake_case_name, {}), + ): + print( + f"{Fore.GREEN} Test {snake_case_name} passed ✓{Style.RESET_ALL}" + ) + else: + print( + f"{Fore.RED} Test {snake_case_name} failed ✗{Style.RESET_ALL}" + ) + all_passed = False + + return all_passed + + def update_expected_outputs(self, actual_outputs_dir: str): + actual_outputs_file = os.path.join( + actual_outputs_dir, + f"{_to_snake_case(self.__class__.__name__)}.json", + ) + with open(actual_outputs_file, "r") as f: + actual_outputs = json.load(f) + + with open(self.expected_outputs_file, "w") as f: + json.dump(actual_outputs, f, indent=2) + + def _load_expected_outputs(self) -> Dict[str, Any]: + if os.path.exists(self.expected_outputs_file): + with open(self.expected_outputs_file, "r") as f: + return json.load(f) + return {} + + def set_exclude_paths(self, test_name: str, exclude_paths: list[str] = []): + self.exclude_paths_map[_to_snake_case(test_name)] = exclude_paths + + def get_test_cases(self) -> Dict[str, callable]: + raise NotImplementedError( + "Subclasses must implement get_test_cases method" + ) + + def _load_expected_outputs(self) -> Dict[str, Any]: + with open(self.expected_outputs_file, "r") as f: + return json.load(f) diff --git a/tests/regression/test_cases/test_document_management.py b/tests/regression/test_cases/test_document_management.py new file mode 100644 index 000000000..4c2ee97bf --- /dev/null +++ b/tests/regression/test_cases/test_document_management.py @@ -0,0 +1,115 @@ +import os + +from r2r import R2RException +from tests.regression.test_cases.base import BaseTest + + +class TestDocumentManagement(BaseTest): + + CHUNKS_FILE_ID = "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa" + UPDATE_FILE_ID = "db02076e-989a-59cd-98d5-e24e15a0bd27" + DELETE_FILE_ID = "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa" + + def __init__(self, client): + super().__init__(client) + exclude_paths = [f"root[{i}]['created_at']" for i in range(20)] + [ + f"root[{i}]['updated_at']" for i in range(20) + ] + + self.set_exclude_paths("documents_overview", exclude_paths) + self.set_exclude_paths("rerun_documents_overview", exclude_paths) + + def get_test_cases(self): + return { + "ingest_sample_files": lambda client: self.ingest_sample_files_test( + client + ), + "reingest_sample_file": lambda client: self.ingest_sample_files_test( + client + ), + "documents_overview": lambda client: self.documents_overview_test( + client + ), + "document_chunks_test": lambda client: self.document_chunks_test( + client + ), + "update_document_test": lambda client: self.update_document_test( + client + ), + "delete_document_test": lambda client: self.delete_document_test( + client + ), + "rerun_documents_overview_test": lambda client: self.documents_overview_test( + client + ), + "rerun_document_chunks_test": lambda client: self.document_chunks_test( + client + ), + } + + def ingest_sample_files_test(self, client): + file_path = os.path.abspath(__file__) + data_path = os.path.join( + os.path.dirname(file_path), + "..", + "..", + "..", + "r2r", + "examples", + "data", + ) + try: + return client.ingest_files( + [ + os.path.join(data_path, file_name) + for file_name in os.listdir(data_path) + ] + ) + except R2RException as e: + return {"results": str(e)} + + def documents_overview_test(self, client): + try: + return client.documents_overview() + except R2RException as e: + return {"results": str(e)} + + def document_chunks_test(self, client): + try: + # Now delete the file + chunks_response = client.document_chunks( + TestDocumentManagement.CHUNKS_FILE_ID + ) + return chunks_response + except R2RException as e: + return {"results": str(e)} + + def update_document_test(self, client): + try: + # Now update the file + file_path = os.path.join( + os.path.dirname(__file__), + "..", + "..", + "..", + "r2r", + "examples", + "data", + "aristotle_v2.txt", + ) + update_response = client.update_files( + [file_path], [TestDocumentManagement.UPDATE_FILE_ID] + ) + return update_response + except R2RException as e: + return {"results": str(e)} + + def delete_document_test(self, client): + try: + # Now delete the file + delete_response = client.delete( + {"document_id": {"$eq": TestDocumentManagement.DELETE_FILE_ID}} + ) + return delete_response + except R2RException as e: + return {"results": str(e)} diff --git a/tests/regression/test_cases/test_group_management.py b/tests/regression/test_cases/test_group_management.py new file mode 100644 index 000000000..543c4e667 --- /dev/null +++ b/tests/regression/test_cases/test_group_management.py @@ -0,0 +1,169 @@ +import uuid + +from tests.regression.test_cases.base import BaseTest + + +class TestGroupManagement(BaseTest): + def __init__(self, client): + super().__init__(client) + self.admin_email = "admin@example.com" + self.admin_password = "change_me_immediately" + self.user_password = "test_password" + + keys_to_ignore = ["group_id", "created_at", "updated_at"] + self.set_exclude_paths( + "create_groups_test", + [f"root['group_1']['results']['{key}']" for key in keys_to_ignore] + + [ + f"root['group_1']['results']['{key}']" + for key in keys_to_ignore + ], + ) + + keys_to_ignore += ["hashed_password"] + self.set_exclude_paths( + "add_users_to_groups_test", + [f"root['user_1']['results']['{key}']" for key in keys_to_ignore] + + [ + f"root['group_1']['results']['{key}']" + for key in keys_to_ignore + ], + ) + + def get_test_cases(self): + return { + "create_groups": self.create_groups_test, + "add_users_to_groups": self.add_users_to_groups_test, + "group_based_document_access": self.group_based_document_access_test, + "admin_ingest_documents": self.admin_ingest_documents_test, + "user_ingest_and_search": self.user_ingest_and_search_test, + "cleanup": self.cleanup_test, + } + + def create_groups_test(self, client): + try: + client.login(self.admin_email, self.admin_password) + group_name_1 = f"Test Group 1 {uuid.uuid4()}" + group_name_2 = f"Test Group 2 {uuid.uuid4()}" + group_1 = client.create_group( + group_name_1, "A test group for permissions" + ) + group_2 = client.create_group( + group_name_2, "Another test group for permissions" + ) + self.group_id_1 = group_1["results"]["group_id"] + self.group_id_2 = group_2["results"]["group_id"] + return {"group_1": group_1, "group_2": group_2} + except Exception as e: + return {"error": str(e)} + + def add_users_to_groups_test(self, client): + try: + self.user_email_1 = f"user1_{uuid.uuid4()}@example.com" + self.user_email_2 = f"user2_{uuid.uuid4()}@example.com" + user_1 = client.register(self.user_email_1, self.user_password) + user_2 = client.register(self.user_email_2, self.user_password) + self.user_id_1 = user_1["results"]["id"] + self.user_id_2 = user_2["results"]["id"] + + client.add_user_to_group(self.user_id_1, self.group_id_1) + client.add_user_to_group(self.user_id_2, self.group_id_2) + client.add_user_to_group(self.user_id_2, self.group_id_1) + + return {"user_1": user_1, "user_2": user_2} + except Exception as e: + return {"error": str(e)} + + def group_based_document_access_test(self, client): + try: + # Admin ingests a document for group 1 + client.login(self.admin_email, self.admin_password) + admin_ingest = client.ingest_files( + file_paths=["tests/regression/test_data/test_document.txt"], + metadatas=[{"group_ids": [str(self.group_id_1)]}], + ) + + # User 1 searches for documents + client.login(self.user_email_1, self.user_password) + user_1_search = client.search("test document") + + # User 2 searches for documents + client.login(self.user_email_2, self.user_password) + user_2_search = client.search("test document") + + return { + "admin_ingest": admin_ingest, + "user_1_search": user_1_search, + "user_2_search": user_2_search, + } + except Exception as e: + return {"error": str(e)} + + def admin_ingest_documents_test(self, client): + try: + client.login(self.admin_email, self.admin_password) + + # Admin ingests a document for group 1 + admin_ingest_group1 = client.ingest_files( + file_paths=[ + "tests/regression/test_data/admin_document_group1.txt" + ], + metadatas=[{"group_ids": [str(self.group_id_1)]}], + ) + + # Admin ingests a document for user 1 + admin_ingest_user1 = client.ingest_files( + file_paths=[ + "tests/regression/test_data/admin_document_user1.txt" + ] + ) + + return { + "admin_ingest_group1": admin_ingest_group1, + "admin_ingest_user1": admin_ingest_user1, + } + except Exception as e: + return {"error": str(e)} + + def user_ingest_and_search_test(self, client): + try: + # User 1 actions + client.login(self.user_email_1, self.user_password) + user_1_ingest = client.ingest_files( + file_paths=["tests/regression/test_data/user1_document.txt"] + ) + user_1_ingest_group = client.ingest_files( + file_paths=[ + "tests/regression/test_data/user1_document_group.txt" + ], + metadatas=[{"group_ids": [str(self.group_id_1)]}], + ) + + user_1_search = client.search("document") + + # User 2 actions + client.login(self.user_email_2, self.user_password) + user_2_ingest = client.ingest_files( + file_paths=["tests/regression/test_data/user2_document.txt"] + ) + user_2_search = client.search("document") + + return { + "user_1_ingest": user_1_ingest, + "user_1_search": user_1_search, + "user_2_ingest": user_2_ingest, + "user_2_search": user_2_search, + } + except Exception as e: + return {"error": str(e)} + + def cleanup_test(self, client): + try: + client.login(self.admin_email, self.admin_password) + client.delete_group(self.group_id_1) + client.delete_group(self.group_id_2) + client.delete_user(self.user_id_1, self.user_password) + client.delete_user(self.user_id_2, self.user_password) + return {"status": "cleanup completed"} + except Exception as e: + return {"error": str(e)} diff --git a/tests/regression/test_cases/test_observability.py b/tests/regression/test_cases/test_observability.py new file mode 100644 index 000000000..a65071434 --- /dev/null +++ b/tests/regression/test_cases/test_observability.py @@ -0,0 +1,26 @@ +from tests.regression.test_cases.base import BaseTest + + +class TestObservability(BaseTest): + def __init__(self, client): + super().__init__(client) + # Add exclude_paths as needed + + def get_test_cases(self): + return { + "users_overview": lambda client: self.users_overview_test(client), + "logs": lambda client: self.logs_test(client), + "analytics": lambda client: self.analytics_test(client), + } + + def users_overview_test(self, client): + return client.users_overview() + + def logs_test(self, client): + return client.logs() + + def analytics_test(self, client): + return client.analytics( + {"search_latencies": "search_latency"}, + {"search_latencies": ["basic_statistics", "search_latency"]}, + ) diff --git a/tests/regression/test_cases/test_retrieval.py b/tests/regression/test_cases/test_retrieval.py new file mode 100644 index 000000000..f336744d4 --- /dev/null +++ b/tests/regression/test_cases/test_retrieval.py @@ -0,0 +1,87 @@ +from tests.regression.test_cases.base import BaseTest + + +class TestRetrieval(BaseTest): + RAG_EXCLUSIONS = ( + [ + f"root['completion']['{field}']" + for field in [ + "id", + "system_fingerprint", + "usage", + "created", + ] + ] + + ["root['completion']['choices'][0]['message']['content']"] + + [f"root['search_results'][{i}]['score']" for i in range(10)] + ) + + def __init__(self, client): + super().__init__(client) + # ignore scores since math epsilon fails for nested floats, exact text is sufficient. + self.set_exclude_paths( + "search", + [ + f"root['vector_search_results'][{i}]['score']" + for i in range(10) + ], + ) + self.set_exclude_paths("basic_rag", TestRetrieval.RAG_EXCLUSIONS) + self.set_exclude_paths("hybrid_rag", TestRetrieval.RAG_EXCLUSIONS) + self.set_exclude_paths("streaming_rag", TestRetrieval.RAG_EXCLUSIONS) + + def get_test_cases(self): + return { + "search": lambda client: self.search_test(client), + "basic_rag": lambda client: self.basic_rag_test(client), + "hybrid_rag": lambda client: self.hybrid_rag_test(client), + "streaming_rag": lambda client: self.streaming_rag_test(client), + } + + def search_test(self, client): + try: + return client.search("What is the capital of France?") + except Exception as e: + return {"results": str(e)} + + def hybrid_search_test(self, client): + try: + return client.search( + "What is the capital of France?", {"do_hybrid_search": True} + ) + except Exception as e: + return {"results": str(e)} + + def basic_rag_test(self, client): + try: + return client.rag("What was Uber's profit in 2020?") + except Exception as e: + return {"results": str(e)} + + def hybrid_rag_test(self, client): + try: + return client.rag("Who is John Snow?", {"do_hybrid_search": True}) + except Exception as e: + return {"results": str(e)} + + def streaming_rag_test(self, client): + try: + response = client.rag( + "What was Lyft's profit in 2020?", + rag_generation_config={"stream": True}, + ) + return { + "results": { + "completion": { + "choices": [ + { + "message": { + "content": f"{''.join([chunk for chunk in response])}" + } + } + ] + } + } + } + except Exception as e: + return {"results": str(e)} diff --git a/tests/regression/test_cases/test_user_management.py b/tests/regression/test_cases/test_user_management.py new file mode 100644 index 000000000..0c6412f60 --- /dev/null +++ b/tests/regression/test_cases/test_user_management.py @@ -0,0 +1,156 @@ +import uuid + +from tests.regression.test_cases.base import BaseTest + + +class TestUserManagement(BaseTest): + VARIABLE_USER_FIELDS = [ + "id", + "email", + "created_at", + "updated_at", + "hashed_password", + "access_token", + "refresh_token", + ] + + def __init__(self, client): + super().__init__(client) + self.set_exclude_paths( + "register_user", + [ + f"root['{field}']" + for field in TestUserManagement.VARIABLE_USER_FIELDS + ], + ) + self.set_exclude_paths( + "login_user", + [ + f"root['{field}']" + for field in ["access_token", "refresh_token"] + ], + ) + self.set_exclude_paths( + "user_info", + [ + f"root['{field}']" + for field in TestUserManagement.VARIABLE_USER_FIELDS + ], + ) + self.set_exclude_paths( + "change_password", + [ + f"root['{field}']" + for field in TestUserManagement.VARIABLE_USER_FIELDS + ], + ) + self.set_exclude_paths( + "update_profile", + [ + f"root['{field}']" + for field in TestUserManagement.VARIABLE_USER_FIELDS + ], + ) + self.set_exclude_paths( + "refresh_token", + [ + f"root['{field}']" + for field in TestUserManagement.VARIABLE_USER_FIELDS + ], + ) + self.user_id_string = str(uuid.uuid4()).split("-")[0] + self.user_id_string_2 = str(uuid.uuid4()).split("-")[0] + + def get_test_cases(self): + return { + "register_user": lambda client: self.register_user_test(client), + # "login_user": lambda client: self.login_user_test(client), + # "user_info": lambda client: self.user_info_test(client), + # "change_password": lambda client: self.change_password_test( + # client + # ), + # # "reset_password": lambda client: self.reset_password_test(client), + # "update_profile": lambda client: self.update_profile_test(client), + # "refresh_token": lambda client: self.refresh_token_test(client), + # "superuser_test": lambda client: self.superuser_test(client), + # "logout": lambda client: self.logout_test(client), + # "delete_account": lambda client: self.delete_user_test(client), + # "login_user": lambda client: self.login_user_test(client), + # "refresh_token": lambda client: self.refresh_token_test(client), + } + + def register_user_test(self, client): + try: + email = f"test_{self.user_id_string}@example.com" + password = "password123" + user = client.register(email, password) + self.user = user + return user + except Exception as e: + return {"results": str(e)} + + def login_user_test(self, client): + try: + email = f"test_{self.user_id_string}@example.com" + password = "password123" + login = client.login(email, password) + return login + except Exception as e: + return {"results": str(e)} + + def user_info_test(self, client): + try: + return client.user() + except Exception as e: + return {"results": str(e)} + + def change_password_test(self, client): + try: + return client.change_password("password123", "new_password") + except Exception as e: + return {"results": str(e)} + + # def reset_password_test(self, client): + # try: + # reset_request = client.request_password_reset("test@example.com") + # # In a real scenario, we'd need to get the reset token from the email + # reset_token = "mock_reset_token" + # return client.confirm_password_reset(reset_token, "new_password") + # except Exception as e: + # return {"results": str(e)} + + def update_profile_test(self, client): + try: + return client.update_user(name="John Doe", bio="R2R enthusiast") + except Exception as e: + return {"results": str(e)} + + def delete_user_test(self, client): + try: + email = f"test_{self.user_id_string_2}@example.com" + password = "password123" + user = client.register(email, password) + + return client.delete_user(user["results"]["id"], "password123") + except Exception as e: + return {"results": str(e)} + + def refresh_token_test(self, client): + try: + return client.refresh_access_token() + except Exception as e: + return {"results": str(e)} + + def superuser_test(self, client): + try: + # Login as admin + client.login("admin@example.com", "change_me_immediately") + return client.users_overview() + except Exception as e: + return {"results": str(e)} + + def logout_test(self, client): + try: + return client.logout() + except Exception as e: + return {"results": str(e)} diff --git a/tests/regression/test_data/admin_document_group1.txt b/tests/regression/test_data/admin_document_group1.txt new file mode 100644 index 000000000..4c2f5aba5 --- /dev/null +++ b/tests/regression/test_data/admin_document_group1.txt @@ -0,0 +1 @@ +admin_document_group1 diff --git a/tests/regression/test_data/admin_document_user1.txt b/tests/regression/test_data/admin_document_user1.txt new file mode 100644 index 000000000..2010bbe57 --- /dev/null +++ b/tests/regression/test_data/admin_document_user1.txt @@ -0,0 +1 @@ +admin_document_user1 diff --git a/tests/regression/test_data/test_document.txt b/tests/regression/test_data/test_document.txt new file mode 100644 index 000000000..402428f6c --- /dev/null +++ b/tests/regression/test_data/test_document.txt @@ -0,0 +1 @@ +this is a test document diff --git a/tests/regression/test_data/user1_document.txt b/tests/regression/test_data/user1_document.txt new file mode 100644 index 000000000..2eb90e11e --- /dev/null +++ b/tests/regression/test_data/user1_document.txt @@ -0,0 +1 @@ +user1_document diff --git a/tests/regression/test_data/user1_document_group.txt b/tests/regression/test_data/user1_document_group.txt new file mode 100644 index 000000000..1c6e16b61 --- /dev/null +++ b/tests/regression/test_data/user1_document_group.txt @@ -0,0 +1 @@ +user1_document_group diff --git a/tests/regression/test_data/user2_document.txt b/tests/regression/test_data/user2_document.txt new file mode 100644 index 000000000..79b842e10 --- /dev/null +++ b/tests/regression/test_data/user2_document.txt @@ -0,0 +1 @@ +user2_document diff --git a/tests/test_abstractions.py b/tests/test_abstractions.py index 9eeed69a6..72dac6964 100644 --- a/tests/test_abstractions.py +++ b/tests/test_abstractions.py @@ -10,7 +10,6 @@ Prompt, Vector, VectorEntry, - VectorSearchRequest, VectorSearchResult, VectorType, generate_id_from_label, @@ -100,59 +99,11 @@ def test_prompt_invalid_input_type(): prompt.format_prompt({"name": "Alice"}) -def test_search_request_with_optional_filters(): - request = VectorSearchRequest( - query="test", limit=10, filters={"category": "books"} - ) - assert request.query == "test" - assert request.limit == 10 - assert request.filters == {"category": "books"} - - -def test_search_result_to_string(): - result = VectorSearchResult( - id=generate_id_from_label("1"), - score=9.5, - metadata={"author": "John Doe"}, - ) - result_str = str(result) - assert ( - result_str - == f"VectorSearchResult(id={str(generate_id_from_label('1'))}, score=9.5, metadata={{'author': 'John Doe'}})" - ) - - -def test_search_result_repr(): - result = VectorSearchResult( - id=generate_id_from_label("1"), - score=9.5, - metadata={"author": "John Doe"}, - ) - assert ( - repr(result) - == f"VectorSearchResult(id={str(generate_id_from_label('1'))}, score=9.5, metadata={{'author': 'John Doe'}})" - ) - - def test_vector_fixed_length_validation(): with pytest.raises(ValueError): Vector(data=[1.0, 2.0], type=VectorType.FIXED, length=3) -def test_vector_entry_serialization(): - vector = Vector(data=[1.0, 2.0], type=VectorType.FIXED, length=2) - entry_id = uuid.uuid4() - entry = VectorEntry( - id=entry_id, vector=vector, metadata={"key": uuid.uuid4()} - ) - serializable = entry.to_serializable() - assert serializable["id"] == str(entry_id) - assert serializable["vector"] == [1.0, 2.0] - assert isinstance( - serializable["metadata"]["key"], str - ) # Check UUID conversion to string - - def test_message_type_enum(): assert str(MessageType.SYSTEM) == "system" assert str(MessageType.USER) == "user" @@ -257,10 +208,15 @@ def test_completion_record_serialization_with_none_values(): def test_completion_record_with_complex_search_results(): - from r2r import VectorSearchResult - search_result = VectorSearchResult( - id=uuid.uuid4(), score=0.95, metadata={"key": "value"} + fragment_id=uuid.uuid4(), + extraction_id=uuid.uuid4(), + document_id=uuid.uuid4(), + user_id=uuid.uuid4(), + group_ids=[], + score=0.95, + text="Sample text", + metadata={"key": "value"}, ) aggregate_result = AggregateSearchResult( vector_search_results=[search_result] @@ -276,10 +232,12 @@ def test_completion_record_with_complex_search_results(): record_dict["search_results"]["vector_search_results"], list ) assert len(record_dict["search_results"]["vector_search_results"]) == 1 - assert ( - record_dict["search_results"]["vector_search_results"][0]["score"] - == 0.95 - ) - assert record_dict["search_results"]["vector_search_results"][0][ - "metadata" - ] == {"key": "value"} + result = record_dict["search_results"]["vector_search_results"][0] + assert result["score"] == 0.95 + assert result["metadata"] == {"key": "value"} + assert "fragment_id" in result + assert "extraction_id" in result + assert "document_id" in result + assert "user_id" in result + assert result["text"] == "Sample text" + assert result["group_ids"] == [] diff --git a/tests/test_auth.py b/tests/test_auth.py index 782530e0e..eaef1c923 100644 --- a/tests/test_auth.py +++ b/tests/test_auth.py @@ -12,7 +12,6 @@ PostgresDBProvider, R2RAuthProvider, R2RException, - UserCreate, ) from r2r.main.services import AuthService @@ -86,9 +85,9 @@ def auth_service(auth_provider, auth_config, pg_vector_db): @pytest.mark.asyncio async def test_create_user(auth_service, auth_provider): - # Register a new user - user = UserCreate(email="create@example.com", password="password123") - new_user = await auth_service.register(user) + new_user = await auth_service.register( + email="create@example.com", password="password123" + ) assert new_user.email == "create@example.com" assert not new_user.is_verified fetched_user = auth_provider.db_provider.relational.get_user_by_email( @@ -100,26 +99,17 @@ async def test_create_user(auth_service, auth_provider): assert fetched_user.is_active == new_user.is_active -# @pytest.mark.asyncio -# async def test_create_user_twice(auth_service, auth_provider): -# # Register a new user -# user = UserCreate(email="create@example.com", password="password123") -# new_user = await auth_service.register(user) -# with pytest.raises(R2RException) as exc_info: -# await auth_service.register(user) - - @pytest.mark.asyncio async def test_verify_user(auth_service, auth_provider): - # Register a new user - user = UserCreate(email="verify@example.com", password="password123") # Mock the generate_verification_code method to return a known value with patch.object( auth_provider.crypto_provider, "generate_verification_code", return_value="123456", ): - new_user = await auth_service.register(user) + new_user = await auth_service.register( + email="verify@example.com", password="password123" + ) # mock verification assert new_user.email == "verify@example.com" @@ -140,15 +130,14 @@ async def test_verify_user(auth_service, auth_provider): @pytest.mark.asyncio async def test_login_success(auth_service, auth_provider): # Register a new user - user = UserCreate( - email="login_test@example.com", password="correct_password" - ) with patch.object( auth_provider.crypto_provider, "generate_verification_code", return_value="123456", ): - new_user = await auth_service.register(user) + new_user = await auth_service.register( + email="login_test@example.com", password="correct_password" + ) # Verify the user auth_provider.verify_email("123456") @@ -167,15 +156,14 @@ async def test_login_success(auth_service, auth_provider): @pytest.mark.asyncio async def test_login_failure_wrong_password(auth_service, auth_provider): # Register a new user - user = UserCreate( - email="login_fail@example.com", password="correct_password" - ) with patch.object( auth_provider.crypto_provider, "generate_verification_code", return_value="123456", ): - new_user = await auth_service.register(user) + new_user = await auth_service.register( + email="login_fail@example.com", password="correct_password" + ) # Verify the user auth_provider.verify_email("123456") @@ -191,8 +179,9 @@ async def test_login_failure_wrong_password(auth_service, auth_provider): @pytest.mark.asyncio async def test_login_failure_unverified_user(auth_service, auth_provider): # Register a new user but don't verify - user = UserCreate(email="unverified@example.com", password="password123") - await auth_service.register(user) + await auth_service.register( + email="unverified@example.com", password="password123" + ) # Attempt login with correct password but unverified account with pytest.raises(R2RException) as exc_info: @@ -221,15 +210,14 @@ async def test_login_with_non_existent_user(auth_service): @pytest.mark.asyncio async def test_verify_email_with_expired_code(auth_service, auth_provider): - user = UserCreate( - email="verify_expired@example.com", password="password123" - ) with patch.object( auth_provider.crypto_provider, "generate_verification_code", return_value="123456", ): - new_user = await auth_service.register(user) + new_user = await auth_service.register( + email="verify_expired@example.com", password="password123" + ) # Get the verification code @@ -246,13 +234,14 @@ async def test_verify_email_with_expired_code(auth_service, auth_provider): @pytest.mark.asyncio async def test_refresh_token_flow(auth_service, auth_provider): # Register and verify a user - user = UserCreate(email="refresh@example.com", password="password123") with patch.object( auth_provider.crypto_provider, "generate_verification_code", return_value="123456", ): - new_user = await auth_service.register(user) + new_user = await auth_service.register( + email="refresh@example.com", password="password123" + ) await auth_service.verify_email("123456") @@ -271,22 +260,22 @@ async def test_refresh_token_flow(auth_service, auth_provider): @pytest.mark.asyncio async def test_refresh_token_with_wrong_user(auth_service, auth_provider): - # Register and verify two users - user1 = UserCreate(email="user1@example.com", password="password123") - user2 = UserCreate(email="user2@example.com", password="password123") - with patch.object( auth_provider.crypto_provider, "generate_verification_code", return_value="123456", ): - new_user1 = await auth_service.register(user1) + new_user1 = await auth_service.register( + email="user1@example.com", password="password123" + ) with patch.object( auth_provider.crypto_provider, "generate_verification_code", return_value="1234567", ): - new_user2 = await auth_service.register(user2) + new_user2 = await auth_service.register( + email="user2@example.com", password="password123" + ) await auth_service.verify_email("123456") await auth_service.verify_email("1234567") @@ -307,15 +296,14 @@ async def test_refresh_token_with_wrong_user(auth_service, auth_provider): async def test_get_current_user_with_expired_token( auth_service, auth_provider ): - user = UserCreate( - email="expired_token@example.com", password="password123" - ) with patch.object( auth_provider.crypto_provider, "generate_verification_code", return_value="123456", ): - new_user = await auth_service.register(user) + new_user = await auth_service.register( + email="expired_token@example.com", password="password123" + ) await auth_service.verify_email("123456") @@ -343,15 +331,14 @@ async def test_get_current_user_with_expired_token( @pytest.mark.asyncio async def test_change_password(auth_service, auth_provider): # Register and verify a user - user = UserCreate( - email="change_password@example.com", password="old_password" - ) with patch.object( auth_provider.crypto_provider, "generate_verification_code", return_value="123456", ): - new_user = await auth_service.register(user) + new_user = await auth_service.register( + email="change_password@example.com", password="old_password" + ) await auth_service.verify_email("123456") # Change password @@ -375,16 +362,14 @@ async def test_change_password(auth_service, auth_provider): async def test_reset_password_flow( auth_service, auth_provider, mock_email_provider ): - # Register and verify a user - user = UserCreate( - email="reset_password@example.com", password="old_password" - ) with patch.object( auth_provider.crypto_provider, "generate_verification_code", return_value="123456", ): - new_user = await auth_service.register(user) + new_user = await auth_service.register( + email="reset_password@example.com", password="old_password" + ) await auth_service.verify_email("123456") # Request password reset @@ -418,13 +403,14 @@ async def test_reset_password_flow( @pytest.mark.asyncio async def test_logout(auth_service, auth_provider): # Register and verify a user - user = UserCreate(email="logout@example.com", password="password123") with patch.object( auth_provider.crypto_provider, "generate_verification_code", return_value="123456", ): - new_user = await auth_service.register(user) + new_user = await auth_service.register( + email="logout@example.com", password="password123" + ) await auth_service.verify_email("123456") # Login to get tokens @@ -443,13 +429,14 @@ async def test_logout(auth_service, auth_provider): @pytest.mark.asyncio async def test_get_user_profile(auth_service, auth_provider): # Register and verify a user - user = UserCreate(email="profile@example.com", password="password123") with patch.object( auth_provider.crypto_provider, "generate_verification_code", return_value="123456", ): - new_user = await auth_service.register(user) + new_user = await auth_service.register( + email="profile@example.com", password="password123" + ) await auth_service.verify_email("123456") # Get user profile @@ -462,25 +449,22 @@ async def test_get_user_profile(auth_service, auth_provider): @pytest.mark.asyncio async def test_update_user_profile(auth_service, auth_provider): # Register and verify a user - user = UserCreate( - email="update_profile@example.com", password="password123" - ) with patch.object( auth_provider.crypto_provider, "generate_verification_code", return_value="123456", ): - new_user = await auth_service.register(user) + new_user = await auth_service.register( + email="update_profile@example.com", password="password123" + ) await auth_service.verify_email("123456") # Update user profile updated_profile = await auth_service.update_user( new_user.id, - { - "name": "John Doe", - "bio": "Test bio", - "profile_picture": "http://example.com/pic.jpg", - }, + name="John Doe", + bio="Test bio", + profile_picture="http://example.com/pic.jpg", ) assert updated_profile.name == "John Doe" assert updated_profile.bio == "Test bio" @@ -496,13 +480,14 @@ async def test_update_user_profile(auth_service, auth_provider): @pytest.mark.asyncio async def test_delete_user_account(auth_service, auth_provider): # Register and verify a user - user = UserCreate(email="delete_user@example.com", password="password123") with patch.object( auth_provider.crypto_provider, "generate_verification_code", return_value="123456", ): - new_user = await auth_service.register(user) + new_user = await auth_service.register( + email="delete_user@example.com", password="password123" + ) await auth_service.verify_email("123456") # Delete user account @@ -522,13 +507,14 @@ async def test_delete_user_account(auth_service, auth_provider): @pytest.mark.asyncio async def test_token_blacklist_cleanup(auth_service, auth_provider): # Register and verify a user - user = UserCreate(email="cleanup@example.com", password="password123") with patch.object( auth_provider.crypto_provider, "generate_verification_code", return_value="123456", ): - await auth_service.register(user) + await auth_service.register( + email="cleanup@example.com", password="password123" + ) await auth_service.verify_email("123456") # Login and logout to create a blacklisted token @@ -560,3 +546,161 @@ async def test_token_blacklist_cleanup(auth_service, auth_provider): assert auth_provider.db_provider.relational.is_token_blacklisted( access_token ) + + +@pytest.mark.asyncio +async def test_register_and_verify(auth_service, auth_provider): + # new_user = await auth_service.register(user) + # Mock verification code generation + with patch.object( + auth_provider.crypto_provider, + "generate_verification_code", + return_value="123456", + ): + new_user = await auth_service.register( + email="newuser@example.com", password="password123" + ) + assert new_user.email == "newuser@example.com" + assert not new_user.is_verified + + await auth_service.verify_email("123456") + + new_user = auth_provider.db_provider.relational.get_user_by_email( + "newuser@example.com" + ) + assert new_user.email == "newuser@example.com" + assert new_user.is_verified + + +@pytest.mark.asyncio +async def test_login_logout(auth_service, auth_provider): + # Mock reset token generation + with patch.object( + auth_provider.crypto_provider, + "generate_verification_code", + return_value="123456", + ): + await auth_service.register( + email="loginuser@example.com", password="password123" + ) + await auth_service.verify_email("123456") + + tokens = await auth_service.login("loginuser@example.com", "password123") + assert "access_token" in tokens + assert "refresh_token" in tokens + + logout_result = await auth_service.logout(tokens["access_token"].token) + assert logout_result["message"] == "Logged out successfully" + + +@pytest.mark.asyncio +async def test_refresh_token(auth_service, auth_provider): + # Mock reset token generation + with patch.object( + auth_provider.crypto_provider, + "generate_verification_code", + return_value="123456", + ): + await auth_service.register( + email="refreshuser@example.com", password="password123" + ) + await auth_service.verify_email("123456") + + tokens = await auth_service.login("refreshuser@example.com", "password123") + new_tokens = await auth_service.refresh_access_token( + "refreshuser@example.com", tokens["refresh_token"].token + ) + assert new_tokens["access_token"].token != tokens["access_token"].token + + +@pytest.mark.asyncio +async def test_change_password(auth_service, auth_provider): + with patch.object( + auth_provider.crypto_provider, + "generate_verification_code", + return_value="123456", + ): + new_user = await auth_service.register( + email="changepass@example.com", password="oldpassword" + ) + await auth_service.verify_email("123456") + + result = await auth_service.change_password( + new_user, "oldpassword", "newpassword" + ) + assert result["message"] == "Password changed successfully" + + with pytest.raises(R2RException): + await auth_service.login("changepass@example.com", "oldpassword") + + tokens = await auth_service.login("changepass@example.com", "newpassword") + assert "access_token" in tokens + + +@pytest.mark.asyncio +async def test_request_reset_password(auth_service): + await auth_service.register( + email="resetpass@example.com", password="password123" + ) + + result = await auth_service.request_password_reset("resetpass@example.com") + assert ( + result["message"] == "If the email exists, a reset link has been sent" + ) + + +@pytest.mark.asyncio +async def test_confirm_reset_password(auth_service, auth_provider): + # Mock reset token generation + with patch.object( + auth_provider.crypto_provider, + "generate_verification_code", + return_value="123456", + ): + await auth_service.register( + email="confirmreset@example.com", password="oldpassword" + ) + await auth_service.verify_email("123456") + await auth_service.request_password_reset("confirmreset@example.com") + result = await auth_service.confirm_password_reset( + "123456", "newpassword" + ) + assert result["message"] == "Password reset successfully" + + tokens = await auth_service.login( + "confirmreset@example.com", "newpassword" + ) + assert "access_token" in tokens + + +@pytest.mark.asyncio +async def test_get_user_profile(auth_service): + new_user = await auth_service.register( + email="profile@example.com", password="password123" + ) + + profile = await auth_service.get_user_profile(new_user.id) + assert profile.email == "profile@example.com" + + +@pytest.mark.asyncio +async def test_update_user_profile(auth_service): + new_user = await auth_service.register( + email="updateprofile@example.com", password="password123" + ) + + updated_user = await auth_service.update_user(new_user.id, name="John Doe") + assert updated_user.name == "John Doe" + + +@pytest.mark.asyncio +async def test_delete_user_account_2(auth_service): + new_user = await auth_service.register( + email="deleteuser@example.com", password="password123" + ) + + result = await auth_service.delete_user(new_user.id, "password123") + assert "deleted" in result["message"] + + with pytest.raises(R2RException): + await auth_service.login("deleteuser@example.com", "password123") diff --git a/tests/test_cli.py b/tests/test_cli.py index ab5ee478e..3466609a4 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -39,20 +39,27 @@ def test_delete_command(runner, mock_r2r_execution_wrapper): mock_instance = mock_r2r_execution_wrapper.return_value mock_instance.delete.return_value = "Deleted successfully" - result = runner.invoke( - cli, ["delete", "--keys", "key1", "--values", "value1"] - ) + result = runner.invoke(cli, ["delete", "--filter", "key1:eq:value1"]) assert result.exit_code == 0 assert "Deleted successfully" in result.output - mock_instance.delete.assert_called_once_with(["key1"], ["value1"]) + mock_instance.delete.assert_called_once_with( + filters={"key1": {"$eq": "value1"}} + ) -def test_delete_command_mismatched_keys_values(runner): +def test_multiple_deletes(runner, mock_r2r_execution_wrapper): + mock_instance = mock_r2r_execution_wrapper.return_value + mock_instance.delete.return_value = "Deleted successfully" + result = runner.invoke( - cli, ["delete", "--keys", "key1", "--values", "value1", "value2"] + cli, + ["delete", "--filter", "key1:eq:value1", "--filter", "key2:eq:value2"], + ) + assert result.exit_code == 0 + assert "Deleted successfully" in result.output + mock_instance.delete.assert_called_once_with( + filters={"key1": {"$eq": "value1"}, "key2": {"$eq": "value2"}} ) - assert result.exit_code != 0 - assert "Got unexpected extra argument" in result.output def test_documents_overview(runner, mock_r2r_execution_wrapper): @@ -75,9 +82,7 @@ def test_documents_overview(runner, mock_r2r_execution_wrapper): assert result.exit_code == 0 assert "Document 1" in result.output assert "Document 2" in result.output - mock_instance.documents_overview.assert_called_once_with( - ["id1", "id2"], None - ) + mock_instance.documents_overview.assert_called_once_with(["id1", "id2"]) def test_document_chunks(runner, mock_r2r_execution_wrapper): @@ -196,7 +201,7 @@ def test_logs(runner, mock_r2r_execution_wrapper): } ] - result = runner.invoke(cli, ["logs", "--log-type-filter", "error"]) + result = runner.invoke(cli, ["logs", "--run-type-filter", "error"]) assert result.exit_code == 0 assert "Run ID: test-run-id" in result.output assert "Run Type: test" in result.output diff --git a/tests/test_client.py b/tests/test_client.py index d41d3e623..40f029398 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -14,18 +14,17 @@ R2REngine, R2RException, Token, - User, - UserCreate, + UserResponse, ) oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") -def create_user(user_create: UserCreate): - return User( +def create_user(email: str, password: str): + return UserResponse( id=uuid.UUID("12345678-1234-5678-1234-567812345678"), - email=user_create.email, - hashed_password="hashed_" + user_create.password, + email=email, + hashed_password="hashed_" + password, is_active=True, is_superuser=False, is_verified=False, @@ -40,7 +39,7 @@ def create_user(user_create: UserCreate): @pytest.fixture(scope="function") def mock_auth_wrapper(): def auth_wrapper(token: str = Depends(oauth2_scheme)): - return User( + return UserResponse( id=uuid.UUID("12345678-1234-5678-1234-567812345678"), email="test@example.com", is_active=True, @@ -60,13 +59,11 @@ def mock_db(): db.relational.create_user.side_effect = create_user db.relational.get_user_by_id.return_value = create_user( - UserCreate(email="test@example.com", password="password") + email="test@example.com", password="password" ) def update_user(user): - updated_user = create_user( - UserCreate(email=user.email, password="password") - ) + updated_user = create_user(email=user.email, password="password") updated_user.name = user.name updated_user.bio = user.bio updated_user.profile_picture = user.profile_picture @@ -81,10 +78,44 @@ async def mock_asearch(*args, **kwargs): return { "vector_search_results": [ { - "id": "doc1", - "metadata": {"text": "Sample search result"}, - "score": 0.95, - } + "fragment_id": "c68dc72e-fc23-5452-8f49-d7bd46088a96", + "extraction_id": "3f3d47f3-8baf-58eb-8bc2-0171fb1c6e09", + "document_id": "3e157b3a-8469-51db-90d9-52e7d896b49b", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "score": 0.23943702876567796, + "text": "Alternate Base Rate means, for any day, a rate per annum equal to the greatest of (i) the Prime Rate in effect on such day, (ii) the Federal Funds Effective Rate in effect on such day \nplus \u00bd of 1% and (iii) the sum of (a) the Adjusted LIBO Rate that would be payable onsuch day for a Eurodollar Borrowing with a one-month interest period", + "metadata": { + "title": "uber_2021.pdf", + "associatedQuery": "What is the capital of France?", + }, + }, + { + "fragment_id": "f0b40c99-e200-507b-a4b9-e931e0b5f321", + "extraction_id": "0348ae71-bccb-58d1-8b5f-36810e46245a", + "document_id": "3e157b3a-8469-51db-90d9-52e7d896b49b", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "score": 0.22033508121967305, + "text": "s, could also restrict our future access to the capital markets.ITEM 1B. UNRESOLVED STAFF\n COMMENTSNot applicable.\nITEM 2. PROPERTIES\nAs\n of December 31, 2021, we leased and owned office facilities around the world totaling 10.6 million square feet, including 2.6 million square feet for ourcorporate headquarte\nrs in the San Francisco Bay Area, California.We", + "metadata": { + "title": "uber_2021.pdf", + "associatedQuery": "What is the capital of France?", + }, + }, + { + "fragment_id": "967c4291-0629-55b6-9323-e2291de8730d", + "extraction_id": "7595cdf2-d1b0-5f13-b853-8ce6857ca5f5", + "document_id": "3e157b3a-8469-51db-90d9-52e7d896b49b", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "score": 0.21763332188129403, + "text": "RFR means, for any RFR Loan denominated in (a) British Pounds, SONIA and (b) Swiss Francs, SARON. \nRFR Borrowing means, as to any Borrowing, the RFR Loans comprising such Borrowing. \nRFR Business Day means, for any Loan denominated in (a) British Pounds, any day except for (i) a Saturday, (ii) a Sunday or (iii) a day on which banks are closed for general business in London and (b) Swiss Francs, any day except for (i) a Saturday, (ii) a Sunday or", + "metadata": { + "title": "uber_2021.pdf", + "associatedQuery": "What is the capital of France?", + }, + }, ] } @@ -134,7 +165,7 @@ def r2r_client(app_client): def test_health_check(r2r_client): response = r2r_client.health() - assert response == {"response": "ok"} + assert response["results"] == {"response": "ok"} def test_register_user(r2r_client, mock_db): @@ -147,31 +178,12 @@ def test_register_user(r2r_client, mock_db): mock_db.relational.create_user.assert_called_once() -# def test_register_existing_user(r2r_client, mock_db): -# user_data = {"email": "existing@example.com", "password": "testpassword"} - -# mock_db.relational.get_user_by_email.return_value = User( -# id=uuid.UUID("12345678-1234-5678-1234-567812345678"), -# email=user_data["email"], -# hashed_password="hashed_password", -# is_active=True, -# is_superuser=False, -# verification_code_expiry=None, -# ) - -# with pytest.raises(R2RException) as exc_info: -# r2r_client.register(**user_data) - -# assert exc_info.value.status_code == 400 -# assert "Email already registered" in str(exc_info.value) - - def test_login_user(r2r_client, mock_db): user_data = {"email": "login_test@example.com", "password": "testpassword"} mock_db.relational.get_user_by_email.return_value = None response = r2r_client.register(**user_data) - mock_db.relational.get_user_by_email.return_value = User( + mock_db.relational.get_user_by_email.return_value = UserResponse( id=uuid.UUID("12345678-1234-5678-1234-567812345678"), email=user_data["email"], hashed_password="hashed_" + user_data["password"], @@ -200,12 +212,15 @@ def test_authenticated_search(r2r_client, mock_db): results = search_response["results"] assert "vector_search_results" in results assert len(results["vector_search_results"]) > 0 - assert results["vector_search_results"][0]["id"] == "doc1" assert ( - results["vector_search_results"][0]["metadata"]["text"] - == "Sample search result" + results["vector_search_results"][0]["fragment_id"] + == "c68dc72e-fc23-5452-8f49-d7bd46088a96" ) - assert results["vector_search_results"][0]["score"] == 0.95 + assert ( + results["vector_search_results"][0]["text"] + == "Alternate Base Rate means, for any day, a rate per annum equal to the greatest of (i) the Prime Rate in effect on such day, (ii) the Federal Funds Effective Rate in effect on such day \nplus \u00bd of 1% and (iii) the sum of (a) the Adjusted LIBO Rate that would be payable onsuch day for a Eurodollar Borrowing with a one-month interest period" + ) + assert results["vector_search_results"][0]["score"] == 0.23943702876567796 @pytest.mark.asyncio @@ -290,29 +305,6 @@ async def test_user_profile(r2r_client, mock_db): # assert profile["results"]["email"] == "profile@example.com" # Update user profile - updated_profile = r2r_client.update_user( - {"name": "John Doe", "bio": "Test bio"} - ) + updated_profile = r2r_client.update_user(name="John Doe", bio="Test bio") assert updated_profile["results"]["name"] == "John Doe" assert updated_profile["results"]["bio"] == "Test bio" - - -# TODO - Fix this test -# @pytest.mark.asyncio -# async def test_delete_user(r2r_client, mock_db): -# # Register and login -# user_data = {"email": "delete@example.com", "password": "password123"} -# r2r_client.register(**user_data) -# r2r_client.login(**user_data) - -# # Delete account -# delete_response = r2r_client.delete_user("password123") -# assert "message" in delete_response["results"] - -# # Ensure client's tokens are cleared -# assert r2r_client.access_token is None -# assert r2r_client._refresh_token is None - -# # Try to login with deleted account (should fail) -# with pytest.raises(R2RException): -# r2r_client.login(**user_data) diff --git a/tests/test_database.py b/tests/test_database.py index 041352c54..b9662a6fe 100644 --- a/tests/test_database.py +++ b/tests/test_database.py @@ -1,4 +1,5 @@ import random +import uuid import pytest from dotenv import load_dotenv @@ -20,7 +21,14 @@ def generate_random_vector_entry(id: str, dimension: int) -> VectorEntry: vector = [random.random() for _ in range(dimension)] metadata = {"key": f"value_{id}"} return VectorEntry( - id=generate_id_from_label(id), vector=Vector(vector), metadata=metadata + fragment_id=generate_id_from_label(id), + extraction_id=uuid.uuid4(), + document_id=uuid.uuid4(), + user_id=uuid.uuid4(), + group_ids=[uuid.uuid4()], + vector=Vector(vector), + text=f"Sample text for {id}", + metadata=metadata, ) @@ -49,18 +57,6 @@ def pg_vector_db(): ) -@pytest.mark.parametrize("db_fixture", ["pg_vector_db"]) -def test_get_metadatas(request, db_fixture): - db = request.getfixturevalue(db_fixture) - for entry in sample_entries: - db.vector.upsert(entry) - - unique_metadatas = db.vector.get_metadatas(metadata_fields=["key"]) - unique_values = set([ele["key"] for ele in unique_metadatas]) - assert len(unique_values) == num_entries - assert all(f"value_id_{i}" in unique_values for i in range(num_entries)) - - @pytest.mark.parametrize("db_fixture", ["pg_vector_db"]) def test_db_initialization(request, db_fixture): db = request.getfixturevalue(db_fixture) @@ -73,7 +69,7 @@ def test_db_copy_and_search(request, db_fixture): db.vector.upsert(sample_entries[0]) results = db.vector.search(query_vector=sample_entries[0].vector.data) assert len(results) == 1 - assert results[0].id == sample_entries[0].id + assert results[0].fragment_id == sample_entries[0].fragment_id assert results[0].score == pytest.approx(1.0, rel=1e-3) @@ -83,7 +79,7 @@ def test_db_upsert_and_search(request, db_fixture): db.vector.upsert(sample_entries[0]) results = db.vector.search(query_vector=sample_entries[0].vector.data) assert len(results) == 1 - assert results[0].id == sample_entries[0].id + assert results[0].fragment_id == sample_entries[0].fragment_id assert results[0].score == pytest.approx(1.0, rel=1e-3) @@ -94,7 +90,7 @@ def test_imperfect_match(request, db_fixture): query_vector = [val + 0.1 for val in sample_entries[0].vector.data] results = db.vector.search(query_vector=query_vector) assert len(results) == 1 - assert results[0].id == sample_entries[0].id + assert results[0].fragment_id == sample_entries[0].fragment_id assert results[0].score < 1.0 @@ -107,7 +103,7 @@ def test_bulk_insert_and_search(request, db_fixture): query_vector = sample_entries[0].vector.data results = db.vector.search(query_vector=query_vector, limit=5) assert len(results) == 5 - assert results[0].id == sample_entries[0].id + assert results[0].fragment_id == sample_entries[0].fragment_id assert results[0].score == pytest.approx(1.0, rel=1e-3) @@ -123,20 +119,18 @@ def test_search_with_filters(request, db_fixture): query_vector=query_vector, filters={"key": filtered_id} ) assert len(results) == 1 - assert results[0].id == sample_entries[0].id + assert results[0].fragment_id == sample_entries[0].fragment_id assert results[0].metadata["key"] == filtered_id @pytest.mark.parametrize("db_fixture", ["pg_vector_db"]) -def test_delete_by_metadata(request, db_fixture): +def test_delete(request, db_fixture): db = request.getfixturevalue(db_fixture) for entry in sample_entries: db.vector.upsert(entry) key_to_delete = sample_entries[0].metadata["key"] - db.vector.delete_by_metadata( - metadata_fields=["key"], metadata_values=[key_to_delete] - ) + db.vector.delete(filters={"key": {"$eq": key_to_delete}}) results = db.vector.search(query_vector=sample_entries[0].vector.data) assert all(result.metadata["key"] != key_to_delete for result in results) @@ -147,13 +141,19 @@ def test_upsert(request, db_fixture): db = request.getfixturevalue(db_fixture) db.vector.upsert(sample_entries[0]) modified_entry = VectorEntry( - id=sample_entries[0].id, + fragment_id=sample_entries[0].fragment_id, + extraction_id=sample_entries[0].extraction_id, + document_id=sample_entries[0].document_id, + user_id=sample_entries[0].user_id, + group_ids=sample_entries[0].group_ids, vector=Vector([0.5, 0.5, 0.5]), + text="Modified text", metadata={"key": "new_value"}, ) db.vector.upsert(modified_entry) results = db.vector.search(query_vector=[0.5, 0.5, 0.5]) assert len(results) == 1 - assert results[0].id == sample_entries[0].id + assert results[0].fragment_id == sample_entries[0].fragment_id assert results[0].metadata["key"] == "new_value" + assert results[0].text == "Modified text" diff --git a/tests/test_end_to_end.py b/tests/test_end_to_end.py index e46d64a6f..4aa0e8615 100644 --- a/tests/test_end_to_end.py +++ b/tests/test_end_to_end.py @@ -7,13 +7,17 @@ from r2r import ( Document, + DocumentInfo, + DocumentStatus, + DocumentType, GenerationConfig, - KVLoggingSingleton, R2RConfig, R2REngine, R2RPipeFactory, R2RPipelineFactory, R2RProviderFactory, + RunLoggingSingleton, + UserResponse, VectorSearchSettings, generate_id_from_label, ) @@ -55,9 +59,12 @@ def app(request): ) try: - KVLoggingSingleton.configure(config.logging) + if os.path.exists(config.logging.logging_path): + os.remove(config.logging.logging_path) + + RunLoggingSingleton.configure(config.logging) except: - KVLoggingSingleton._config.logging_path = ( + RunLoggingSingleton._config.logging_path = ( config.logging.logging_path ) @@ -69,27 +76,51 @@ def app(request): @pytest.fixture def logging_connection(): - return KVLoggingSingleton() + return RunLoggingSingleton() + + +@pytest.fixture +def user(): + return UserResponse( + id=generate_id_from_label("user"), + email="test@test.com", + hashed_password="test", + ) @pytest.mark.parametrize("app", ["postgres"], indirect=True) @pytest.mark.asyncio async def test_ingest_txt_document(app, logging_connection): + user_id = uuid.uuid4() + group_id = uuid.uuid4() + doc_id = uuid.uuid4() await app.aingest_documents( [ Document( - id=generate_id_from_label("doc_1"), + id=doc_id, + group_ids=[group_id], + user_id=user_id, data="The quick brown fox jumps over the lazy dog.", - type="txt", + type=DocumentType.TXT, metadata={"author": "John Doe"}, ), ] ) + # Verify the document was ingested correctly + docs_overview = await app.adocuments_overview(document_ids=[doc_id]) + assert len(docs_overview) == 1 + assert docs_overview[0].id == doc_id + assert docs_overview[0].group_ids == [group_id] + assert docs_overview[0].user_id == user_id + assert docs_overview[0].type == DocumentType.TXT + assert docs_overview[0].metadata["author"] == "John Doe" + assert docs_overview[0].status == DocumentStatus.SUCCESS + @pytest.mark.parametrize("app", ["postgres"], indirect=True) @pytest.mark.asyncio -async def test_ingest_txt_file(app, logging_connection): +async def test_ingest_txt_file(app, user): # Prepare the test data metadata = {"author": "John Doe"} files = [ @@ -113,13 +144,16 @@ async def test_ingest_txt_file(app, logging_connection): file.file.seek(0, 2) # Move to the end of the file file.size = file.file.tell() # Get the file size file.file.seek(0) # Move back to the start of the file - - await app.aingest_files(metadatas=[metadata], files=files) + await app.aingest_files(metadatas=[metadata], files=files, user=user) @pytest.mark.parametrize("app", ["postgres"], indirect=True) @pytest.mark.asyncio -async def test_ingest_search_txt_file(app, logging_connection): +async def test_ingest_search_txt_file(app, user, logging_connection): + + # Convert metadata to JSON string + run_info = await logging_connection.get_info_logs(run_type_filter="search") + # Prepare the test data metadata = {} files = [ @@ -146,14 +180,20 @@ async def test_ingest_search_txt_file(app, logging_connection): file.file.seek(0) # Move back to the start of the file # Convert metadata to JSON string + run_info = await logging_connection.get_info_logs(run_type_filter="search") + + ingestion_result = await app.aingest_files( + files=files, user=user, metadatas=[metadata] + ) - await app.aingest_files(metadatas=[metadata], files=files) + run_info = await logging_connection.get_info_logs(run_type_filter="search") search_results = await app.asearch("who was aristotle?") + print("search results = ", search_results["vector_search_results"][0]) assert len(search_results["vector_search_results"]) == 10 assert ( "was an Ancient Greek philosopher and polymath" - in search_results["vector_search_results"][0]["metadata"]["text"] + in search_results["vector_search_results"][0]["text"] ) search_results = await app.asearch( @@ -163,17 +203,8 @@ async def test_ingest_search_txt_file(app, logging_connection): assert len(search_results["vector_search_results"]) == 20 assert ( "was an Ancient Greek philosopher and polymath" - in search_results["vector_search_results"][0]["metadata"]["text"] - ) - run_info = await logging_connection.get_run_info(log_type_filter="search") - - assert len(run_info) == 2, f"Expected 2 runs, but got {len(run_info)}" - - logs = await logging_connection.get_logs( - [run.run_id for run in run_info], 100 + in search_results["vector_search_results"][0]["text"] ) - assert len(logs) == 6, f"Expected 6 logs, but got {len(logs)}" - ## test stream response = await app.arag( query="Who was aristotle?", @@ -191,6 +222,42 @@ async def test_ingest_search_txt_file(app, logging_connection): assert "Ancient" in collector +@pytest.mark.parametrize("app", ["postgres"], indirect=True) +@pytest.mark.asyncio +async def test_double_ingest(app, logging_connection): + await app.aingest_documents( + [ + Document( + id=generate_id_from_label("doc_1"), + group_ids=[generate_id_from_label("group_1")], + user_id=generate_id_from_label("user_id"), + data="The quick brown fox jumps over the lazy dog.", + type=DocumentType.TXT, + metadata={"author": "John Doe"}, + ), + ] + ) + search_results = await app.asearch("who was aristotle?") + + assert len(search_results["vector_search_results"]) == 1 + with pytest.raises(Exception): + try: + await app.aingest_documents( + [ + Document( + id=generate_id_from_label("doc_1"), + group_ids=[generate_id_from_label("group_1")], + user_id=generate_id_from_label("user_id"), + data="The quick brown fox jumps over the lazy dog.", + type=DocumentType.TXT, + metadata={"author": "John Doe"}, + ), + ] + ) + except asyncio.CancelledError: + pass + + @pytest.mark.parametrize("app", ["postgres"], indirect=True) @pytest.mark.asyncio async def test_ingest_search_then_delete(app, logging_connection): @@ -199,6 +266,8 @@ async def test_ingest_search_then_delete(app, logging_connection): [ Document( id=generate_id_from_label("doc_1"), + group_ids=[generate_id_from_label("group_1")], + user_id=generate_id_from_label("user_1"), data="The quick brown fox jumps over the lazy dog.", type="txt", metadata={"author": "John Doe"}, @@ -214,18 +283,17 @@ async def test_ingest_search_then_delete(app, logging_connection): len(search_results["vector_search_results"]) > 0 ), "Expected search results, but got none" assert ( - search_results["vector_search_results"][0]["metadata"]["text"] + search_results["vector_search_results"][0]["text"] == "The quick brown fox jumps over the lazy dog." ) # Delete the document - delete_result = await app.adelete(["author"], ["John Doe"]) + delete_result = await app.adelete(filters={"author": {"$eq": "John Doe"}}) # Verify the deletion was successful - expected_deletion_message = "deleted successfully" assert ( - expected_deletion_message in delete_result - ), f"Expected successful deletion message, but got {delete_result}" + len(delete_result) > 0 + ), f"Expected at least one document to be deleted, but got {delete_result}" # Search for the document again search_results_2 = await app.asearch("who was aristotle?") @@ -233,27 +301,34 @@ async def test_ingest_search_then_delete(app, logging_connection): # Verify that the search results are empty assert ( len(search_results_2["vector_search_results"]) == 0 - ), f"Expected no search results, but got {search_results_2['results']}" + ), f"Expected no search results, but got {search_results_2['vector_search_results']}" -@pytest.mark.parametrize("app", ["local", "postgres"], indirect=True) +@pytest.mark.parametrize("app", ["postgres"], indirect=True) @pytest.mark.asyncio async def test_ingest_user_documents(app, logging_connection): user_id_0 = generate_id_from_label("user_0") user_id_1 = generate_id_from_label("user_1") + doc_id_0 = generate_id_from_label("doc_01") + doc_id_1 = generate_id_from_label("doc_11") + await app.aingest_documents( [ Document( - id=generate_id_from_label("doc_01"), + id=doc_id_0, + group_ids=[generate_id_from_label("group_0")], + user_id=user_id_0, data="The quick brown fox jumps over the lazy dog.", type="txt", - metadata={"author": "John Doe", "user_id": user_id_0}, + metadata={"author": "John Doe"}, ), Document( - id=generate_id_from_label("doc_11"), + id=doc_id_1, + group_ids=[generate_id_from_label("group_1")], + user_id=user_id_1, data="The lazy dog jumps over the quick brown fox.", type="txt", - metadata={"author": "John Doe", "user_id": user_id_1}, + metadata={"author": "John Doe"}, ), ] ) @@ -271,21 +346,33 @@ async def test_ingest_user_documents(app, logging_connection): assert ( len(user_1_docs) == 1 ), f"Expected 1 document for user {user_id_1}, but got {len(user_1_docs)}" - assert user_0_docs[0].document_id == generate_id_from_label( - "doc_01" - ), f"Expected document id {str(generate_id_from_label('doc_0'))} for user {user_id_0}, but got {user_0_docs[0].document_id}" - assert user_1_docs[0].document_id == generate_id_from_label( - "doc_11" - ), f"Expected document id {str(generate_id_from_label('doc_1'))} for user {user_id_1}, but got {user_1_docs[0].document_id}" + assert ( + user_0_docs[0].id == doc_id_0 + ), f"Expected document id {doc_id_0} for user {user_id_0}, but got {user_0_docs[0].id}" + assert ( + user_1_docs[0].id == doc_id_1 + ), f"Expected document id {doc_id_1} for user {user_id_1}, but got {user_1_docs[0].id}" + + # Clean up + delete_result = await app.adelete( + filters={"document_id": {"$in": [doc_id_0, doc_id_1]}} + ) + + assert ( + len(delete_result) == 2 + ), f"Expected 2 chunks to be deleted, but got {len(delete_result)}" @pytest.mark.parametrize("app", ["postgres"], indirect=True) @pytest.mark.asyncio async def test_delete_by_id(app, logging_connection): + doc_id = generate_id_from_label("doc_0") await app.aingest_documents( [ Document( - id=generate_id_from_label("doc_1"), + id=doc_id, + group_ids=[], + user_id=generate_id_from_label("user_0"), data="The quick brown fox jumps over the lazy dog.", type="txt", metadata={"author": "John Doe"}, @@ -295,312 +382,9 @@ async def test_delete_by_id(app, logging_connection): search_results = await app.asearch("who was aristotle?") assert len(search_results["vector_search_results"]) > 0 - await app.adelete(["document_id"], [str(generate_id_from_label("doc_1"))]) + delete_result = await app.adelete(filters={"document_id": {"$eq": doc_id}}) + assert ( + len(delete_result) > 0 + ), f"Expected at least one document to be deleted, but got {delete_result}" search_results = await app.asearch("who was aristotle?") assert len(search_results["vector_search_results"]) == 0 - - -@pytest.mark.parametrize("app", ["postgres"], indirect=True) -@pytest.mark.asyncio -async def test_double_ingest(app, logging_connection): - await app.aingest_documents( - [ - Document( - id=generate_id_from_label("doc_1"), - data="The quick brown fox jumps over the lazy dog.", - type="txt", - metadata={"author": "John Doe"}, - ), - ] - ) - search_results = await app.asearch("who was aristotle?") - - assert len(search_results["vector_search_results"]) == 1 - with pytest.raises(Exception): - try: - await app.aingest_documents( - [ - Document( - id=generate_id_from_label("doc_1"), - data="The quick brown fox jumps over the lazy dog.", - type="txt", - metadata={"author": "John Doe"}, - ), - ] - ) - except asyncio.CancelledError: - pass - - -@pytest.mark.parametrize("app", ["pgvector"], indirect=True) -@pytest.mark.asyncio -async def test_ingest_txt_file(app, logging_connection): - try: - # Prepare the test data - metadata = {"author": "John Doe"} - files = [ - UploadFile( - filename="test.txt", - file=open( - os.path.join( - os.path.dirname(__file__), - "..", - "r2r", - "examples", - "data", - "test.txt", - ), - "rb", - ), - ) - ] - # Set file size manually - for file in files: - file.file.seek(0, 2) # Move to the end of the file - file.size = file.file.tell() # Get the file size - file.file.seek(0) # Move back to the start of the file - - await app.aingest_files(metadatas=[metadata], files=files) - except asyncio.CancelledError: - pass - - -@pytest.mark.parametrize("app", ["pgvector"], indirect=True) -@pytest.mark.asyncio -async def test_ingest_search_txt_file(app, logging_connection): - try: - # Prepare the test data - metadata = {} - files = [ - UploadFile( - filename="aristotle.txt", - file=open( - os.path.join( - os.path.dirname(__file__), - "..", - "r2r", - "examples", - "data", - "aristotle.txt", - ), - "rb", - ), - ), - ] - - # Set file size manually - for file in files: - file.file.seek(0, 2) # Move to the end of the file - file.size = file.file.tell() # Get the file size - file.file.seek(0) # Move back to the start of the file - - result = await app.aingest_files(metadatas=[metadata], files=files) - print(result) - - search_results = await app.asearch("who was aristotle?") - print("search_results = ", search_results) - assert len(search_results["vector_search_results"]) == 10 - assert ( - "was an Ancient Greek philosopher and polymath" - in search_results["vector_search_results"][0]["metadata"]["text"] - ) - - search_results = await app.asearch( - "who was aristotle?", - vector_search_settings=VectorSearchSettings(search_limit=20), - ) - assert len(search_results["vector_search_results"]) == 20 - assert ( - "was an Ancient Greek philosopher and polymath" - in search_results["vector_search_results"][0]["metadata"]["text"] - ) - run_info = await logging_connection.get_run_info( - log_type_filter="search" - ) - - assert len(run_info) == 2, f"Expected 2 runs, but got {len(run_info)}" - - logs = await logging_connection.get_logs( - [run.run_id for run in run_info], 100 - ) - assert len(logs) == 6, f"Expected 6 logs, but got {len(logs)}" - - ## test stream - response = await app.arag( - query="Who was aristotle?", - rag_generation_config=GenerationConfig( - **{"model": "gpt-3.5-turbo", "stream": True} - ), - ) - collector = "" - async for chunk in response: - collector += chunk - assert "Aristotle" in collector - assert "Greek" in collector - assert "philosopher" in collector - assert "polymath" in collector - assert "Ancient" in collector - except asyncio.CancelledError: - pass - - -@pytest.mark.parametrize("app", ["pgvector"], indirect=True) -@pytest.mark.asyncio -async def test_ingest_search_then_delete(app, logging_connection): - try: - # Ingest a document - await app.aingest_documents( - [ - Document( - id=generate_id_from_label("doc_1"), - data="The quick brown fox jumps over the lazy dog.", - type="txt", - metadata={"author": "John Doe"}, - ), - ] - ) - - # Search for the document - search_results = await app.asearch("who was aristotle?") - - # Verify that the search results are not empty - assert ( - len(search_results["vector_search_results"]) > 0 - ), "Expected search results, but got none" - assert ( - search_results["vector_search_results"][0]["metadata"]["text"] - == "The quick brown fox jumps over the lazy dog." - ) - - # Delete the document - delete_result = await app.adelete(["author"], ["John Doe"]) - - # Verify the deletion was successful - expected_deletion_message = "deleted successfully" - assert ( - expected_deletion_message in delete_result - ), f"Expected successful deletion message, but got {delete_result}" - - # Search for the document again - search_results_2 = await app.asearch("who was aristotle?") - - # Verify that the search results are empty - assert ( - len(search_results_2["vector_search_results"]) == 0 - ), f"Expected no search results, but got {search_results_2['results']}" - except asyncio.CancelledError: - pass - - -@pytest.mark.parametrize("app", ["local", "pgvector"], indirect=True) -@pytest.mark.asyncio -async def test_ingest_user_documents(app, logging_connection): - try: - user_id_0 = generate_id_from_label("user_0") - user_id_1 = generate_id_from_label("user_1") - - try: - await app.aingest_documents( - [ - Document( - id=generate_id_from_label("doc_01"), - data="The quick brown fox jumps over the lazy dog.", - type="txt", - metadata={"author": "John Doe", "user_id": user_id_0}, - ), - Document( - id=generate_id_from_label("doc_11"), - data="The lazy dog jumps over the quick brown fox.", - type="txt", - metadata={"author": "John Doe", "user_id": user_id_1}, - ), - ] - ) - user_id_results = await app.ausers_overview([user_id_0, user_id_1]) - assert set([stats.user_id for stats in user_id_results]) == set( - [user_id_0, user_id_1] - ), f"Expected user ids {user_id_0} and {user_id_1}, but got {user_id_results}" - - user_0_docs = await app.adocuments_overview(user_ids=[user_id_0]) - user_1_docs = await app.adocuments_overview(user_ids=[user_id_1]) - - assert ( - len(user_0_docs) == 1 - ), f"Expected 1 document for user {user_id_0}, but got {len(user_0_docs)}" - assert ( - len(user_1_docs) == 1 - ), f"Expected 1 document for user {user_id_1}, but got {len(user_1_docs)}" - assert user_0_docs[0].document_id == generate_id_from_label( - "doc_01" - ), f"Expected document id {str(generate_id_from_label('doc_0'))} for user {user_id_0}, but got {user_0_docs[0].document_id}" - assert user_1_docs[0].document_id == generate_id_from_label( - "doc_11" - ), f"Expected document id {str(generate_id_from_label('doc_1'))} for user {user_id_1}, but got {user_1_docs[0].document_id}" - finally: - await app.adelete( - ["document_id", "document_id"], - [ - str(generate_id_from_label("doc_01")), - str(generate_id_from_label("doc_11")), - ], - ) - except asyncio.CancelledError: - pass - - -@pytest.mark.parametrize("app", ["pgvector"], indirect=True) -@pytest.mark.asyncio -async def test_delete_by_id(app, logging_connection): - try: - await app.aingest_documents( - [ - Document( - id=generate_id_from_label("doc_1"), - data="The quick brown fox jumps over the lazy dog.", - type="txt", - metadata={"author": "John Doe"}, - ), - ] - ) - search_results = await app.asearch("who was aristotle?") - - assert len(search_results["vector_search_results"]) > 0 - await app.adelete( - ["document_id"], [str(generate_id_from_label("doc_1"))] - ) - search_results = await app.asearch("who was aristotle?") - assert len(search_results["vector_search_results"]) == 0 - except asyncio.CancelledError: - pass - - -@pytest.mark.parametrize("app", ["pgvector"], indirect=True) -@pytest.mark.asyncio -async def test_double_ingest(app, logging_connection): - try: - await app.aingest_documents( - [ - Document( - id=generate_id_from_label("doc_1"), - data="The quick brown fox jumps over the lazy dog.", - type="txt", - metadata={"author": "John Doe"}, - ), - ] - ) - search_results = await app.asearch("who was aristotle?") - - assert len(search_results["vector_search_results"]) == 1 - with pytest.raises(Exception): - await app.aingest_documents( - [ - Document( - id=generate_id_from_label("doc_1"), - data="The quick brown fox jumps over the lazy dog.", - type="txt", - metadata={"author": "John Doe"}, - ), - ] - ) - except asyncio.CancelledError: - pass diff --git a/tests/test_groups.py b/tests/test_groups.py new file mode 100644 index 000000000..c6eb6c8a2 --- /dev/null +++ b/tests/test_groups.py @@ -0,0 +1,415 @@ +import random +from datetime import datetime +from uuid import UUID + +import pytest + +from r2r import DatabaseConfig, R2RException +from r2r.base.abstractions import DocumentInfo, DocumentStatus, DocumentType +from r2r.providers import BCryptConfig, BCryptProvider, PostgresDBProvider + + +# Add this fixture to create test documents +@pytest.fixture +def test_documents(pg_db, test_group): + documents = [] + for i in range(5): + doc = DocumentInfo( + id=UUID(f"00000000-0000-0000-0000-{i:012d}"), + group_ids=[test_group.group_id], + user_id=UUID("00000000-0000-0000-0000-000000000000"), + type=DocumentType.PDF, + metadata={}, + title=f"Test Document {i}", + version="1.0", + size_in_bytes=1000, + status=DocumentStatus.PROCESSING, + ) + pg_db.relational.upsert_documents_overview([doc]) + documents.append(doc) + yield documents + # Clean up documents after the test + for doc in documents: + pg_db.relational.delete_from_documents_overview(doc.id) + + +# Fixture for PostgresDBProvider +@pytest.fixture(scope="function") +def pg_db(): + config = DatabaseConfig.create( + provider="postgres", + vecs_collection=f"test_collection_{random.randint(1, 1_000_000_000_000_000_000)}", + ) + crypto_provider = BCryptProvider(BCryptConfig()) + db = PostgresDBProvider( + config, dimension=3, crypto_provider=crypto_provider + ) + yield db + # Teardown + db.vx.delete_collection(db.collection_name) + + +# Improvement: Use a fixture for creating a test group +@pytest.fixture +def test_group(pg_db): + group = pg_db.relational.create_group( + "Test Group", "This is a test group." + ) + yield group + pg_db.relational.delete_group(group.group_id) + + +# Improvement: Use a fixture for creating a test user +@pytest.fixture +def test_user(pg_db): + + created_user = pg_db.relational.create_user( + email=f"test_{datetime.now().timestamp()}@example.com", + password="password", + ) + yield created_user + pg_db.relational.delete_user(created_user.id) + + +def test_create_group(pg_db): + group_name = "Test Group" + group_description = "This is a test group." + group = pg_db.relational.create_group( + name=group_name, description=group_description + ) + assert isinstance(group.group_id, UUID) + assert group.name == group_name + assert group.description == group_description + # Improvement: Check for created_at and updated_at fields + assert isinstance(group.created_at, datetime) + assert isinstance(group.updated_at, datetime) + + +def test_get_group(pg_db, test_group): + fetched_group = pg_db.relational.get_group(test_group.group_id) + assert fetched_group == test_group + + +def test_update_group(pg_db, test_group): + new_name = "Updated Group" + new_description = "This is an updated test group." + updated = pg_db.relational.update_group( + test_group.group_id, name=new_name, description=new_description + ) + assert updated + fetched_group = pg_db.relational.get_group(test_group.group_id) + assert fetched_group.name == new_name + assert fetched_group.description == new_description + # Improvement: Check that updated_at has changed + assert fetched_group.updated_at > test_group.updated_at + + +def test_delete_group(pg_db): + group = pg_db.relational.create_group( + "Temporary Group", "This group will be deleted" + ) + pg_db.relational.delete_group(group.group_id) + with pytest.raises(R2RException): + fetched_group = pg_db.relational.get_group(group.group_id) + + +def test_list_groups(pg_db, test_group): + # First, ensure we have at least two groups + second_group = pg_db.relational.create_group( + "Second Test Group", "This is another test group." + ) + + # Now test listing groups + groups = pg_db.relational.list_groups() + assert len(groups) >= 2 + assert any(group.group_id == test_group.group_id for group in groups) + assert any(group.group_id == second_group.group_id for group in groups) + + # Test pagination + first_page = pg_db.relational.list_groups(limit=1) + assert len(first_page) == 1 + second_page = pg_db.relational.list_groups(offset=1, limit=1) + assert len(second_page) == 1 + + # Ensure first and second pages are different + assert first_page[0].group_id != second_page[0].group_id + + # Test requesting more groups than exist + all_groups = pg_db.relational.list_groups(limit=1000) + assert len(all_groups) >= 2 + + # Clean up the second group + pg_db.relational.delete_group(second_group.group_id) + + +def test_add_user_to_group(pg_db, test_group, test_user): + added = pg_db.relational.add_user_to_group( + test_user.id, test_group.group_id + ) + user_groups = pg_db.relational.get_groups_for_user(test_user.id) + assert any(g.group_id == test_group.group_id for g in user_groups) + + test_group = pg_db.relational.create_group( + "Another Group", "Another test group" + ) + # # Improvement: Test adding the same user twice + pg_db.relational.add_user_to_group(test_user.id, test_group.group_id) + + +def test_remove_user_from_group(pg_db, test_group, test_user): + # TODO - modify this test to use a fixture for creating a test group + test_group_ = pg_db.relational.create_group( + "Another Group", "Another test group" + ) + + pg_db.relational.add_user_to_group(test_user.id, test_group_.group_id) + removed = pg_db.relational.remove_user_from_group( + test_user.id, test_group_.group_id + ) + user_groups = pg_db.relational.get_groups_for_user(test_user.id) + assert all(g.group_id != test_group_.group_id for g in user_groups) + # Improvement: Test removing a user that's not in the group + with pytest.raises(R2RException): + pg_db.relational.remove_user_from_group( + test_user.id, test_group_.group_id + ) + + +def test_get_users_in_group(pg_db, test_group, test_user): + pg_db.relational.add_user_to_group(test_user.id, test_group.group_id) + users_in_group = pg_db.relational.get_users_in_group(test_group.group_id) + assert any(u.id == test_user.id for u in users_in_group) + # Improvement: Test pagination + first_page = pg_db.relational.get_users_in_group( + test_group.group_id, limit=1 + ) + assert len(first_page) == 1 + + +def test_get_all_groups(pg_db, test_group): + # Create multiple groups + group1 = pg_db.relational.create_group("Group 1", "Description 1") + group2 = pg_db.relational.create_group("Group 2", "Description 2") + + all_groups = pg_db.relational.list_groups() + + assert len(all_groups) >= 3 # Including test_group + assert any(g.group_id == test_group.group_id for g in all_groups) + assert any(g.group_id == group1.group_id for g in all_groups) + assert any(g.group_id == group2.group_id for g in all_groups) + + +def test_get_groups_by_ids(pg_db): + group1 = pg_db.relational.create_group("Group 1", "Description 1") + group2 = pg_db.relational.create_group("Group 2", "Description 2") + + groups = pg_db.relational.get_groups_by_ids( + [group1.group_id, group2.group_id] + ) + + assert len(groups) == 2 + assert any(g.group_id == group1.group_id for g in groups) + assert any(g.group_id == group2.group_id for g in groups) + + +def test_get_group_count(pg_db, test_group): + initial_count = pg_db.relational.get_group_count() + + pg_db.relational.create_group("New Group", "New Description") + + new_count = pg_db.relational.get_group_count() + assert new_count == initial_count + 1 + + +def test_get_groups_overview(pg_db, test_group, test_user): + pg_db.relational.add_user_to_group(test_user.id, test_group.group_id) + + overview = pg_db.relational.get_groups_overview([test_group.group_id]) + + assert len(overview) == 1 + assert overview[0].group_id == test_group.group_id + assert overview[0].name == test_group.name + assert overview[0].description == test_group.description + assert overview[0].user_count == 1 + + +# Test for adding the same user twice (idempotency) +def test_add_user_to_group_idempotency(pg_db, test_group, test_user): + # Add user for the first time + added1 = pg_db.relational.add_user_to_group( + test_user.id, test_group.group_id + ) + assert added1 + + # Try to add the same user again + added2 = pg_db.relational.add_user_to_group( + test_user.id, test_group.group_id + ) + assert not added2 # Should return False as user is already in the group + + # Verify user is in the group only once + users_in_group = pg_db.relational.get_users_in_group(test_group.group_id) + assert len([u for u in users_in_group if u.id == test_user.id]) == 1 + + +# Test for removing a user that's not in the group +def test_remove_user_not_in_group(pg_db, test_group, test_user): + # Ensure user is not in the group + pg_db.relational.add_user_to_group(test_user.id, test_group.group_id) + pg_db.relational.remove_user_from_group(test_user.id, test_group.group_id) + + # Try to remove the user again + with pytest.raises(R2RException): + pg_db.relational.remove_user_from_group( + test_user.id, test_group.group_id + ) + + +# Improvement: Add test for non-existent group and user +def test_edge_cases(pg_db): + non_existent_id = UUID("00000000-0000-0000-0000-000000000000") + # assert pg_db.relational.get_group(non_existent_id) is None + # ensure error + with pytest.raises(R2RException): + pg_db.relational.get_group(non_existent_id) + with pytest.raises(R2RException): + pg_db.relational.update_group( + non_existent_id, name="New Name", description="New Description" + ) + with pytest.raises(R2RException): + pg_db.relational.delete_group(non_existent_id) + with pytest.raises(R2RException): + pg_db.relational.add_user_to_group(non_existent_id, non_existent_id) + with pytest.raises(R2RException): + assert not pg_db.relational.remove_user_from_group( + non_existent_id, non_existent_id + ) + with pytest.raises(R2RException): + assert pg_db.relational.get_users_in_group(non_existent_id) == [] + + +def test_get_users_in_group_with_pagination(pg_db, test_group): + # Create multiple users and add them to the group + users = [] + for i in range(5): + user = pg_db.relational.create_user( + email=f"test_user_{i}@example.com", password="password" + ) + pg_db.relational.add_user_to_group(user.id, test_group.group_id) + users.append(user) + + # Test first page + first_page = pg_db.relational.get_users_in_group( + test_group.group_id, offset=0, limit=3 + ) + assert len(first_page) == 3 + + # Test second page + second_page = pg_db.relational.get_users_in_group( + test_group.group_id, offset=3, limit=3 + ) + assert len(second_page) == 2 + + # Ensure all users are different + all_users = first_page + second_page + assert len(set(u.id for u in all_users)) == 5 + + # Clean up + for user in users: + pg_db.relational.delete_user(user.id) + + +def test_get_groups_overview_with_pagination(pg_db): + # Create multiple groups + groups = [ + pg_db.relational.create_group(f"Group {i}", f"Description {i}") + for i in range(5) + ] + + # Test first page + first_page = pg_db.relational.get_groups_overview(offset=0, limit=3) + assert len(first_page) == 3 + + # Test second page + second_page = pg_db.relational.get_groups_overview(offset=3, limit=3) + assert len(second_page) == 2 + + # Ensure all groups are different + all_groups = first_page + second_page + assert len(set(g.group_id for g in all_groups)) == 5 + + # Clean up + for group in groups: + pg_db.relational.delete_group(group.group_id) + + +def test_get_groups_for_user_with_pagination(pg_db, test_user): + # Create multiple groups and add the user to them + groups = [] + for i in range(5): + group = pg_db.relational.create_group(f"Group {i}", f"Description {i}") + pg_db.relational.add_user_to_group(test_user.id, group.group_id) + groups.append(group) + + # Test first page + first_page = pg_db.relational.get_groups_for_user( + test_user.id, offset=0, limit=3 + ) + assert len(first_page) == 3 + + # Test second page + second_page = pg_db.relational.get_groups_for_user( + test_user.id, offset=3, limit=3 + ) + assert len(second_page) == 2 + + # Ensure all groups are different + all_groups = first_page + second_page + assert len(set(g.group_id for g in all_groups)) == 5 + + # Clean up + for group in groups: + pg_db.relational.delete_group(group.group_id) + + +def test_get_documents_in_group(pg_db, test_group, test_documents): + # Test getting all documents + all_docs = pg_db.relational.get_documents_in_group(test_group.group_id) + assert len(all_docs) == 5 + assert all(isinstance(doc, DocumentInfo) for doc in all_docs) + assert all(test_group.group_id in doc.group_ids for doc in all_docs) + + # Test pagination - first page + first_page = pg_db.relational.get_documents_in_group( + test_group.group_id, offset=0, limit=3 + ) + assert len(first_page) == 3 + + # Test pagination - second page + second_page = pg_db.relational.get_documents_in_group( + test_group.group_id, offset=3, limit=3 + ) + assert len(second_page) == 2 + + # Ensure all documents are different + all_docs = first_page + second_page + assert len(set(doc.id for doc in all_docs)) == 5 + + # Test ordering (should be in descending order of created_at) + assert all( + all_docs[i].created_at >= all_docs[i + 1].created_at + for i in range(len(all_docs) - 1) + ) + + # Test with non-existent group + non_existent_id = UUID("00000000-0000-0000-0000-000000000000") + with pytest.raises(R2RException): + pg_db.relational.get_documents_in_group(non_existent_id) + + # Test with empty group + empty_group = pg_db.relational.create_group("Empty Group", "No documents") + empty_docs = pg_db.relational.get_documents_in_group(empty_group.group_id) + assert len(empty_docs) == 0 + + # Clean up + pg_db.relational.delete_group(empty_group.group_id) diff --git a/tests/test_groups_client.py b/tests/test_groups_client.py new file mode 100644 index 000000000..a9319b9cd --- /dev/null +++ b/tests/test_groups_client.py @@ -0,0 +1,376 @@ +import uuid +from datetime import datetime +from unittest.mock import MagicMock + +import pytest +from fastapi import Depends +from fastapi.security import OAuth2PasswordBearer +from fastapi.testclient import TestClient + +from r2r import R2RApp, R2RBuilder, R2RClient, R2REngine, Token, UserResponse +from r2r.base import GroupResponse + +oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") + + +def create_superuser(email: str, password: str): + return UserResponse( + id=uuid.UUID("12345678-1234-5678-1234-567812345678"), + email=email, + hashed_password="hashed_" + password, + is_active=True, + is_superuser=True, + is_verified=True, + name="Test Superuser", + bio="Test Superuser Bio", + profile_picture="http://example.com/superuser_pic.jpg", + created_at=datetime.utcnow(), + updated_at=datetime.utcnow(), + ) + + +@pytest.fixture(scope="function") +def mock_auth_wrapper(): + def auth_wrapper(token: str = Depends(oauth2_scheme)): + return UserResponse( + id=uuid.UUID("12345678-1234-5678-1234-567812345678"), + email="admin@example.com", + is_active=True, + hashed_password="xxx", + is_superuser=True, + ) + + return auth_wrapper + + +@pytest.fixture(scope="function") +def mock_db(): + db = MagicMock() + db.relational.get_user_by_email.return_value = ( + None # Simulate empty database + ) + db.relational.create_user.side_effect = create_superuser + db.relational.get_user_by_id.return_value = create_superuser( + email="admin@example.com", password="adminpassword" + ) + + def mock_update_user(user): + return UserResponse( + id=uuid.UUID("12345678-1234-5678-1234-567812345678"), + email=user.email, + hashed_password="hashed_password", + is_active=True, + is_superuser=True, + is_verified=True, + name=user.name, + bio=user.bio, + profile_picture=user.profile_picture, + created_at=datetime.utcnow(), + updated_at=datetime.utcnow(), + ) + + db.relational.update_user.side_effect = mock_update_user + + def mock_create_group(**kwargs): + return GroupResponse( + group_id=uuid.uuid4(), + name=kwargs.get("name", "Test Group"), + description=kwargs.get("description", "A test group"), + created_at=datetime.utcnow(), + updated_at=datetime.utcnow(), + ).dict() + + db.relational.create_group = MagicMock(side_effect=mock_create_group) + + def mock_get_group(group_id): + return GroupResponse( + group_id=group_id, + name="Test Group", + description="A test group", + created_at=datetime.utcnow(), + updated_at=datetime.utcnow(), + ).dict() + + db.relational.get_group = MagicMock(side_effect=mock_get_group) + + def mock_update_group(group_id, name, description): + return GroupResponse( + group_id=group_id, + name=name, + description=description, + created_at=datetime.utcnow(), + updated_at=datetime.utcnow(), + ).dict() + + db.relational.update_group = MagicMock(side_effect=mock_update_group) + + db.relational.delete_group = MagicMock(return_value=True) + + def mock_list_groups(offset=0, limit=100): + return [ + GroupResponse( + group_id=uuid.uuid4(), + name=f"Group {i}", + description=f"Description {i}", + created_at=datetime.utcnow(), + updated_at=datetime.utcnow(), + ).dict() + for i in range(1, 3) + ] + + db.relational.list_groups = MagicMock(side_effect=mock_list_groups) + + db.relational.add_user_to_group = MagicMock(return_value=True) + db.relational.remove_user_from_group = MagicMock(return_value=True) + db.relational.get_users_in_group = MagicMock( + return_value=[ + UserResponse( + id=uuid.UUID("12345678-1234-5678-1234-567812345678"), + email="test1@gmail.com", + hashed_password="hashed_password", + is_active=True, + is_superuser=True, + is_verified=True, + created_at=datetime.utcnow(), + updated_at=datetime.utcnow(), + ), + UserResponse( + id=uuid.UUID("12345678-1234-5678-1234-567812345678"), + email="test2@gmail.com", + hashed_password="hashed_password", + is_active=True, + is_superuser=True, + is_verified=True, + created_at=datetime.utcnow(), + updated_at=datetime.utcnow(), + ), + ] + ) + db.relational.get_groups_for_user = MagicMock(side_effect=mock_list_groups) + + def mock_groups_overview(group_ids): + return [ + { + "group_id": str(uuid.uuid4()), + "name": f"Group {i}", + "description": f"Description {i}", + "created_at": datetime.utcnow(), + "updated_at": datetime.utcnow(), + "user_count": i * 2, + "document_count": i * 2, + } + for i in range(1, 3) + ] + + db.relational.get_groups_overview = MagicMock( + side_effect=mock_groups_overview + ) + + return db + + +@pytest.fixture(scope="function") +def r2r_client(app_client): + return R2RClient(base_url="http://testserver", custom_client=app_client) + + +def authenticate_superuser(r2r_client, mock_db): + user_data = {"email": "admin@example.com", "password": "adminpassword"} + mock_db.relational.get_user_by_email.return_value = None + r2r_client.register(**user_data) + + # Create a superuser + superuser = UserResponse( + id=uuid.UUID("12345678-1234-5678-1234-567812345678"), + email=user_data["email"], + hashed_password="hashed_" + user_data["password"], + is_active=True, + is_superuser=True, + verification_code_expiry=None, + ) + + mock_db.relational.get_user_by_email.return_value = superuser + mock_db.relational.get_user_by_id.return_value = superuser + + # Login as superuser + response = r2r_client.login(**user_data) + assert "access_token" in response["results"] + + +@pytest.fixture(scope="function") +def app_client(mock_db, mock_auth_wrapper): + config = R2RBuilder._get_config("auth") + providers = MagicMock() + providers.auth.login.return_value = { + "access_token": Token(token="access_token", token_type="access"), + "refresh_token": Token(token="refresh_token", token_type="refresh"), + } + providers.auth.auth_wrapper = mock_auth_wrapper + providers.auth.register.side_effect = mock_db.relational.create_user + providers.auth.verify_email.return_value = { + "message": "Email verified successfully" + } + providers.auth.change_password.return_value = { + "message": "Password changed successfully" + } + providers.auth.request_password_reset.return_value = { + "message": "If the email exists, a reset link has been sent" + } + providers.auth.confirm_password_reset.return_value = { + "message": "Password reset successfully" + } + providers.auth.logout.return_value = {"message": "Logged out successfully"} + + providers.database = mock_db + pipelines = MagicMock() + agents = MagicMock() + engine = R2REngine( + config=config, + providers=providers, + pipelines=pipelines, + agents=agents, + ) + + async def mock_asearch(*args, **kwargs): + return { + "vector_search_results": [ + { + "id": "doc1", + "metadata": {"text": "Sample search result"}, + "score": 0.95, + } + ] + } + + engine.asearch = mock_asearch + app = R2RApp(engine) + return TestClient(app.app) + + +@pytest.fixture +def group_id(): + return uuid.uuid4() + + +@pytest.fixture +def user_id(): + return uuid.uuid4() + + +@pytest.mark.asyncio +async def test_user_profile(r2r_client, mock_db): + r2r_client.register(email="profile@example.com", password="password123") + r2r_client.login(email="profile@example.com", password="password123") + + updated_profile = r2r_client.update_user(name="John Doe", bio="Test bio") + assert updated_profile["results"]["name"] == "John Doe" + assert updated_profile["results"]["bio"] == "Test bio" + + +# TODO - Revive these tests later. +# def test_create_group(r2r_client, mock_db): +# authenticate_superuser(r2r_client, mock_db) +# group_data = {"name": "Test Group", "description": "A test group"} +# response = r2r_client.create_group(**group_data) +# assert "results" in response +# print('response = ', response) +# assert response["results"]["name"] == group_data["name"] +# assert response["results"]["description"] == group_data["description"] +# mock_db.relational.create_group.assert_called_once_with(**group_data) + + +@pytest.mark.asyncio +async def test_get_group(r2r_client, mock_db, group_id): + authenticate_superuser(r2r_client, mock_db) + response = r2r_client.get_group(group_id) + assert "results" in response + assert response["results"]["group_id"] == str(group_id) + assert response["results"]["name"] == "Test Group" + mock_db.relational.get_group.assert_called_once_with(group_id) + + +@pytest.mark.asyncio +async def test_update_group(r2r_client, mock_db, group_id): + authenticate_superuser(r2r_client, mock_db) + update_data = { + "name": "Test Group", + "description": "An updated test group", + } + # mock_db.relational.update_group.return_value = True + response = r2r_client.update_group(group_id, **update_data) + assert "results" in response + assert ( + response["results"]["description"] == "An updated test group" + ) # is True + mock_db.relational.update_group.assert_called_once_with( + *(group_id, "Test Group", "An updated test group") + ) + + +@pytest.mark.asyncio +async def test_list_groups(r2r_client, mock_db): + authenticate_superuser(r2r_client, mock_db) + # mock_db.relational.list_groups.return_value = mock_groups + response = r2r_client.list_groups() + assert "results" in response + assert len(response["results"]) == 2 + mock_db.relational.list_groups.assert_called_once_with(offset=0, limit=100) + + +@pytest.mark.asyncio +async def test_get_users_in_group(r2r_client, mock_db, group_id): + authenticate_superuser(r2r_client, mock_db) + response = r2r_client.get_users_in_group(group_id) + assert "results" in response + assert len(response["results"]) == 2 + mock_db.relational.get_users_in_group.assert_called_once_with( + group_id, 0, 100 + ) + + +@pytest.mark.asyncio +async def test_get_groups_for_user(r2r_client, mock_db, user_id): + authenticate_superuser(r2r_client, mock_db) + # mock_groups = [ + # {"id": str(uuid.uuid4()), "name": "Group 1"}, + # {"id": str(uuid.uuid4()), "name": "Group 2"}, + # ] + # mock_db.relational.get_groups_for_user.return_value = mock_groups + response = r2r_client.get_groups_for_user(user_id) + assert "results" in response + assert len(response["results"]) == 2 + # assert response["results"] == mock_groups + mock_db.relational.get_groups_for_user.assert_called_once_with(user_id) + + +@pytest.mark.asyncio +async def test_groups_overview(r2r_client, mock_db): + authenticate_superuser(r2r_client, mock_db) + # mock_overview = [ + # {"id": str(uuid.uuid4()), "name": "Group 1", "member_count": 5}, + # {"id": str(uuid.uuid4()), "name": "Group 2", "member_count": 3}, + # ] + # mock_db.relational.get_groups_overview.return_value = mock_overview + response = r2r_client.groups_overview() + assert "results" in response + assert len(response["results"]) == 2 + # assert response["results"] == mock_overview + mock_db.relational.get_groups_overview.assert_called_once_with(None) + + +@pytest.mark.asyncio +async def test_groups_overview_with_ids(r2r_client, mock_db): + authenticate_superuser(r2r_client, mock_db) + group_ids = [uuid.uuid4(), uuid.uuid4()] + # mock_overview = [ + # {"id": str(group_ids[0]), "name": "Group 1", "member_count": 5}, + # {"id": str(group_ids[1]), "name": "Group 2", "member_count": 3}, + # ] + # mock_db.relational.get_groups_overview.return_value = mock_overview + response = r2r_client.groups_overview(group_ids) + assert "results" in response + assert len(response["results"]) == 2 + # assert response["results"] == mock_overview + mock_db.relational.get_groups_overview.assert_called_once_with( + [str(gid) for gid in group_ids] + ) diff --git a/tests/test_ingestion_service.py b/tests/test_ingestion_service.py index c3dfc08be..e76973643 100644 --- a/tests/test_ingestion_service.py +++ b/tests/test_ingestion_service.py @@ -15,6 +15,7 @@ R2RDocumentProcessingError, R2RException, RunManager, + UserResponse, generate_id_from_label, ) from r2r.main import R2RPipelines, R2RProviders @@ -82,8 +83,10 @@ def ingestion_service(mock_vector_db, mock_embedding_model): async def test_ingest_single_document(ingestion_service, mock_vector_db): document = Document( id=generate_id_from_label("test_id"), - data="Test content", + group_ids=[], + user_id=generate_id_from_label("user_1"), type="txt", + data="Test content", metadata={}, ) @@ -96,9 +99,9 @@ async def test_ingest_single_document(ingestion_service, mock_vector_db): result = await ingestion_service.ingest_documents([document]) - assert result["processed_documents"] == [ - f"Document '{document.id}' processed successfully." - ] + assert result["processed_documents"][0].id == generate_id_from_label( + "test_id" + ) assert not result["failed_documents"] assert not result["skipped_documents"] @@ -107,18 +110,22 @@ async def test_ingest_single_document(ingestion_service, mock_vector_db): async def test_ingest_duplicate_document(ingestion_service, mock_vector_db): document = Document( id=generate_id_from_label("test_id"), - data="Test content", + group_ids=[], + user_id=generate_id_from_label("user_1"), type="txt", + data="Test content", metadata={}, ) mock_vector_db.relational.get_documents_overview.return_value = [ DocumentInfo( - document_id=document.id, + id=document.id, + group_ids=[], + user_id=generate_id_from_label("user_1"), version="v0", size_in_bytes=len(document.data), metadata={}, title=str(document.id), - user_id=None, + type="txt", created_at=datetime.now(), updated_at=datetime.now(), status="success", @@ -141,13 +148,18 @@ async def test_ingest_file(ingestion_service): file_mock.file.seek(0) file_mock.size = len(file_content) # Set file size manually + user = UserResponse( + id=generate_id_from_label("user1"), + email="email@test.com", + hashed_password="password", + ) ingestion_service.pipelines.ingestion_pipeline.run.return_value = { "embedding_pipeline_output": [ - (generate_id_from_label("test.txt"), None) + (generate_id_from_label(f"test.txt-{user.id}"), None) ] } - result = await ingestion_service.ingest_files([file_mock]) + result = await ingestion_service.ingest_files([file_mock], user=user) assert len(result["processed_documents"]) == 1 assert not result["failed_documents"] @@ -162,6 +174,8 @@ async def test_ingest_mixed_success_and_failure( Document( id=generate_id_from_label("success_id"), data="Success content", + group_ids=[], + user_id=generate_id_from_label("user_1"), type="txt", metadata={}, ), @@ -169,6 +183,8 @@ async def test_ingest_mixed_success_and_failure( id=generate_id_from_label("failure_id"), data="Failure content", type="txt", + group_ids=[], + user_id=generate_id_from_label("user_1"), metadata={}, ), ] @@ -193,18 +209,20 @@ async def test_ingest_mixed_success_and_failure( assert len(result["processed_documents"]) == 1 assert len(result["failed_documents"]) == 1 - assert str(documents[0].id) in result["processed_documents"][0] - assert str(documents[1].id) in result["failed_documents"][0] - assert "Embedding failed" in result["failed_documents"][0] + assert documents[0].id in [doc.id for doc in result["processed_documents"]] + assert documents[1].id in [ + doc["document_id"] for doc in result["failed_documents"] + ] + assert "Embedding failed" in str(result["failed_documents"][0]["result"]) assert mock_vector_db.relational.upsert_documents_overview.call_count == 2 upserted_docs = ( mock_vector_db.relational.upsert_documents_overview.call_args[0][0] ) assert len(upserted_docs) == 2 - assert upserted_docs[0].document_id == documents[0].id + assert upserted_docs[0].id == documents[0].id assert upserted_docs[0].status == "success" - assert upserted_docs[1].document_id == documents[1].id + assert upserted_docs[1].id == documents[1].id assert upserted_docs[1].status == "failure" @@ -216,64 +234,42 @@ async def test_ingest_unsupported_file_type(ingestion_service): file_mock.file.seek(0) file_mock.size = 12 # Set file size manually + user = UserResponse( + id=generate_id_from_label("user1"), + email="email@test.com", + hashed_password="password", + ) + with pytest.raises(R2RException) as exc_info: - await ingestion_service.ingest_files([file_mock]) + await ingestion_service.ingest_files([file_mock], user=user) assert "is not a valid DocumentType" in str(exc_info.value) -# @pytest.mark.asyncio -# async def test_ingest_large_file(ingestion_service): -# large_content = b"Large content" * 1000000 # 12MB content -# file_mock = UploadFile( -# filename="large_file.txt", file=io.BytesIO(large_content) -# ) -# file_mock.file.seek(0) -# file_mock.size = len(large_content) # Set file size manually - -# ingestion_service.config.app.get.return_value = ( -# 10 # Set max file size to 10MB -# ) - -# with pytest.raises(R2RException) as exc_info: -# await ingestion_service.ingest_files([file_mock]) - -# assert "File size exceeds maximum allowed size" in str(exc_info.value) - - -# @pytest.mark.asyncio -# async def test_concurrent_ingestion(ingestion_service, mock_vector_db): -# document = Document(id=generate_id_from_label("test_id"), data="Test content", type="txt", metadata={}) - -# async def ingestion_task(): -# return await ingestion_service.ingest_documents([document]) - -# # Simulate concurrent ingestion attempts -# results = await asyncio.gather(ingestion_task(), ingestion_task(), ingestion_task()) - -# # Check that only one ingestion succeeded and others were skipped -# assert sum(len(r["processed_documents"]) for r in results) == 1 -# assert sum(len(r["skipped_documents"]) for r in results) == 2 - - @pytest.mark.asyncio async def test_partial_ingestion_success(ingestion_service, mock_vector_db): documents = [ Document( id=generate_id_from_label("success_1"), data="Success content 1", + group_ids=[], + user_id=generate_id_from_label("user_1"), type="txt", metadata={}, ), Document( id=generate_id_from_label("fail"), data="Fail content", + group_ids=[], + user_id=generate_id_from_label("user_1"), type="txt", metadata={}, ), Document( id=generate_id_from_label("success_2"), data="Success content 2", + group_ids=[], + user_id=generate_id_from_label("user_1"), type="txt", metadata={}, ), @@ -297,20 +293,34 @@ async def test_partial_ingestion_success(ingestion_service, mock_vector_db): assert len(result["processed_documents"]) == 2 assert len(result["failed_documents"]) == 1 - assert str(documents[1].id) in result["failed_documents"][0] + assert documents[1].id in [ + doc["document_id"] for doc in result["failed_documents"] + ] @pytest.mark.asyncio async def test_version_increment(ingestion_service, mock_vector_db): + + user = UserResponse( + id=generate_id_from_label("user1"), + email="email@test.com", + hashed_password="password", + ) + document = Document( id=generate_id_from_label("test_id"), data="Test content", + group_ids=[], + user_id=generate_id_from_label("user_1"), type="txt", metadata={}, ) mock_vector_db.relational.get_documents_overview.return_value = [ DocumentInfo( - document_id=document.id, + id=document.id, + group_ids=[], + user_id=generate_id_from_label("user_1"), + type="txt", version="v2", status="success", size_in_bytes=0, @@ -321,7 +331,7 @@ async def test_version_increment(ingestion_service, mock_vector_db): file_mock = UploadFile( filename="test.txt", file=io.BytesIO(b"Updated content") ) - await ingestion_service.update_files([file_mock], [document.id]) + await ingestion_service.update_files([file_mock], [document.id], user=user) calls = mock_vector_db.relational.upsert_documents_overview.call_args_list assert len(calls) == 2 @@ -332,7 +342,10 @@ async def test_version_increment(ingestion_service, mock_vector_db): async def test_process_ingestion_results_error_handling(ingestion_service): document_infos = [ DocumentInfo( - document_id=uuid.uuid4(), + id=uuid.uuid4(), + group_ids=[], + user_id=generate_id_from_label("user_1"), + type="txt", version="v0", status="processing", size_in_bytes=0, @@ -342,10 +355,10 @@ async def test_process_ingestion_results_error_handling(ingestion_service): ingestion_results = { "embedding_pipeline_output": [ ( - document_infos[0].document_id, + document_infos[0].id, R2RDocumentProcessingError( "Unexpected error", - document_id=document_infos[0].document_id, + document_id=document_infos[0].id, ), ) ] @@ -355,40 +368,10 @@ async def test_process_ingestion_results_error_handling(ingestion_service): ingestion_results, document_infos, [], - {document_infos[0].document_id: "test"}, ) assert len(result["failed_documents"]) == 1 - assert "Unexpected error" in result["failed_documents"][0] - - -# @pytest.mark.asyncio -# async def test_file_size_limit_edge_cases(ingestion_service): -# ingestion_service.config.app.get.return_value = 1 # 1MB limit - -# just_under_limit = b"x" * (1024 * 1024 - 1) -# at_limit = b"x" * (1024 * 1024) -# over_limit = b"x" * (1024 * 1024 + 1) - -# file_under = UploadFile( -# filename="under.txt", -# file=io.BytesIO(just_under_limit), -# size=1024 * 1024 - 1, -# ) -# file_at = UploadFile( -# filename="at.txt", file=io.BytesIO(at_limit), size=1024 * 1024 -# ) -# file_over = UploadFile( -# filename="over.txt", file=io.BytesIO(over_limit), size=1024 * 1024 + 1 -# ) - -# await ingestion_service.ingest_files([file_under]) # Should succeed -# await ingestion_service.ingest_files([file_at]) # Should succeed - -# with pytest.raises( -# R2RException, match="File size exceeds maximum allowed size" -# ): -# await ingestion_service.ingest_files([file_over]) + assert "Unexpected error" in str(result["failed_documents"][0]) @pytest.mark.asyncio @@ -398,6 +381,8 @@ async def test_document_status_update_after_ingestion( document = Document( id=generate_id_from_label("test_id"), data="Test content", + group_ids=[], + user_id=generate_id_from_label("user_1"), type="txt", metadata={}, ) @@ -421,5 +406,5 @@ async def test_document_status_update_after_ingestion( ][0] ) assert len(second_call_args) == 1 - assert second_call_args[0].document_id == document.id + assert second_call_args[0].id == document.id assert second_call_args[0].status == "success" diff --git a/tests/test_kg.py b/tests/test_kg.py new file mode 100644 index 000000000..4111971ce --- /dev/null +++ b/tests/test_kg.py @@ -0,0 +1,139 @@ +import json +import uuid +from unittest.mock import Mock, patch + +import pytest + +from r2r.base.abstractions.document import DocumentFragment +from r2r.base.abstractions.graph import Entity, Triple +from r2r.base.providers.kg import KGConfig +from r2r.providers.kg.neo4j.provider import Neo4jKGProvider + + +@pytest.fixture +def neo4j_kg_provider(): + extra_fields = { + "user": "neo4j", + "password": "ineedastrongerpassword", + "url": "bolt://localhost:7688", + "database": "neo4j", + } + config = KGConfig(provider="neo4j", extra_fields=extra_fields) + return Neo4jKGProvider(config) + + +@pytest.fixture(autouse=True) +def clean_graph(neo4j_kg_provider): + neo4j_kg_provider.delete_all_nodes() + yield + neo4j_kg_provider.delete_all_nodes() + + +def get_uuid(): + return str(uuid.uuid4()) + + +@pytest.fixture +def test_chunks(): + return [ + DocumentFragment( + id=get_uuid(), + data="Test chunk 1", + metadata={"testkey": "testvalue"}, + document_id=get_uuid(), + extraction_id=get_uuid(), + ), + DocumentFragment( + id=get_uuid(), + data="Test chunk 2", + metadata={"testkey": "testvalue"}, + document_id=get_uuid(), + extraction_id=get_uuid(), + ), + ] + + +@pytest.fixture +def test_entities(): + return [ + Entity( + id=get_uuid(), + category="Test category 1", + subcategory=None, + value="Test entity 1", + description="Test entity 1 description", + description_embedding=[1.0, 2.0, 3.0], + name_embedding=[1.0, 2.0, 3.0], + graph_embedding=[1.0, 2.0, 3.0], + community_ids=[get_uuid()], + text_unit_ids=[get_uuid()], + document_ids=[get_uuid(), get_uuid()], + rank=1, + attributes={"testkey": "testvalue"}, + ), + # Entity(id=get_uuid(), category="Test category 2", subcategory=None, value="Test entity 2", description="Test entity 2 description", description_embedding=[1.0, 2.0, 3.0], name_embedding=[1.0, 2.0, 3.0], graph_embedding=[1.0, 2.0, 3.0], community_ids=[get_uuid()], text_unit_ids=[get_uuid()], document_ids=[get_uuid(), get_uuid()], rank=1, attributes={"testkey": "testvalue"}) + ] + + +@pytest.fixture +def test_triples(): + return [ + Triple( + id=get_uuid(), + subject=get_uuid(), + predicate="test_predicate", + object=get_uuid(), + weight=1.0, + description="Test triple description", + predicate_embedding=[1.0, 2.0, 3.0], + text_unit_ids=[get_uuid()], + document_ids=[get_uuid()], + attributes={"testkey": "testvalue"}, + ) + ] + + +def test_upsert_chunks(neo4j_kg_provider, test_chunks, clean_graph): + neo4j_kg_provider.upsert_chunks(test_chunks) + neo4j_output = neo4j_kg_provider.get_chunks() + chunks = [record["c"]._properties for record in neo4j_output.records] + assert len(chunks) == len(test_chunks) + for chunk, test_chunk in zip(chunks, test_chunks): + assert chunk["id"] == str(test_chunk.id) + assert chunk["data"] == test_chunk.data + assert json.loads(chunk["metadata"]) == test_chunk.metadata + assert chunk["document_id"] == str(test_chunk.document_id) + assert chunk["extraction_id"] == str(test_chunk.extraction_id) + + +def test_upsert_entities(neo4j_kg_provider, test_entities): + neo4j_kg_provider.upsert_entities(test_entities) + neo4j_output = neo4j_kg_provider.get_entities() + entities = [record["e"]._properties for record in neo4j_output.records] + assert len(entities) == len(test_entities) + for entity, test_entity in zip(entities, test_entities): + assert entity["id"] == test_entity.id + assert entity["category"] == test_entity.category + assert entity["value"] == test_entity.value + assert entity["description"] == test_entity.description + + +def test_upsert_triples(neo4j_kg_provider, test_triples): + triples_count = neo4j_kg_provider.upsert_triples(test_triples) + triples = neo4j_kg_provider.get_triples() + assert len(triples) == len(test_triples) + for triple, test_triple in zip(triples, test_triples): + assert triple.id == test_triple.id + assert triple.subject == test_triple.subject + assert triple.predicate == test_triple.predicate + assert triple.object == test_triple.object + + +def test_upsert_communities(neo4j_kg_provider, test_communities): + neo4j_kg_provider.upsert_communities(test_communities) + neo4j_output = neo4j_kg_provider.get_communities() + communities = [record["c"]._properties for record in neo4j_output.records] + assert len(communities) == len(test_communities) + for community, test_community in zip(communities, test_communities): + assert community["id"] == test_community.id + assert community["name"] == test_community.name diff --git a/tests/test_logging.py b/tests/test_logging.py index d0255d37e..7e4372a5e 100644 --- a/tests/test_logging.py +++ b/tests/test_logging.py @@ -2,16 +2,17 @@ import logging import os import uuid +from uuid import UUID import pytest from r2r import ( - LocalKVLoggingProvider, + LocalRunLoggingProvider, LoggingConfig, - PostgresKVLoggingProvider, PostgresLoggingConfig, - RedisKVLoggingProvider, + PostgresRunLoggingProvider, RedisLoggingConfig, + RedisRunLoggingProvider, generate_run_id, ) @@ -35,267 +36,172 @@ async def cleanup_tasks(): async def local_provider(): unique_id = str(uuid.uuid4()) logging_path = f"test_{unique_id}.sqlite" - provider = LocalKVLoggingProvider(LoggingConfig(logging_path=logging_path)) - await provider.init() + provider = LocalRunLoggingProvider( + LoggingConfig(logging_path=logging_path) + ) + await provider._init() yield provider await provider.close() if os.path.exists(logging_path): os.remove(logging_path) -@pytest.mark.asyncio -async def test_local_logging(local_provider): - run_id = generate_run_id() - await local_provider.log(run_id, "key", "value") - logs = await local_provider.get_logs([run_id]) - assert len(logs) == 1 - assert logs[0]["key"] == "key" - assert logs[0]["value"] == "value" - - -# FIXME: This test is causing Pytest to hang -# @pytest.mark.asyncio -# async def test_multiple_log_entries(local_provider): -# """Test logging multiple entries and retrieving them.""" -# run_id_0 = generate_run_id() -# run_id_1 = generate_run_id() -# run_id_2 = generate_run_id() -# await local_provider.init() - -# entries = [ -# (run_id_0, "key_0", "value_0"), -# (run_id_1, "key_1", "value_1"), -# (run_id_2, "key_2", "value_2"), -# ] -# for run_id, key, value in entries: -# await local_provider.log(run_id, key, value) - -# logs = await local_provider.get_logs([run_id_0, run_id_1, run_id_2]) -# assert len(logs) == 3 - -# # Check that logs are returned in the correct order (most recent first if applicable) -# for log in logs: -# selected_entry = [ -# entry for entry in entries if entry[0] == log["log_id"] -# ][0] -# assert log["log_id"] == selected_entry[0] -# assert log["key"] == selected_entry[1] -# assert log["value"] == selected_entry[2] - - -# FIXME: This test is causing Pytest to hang -# @pytest.mark.asyncio -# async def test_log_retrieval_limit(local_provider): -# """Test the max_logs limit parameter works correctly.""" -# await local_provider.init() - -# run_ids = [] -# for i in range(10): # Add 10 entries -# run_ids.append(generate_run_id()) -# await local_provider.log(run_ids[-1], f"key_{i}", f"value_{i}") - -# logs = await local_provider.get_logs(run_ids[:5]) -# assert len(logs) == 5 # Ensure only 5 logs are returned - - -# FIXME: This test is causing Pytest to hang -# @pytest.mark.asyncio -# async def test_specific_run_type_retrieval(local_provider): -# """Test retrieving logs for a specific run type works correctly.""" -# await local_provider.init() -# run_id_0 = generate_run_id() -# run_id_1 = generate_run_id() - -# await local_provider.log( -# run_id_0, "pipeline_type", "search", is_info_log=True -# ) -# await local_provider.log(run_id_0, "key_0", "value_0") -# await local_provider.log( -# run_id_1, "pipeline_type", "rag", is_info_log=True -# ) -# await local_provider.log(run_id_1, "key_1", "value_1") - -# run_info = await local_provider.get_run_info(log_type_filter="search") -# logs = await local_provider.get_logs([run.run_id for run in run_info]) -# assert len(logs) == 1 -# assert logs[0]["log_id"] == run_id_0 -# assert logs[0]["key"] == "key_0" -# assert logs[0]["value"] == "value_0" - - @pytest.fixture(scope="function") async def postgres_provider(): log_table = f"logs_{str(uuid.uuid4()).replace('-', '_')}" log_info_table = f"log_info_{str(uuid.uuid4()).replace('-', '_')}" - provider = PostgresKVLoggingProvider( + provider = PostgresRunLoggingProvider( PostgresLoggingConfig( log_table=log_table, log_info_table=log_info_table ) ) - await provider.init() + await provider._init() yield provider await provider.close() +@pytest.fixture +async def provider(request): + return request.getfixturevalue(request.param) + + +all_providers = [ + pytest.param("local_provider", id="local"), + pytest.param("postgres_provider", id="postgres"), +] + + @pytest.mark.asyncio -async def test_postgres_logging(postgres_provider): - """Test logging and retrieving from the postgres logging provider.""" - await postgres_provider.init() +@pytest.mark.parametrize("provider", all_providers, indirect=True) +async def test_logging(provider): run_id = generate_run_id() - await postgres_provider.log(run_id, "key", "value") - logs = await postgres_provider.get_logs([run_id]) + await provider.log(run_id, "key", "value") + logs = await provider.get_logs([run_id]) assert len(logs) == 1 assert logs[0]["key"] == "key" assert logs[0]["value"] == "value" @pytest.mark.asyncio -async def test_postgres_multiple_log_entries(postgres_provider): - """Test logging multiple entries and retrieving them.""" - await postgres_provider.init() - run_id_0 = generate_run_id() - run_id_1 = generate_run_id() - run_id_2 = generate_run_id() - +@pytest.mark.parametrize("provider", all_providers, indirect=True) +async def test_multiple_log_entries(provider): + run_ids = [generate_run_id() for _ in range(3)] entries = [ - (run_id_0, "key_0", "value_0"), - (run_id_1, "key_1", "value_1"), - (run_id_2, "key_2", "value_2"), + (run_id, f"key_{i}", f"value_{i}") for i, run_id in enumerate(run_ids) ] for run_id, key, value in entries: - await postgres_provider.log(run_id, key, value) + await provider.log(run_id, key, value) - logs = await postgres_provider.get_logs([run_id_0, run_id_1, run_id_2]) - assert len(logs) == 3 + logs = await provider.get_logs(run_ids) + assert len(logs) == 3, f"Expected 3 logs, got {len(logs)}" - # Check that logs are returned in the correct order (most recent first if applicable) for log in logs: - selected_entry = [ - entry for entry in entries if entry[0] == log["log_id"] - ][0] - assert log["log_id"] == selected_entry[0] + run_id = log.get("run_id") + assert run_id is not None, f"Log entry is missing 'run_id': {log}" + + if isinstance(run_id, str): + run_id = UUID(run_id) + + matching_entries = [entry for entry in entries if entry[0] == run_id] + assert ( + len(matching_entries) == 1 + ), f"No matching entry found for run_id {run_id}" + + selected_entry = matching_entries[0] assert log["key"] == selected_entry[1] assert log["value"] == selected_entry[2] + # Additional check to ensure all entries were logged + logged_ids = set( + ( + UUID(log["run_id"]) + if isinstance(log["run_id"], str) + else log["run_id"] + ) + for log in logs + ) + entry_ids = set(entry[0] for entry in entries) + assert ( + logged_ids == entry_ids + ), f"Mismatch between logged IDs {logged_ids} and entry IDs {entry_ids}" + @pytest.mark.asyncio -async def test_postgres_log_retrieval_limit(postgres_provider): - """Test the max_logs limit parameter works correctly.""" - await postgres_provider.init() +@pytest.mark.parametrize("provider", all_providers, indirect=True) +async def test_log_retrieval_limit(provider): run_ids = [] - for i in range(10): # Add 10 entries + for i in range(10): run_ids.append(generate_run_id()) - await postgres_provider.log(run_ids[-1], f"key_{i}", f"value_{i}") + await provider.log(run_ids[-1], f"key_{i}", f"value_{i}") - logs = await postgres_provider.get_logs(run_ids[:5]) - assert len(logs) == 5 # Ensure only 5 logs are returned + logs = await provider.get_logs(run_ids[:5]) + assert len(logs) == 5 @pytest.mark.asyncio -async def test_postgres_specific_run_type_retrieval(postgres_provider): - """Test retrieving logs for a specific run type works correctly.""" - await postgres_provider.init() - run_id_0 = generate_run_id() - run_id_1 = generate_run_id() - - await postgres_provider.log( - run_id_0, "pipeline_type", "search", is_info_log=True - ) - await postgres_provider.log(run_id_0, "key_0", "value_0") - await postgres_provider.log( - run_id_1, "pipeline_type", "rag", is_info_log=True - ) - await postgres_provider.log(run_id_1, "key_1", "value_1") +@pytest.mark.parametrize("provider", all_providers, indirect=True) +async def test_specific_run_type_retrieval(provider): + run_id_0, run_id_1 = generate_run_id(), generate_run_id() + + await provider.log(run_id_0, "run_type", "RETRIEVAL") + await provider.log(run_id_0, "key_0", "value_0") + await provider.log(run_id_1, "run_type", "MANAGEMENT") + await provider.log(run_id_1, "key_1", "value_1") + + # Log info for both run IDs + await provider.info_log(run_id_0, "RETRIEVAL", uuid.uuid4()) + await provider.info_log(run_id_1, "MANAGEMENT", uuid.uuid4()) + + run_info = await provider.get_info_logs(run_type_filter="RETRIEVAL") + assert ( + len(run_info) == 1 + ), f"Expected 1 'RETRIEVAL' log, got {len(run_info)}" + assert ( + run_info[0].run_id == run_id_0 + ), f"Expected run_id {run_id_0}, got {run_info[0].run_id}" + + logs = await provider.get_logs([run.run_id for run in run_info]) + assert len(logs) == 2, f"Expected 2 logs for run_id_0, got {len(logs)}" + assert all( + log["run_id"] == run_id_0 for log in logs + ), "All logs should be for run_id_0" + assert any( + log["key"] == "run_type" and log["value"] == "RETRIEVAL" + for log in logs + ), "Should have a 'RETRIEVAL' log" + assert any( + log["key"] == "key_0" and log["value"] == "value_0" for log in logs + ), "Should have a 'key_0' log" - run_info = await postgres_provider.get_run_info(log_type_filter="search") - logs = await postgres_provider.get_logs([run.run_id for run in run_info]) - assert len(logs) == 1 - assert logs[0]["log_id"] == run_id_0 - assert logs[0]["key"] == "key_0" - assert logs[0]["value"] == "value_0" - - -# @pytest.fixture(scope="function") -# async def redis_provider(): -# log_table = f"logs_{str(uuid.uuid4()).replace('-', '_')}" -# log_info_table = f"log_info_{str(uuid.uuid4()).replace('-', '_')}" -# provider = RedisKVLoggingProvider( -# RedisLoggingConfig(log_table=log_table, log_info_table=log_info_table) -# ) -# await provider.init() -# yield provider -# await provider.close() - - -# @pytest.mark.asyncio -# async def test_redis_logging(redis_provider): -# """Test logging and retrieving from the Redis logging provider.""" -# run_id = generate_run_id() -# await redis_provider.log(run_id, "key", "value") -# logs = await redis_provider.get_logs([run_id]) -# assert len(logs) == 1 -# assert logs[0]["key"] == "key" -# assert logs[0]["value"] == "value" - - -# @pytest.mark.asyncio -# async def test_redis_multiple_log_entries(redis_provider): -# """Test logging multiple entries and retrieving them.""" -# run_id_0 = generate_run_id() -# run_id_1 = generate_run_id() -# run_id_2 = generate_run_id() - -# entries = [ -# (run_id_0, "key_0", "value_0"), -# (run_id_1, "key_1", "value_1"), -# (run_id_2, "key_2", "value_2"), -# ] -# for run_id, key, value in entries: -# await redis_provider.log(run_id, key, value) - -# logs = await redis_provider.get_logs([run_id_0, run_id_1, run_id_2]) -# assert len(logs) == 3 - -# # Check that logs are returned in the correct order (most recent first if applicable) -# for log in logs: -# selected_entry = [ -# entry for entry in entries if entry[0] == log["log_id"] -# ][0] -# assert log["log_id"] == selected_entry[0] -# assert log["key"] == selected_entry[1] -# assert log["value"] == selected_entry[2] - - -# @pytest.mark.asyncio -# async def test_redis_log_retrieval_limit(redis_provider): -# """Test the max_logs limit parameter works correctly.""" -# run_ids = [] -# for i in range(10): # Add 10 entries -# run_ids.append(generate_run_id()) -# await redis_provider.log(run_ids[-1], f"key_{i}", f"value_{i}") - -# logs = await redis_provider.get_logs(run_ids[:5]) -# assert len(logs) == 5 # Ensure only 5 logs are returned - - -# @pytest.mark.asyncio -# async def test_redis_specific_run_type_retrieval(redis_provider): -# """Test retrieving logs for a specific run type works correctly.""" -# run_id_0 = generate_run_id() -# run_id_1 = generate_run_id() - -# await redis_provider.log( -# run_id_0, "pipeline_type", "search", is_info_log=True -# ) -# await redis_provider.log(run_id_0, "key_0", "value_0") -# await redis_provider.log( -# run_id_1, "pipeline_type", "rag", is_info_log=True -# ) -# await redis_provider.log(run_id_1, "key_1", "value_1") - -# run_info = await redis_provider.get_run_info(log_type_filter="search") -# logs = await redis_provider.get_logs([run.run_id for run in run_info]) -# assert len(logs) == 1 -# assert logs[0]["log_id"] == run_id_0 -# assert logs[0]["key"] == "key_0" -# assert logs[0]["value"] == "value_0" + +@pytest.mark.asyncio +@pytest.mark.parametrize("provider", all_providers, indirect=True) +async def test_info_logging(provider): + run_id = generate_run_id() + user_id = uuid.uuid4() + run_type = "RETRIEVAL" + await provider.info_log(run_id, run_type, user_id) + info_logs = await provider.get_info_logs() + assert len(info_logs) == 1 + assert info_logs[0].run_id == run_id + assert info_logs[0].run_type == run_type + assert info_logs[0].user_id == user_id + + +@pytest.mark.asyncio +@pytest.mark.parametrize("provider", all_providers, indirect=True) +async def test_get_info_logs_with_user_filter(provider): + user_id_1, user_id_2 = uuid.uuid4(), uuid.uuid4() + await provider.info_log(generate_run_id(), "RETRIEVAL", user_id_1) + await provider.info_log(generate_run_id(), "MANAGEMENT", user_id_2) + + info_logs = await provider.get_info_logs(user_ids=[user_id_1]) + assert len(info_logs) == 1 + assert info_logs[0].user_id == user_id_1 + + info_logs = await provider.get_info_logs( + run_type_filter="MANAGEMENT", user_ids=[user_id_2] + ) + assert len(info_logs) == 1 + assert info_logs[0].user_id == user_id_2 + assert info_logs[0].run_type == "MANAGEMENT" diff --git a/tests/test_vector_db.py b/tests/test_vector_db.py new file mode 100644 index 000000000..fe24384cf --- /dev/null +++ b/tests/test_vector_db.py @@ -0,0 +1,282 @@ +import random +from uuid import UUID, uuid4 + +import pytest + +from r2r.base import DatabaseConfig, Vector, VectorEntry +from r2r.providers import PostgresDBProvider + + +@pytest.fixture +def vector_db(): + random_collection_name = ( + f"test_collection_{random.randint(0, 1_000_000_000)}" + ) + config = DatabaseConfig.create( + provider="postgres", vecs_collection=random_collection_name + ) + db = PostgresDBProvider(config, dimension=3) + yield db.vector + # Teardown + db.vx.delete_collection( + db.config.extra_fields.get("vecs_collection", None) + ) + + +@pytest.fixture +def sample_entries(vector_db): + entries = [ + VectorEntry( + fragment_id=uuid4(), + extraction_id=uuid4(), + document_id=uuid4(), + user_id=uuid4(), + group_ids=[uuid4()], + vector=Vector([0.1, 0.2, 0.3]), + text="Apple", + metadata={ + "category": "fruit", + "color": "red", + "price": 1.0, + }, + ), + VectorEntry( + fragment_id=uuid4(), + extraction_id=uuid4(), + document_id=uuid4(), + user_id=uuid4(), + group_ids=[uuid4()], + vector=Vector([0.2, 0.3, 0.4]), + text="Banana", + metadata={ + "category": "fruit", + "color": "yellow", + "price": 0.5, + }, + ), + VectorEntry( + fragment_id=uuid4(), + extraction_id=uuid4(), + document_id=uuid4(), + user_id=uuid4(), + group_ids=[uuid4()], + vector=Vector([0.3, 0.4, 0.5]), + text="Carrot", + metadata={ + "category": "vegetable", + "color": "orange", + "price": 0.75, + }, + ), + VectorEntry( + fragment_id=uuid4(), + extraction_id=uuid4(), + document_id=uuid4(), + user_id=uuid4(), + group_ids=[uuid4()], + vector=Vector([0.4, 0.5, 0.6]), + text="Durian", + metadata={ + "category": "fruit", + "color": "green", + "price": 5.0, + }, + ), + ] + for entry in entries: + vector_db.upsert(entry) + return entries + + +def test_search_equality_filter(vector_db, sample_entries): + query_vector = Vector([0.2, 0.3, 0.4]) + results = vector_db.search( + query_vector.data, + limit=10, + filters={"category": {"$eq": "fruit"}}, + ) + assert len(results) == 3 + assert all(r.metadata["category"] == "fruit" for r in results) + + +def test_search_not_equal_filter(vector_db, sample_entries): + query_vector = Vector([0.2, 0.3, 0.4]) + results = vector_db.search( + query_vector.data, + limit=10, + filters={"category": {"$ne": "fruit"}}, + ) + assert len(results) == 1 + assert results[0].metadata["category"] == "vegetable" + + +def test_search_greater_than_filter(vector_db, sample_entries): + query_vector = Vector([0.2, 0.3, 0.4]) + results = vector_db.search( + query_vector.data, + limit=10, + filters={"price": {"$gt": 1.0}}, + ) + assert len(results) == 1 + assert results[0].text == "Durian" + + +def test_search_less_than_or_equal_filter(vector_db, sample_entries): + query_vector = Vector([0.2, 0.3, 0.4]) + results = vector_db.search( + query_vector.data, + limit=10, + filters={"price": {"$lte": 1.0}}, + ) + assert len(results) == 3 + assert all(r.metadata["price"] <= 1.0 for r in results) + + +def test_search_in_filter(vector_db, sample_entries): + query_vector = Vector([0.2, 0.3, 0.4]) + results = vector_db.search( + query_vector.data, + limit=10, + filters={"color": {"$in": ["red", "yellow"]}}, + ) + assert len(results) == 2 + assert all(r.metadata["color"] in ["red", "yellow"] for r in results) + + +def test_search_complex_and_filter(vector_db, sample_entries): + query_vector = Vector([0.2, 0.3, 0.4]) + results = vector_db.search( + query_vector.data, + limit=10, + filters={ + "$and": [ + {"category": {"$eq": "fruit"}}, + {"price": {"$lt": 2.0}}, + {"color": {"$ne": "yellow"}}, + ] + }, + ) + assert len(results) == 1 + assert results[0].text == "Apple" + + +def test_search_complex_or_filter(vector_db, sample_entries): + query_vector = Vector([0.2, 0.3, 0.4]) + results = vector_db.search( + query_vector.data, + limit=10, + filters={ + "$or": [ + {"category": {"$eq": "vegetable"}}, + {"price": {"$gte": 5.0}}, + ] + }, + ) + assert len(results) == 2 + assert any(r.metadata["category"] == "vegetable" for r in results) + assert any(r.metadata["price"] >= 5.0 for r in results) + + +def test_search_nested_and_or_filters(vector_db, sample_entries): + query_vector = Vector([0.2, 0.3, 0.4]) + results = vector_db.search( + query_vector.data, + limit=10, + filters={ + "$and": [ + {"category": {"$eq": "fruit"}}, + { + "$or": [ + {"color": {"$in": ["red", "yellow"]}}, + {"price": {"$gt": 2.0}}, + ] + }, + ] + }, + ) + assert len(results) == 3 + assert all(r.metadata["category"] == "fruit" for r in results) + assert all( + r.metadata["color"] in ["red", "yellow"] or r.metadata["price"] > 2.0 + for r in results + ) + + +def test_delete_equality(vector_db, sample_entries): + deleted_ids = vector_db.delete({"category": {"$eq": "vegetable"}}) + assert len(deleted_ids) == 1 + remaining = vector_db.search(Vector([0.2, 0.3, 0.4]).data, limit=10) + assert len(remaining) == 3 + assert all(r.metadata["category"] == "fruit" for r in remaining) + + +def test_delete_greater_than(vector_db, sample_entries): + deleted_ids = vector_db.delete({"price": {"$gt": 1.0}}) + assert len(deleted_ids) == 1 + remaining = vector_db.search(Vector([0.2, 0.3, 0.4]).data, limit=10) + assert len(remaining) == 3 + assert all(r.metadata["price"] <= 1.0 for r in remaining) + + +def test_delete_in(vector_db, sample_entries): + deleted_ids = vector_db.delete({"color": {"$in": ["red", "yellow"]}}) + assert len(deleted_ids) == 2 + remaining = vector_db.search(Vector([0.2, 0.3, 0.4]).data, limit=10) + assert len(remaining) == 2 + assert all(r.metadata["color"] not in ["red", "yellow"] for r in remaining) + + +def test_delete_complex_and(vector_db, sample_entries): + deleted_ids = vector_db.delete( + { + "$and": [ + {"category": {"$eq": "fruit"}}, + {"price": {"$lt": 1.0}}, + ] + } + ) + assert len(deleted_ids) == 1 + remaining = vector_db.search(Vector([0.2, 0.3, 0.4]).data, limit=10) + assert len(remaining) == 3 + assert not any( + r.metadata["category"] == "fruit" and r.metadata["price"] < 1.0 + for r in remaining + ) + + +def test_delete_complex_or(vector_db, sample_entries): + deleted_ids = vector_db.delete( + { + "$or": [ + {"category": {"$eq": "vegetable"}}, + {"price": {"$gte": 5.0}}, + ] + } + ) + assert len(deleted_ids) == 2 + remaining = vector_db.search(Vector([0.2, 0.3, 0.4]).data, limit=10) + assert len(remaining) == 2 + assert all( + r.metadata["category"] != "vegetable" and r.metadata["price"] < 5.0 + for r in remaining + ) + + +def test_delete_nested_and_or(vector_db, sample_entries): + deleted_ids = vector_db.delete( + { + "$and": [ + {"category": {"$eq": "fruit"}}, + { + "$or": [ + {"color": {"$in": ["red", "yellow"]}}, + {"price": {"$gt": 2.0}}, + ] + }, + ] + } + ) + assert len(deleted_ids) == 3 + remaining = vector_db.search(Vector([0.2, 0.3, 0.4]).data, limit=10) + assert len(remaining) == 1 + assert remaining[0].metadata["category"] == "vegetable" From de8e1aafaecd0837d83155acaa7c5b7ec0b3345a Mon Sep 17 00:00:00 2001 From: Nolan Tremelling <34580718+NolanTrem@users.noreply.github.com> Date: Fri, 16 Aug 2024 16:43:01 -0700 Subject: [PATCH 02/74] Clean up API (#878) * Get running * fixes in sdk * Add in more fixes --- alembic.ini | 116 ------------------ alembic/env.py | 77 ------------ alembic/script.py.mako | 26 ---- .../7423a09421e9_add_user_id_to_logs.py | 47 ------- r2r/base/abstractions/search.py | 2 +- r2r/base/api/models/__init__.py | 4 - r2r/base/api/models/ingestion/responses.py | 2 +- r2r/base/api/models/management/responses.py | 8 -- r2r/base/api/models/retrieval/responses.py | 6 +- r2r/cli/cli.py | 1 - r2r/cli/commands/server_operations.py | 26 ---- r2r/main/api/client/auth.py | 12 +- r2r/main/api/client/client.py | 4 +- r2r/main/api/client/ingestion.py | 30 ----- r2r/main/api/client/management.py | 5 +- r2r/main/api/client/restructure.py | 2 +- r2r/main/api/routes/ingestion/base.py | 27 ++-- r2r/main/api/routes/management/base.py | 11 +- r2r/main/services/management_service.py | 83 ++++++------- r2r/providers/database/vector.py | 8 +- 20 files changed, 83 insertions(+), 414 deletions(-) delete mode 100644 alembic.ini delete mode 100644 alembic/env.py delete mode 100644 alembic/script.py.mako delete mode 100644 alembic/versions/7423a09421e9_add_user_id_to_logs.py diff --git a/alembic.ini b/alembic.ini deleted file mode 100644 index 4e036789e..000000000 --- a/alembic.ini +++ /dev/null @@ -1,116 +0,0 @@ -# A generic, single database configuration. - -[alembic] -# path to migration scripts -# Use forward slashes (/) also on windows to provide an os agnostic path -script_location = alembic - -# template used to generate migration file names; The default value is %%(rev)s_%%(slug)s -# Uncomment the line below if you want the files to be prepended with date and time -# see https://alembic.sqlalchemy.org/en/latest/tutorial.html#editing-the-ini-file -# for all available tokens -# file_template = %%(year)d_%%(month).2d_%%(day).2d_%%(hour).2d%%(minute).2d-%%(rev)s_%%(slug)s - -# sys.path path, will be prepended to sys.path if present. -# defaults to the current working directory. -prepend_sys_path = . - -# timezone to use when rendering the date within the migration file -# as well as the filename. -# If specified, requires the python>=3.9 or backports.zoneinfo library. -# Any required deps can installed by adding `alembic[tz]` to the pip requirements -# string value is passed to ZoneInfo() -# leave blank for localtime -# timezone = - -# max length of characters to apply to the "slug" field -# truncate_slug_length = 40 - -# set to 'true' to run the environment during -# the 'revision' command, regardless of autogenerate -# revision_environment = false - -# set to 'true' to allow .pyc and .pyo files without -# a source .py file to be detected as revisions in the -# versions/ directory -# sourceless = false - -# version location specification; This defaults -# to alembic/versions. When using multiple version -# directories, initial revisions must be specified with --version-path. -# The path separator used here should be the separator specified by "version_path_separator" below. -# version_locations = %(here)s/bar:%(here)s/bat:alembic/versions - -# version path separator; As mentioned above, this is the character used to split -# version_locations. The default within new alembic.ini files is "os", which uses os.pathsep. -# If this key is omitted entirely, it falls back to the legacy behavior of splitting on spaces and/or commas. -# Valid values for version_path_separator are: -# -# version_path_separator = : -# version_path_separator = ; -# version_path_separator = space -version_path_separator = os # Use os.pathsep. Default configuration used for new projects. - -# set to 'true' to search source files recursively -# in each "version_locations" directory -# new in Alembic version 1.10 -# recursive_version_locations = false - -# the output encoding used when revision files -# are written from script.py.mako -# output_encoding = utf-8 - -sqlalchemy.url = sqlite:///local.sqlite - - -[post_write_hooks] -# post_write_hooks defines scripts or Python functions that are run -# on newly generated revision scripts. See the documentation for further -# detail and examples - -# format using "black" - use the console_scripts runner, against the "black" entrypoint -# hooks = black -# black.type = console_scripts -# black.entrypoint = black -# black.options = -l 79 REVISION_SCRIPT_FILENAME - -# lint with attempts to fix using "ruff" - use the exec runner, execute a binary -# hooks = ruff -# ruff.type = exec -# ruff.executable = %(here)s/.venv/bin/ruff -# ruff.options = --fix REVISION_SCRIPT_FILENAME - -# Logging configuration -[loggers] -keys = root,sqlalchemy,alembic - -[handlers] -keys = console - -[formatters] -keys = generic - -[logger_root] -level = WARN -handlers = console -qualname = - -[logger_sqlalchemy] -level = WARN -handlers = -qualname = sqlalchemy.engine - -[logger_alembic] -level = INFO -handlers = -qualname = alembic - -[handler_console] -class = StreamHandler -args = (sys.stderr,) -level = NOTSET -formatter = generic - -[formatter_generic] -format = %(levelname)-5.5s [%(name)s] %(message)s -datefmt = %H:%M:%S diff --git a/alembic/env.py b/alembic/env.py deleted file mode 100644 index b2040b5f7..000000000 --- a/alembic/env.py +++ /dev/null @@ -1,77 +0,0 @@ -from logging.config import fileConfig - -from sqlalchemy import engine_from_config, pool - -from alembic import context - -# this is the Alembic Config object, which provides -# access to the values within the .ini file in use. -config = context.config - -# Interpret the config file for Python logging. -# This line sets up loggers basically. -if config.config_file_name is not None: - fileConfig(config.config_file_name) - -# add your model's MetaData object here -# for 'autogenerate' support -# from myapp import mymodel -# target_metadata = mymodel.Base.metadata -target_metadata = None - -# other values from the config, defined by the needs of env.py, -# can be acquired: -# my_important_option = config.get_main_option("my_important_option") -# ... etc. - - -def run_migrations_offline() -> None: - """Run migrations in 'offline' mode. - - This configures the context with just a URL - and not an Engine, though an Engine is acceptable - here as well. By skipping the Engine creation - we don't even need a DBAPI to be available. - - Calls to context.execute() here emit the given string to the - script output. - - """ - url = config.get_main_option("sqlalchemy.url") - context.configure( - url=url, - target_metadata=target_metadata, - literal_binds=True, - dialect_opts={"paramstyle": "named"}, - ) - - with context.begin_transaction(): - context.run_migrations() - - -def run_migrations_online() -> None: - """Run migrations in 'online' mode. - - In this scenario we need to create an Engine - and associate a connection with the context. - - """ - connectable = engine_from_config( - config.get_section(config.config_ini_section, {}), - prefix="sqlalchemy.", - poolclass=pool.NullPool, - ) - - with connectable.connect() as connection: - context.configure( - connection=connection, target_metadata=target_metadata - ) - - with context.begin_transaction(): - context.run_migrations() - - -if context.is_offline_mode(): - run_migrations_offline() -else: - run_migrations_online() diff --git a/alembic/script.py.mako b/alembic/script.py.mako deleted file mode 100644 index fbc4b07dc..000000000 --- a/alembic/script.py.mako +++ /dev/null @@ -1,26 +0,0 @@ -"""${message} - -Revision ID: ${up_revision} -Revises: ${down_revision | comma,n} -Create Date: ${create_date} - -""" -from typing import Sequence, Union - -from alembic import op -import sqlalchemy as sa -${imports if imports else ""} - -# revision identifiers, used by Alembic. -revision: str = ${repr(up_revision)} -down_revision: Union[str, None] = ${repr(down_revision)} -branch_labels: Union[str, Sequence[str], None] = ${repr(branch_labels)} -depends_on: Union[str, Sequence[str], None] = ${repr(depends_on)} - - -def upgrade() -> None: - ${upgrades if upgrades else "pass"} - - -def downgrade() -> None: - ${downgrades if downgrades else "pass"} diff --git a/alembic/versions/7423a09421e9_add_user_id_to_logs.py b/alembic/versions/7423a09421e9_add_user_id_to_logs.py deleted file mode 100644 index bf451889e..000000000 --- a/alembic/versions/7423a09421e9_add_user_id_to_logs.py +++ /dev/null @@ -1,47 +0,0 @@ -"""add_user_id_to_logs - -Revision ID: 7423a09421e9 -Revises: -Create Date: 2024-08-05 10:49:10.714423 - -""" - -from typing import Sequence, Union - -import sqlalchemy as sa -from sqlalchemy.engine.reflection import Inspector - -from alembic import op - -# revision identifiers, used by Alembic. -revision: str = "7423a09421e9" -down_revision: Union[str, None] = None -branch_labels: Union[str, Sequence[str], None] = None -depends_on: Union[str, Sequence[str], None] = None - - -def upgrade(): - conn = op.get_bind() - inspector = Inspector.from_engine(conn) - - # Check and add user_id to logs table if it doesn't exist - if "user_id" not in [col["name"] for col in inspector.get_columns("logs")]: - op.add_column("logs", sa.Column("user_id", sa.String(), nullable=True)) - - # Check and add user_id to log_info table if it doesn't exist - if "user_id" not in [ - col["name"] for col in inspector.get_columns("log_info") - ]: - op.add_column( - "log_info", sa.Column("user_id", sa.String(), nullable=True) - ) - - -def downgrade(): - # Remove user_id column from logs table if it exists - with op.batch_alter_table("logs") as batch_op: - batch_op.drop_column("user_id") - - # Remove user_id column from log_info table if it exists - with op.batch_alter_table("log_info") as batch_op: - batch_op.drop_column("user_id") diff --git a/r2r/base/abstractions/search.py b/r2r/base/abstractions/search.py index 6218ec33b..7c94bd02d 100644 --- a/r2r/base/abstractions/search.py +++ b/r2r/base/abstractions/search.py @@ -40,7 +40,7 @@ def dict(self) -> dict: } class Config: - schema_extra = [ + json_schema_extra = [ { "fragment_id": "c68dc72e-fc23-5452-8f49-d7bd46088a96", "extraction_id": "3f3d47f3-8baf-58eb-8bc2-0171fb1c6e09", diff --git a/r2r/base/api/models/__init__.py b/r2r/base/api/models/__init__.py index d0afb1ec5..9944d0fb7 100644 --- a/r2r/base/api/models/__init__.py +++ b/r2r/base/api/models/__init__.py @@ -8,7 +8,6 @@ from .management.responses import ( AnalyticsResponse, AppSettingsResponse, - DeleteResponse, DocumentChunkResponse, DocumentOverviewResponse, GroupOverviewResponse, @@ -22,7 +21,6 @@ WrappedAddUserResponse, WrappedAnalyticsResponse, WrappedAppSettingsResponse, - WrappedDeleteResponse, WrappedDocumentChunkResponse, WrappedDocumentOverviewResponse, WrappedGroupListResponse, @@ -62,7 +60,6 @@ "AppSettingsResponse", "ScoreCompletionResponse", "UserOverviewResponse", - "DeleteResponse", "DocumentOverviewResponse", "DocumentChunkResponse", "KnowledgeGraphResponse", @@ -75,7 +72,6 @@ "WrappedAppSettingsResponse", "WrappedScoreCompletionResponse", "WrappedUserOverviewResponse", - "WrappedDeleteResponse", "WrappedDocumentOverviewResponse", "WrappedDocumentChunkResponse", "WrappedKnowledgeGraphResponse", diff --git a/r2r/base/api/models/ingestion/responses.py b/r2r/base/api/models/ingestion/responses.py index 76da3af35..b93d32583 100644 --- a/r2r/base/api/models/ingestion/responses.py +++ b/r2r/base/api/models/ingestion/responses.py @@ -50,7 +50,7 @@ class IngestionResponse(BaseModel): ) class Config: - schema_extra = { + json_schema_extra = { "example": { "processed_documents": [ { diff --git a/r2r/base/api/models/management/responses.py b/r2r/base/api/models/management/responses.py index de5da333e..9a04b25a1 100644 --- a/r2r/base/api/models/management/responses.py +++ b/r2r/base/api/models/management/responses.py @@ -53,13 +53,6 @@ class UserOverviewResponse(BaseModel): document_ids: List[UUID] -class DeleteResponse(BaseModel): - fragment_id: UUID - document_id: UUID - extraction_id: UUID - text: str - - class DocumentOverviewResponse(BaseModel): id: UUID title: str @@ -114,7 +107,6 @@ class AddUserResponse(BaseModel): WrappedAppSettingsResponse = ResultsWrapper[AppSettingsResponse] WrappedScoreCompletionResponse = ResultsWrapper[ScoreCompletionResponse] WrappedUserOverviewResponse = ResultsWrapper[List[UserOverviewResponse]] -WrappedDeleteResponse = ResultsWrapper[dict[str, DeleteResponse]] WrappedDocumentOverviewResponse = ResultsWrapper[ List[DocumentOverviewResponse] ] diff --git a/r2r/base/api/models/retrieval/responses.py b/r2r/base/api/models/retrieval/responses.py index b609b9a2b..36b9543e7 100644 --- a/r2r/base/api/models/retrieval/responses.py +++ b/r2r/base/api/models/retrieval/responses.py @@ -17,7 +17,7 @@ class SearchResponse(BaseModel): ) class Config: - schema_extra = { + json_schema_extra = { "example": { "vector_search_results": [ { @@ -50,7 +50,7 @@ class RAGResponse(BaseModel): ) class Config: - schema_extra = { + json_schema_extra = { "example": { "completion": { "id": "chatcmpl-example123", @@ -104,7 +104,7 @@ class RAGAgentResponse(BaseModel): ) class Config: - schema_extra = { + json_schema_extra = { "example": { "completion": { "id": "chatcmpl-example456", diff --git a/r2r/cli/cli.py b/r2r/cli/cli.py index 0e7fbdadf..c2cda4a29 100644 --- a/r2r/cli/cli.py +++ b/r2r/cli/cli.py @@ -12,7 +12,6 @@ cli.add_command(server_operations.docker_down) cli.add_command(server_operations.generate_report) cli.add_command(server_operations.health) -cli.add_command(server_operations.migrate) cli.add_command(server_operations.serve) cli.add_command(server_operations.update) cli.add_command(server_operations.version) diff --git a/r2r/cli/commands/server_operations.py b/r2r/cli/commands/server_operations.py index 0632762ca..1e0ae8933 100644 --- a/r2r/cli/commands/server_operations.py +++ b/r2r/cli/commands/server_operations.py @@ -7,8 +7,6 @@ import click from dotenv import load_dotenv -from alembic import command -from alembic.config import Config from r2r.cli.command_group import cli from r2r.cli.utils.docker_utils import ( bring_down_docker_compose, @@ -134,30 +132,6 @@ def health(obj): click.echo(response) -@cli.command() -@click.option( - "--config", - default="alembic.ini", - help="Path to the Alembic configuration file", -) -@click.pass_obj -def migrate(obj, config): - """Run database migrations.""" - click.echo("Running database migrations...") - - try: - # Create Alembic configuration - alembic_cfg = Config(config) - - # Run the migration - command.upgrade(alembic_cfg, "head") - - click.echo("Migrations completed successfully.") - except Exception as e: - click.echo(f"Error running migrations: {str(e)}") - sys.exit(1) - - @cli.command() @click.option("--host", default="0.0.0.0", help="Host to run the server on") @click.option("--port", default=8000, help="Port to run the server on") diff --git a/r2r/main/api/client/auth.py b/r2r/main/api/client/auth.py index 63b1afb9e..c1a627056 100644 --- a/r2r/main/api/client/auth.py +++ b/r2r/main/api/client/auth.py @@ -6,12 +6,12 @@ class AuthMethods: - @staticmethod async def register(client, email: str, password: str) -> UserResponse: data = {"email": email, "password": password} return await client._make_request("POST", "register", json=data) + @staticmethod async def verify_email(client, verification_code: str) -> dict: return await client._make_request( "POST", @@ -19,6 +19,7 @@ async def verify_email(client, verification_code: str) -> dict: json={"verification_code": verification_code}, ) + @staticmethod async def login(client, email: str, password: str) -> dict[str, Token]: data = {"username": email, "password": password} response = await client._make_request("POST", "login", data=data) @@ -26,9 +27,11 @@ async def login(client, email: str, password: str) -> dict[str, Token]: client._refresh_token = response["results"]["refresh_token"]["token"] return response["results"] + @staticmethod async def user(client) -> UserResponse: return await client._make_request("GET", "user") + @staticmethod async def refresh_access_token(client) -> dict[str, Token]: data = {"refresh_token": client._refresh_token} response = await client._make_request( @@ -38,6 +41,7 @@ async def refresh_access_token(client) -> dict[str, Token]: client._refresh_token = response["results"]["refresh_token"]["token"] return response["results"] + @staticmethod async def change_password( client, current_password: str, new_password: str ) -> dict: @@ -47,26 +51,31 @@ async def change_password( } return await client._make_request("POST", "change_password", json=data) + @staticmethod async def request_password_reset(client, email: str) -> dict: return await client._make_request( "POST", "request_password_reset", json={"email": email} ) + @staticmethod async def confirm_password_reset( client, reset_token: str, new_password: str ) -> dict: data = {"reset_token": reset_token, "new_password": new_password} return await client._make_request("POST", "reset_password", json=data) + @staticmethod async def logout(client) -> dict: response = await client._make_request("POST", "logout") client.access_token = None client._refresh_token = None return response + @staticmethod async def get_user_profile(client, user_id: uuid.UUID) -> UserResponse: return await client._make_request("GET", f"user/{user_id}") + @staticmethod async def update_user( client, email: Optional[str] = None, @@ -83,6 +92,7 @@ async def update_user( data = {k: v for k, v in data.items() if v is not None} return await client._make_request("PUT", "user", json=data) + @staticmethod async def delete_user( client, user_id: uuid.UUID, password: Optional[str] = None ) -> dict: diff --git a/r2r/main/api/client/client.py b/r2r/main/api/client/client.py index 7f0cf3bfd..d4991e432 100644 --- a/r2r/main/api/client/client.py +++ b/r2r/main/api/client/client.py @@ -64,7 +64,7 @@ async def handle_request_error_async(response): else: message = str(error_content) except Exception: - message = response.text() + message = response.text raise R2RException( status_code=response.status_code, @@ -135,7 +135,7 @@ async def _make_request(self, method, endpoint, **kwargs): except httpx.RequestError as e: raise R2RException( status_code=500, message=f"Request failed: {str(e)}" - ) + ) from e def _get_auth_header(self) -> dict: if not self.access_token: diff --git a/r2r/main/api/client/ingestion.py b/r2r/main/api/client/ingestion.py index 5e85e8304..9a2514cca 100644 --- a/r2r/main/api/client/ingestion.py +++ b/r2r/main/api/client/ingestion.py @@ -163,36 +163,6 @@ async def update_files( "POST", "update_files", data=data, files=files ) - @staticmethod - async def get_document_info(client, document_id: str) -> dict: - """ - Retrieve information about a specific document. - - Args: - document_id (str): The ID of the document to retrieve information for. - - Returns: - dict: Document information including metadata, status, and version. - """ - return await client._make_request( - "GET", f"document_info/{document_id}" - ) - - @staticmethod - async def delete_document(client, document_id: str) -> dict: - """ - Delete a specific document from the system. - - Args: - document_id (str): The ID of the document to delete. - - Returns: - dict: Confirmation of document deletion. - """ - return await client._make_request( - "DELETE", f"delete_document/{document_id}" - ) - @staticmethod async def list_documents( client, diff --git a/r2r/main/api/client/management.py b/r2r/main/api/client/management.py index b056c6034..dac614bb9 100644 --- a/r2r/main/api/client/management.py +++ b/r2r/main/api/client/management.py @@ -14,8 +14,11 @@ async def update_prompt( client, name: str, template: Optional[str] = None, - input_types: Optional[dict[str, str]] = {}, + input_types: Optional[dict[str, str]] = None, ) -> dict: + if input_types is None: + input_types = {} + data = { "name": name, "template": template, diff --git a/r2r/main/api/client/restructure.py b/r2r/main/api/client/restructure.py index e117243f8..0fcbc9f82 100644 --- a/r2r/main/api/client/restructure.py +++ b/r2r/main/api/client/restructure.py @@ -41,7 +41,7 @@ async def query_graph(client, query: str) -> Dict[str, Any]: ) @staticmethod - async def get_graph_statistics(self) -> Dict[str, Any]: + async def get_graph_statistics(client) -> Dict[str, Any]: """ Get statistics about the knowledge graph. diff --git a/r2r/main/api/routes/ingestion/base.py b/r2r/main/api/routes/ingestion/base.py index 8da142dca..db23021e0 100644 --- a/r2r/main/api/routes/ingestion/base.py +++ b/r2r/main/api/routes/ingestion/base.py @@ -182,20 +182,19 @@ async def ingest_files_app( # Handle user management logic at the request level if not auth_user: for metadata in metadatas or []: - if "user_id" in metadata: - if not is_superuser and metadata["user_id"] != str( - auth_user.id - ): - raise R2RException( - status_code=403, - message="Non-superusers cannot set user_id in metadata.", - ) - if "group_ids" in metadata: - if not is_superuser: - raise R2RException( - status_code=403, - message="Non-superusers cannot set group_ids in metadata.", - ) + if "user_id" in metadata and ( + not is_superuser + and metadata["user_id"] != str(auth_user.id) + ): + raise R2RException( + status_code=403, + message="Non-superusers cannot set user_id in metadata.", + ) + if "group_ids" in metadata and not is_superuser: + raise R2RException( + status_code=403, + message="Non-superusers cannot set group_ids in metadata.", + ) # If user is not a superuser, set user_id in metadata metadata["user_id"] = str(auth_user.id) diff --git a/r2r/main/api/routes/management/base.py b/r2r/main/api/routes/management/base.py index fc3b3250b..f5dfb90ff 100644 --- a/r2r/main/api/routes/management/base.py +++ b/r2r/main/api/routes/management/base.py @@ -5,7 +5,7 @@ from typing import Optional import psutil -from fastapi import Body, Depends, Path, Query +from fastapi import Body, Depends, Path, Query, Response from pydantic import BaseModel from r2r.base import R2RException @@ -13,7 +13,6 @@ WrappedAddUserResponse, WrappedAnalyticsResponse, WrappedAppSettingsResponse, - WrappedDeleteResponse, WrappedDocumentChunkResponse, WrappedDocumentOverviewResponse, WrappedGroupListResponse, @@ -136,14 +135,14 @@ async def get_analytics_app( f"Invalid data in query parameters: {str(e)}", 400 ) - @self.router.delete("/delete") + @self.router.delete("/delete", status_code=204) @self.base_endpoint async def delete_app( filters: Optional[str] = Query("{}"), auth_user=Depends(self.engine.providers.auth.auth_wrapper), - ) -> WrappedDeleteResponse: + ) -> None: filters_dict = json.loads(filters) if filters else None - return await self.engine.adelete(filters=filters_dict) + await self.engine.adelete(filters=filters_dict) @self.router.get("/document_chunks") @self.base_endpoint @@ -190,7 +189,7 @@ async def documents_overview_app( auth_user=Depends(self.engine.providers.auth.auth_wrapper), ) -> WrappedDocumentOverviewResponse: request_user_ids = ( - [auth_user.id] if not auth_user.is_superuser else None + None if auth_user.is_superuser else [auth_user.id] ) return await self.engine.adocuments_overview( user_ids=request_user_ids, diff --git a/r2r/main/services/management_service.py b/r2r/main/services/management_service.py index 4ff8f4101..1833ba218 100644 --- a/r2r/main/services/management_service.py +++ b/r2r/main/services/management_service.py @@ -4,6 +4,8 @@ from collections import defaultdict from typing import Any, Dict, List, Optional, Tuple +import toml + from r2r.base import ( AnalysisTypes, LogFilterCriteria, @@ -41,18 +43,6 @@ def __init__( logging_connection, ) - @telemetry_event("UpdatePrompt") - async def update_prompt( - self, - name: str, - template: Optional[str] = None, - input_types: Optional[dict[str, str]] = {}, - *args, - **kwargs, - ): - self.providers.prompt.update_prompt(name, template, input_types) - return f"Prompt '{name}' added successfully." - @telemetry_event("Logs") async def alogs( self, run_type_filter: Optional[str] = None, max_runs: int = 100 @@ -72,7 +62,6 @@ async def alogs( logs = await self.logging_connection.get_logs(run_ids) aggregated_logs = [] - warning_shown = False for run in run_info: run_logs = [ @@ -98,14 +87,8 @@ async def alogs( if run.timestamp: log_entry["timestamp"] = run.timestamp.isoformat() - if hasattr(run, "user_id"): - if run.user_id is not None: - log_entry["user_id"] = run.user_id - elif not warning_shown: - logger.warning( - "Logs are missing user ids. This may be due to an outdated database schema. Please run `r2r migrate` to run database migrations." - ) - warning_shown = True + if hasattr(run, "user_id") and run.user_id is not None: + log_entry["user_id"] = run.user_id aggregated_logs.append(log_entry) @@ -196,8 +179,10 @@ async def aanalytics( @telemetry_event("AppSettings") async def aapp_settings(self, *args: Any, **kwargs: Any): prompts = self.providers.prompt.get_all_prompts() + config_toml = self.config.to_toml() + config_dict = toml.loads(config_toml) return { - "config": self.config.to_toml(), + "config": config_dict, "prompts": { name: prompt.dict() for name, prompt in prompts.items() }, @@ -298,7 +283,7 @@ async def delete( self.providers.database.relational.delete_from_documents_overview( document_id ) - return results + return {} @telemetry_event("DocumentsOverview") async def adocuments_overview( @@ -382,10 +367,9 @@ async def aassign_document_to_group( self, document_id: str, group_id: uuid.UUID ): - success = self.providers.database.vector.assign_document_to_group( + if self.providers.database.vector.assign_document_to_group( document_id, group_id - ) - if success: + ): return {"message": "Document assigned to group successfully"} else: raise R2RException( @@ -397,10 +381,9 @@ async def aassign_document_to_group( async def aremove_document_from_group( self, document_id: str, group_id: uuid.UUID ): - success = self.providers.database.vector.remove_document_from_group( + if self.providers.database.vector.remove_document_from_group( document_id, group_id - ) - if success: + ): return {"message": "Document removed from group successfully"} else: raise R2RException( @@ -435,27 +418,39 @@ def generate_output( # Print grouped relationships for subject, relations in grouped_relationships.items(): - output.append(f"\n== {subject} ==") - for relation, objects in relations.items(): - output.append(f" {relation}:") - for obj in objects: - output.append(f" - {obj}") + output.extend( + [ + f"\n== {subject} ==", + *(f" {relation}:" for relation in relations), + *( + f" - {obj}" + for objects in relations.values() + for obj in objects + ), + ] + ) # Print basic graph statistics - output.append("\n== Graph Statistics ==") - output.append(f"Number of nodes: {len(graph)}") - output.append( - f"Number of edges: {sum(len(neighbors) for neighbors in graph.values())}" - ) - output.append( - f"Number of connected components: {self.count_connected_components(graph)}" + output.extend( + [ + "\n== Graph Statistics ==", + f"Number of nodes: {len(graph)}", + f"Number of edges: {sum(len(neighbors) for neighbors in graph.values())}", + f"Number of connected components: {self.count_connected_components(graph)}", + ] ) # Find central nodes central_nodes = self.get_central_nodes(graph) - output.append("\n== Most Central Nodes ==") - for node, centrality in central_nodes: - output.append(f" {node}: {centrality:.4f}") + output.extend( + [ + "\n== Most Central Nodes ==", + *( + f" {node}: {centrality:.4f}" + for node, centrality in central_nodes + ), + ] + ) return output diff --git a/r2r/providers/database/vector.py b/r2r/providers/database/vector.py index c8523a159..0b3728fef 100644 --- a/r2r/providers/database/vector.py +++ b/r2r/providers/database/vector.py @@ -41,11 +41,9 @@ def __init__(self, config: DatabaseConfig, *args, **kwargs): ) # Check if a complete Postgres URI is provided - postgres_uri = self.config.extra_fields.get( + if postgres_uri := self.config.extra_fields.get( "postgres_uri" - ) or os.getenv("POSTGRES_URI") - - if postgres_uri: + ) or os.getenv("POSTGRES_URI"): # Log loudly that Postgres URI is being used logger.warning("=" * 50) logger.warning( @@ -353,7 +351,7 @@ def hybrid_search( ) params = { - "query_text": str(query_text), + "query_text": query_text, "query_embedding": list(query_vector), "match_limit": limit, "full_text_weight": full_text_weight, From 91f35c903af51cf93c1a6aab36b7d6b2c4fdbca5 Mon Sep 17 00:00:00 2001 From: emrgnt-cmplxty <68796651+emrgnt-cmplxty@users.noreply.github.com> Date: Fri, 16 Aug 2024 17:39:54 -0700 Subject: [PATCH 03/74] Feature/merge dev owen changes (#880) * add group ids to document abstraction, first steps * extend group permissions * up * add tests for new group features * up * fixup auth * onboard extensive regression tests * adding regression tests * finish tests * rm selenium * test observability * uncomment tests * checkin first set of group tests * modify search, passing vector tests * checkin work * full delete logic * update search to use new filters * check in * Clean up * Check in * add search * tests/test_end_to_end.py::test_ingest_txt_document passing * cleanup logging * make schemas explicit * move to run logger abstraction * cleanup some test workflows * revive tests * tweak to pass tests * tweak rrf * finish hybrid search cleanup * fixup on regr tests, regen payloads * refresh payloads * refactor api model * Feature/refactor api model (#868) * cleanup imports * flake and cleanup * coherent global import / export structure * add ingestion response models * add management response models * cleanups * checkin work on routes * remove request models * last fixes * merge * add user / group gating * working test groups * updating client * rename service to restructure * add get documents for group endpoint * fix client bugs * return delete format * merge cleanups * merge * finalize --------- Co-authored-by: NolanTrem <34580718+NolanTrem@users.noreply.github.com> --- r2r/base/abstractions/user.py | 7 + r2r/base/providers/database.py | 118 -------- r2r/{examples => }/configs/auth.toml | 0 r2r/{examples => }/configs/graphrag.toml | 0 r2r/{examples => }/configs/local_llm.toml | 0 .../configs/local_llm_neo4j_kg.toml | 0 r2r/{examples => }/configs/neo4j_kg.toml | 0 .../configs/neo4j_kg_no_vector_postgres.toml | 0 .../configs/postgres_logging.toml | 0 r2r/main/api/client/__init__.py | 2 + r2r/main/api/client/auth.py | 8 +- r2r/main/api/client/client.py | 9 +- r2r/main/api/client/ingestion.py | 68 +---- r2r/main/api/client/management.py | 58 +++- r2r/main/api/client/retrieval.py | 8 +- r2r/main/api/routes/auth/base.py | 5 +- r2r/main/api/routes/ingestion/base.py | 27 +- r2r/main/api/routes/management/base.py | 76 ++++- r2r/main/api/routes/restructure/__init__.py | 0 r2r/main/api/routes/restructure/base.py | 37 +++ r2r/main/app.py | 3 +- r2r/main/assembly/builder.py | 4 +- r2r/main/engine.py | 6 + r2r/main/services/auth_service.py | 7 - r2r/main/services/management_service.py | 28 +- r2r/providers/auth/r2r_auth.py | 6 - r2r/providers/database/group.py | 36 +-- r2r/providers/database/user.py | 105 +++++-- r2r/providers/database/vector.py | 8 +- tests/test_auth.py | 46 +-- tests/test_client.py | 66 +++++ tests/test_end_to_end.py | 31 +- tests/test_groups.py | 9 - tests/test_groups_client.py | 10 +- tests/test_kg.py | 278 +++++++++--------- 35 files changed, 555 insertions(+), 511 deletions(-) rename r2r/{examples => }/configs/auth.toml (100%) rename r2r/{examples => }/configs/graphrag.toml (100%) rename r2r/{examples => }/configs/local_llm.toml (100%) rename r2r/{examples => }/configs/local_llm_neo4j_kg.toml (100%) rename r2r/{examples => }/configs/neo4j_kg.toml (100%) rename r2r/{examples => }/configs/neo4j_kg_no_vector_postgres.toml (100%) rename r2r/{examples => }/configs/postgres_logging.toml (100%) create mode 100644 r2r/main/api/routes/restructure/__init__.py create mode 100644 r2r/main/api/routes/restructure/base.py diff --git a/r2r/base/abstractions/user.py b/r2r/base/abstractions/user.py index 5bc7229c8..26d2aaaca 100644 --- a/r2r/base/abstractions/user.py +++ b/r2r/base/abstractions/user.py @@ -36,6 +36,13 @@ class TokenData(BaseModel): class UserStats(BaseModel): user_id: UUID + email: str + is_superuser: bool + is_active: bool + is_verified: bool + created_at: datetime + updated_at: datetime + group_ids: list[UUID] num_files: int total_size_in_bytes: int document_ids: list[UUID] diff --git a/r2r/base/providers/database.py b/r2r/base/providers/database.py index ddc1a120e..a286e3151 100644 --- a/r2r/base/providers/database.py +++ b/r2r/base/providers/database.py @@ -34,130 +34,12 @@ class VectorDBProvider(Provider, ABC): def _initialize_vector_db(self, dimension: int) -> None: pass - @abstractmethod - def create_index(self, index_type, column_name, index_options): - pass - - @abstractmethod - def upsert(self, entry: VectorEntry, commit: bool = True) -> None: - pass - - @abstractmethod - def search( - self, - query_vector: list[float], - filters: dict[str, VectorDBFilterValue] = {}, - limit: int = 10, - *args, - **kwargs, - ) -> list[VectorSearchResult]: - pass - - @abstractmethod - def hybrid_search( - self, - query_text: str, - query_vector: list[float], - limit: int = 10, - filters: Optional[dict[str, VectorDBFilterValue]] = None, - full_text_weight: float = 1.0, - semantic_weight: float = 1.0, - rrf_k: int = 20, - *args, - **kwargs, - ) -> list[VectorSearchResult]: - pass - - @abstractmethod - def delete(self, filters: dict[str, VectorDBFilterValue]) -> list[str]: - pass - class RelationalDBProvider(Provider, ABC): @abstractmethod def _initialize_relational_db(self) -> None: pass - @abstractmethod - def upsert_documents_overview( - self, document_infs: list[DocumentInfo] - ) -> None: - pass - - @abstractmethod - def get_documents_overview( - self, - filter_user_ids: Optional[str] = None, - filter_group_ids: Optional[list[str]] = None, - filter_document_ids: Optional[list[str]] = None, - ) -> list[DocumentInfo]: - pass - - @abstractmethod - def delete_from_documents_overview( - self, document_id: str, version: Optional[str] = None - ) -> dict: - pass - - @abstractmethod - def get_users_overview(self, user_ids: Optional[list[str]] = None) -> dict: - pass - - @abstractmethod - def create_user(self, email: str, password: str) -> UserResponse: - pass - - @abstractmethod - def get_user_by_email(self, email: str) -> Optional[UserResponse]: - pass - - @abstractmethod - def store_verification_code( - self, user_id: UUID, verification_code: str, expiry: datetime - ): - pass - - @abstractmethod - def get_user_id_by_verification_code( - self, verification_code: str - ) -> Optional[UUID]: - pass - - @abstractmethod - def mark_user_as_verified(self, user_id: UUID): - pass - - @abstractmethod - def mark_user_as_superuser(self, user_id: UUID): - pass - - @abstractmethod - def remove_verification_code(self, verification_code: str): - pass - - @abstractmethod - def get_user_by_id(self, user_id: UUID) -> Optional[UserResponse]: - pass - - @abstractmethod - def update_user( - self, - user_id: UUID, - email: Optional[str], - name: Optional[str], - bio: Optional[str], - profile_picture: Optional[str], - ) -> UserResponse: - pass - - @abstractmethod - def delete_user(self, user_id: UUID): - pass - - @abstractmethod - def get_all_users(self) -> list[UserResponse]: - pass - class DatabaseProvider(Provider): diff --git a/r2r/examples/configs/auth.toml b/r2r/configs/auth.toml similarity index 100% rename from r2r/examples/configs/auth.toml rename to r2r/configs/auth.toml diff --git a/r2r/examples/configs/graphrag.toml b/r2r/configs/graphrag.toml similarity index 100% rename from r2r/examples/configs/graphrag.toml rename to r2r/configs/graphrag.toml diff --git a/r2r/examples/configs/local_llm.toml b/r2r/configs/local_llm.toml similarity index 100% rename from r2r/examples/configs/local_llm.toml rename to r2r/configs/local_llm.toml diff --git a/r2r/examples/configs/local_llm_neo4j_kg.toml b/r2r/configs/local_llm_neo4j_kg.toml similarity index 100% rename from r2r/examples/configs/local_llm_neo4j_kg.toml rename to r2r/configs/local_llm_neo4j_kg.toml diff --git a/r2r/examples/configs/neo4j_kg.toml b/r2r/configs/neo4j_kg.toml similarity index 100% rename from r2r/examples/configs/neo4j_kg.toml rename to r2r/configs/neo4j_kg.toml diff --git a/r2r/examples/configs/neo4j_kg_no_vector_postgres.toml b/r2r/configs/neo4j_kg_no_vector_postgres.toml similarity index 100% rename from r2r/examples/configs/neo4j_kg_no_vector_postgres.toml rename to r2r/configs/neo4j_kg_no_vector_postgres.toml diff --git a/r2r/examples/configs/postgres_logging.toml b/r2r/configs/postgres_logging.toml similarity index 100% rename from r2r/examples/configs/postgres_logging.toml rename to r2r/configs/postgres_logging.toml diff --git a/r2r/main/api/client/__init__.py b/r2r/main/api/client/__init__.py index 64ce2e9f6..0d6c2e934 100644 --- a/r2r/main/api/client/__init__.py +++ b/r2r/main/api/client/__init__.py @@ -1 +1,3 @@ from .client import R2RClient + +__all__ = ["R2RClient"] diff --git a/r2r/main/api/client/auth.py b/r2r/main/api/client/auth.py index c1a627056..151753310 100644 --- a/r2r/main/api/client/auth.py +++ b/r2r/main/api/client/auth.py @@ -25,7 +25,7 @@ async def login(client, email: str, password: str) -> dict[str, Token]: response = await client._make_request("POST", "login", data=data) client.access_token = response["results"]["access_token"]["token"] client._refresh_token = response["results"]["refresh_token"]["token"] - return response["results"] + return response @staticmethod async def user(client) -> UserResponse: @@ -39,7 +39,7 @@ async def refresh_access_token(client) -> dict[str, Token]: ) client.access_token = response["results"]["access_token"]["token"] client._refresh_token = response["results"]["refresh_token"]["token"] - return response["results"] + return response @staticmethod async def change_password( @@ -71,10 +71,6 @@ async def logout(client) -> dict: client._refresh_token = None return response - @staticmethod - async def get_user_profile(client, user_id: uuid.UUID) -> UserResponse: - return await client._make_request("GET", f"user/{user_id}") - @staticmethod async def update_user( client, diff --git a/r2r/main/api/client/client.py b/r2r/main/api/client/client.py index d4991e432..a6935c1b2 100644 --- a/r2r/main/api/client/client.py +++ b/r2r/main/api/client/client.py @@ -53,7 +53,7 @@ async def handle_request_error_async(response): if response.headers.get("content-type") == "application/json": error_content = await response.json() else: - error_content = await response.text() + error_content = await response.text if isinstance(error_content, dict) and "detail" in error_content: detail = error_content["detail"] @@ -123,19 +123,20 @@ async def _make_request(self, method, endpoint, **kwargs): if isinstance(self.client, TestClient): response = getattr(self.client, method.lower())( - url, headers=headers, **kwargs + url, headers=headers, params=params, **kwargs ) + return response.json() if response.content else None else: try: response = await self.client.request( method, url, headers=headers, params=params, **kwargs ) await handle_request_error_async(response) - return response.json() + return response.json() if response.content else None except httpx.RequestError as e: raise R2RException( status_code=500, message=f"Request failed: {str(e)}" - ) from e + ) def _get_auth_header(self) -> dict: if not self.access_token: diff --git a/r2r/main/api/client/ingestion.py b/r2r/main/api/client/ingestion.py index 9a2514cca..061f410cb 100644 --- a/r2r/main/api/client/ingestion.py +++ b/r2r/main/api/client/ingestion.py @@ -4,40 +4,10 @@ from contextlib import ExitStack from typing import List, Optional, Union -from r2r.base import ChunkingConfig, Document, DocumentType +from r2r.base import ChunkingConfig class IngestionMethods: - @staticmethod - async def ingest_documents( - client, - documents: List[Document], - versions: Optional[List[str]] = None, - chunking_config_override: Optional[Union[dict, ChunkingConfig]] = None, - ) -> dict: - """ - Ingest a list of documents into the system. - - Args: - documents (List[Document]): List of Document objects to ingest. - versions (Optional[List[str]]): List of version strings for each document. - chunking_config_override (Optional[Union[dict, ChunkingConfig]]): Custom chunking configuration. - - Returns: - dict: Ingestion results containing processed, failed, and skipped documents. - """ - data = { - "documents": [doc.dict() for doc in documents], - "versions": versions, - "chunking_config_override": ( - chunking_config_override.dict() - if isinstance(chunking_config_override, ChunkingConfig) - else chunking_config_override - ), - } - return await client._make_request( - "POST", "ingest_documents", json=data - ) @staticmethod async def ingest_files( @@ -162,39 +132,3 @@ async def update_files( return await client._make_request( "POST", "update_files", data=data, files=files ) - - @staticmethod - async def list_documents( - client, - user_id: Optional[str] = None, - group_ids: Optional[List[str]] = None, - document_type: Optional[DocumentType] = None, - status: Optional[str] = None, - page: int = 1, - page_size: int = 50, - ) -> dict: - """ - List documents based on various filters. - - Args: - user_id (Optional[str]): Filter by user ID. - group_ids (Optional[List[str]]): Filter by group IDs. - document_type (Optional[DocumentType]): Filter by document type. - status (Optional[str]): Filter by document status. - page (int): Page number for pagination. - page_size (int): Number of items per page. - - Returns: - dict: List of documents matching the specified filters. - """ - params = { - "user_id": user_id, - "group_ids": json.dumps(group_ids) if group_ids else None, - "document_type": document_type.value if document_type else None, - "status": status, - "page": page, - "page_size": page_size, - } - return await client._make_request( - "GET", "list_documents", params=params - ) diff --git a/r2r/main/api/client/management.py b/r2r/main/api/client/management.py index dac614bb9..b42bb3f13 100644 --- a/r2r/main/api/client/management.py +++ b/r2r/main/api/client/management.py @@ -1,5 +1,6 @@ +import json import uuid -from typing import Optional +from typing import Any, Optional, Union from r2r.base import VectorDBFilterValue @@ -14,11 +15,8 @@ async def update_prompt( client, name: str, template: Optional[str] = None, - input_types: Optional[dict[str, str]] = None, + input_types: Optional[dict[str, str]] = {}, ) -> dict: - if input_types is None: - input_types = {} - data = { "name": name, "template": template, @@ -73,9 +71,11 @@ async def delete( client, filters: dict[str, VectorDBFilterValue], ) -> dict: + filters_json = json.dumps(filters) + return await client._make_request( - "DELETE", "delete", json={"filters": filters} - ) + "DELETE", "delete", params={"filters": filters_json} + ) or {"results": {}} @staticmethod async def documents_overview( @@ -103,7 +103,7 @@ async def document_chunks( document_id: uuid.UUID, ) -> dict: return await client._make_request( - "GET", f"document_chunks/{document_id}" + "GET", "document_chunks", params={"document_id": document_id} ) @staticmethod @@ -261,10 +261,50 @@ async def get_groups_for_user( async def groups_overview( client, group_ids: Optional[list[uuid.UUID]] = None, + limit: int = 100, + offset: int = 0, ) -> dict: params = { - "group_ids": [str(gid) for gid in group_ids] if group_ids else None + "limit": limit, + "offset": offset, } + if group_ids is not None: + params["group_ids"] = [str(gid) for gid in group_ids] return await client._make_request( "GET", "groups_overview", params=params ) + + @staticmethod + async def get_documents_in_group( + client, + group_id: uuid.UUID, + offset: int = 0, + limit: int = 100, + ) -> dict: + params = { + "offset": offset, + "limit": limit, + } + return await client._make_request( + "GET", f"group/{group_id}/documents", params=params + ) + + @staticmethod + async def analytics( + client, + filter_criteria: Optional[Union[dict, str]] = None, + analysis_types: Optional[Union[dict, str]] = None, + ) -> dict: + params = {} + if filter_criteria: + if isinstance(filter_criteria, dict): + params["filter_criteria"] = json.dumps(filter_criteria) + else: + params["filter_criteria"] = filter_criteria + if analysis_types: + if isinstance(analysis_types, dict): + params["analysis_types"] = json.dumps(analysis_types) + else: + params["analysis_types"] = analysis_types + + return await client._make_request("GET", "analytics", params=params) diff --git a/r2r/main/api/client/retrieval.py b/r2r/main/api/client/retrieval.py index 93771a85a..c28d1d2b2 100644 --- a/r2r/main/api/client/retrieval.py +++ b/r2r/main/api/client/retrieval.py @@ -40,7 +40,7 @@ async def search( ), } response = await client._make_request("POST", "search", json=data) - return SearchResponse(**response["results"]) + return response @staticmethod async def rag( @@ -87,7 +87,7 @@ async def stream_response(): return stream_response() else: response = await client._make_request("POST", "rag", json=data) - return RAGResponse(**response["results"]) + return response @staticmethod async def agent( @@ -118,7 +118,7 @@ async def agent( ] data = { - "messages": [msg.dict() for msg in messages], + "messages": [msg.model_dump() for msg in messages], "rag_generation_config": rag_generation_config.dict(), "vector_search_settings": ( vector_search_settings.dict() @@ -143,4 +143,4 @@ async def stream_response(): return stream_response() else: response = await client._make_request("POST", "agent", json=data) - return [Message(**msg) for msg in response["results"]] + return response diff --git a/r2r/main/api/routes/auth/base.py b/r2r/main/api/routes/auth/base.py index f824bb66a..62a6c7285 100644 --- a/r2r/main/api/routes/auth/base.py +++ b/r2r/main/api/routes/auth/base.py @@ -165,16 +165,17 @@ async def request_password_reset_app( This endpoint initiates the password reset process by sending a reset link to the specified email address. """ + print("email = ", email) result = await self.engine.arequest_password_reset(email) return GenericMessageResponse(message=result["message"]) @self.router.post( - "/reset_password/{reset_token}", + "/reset_password", response_model=WrappedGenericMessageResponse, ) @self.base_endpoint async def reset_password_app( - reset_token: str = Path(..., description="Password reset token"), + reset_token: str = Body(..., description="Password reset token"), new_password: str = Body(..., description="New password"), ): result = await self.engine.aconfirm_password_reset( diff --git a/r2r/main/api/routes/ingestion/base.py b/r2r/main/api/routes/ingestion/base.py index db23021e0..8da142dca 100644 --- a/r2r/main/api/routes/ingestion/base.py +++ b/r2r/main/api/routes/ingestion/base.py @@ -182,19 +182,20 @@ async def ingest_files_app( # Handle user management logic at the request level if not auth_user: for metadata in metadatas or []: - if "user_id" in metadata and ( - not is_superuser - and metadata["user_id"] != str(auth_user.id) - ): - raise R2RException( - status_code=403, - message="Non-superusers cannot set user_id in metadata.", - ) - if "group_ids" in metadata and not is_superuser: - raise R2RException( - status_code=403, - message="Non-superusers cannot set group_ids in metadata.", - ) + if "user_id" in metadata: + if not is_superuser and metadata["user_id"] != str( + auth_user.id + ): + raise R2RException( + status_code=403, + message="Non-superusers cannot set user_id in metadata.", + ) + if "group_ids" in metadata: + if not is_superuser: + raise R2RException( + status_code=403, + message="Non-superusers cannot set group_ids in metadata.", + ) # If user is not a superuser, set user_id in metadata metadata["user_id"] = str(auth_user.id) diff --git a/r2r/main/api/routes/management/base.py b/r2r/main/api/routes/management/base.py index f5dfb90ff..8b1435991 100644 --- a/r2r/main/api/routes/management/base.py +++ b/r2r/main/api/routes/management/base.py @@ -5,7 +5,7 @@ from typing import Optional import psutil -from fastapi import Body, Depends, Path, Query, Response +from fastapi import Body, Depends, Path, Query from pydantic import BaseModel from r2r.base import R2RException @@ -138,11 +138,11 @@ async def get_analytics_app( @self.router.delete("/delete", status_code=204) @self.base_endpoint async def delete_app( - filters: Optional[str] = Query("{}"), + filters: str = Query(..., description="JSON-encoded filters"), auth_user=Depends(self.engine.providers.auth.auth_wrapper), ) -> None: filters_dict = json.loads(filters) if filters else None - await self.engine.adelete(filters=filters_dict) + return await self.engine.adelete(filters=filters_dict) @self.router.get("/document_chunks") @self.base_endpoint @@ -189,7 +189,7 @@ async def documents_overview_app( auth_user=Depends(self.engine.providers.auth.auth_wrapper), ) -> WrappedDocumentOverviewResponse: request_user_ids = ( - None if auth_user.is_superuser else [auth_user.id] + [auth_user.id] if not auth_user.is_superuser else None ) return await self.engine.adocuments_overview( user_ids=request_user_ids, @@ -314,12 +314,12 @@ async def remove_user_from_group_app( return await self.engine.aremove_user_from_group(user_id, group_id) # TODO - Proivde response model - @self.router.get("/get_users_in_group/{group_id}/{offset}/{limit}") + @self.router.get("/get_users_in_group/{group_id}") @self.base_endpoint async def get_users_in_group_app( group_id: uuid.UUID = Path(..., description="Group ID"), - offset: int = Path(..., description="Offset"), - limit: int = Path(..., description="limit"), + offset: int = Query(..., description="Offset"), + limit: int = Query(..., description="limit"), auth_user=Depends(self.engine.providers.auth.auth_wrapper), ): if not auth_user.is_superuser: @@ -347,15 +347,20 @@ async def get_groups_for_user_app( @self.base_endpoint async def groups_overview_app( group_ids: Optional[list[uuid.UUID]] = Query(None), + limit: Optional[int] = Query(100, ge=1, le=1000), + offset: Optional[int] = Query(0, ge=0), auth_user=Depends(self.engine.providers.auth.auth_wrapper), ) -> WrappedGroupOverviewResponse: + print("... group_ids = ", group_ids) if not auth_user.is_superuser: raise R2RException( "Only a superuser can call the `groups_overview` endpoint.", 403, ) - return await self.engine.agroups_overview(group_ids=group_ids) + return await self.engine.agroups_overview( + group_ids=group_ids, limit=limit, offset=offset + ) @self.router.post("/score_completion") @self.base_endpoint @@ -406,7 +411,56 @@ async def get_document_groups_app( ) -> WrappedGroupListResponse: return await self.engine.aget_document_groups(document_id) + @self.router.get("/group/{group_id}/documents") + @self.base_endpoint + async def get_documents_in_group_app( + group_id: uuid.UUID = Path(..., description="Group ID"), + offset: int = Query(0, ge=0), + limit: int = Query(100, ge=1, le=1000), + auth_user=Depends(self.engine.providers.auth.auth_wrapper), + ) -> WrappedDocumentOverviewResponse: + if not auth_user.is_superuser: + raise R2RException( + "Only a superuser can get documents in a group.", 403 + ) + return await self.engine.aget_documents_in_group( + group_id, offset, limit + ) -class R2RExtractionRequest(BaseModel): - entity_types: list[str] - relations: list[str] + @self.router.post("/assign_document_to_group") + @self.base_endpoint + async def assign_document_to_group_app( + document_id: str = Body(..., description="Document ID"), + group_id: uuid.UUID = Body(..., description="Group ID"), + auth_user=Depends(self.engine.providers.auth.auth_wrapper), + ) -> WrappedGroupResponse: + if not auth_user.is_superuser: + raise R2RException( + "Only a superuser can assign documents to groups.", 403 + ) + return await self.engine.aassign_document_to_group( + document_id, group_id + ) + + @self.router.post("/remove_document_from_group") + @self.base_endpoint + async def remove_document_from_group_app( + document_id: str = Body(..., description="Document ID"), + group_id: uuid.UUID = Body(..., description="Group ID"), + auth_user=Depends(self.engine.providers.auth.auth_wrapper), + ) -> WrappedGroupResponse: + if not auth_user.is_superuser: + raise R2RException( + "Only a superuser can remove documents from groups.", 403 + ) + return await self.engine.aremove_document_from_group( + document_id, group_id + ) + + @self.router.get("/get_document_groups/{document_id}") + @self.base_endpoint + async def get_document_groups_app( + document_id: str = Path(..., description="Document ID"), + auth_user=Depends(self.engine.providers.auth.auth_wrapper), + ) -> WrappedGroupListResponse: + return await self.engine.aget_document_groups(document_id) diff --git a/r2r/main/api/routes/restructure/__init__.py b/r2r/main/api/routes/restructure/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/r2r/main/api/routes/restructure/base.py b/r2r/main/api/routes/restructure/base.py new file mode 100644 index 000000000..142c0ded8 --- /dev/null +++ b/r2r/main/api/routes/restructure/base.py @@ -0,0 +1,37 @@ +from typing import List, Optional + +from fastapi import Depends + +from r2r.main.api.routes.base_router import BaseRouter +from r2r.main.engine import R2REngine + + +class RestructureRouter(BaseRouter): + def __init__(self, engine: R2REngine): + super().__init__(engine) + self.setup_routes() + + def setup_routes(self): + @self.router.post("/enrich_graph") + @self.base_endpoint + async def enrich_graph( + query: str, + entity_types: Optional[List[str]] = None, + relationships: Optional[List[str]] = None, + generation_config: Optional[dict] = None, + auth_user=( + Depends(self.engine.providers.auth.auth_wrapper) + if self.engine.providers.auth + else None + ), + ): + request = { + "query": query, + "entity_types": entity_types, + "relationships": relationships, + "generation_config": generation_config, + } + return await self.engine.enrich_graph(request) + + +# ... existing code ... diff --git a/r2r/main/app.py b/r2r/main/app.py index ec9d4c479..0727d81c1 100644 --- a/r2r/main/app.py +++ b/r2r/main/app.py @@ -22,6 +22,7 @@ def _setup_routes(self): from .api.routes.ingestion import base as ingestion_base from .api.routes.kg import base as kg_base from .api.routes.management import base as management_base + from .api.routes.restructure import base as kg_base from .api.routes.retrieval import base as retrieval_base self.app = FastAPI() @@ -38,7 +39,7 @@ def _setup_routes(self): ) auth_router = auth_base.AuthRouter.build_router(self.engine) - kg_router = kg_base.KGRouter.build_router(self.engine) + kg_router = kg_base.RestructureRouter.build_router(self.engine) # Include routers in the app self.app.include_router(ingestion_router, prefix="/v1") diff --git a/r2r/main/assembly/builder.py b/r2r/main/assembly/builder.py index 9b34a0a0c..1fb007bbc 100644 --- a/r2r/main/assembly/builder.py +++ b/r2r/main/assembly/builder.py @@ -33,9 +33,7 @@ class R2RBuilder: current_file_path = os.path.dirname(__file__) - config_root = os.path.join( - current_file_path, "..", "..", "examples", "configs" - ) + config_root = os.path.join(current_file_path, "..", "..", "configs") CONFIG_OPTIONS = {} for file in os.listdir(config_root): diff --git a/r2r/main/engine.py b/r2r/main/engine.py index 433c91ea0..c90257cfd 100644 --- a/r2r/main/engine.py +++ b/r2r/main/engine.py @@ -254,3 +254,9 @@ async def aget_groups_for_user(self, *args, **kwargs): @syncable async def agroups_overview(self, *args, **kwargs): return await self.management_service.agroups_overview(*args, **kwargs) + + @syncable + async def aget_documents_in_group(self, *args, **kwargs): + return await self.management_service.aget_documents_in_group( + *args, **kwargs + ) diff --git a/r2r/main/services/auth_service.py b/r2r/main/services/auth_service.py index 721be4b9a..f99941478 100644 --- a/r2r/main/services/auth_service.py +++ b/r2r/main/services/auth_service.py @@ -106,13 +106,6 @@ async def confirm_password_reset( async def logout(self, token: str) -> dict[str, str]: return self.providers.auth.logout(token) - @telemetry_event("GetUserProfile") - async def get_user_profile(self, user_id: uuid.UUID) -> UserResponse: - user = self.providers.database.relational.get_user_by_id(user_id) - if not user: - raise R2RException(status_code=404, message="User not found") - return user - @telemetry_event("UpdateUserProfile") async def update_user( self, diff --git a/r2r/main/services/management_service.py b/r2r/main/services/management_service.py index 1833ba218..dd8ef20bc 100644 --- a/r2r/main/services/management_service.py +++ b/r2r/main/services/management_service.py @@ -4,8 +4,6 @@ from collections import defaultdict from typing import Any, Dict, List, Optional, Tuple -import toml - from r2r.base import ( AnalysisTypes, LogFilterCriteria, @@ -283,7 +281,7 @@ async def delete( self.providers.database.relational.delete_from_documents_overview( document_id ) - return {} + return None @telemetry_event("DocumentsOverview") async def adocuments_overview( @@ -367,9 +365,10 @@ async def aassign_document_to_group( self, document_id: str, group_id: uuid.UUID ): - if self.providers.database.vector.assign_document_to_group( + success = self.providers.database.vector.assign_document_to_group( document_id, group_id - ): + ) + if success: return {"message": "Document assigned to group successfully"} else: raise R2RException( @@ -381,9 +380,10 @@ async def aassign_document_to_group( async def aremove_document_from_group( self, document_id: str, group_id: uuid.UUID ): - if self.providers.database.vector.remove_document_from_group( + success = self.providers.database.vector.remove_document_from_group( document_id, group_id - ): + ) + if success: return {"message": "Document removed from group successfully"} else: raise R2RException( @@ -559,9 +559,21 @@ async def aget_groups_for_user(self, user_id: uuid.UUID) -> list[dict]: async def agroups_overview( self, group_ids: Optional[list[uuid.UUID]] = None, + offset: int = 0, + limit: int = 100, *args, **kwargs, ): return self.providers.database.relational.get_groups_overview( - [str(ele) for ele in group_ids] if group_ids else None + [str(ele) for ele in group_ids] if group_ids else None, + offset, + limit, + ) + + @telemetry_event("GetDocumentsInGroup") + async def aget_documents_in_group( + self, group_id: uuid.UUID, offset: int = 0, limit: int = 100 + ) -> list[dict]: + return self.providers.database.relational.get_documents_in_group( + group_id, offset, limit ) diff --git a/r2r/providers/auth/r2r_auth.py b/r2r/providers/auth/r2r_auth.py index 59f93bf60..e52e6aab7 100644 --- a/r2r/providers/auth/r2r_auth.py +++ b/r2r/providers/auth/r2r_auth.py @@ -118,12 +118,6 @@ def get_current_active_user( return current_user def register(self, email: str, password: str) -> Dict[str, str]: - # Check if user already exists - if self.db_provider.relational.get_user_by_email(email): - raise R2RException( - status_code=400, message="Email already registered" - ) - # Create new user new_user = self.db_provider.relational.create_user(email, password) diff --git a/r2r/providers/database/group.py b/r2r/providers/database/group.py index d3ef324ba..cd2a73f36 100644 --- a/r2r/providers/database/group.py +++ b/r2r/providers/database/group.py @@ -15,7 +15,6 @@ class GroupMixin(DatabaseMixin): def create_table(self) -> None: - print("creating group table = ", self._get_table_name("groups")) query = f""" CREATE TABLE IF NOT EXISTS {self._get_table_name('groups')} ( group_id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), @@ -207,13 +206,6 @@ def remove_user_from_group(self, user_id: UUID, group_id: UUID) -> None: message="User is not a member of the specified group", ) - def get_group_count(self) -> int: - query = f""" - SELECT COUNT(*) FROM {self._get_table_name('groups')} - """ - result = self.execute_query(query).fetchone() - return result[0] - def get_users_in_group( self, group_id: UUID, offset: int = 0, limit: int = 100 ) -> list[UserResponse]: @@ -271,24 +263,19 @@ def get_documents_in_group( ) -> list[DocumentInfo]: """ Get all documents in a specific group with pagination. - Args: group_id (UUID): The ID of the group to get documents from. offset (int): The number of documents to skip. limit (int): The maximum number of documents to return. - Returns: List[DocumentInfo]: A list of DocumentInfo objects representing the documents in the group. - Raises: R2RException: If the group doesn't exist. """ if not self.group_exists(group_id): raise R2RException(status_code=404, message="Group not found") - query = f""" - SELECT d.document_id, d.group_ids, d.user_id, d.type, d.metadata, d.title, - d.version, d.size_in_bytes, d.status, d.created_at, d.updated_at + SELECT d.document_id, d.user_id, d.type, d.metadata, d.title, d.version, d.size_in_bytes, d.status, d.created_at, d.updated_at FROM {self._get_table_name('document_info')} d WHERE :group_id = ANY(d.group_ids) ORDER BY d.created_at DESC @@ -298,20 +285,19 @@ def get_documents_in_group( results = self.execute_query( query, {"group_id": group_id, "offset": offset, "limit": limit} ).fetchall() - return [ DocumentInfo( id=row[0], - group_ids=row[1], - user_id=row[2], - type=DocumentType(row[3]), - metadata=row[4], - title=row[5], - version=row[6], - size_in_bytes=row[7], - status=DocumentStatus(row[8]), - created_at=row[9], - updated_at=row[10], + user_id=row[1], + type=DocumentType(row[2]), + metadata=row[3], + title=row[4], + version=row[5], + size_in_bytes=row[6], + status=DocumentStatus(row[7]), + created_at=row[8], + updated_at=row[9], + group_ids=[group_id], ) for row in results ] diff --git a/r2r/providers/database/user.py b/r2r/providers/database/user.py index 35b7f8c75..0bc0e246c 100644 --- a/r2r/providers/database/user.py +++ b/r2r/providers/database/user.py @@ -4,7 +4,7 @@ from sqlalchemy import text -from r2r.base.abstractions import R2RException +from r2r.base.abstractions import R2RException, UserStats from r2r.base.api.models.auth.responses import UserResponse from r2r.base.utils import generate_id_from_label @@ -77,7 +77,7 @@ def get_user_by_id(self, user_id: UUID) -> Optional[UserResponse]: else None ) - def get_user_by_email(self, email: str) -> Optional[UserResponse]: + def get_user_by_email(self, email: str) -> UserResponse: query, params = ( QueryBuilder(self._get_table_name("users")) .select( @@ -100,30 +100,34 @@ def get_user_by_email(self, email: str) -> Optional[UserResponse]: .build() ) result = self.execute_query(query, params).fetchone() - return ( - UserResponse( - id=result[0], - email=result[1], - hashed_password=result[2], - is_superuser=result[3], - is_active=result[4], - is_verified=result[5], - created_at=result[6], - updated_at=result[7], - name=result[8], - profile_picture=result[9], - bio=result[10], - group_ids=result[11], - ) - if result - else None + if not result: + raise R2RException(status_code=404, message="User not found") + + return UserResponse( + id=result[0], + email=result[1], + hashed_password=result[2], + is_superuser=result[3], + is_active=result[4], + is_verified=result[5], + created_at=result[6], + updated_at=result[7], + name=result[8], + profile_picture=result[9], + bio=result[10], + group_ids=result[11], ) def create_user(self, email: str, password: str) -> UserResponse: - if self.get_user_by_email(email): - raise R2RException( - status_code=400, message="User with this email already exists" - ) + try: + if self.get_user_by_email(email): + raise R2RException( + status_code=400, + message="User with this email already exists", + ) + except R2RException as e: + if e.status_code != 404: + raise e hashed_password = self.crypto_provider.get_password_hash(password) query = f""" @@ -430,3 +434,58 @@ def mark_user_as_verified(self, user_id: UUID): if not result.rowcount: raise R2RException(status_code=404, message="User not found") + + def get_users_overview( + self, + user_ids: Optional[list[UUID]] = None, + offset: int = 0, + limit: int = 100, + ) -> list[UserStats]: + query = f""" + WITH user_docs AS ( + SELECT + u.user_id, + u.email, + u.is_superuser, + u.is_active, + u.is_verified, + u.created_at, + u.updated_at, + u.group_ids, + COUNT(d.document_id) AS num_files, + COALESCE(SUM(d.size_in_bytes), 0) AS total_size_in_bytes, + ARRAY_AGG(d.document_id) FILTER (WHERE d.document_id IS NOT NULL) AS document_ids + FROM {self._get_table_name('users')} u + LEFT JOIN {self._get_table_name('document_info')} d ON u.user_id = d.user_id + {f"WHERE u.user_id = ANY(CAST(:user_ids AS UUID[]))" if user_ids else ""} + GROUP BY u.user_id, u.email, u.is_superuser, u.is_active, u.is_verified, u.created_at, u.updated_at, u.group_ids + ) + SELECT * + FROM user_docs + ORDER BY email + OFFSET :offset + LIMIT :limit + """ + + params = {"offset": offset, "limit": limit} + if user_ids: + params["user_ids"] = [str(ele) for ele in user_ids] + + results = self.execute_query(query, params).fetchall() + + return [ + UserStats( + user_id=row[0], + email=row[1], + is_superuser=row[2], + is_active=row[3], + is_verified=row[4], + created_at=row[5], + updated_at=row[6], + group_ids=row[7], + num_files=row[8], + total_size_in_bytes=row[9], + document_ids=row[10], + ) + for row in results + ] diff --git a/r2r/providers/database/vector.py b/r2r/providers/database/vector.py index 0b3728fef..c8523a159 100644 --- a/r2r/providers/database/vector.py +++ b/r2r/providers/database/vector.py @@ -41,9 +41,11 @@ def __init__(self, config: DatabaseConfig, *args, **kwargs): ) # Check if a complete Postgres URI is provided - if postgres_uri := self.config.extra_fields.get( + postgres_uri = self.config.extra_fields.get( "postgres_uri" - ) or os.getenv("POSTGRES_URI"): + ) or os.getenv("POSTGRES_URI") + + if postgres_uri: # Log loudly that Postgres URI is being used logger.warning("=" * 50) logger.warning( @@ -351,7 +353,7 @@ def hybrid_search( ) params = { - "query_text": query_text, + "query_text": str(query_text), "query_embedding": list(query_vector), "match_limit": limit, "full_text_weight": full_text_weight, diff --git a/tests/test_auth.py b/tests/test_auth.py index eaef1c923..211e9ff0c 100644 --- a/tests/test_auth.py +++ b/tests/test_auth.py @@ -197,15 +197,15 @@ async def test_login_failure_nonexistent_user(auth_service): with pytest.raises(R2RException) as exc_info: await auth_service.login("nonexistent@example.com", "password123") - assert exc_info.value.status_code == 401 - assert exc_info.value.message == "Incorrect email or password" + assert exc_info.value.status_code == 404 + assert exc_info.value.message == "User not found" @pytest.mark.asyncio async def test_login_with_non_existent_user(auth_service): with pytest.raises(R2RException) as exc_info: await auth_service.login("nonexistent@example.com", "password123") - assert "Incorrect email or password" in str(exc_info.value) + assert "User not found" in str(exc_info.value) @pytest.mark.asyncio @@ -426,26 +426,6 @@ async def test_logout(auth_service, auth_provider): assert exc_info.value.status_code == 401 -@pytest.mark.asyncio -async def test_get_user_profile(auth_service, auth_provider): - # Register and verify a user - with patch.object( - auth_provider.crypto_provider, - "generate_verification_code", - return_value="123456", - ): - new_user = await auth_service.register( - email="profile@example.com", password="password123" - ) - await auth_service.verify_email("123456") - - # Get user profile - profile = await auth_service.get_user_profile(new_user.id) - assert profile.email == "profile@example.com" - assert profile.name is None - assert profile.bio is None - - @pytest.mark.asyncio async def test_update_user_profile(auth_service, auth_provider): # Register and verify a user @@ -470,12 +450,6 @@ async def test_update_user_profile(auth_service, auth_provider): assert updated_profile.bio == "Test bio" assert updated_profile.profile_picture == "http://example.com/pic.jpg" - # Verify that the profile was updated - profile = await auth_service.get_user_profile(new_user.id) - assert profile.name == "John Doe" - assert profile.bio == "Test bio" - assert profile.profile_picture == "http://example.com/pic.jpg" - @pytest.mark.asyncio async def test_delete_user_account(auth_service, auth_provider): @@ -495,13 +469,15 @@ async def test_delete_user_account(auth_service, auth_provider): # Try to get the deleted user's profile with pytest.raises(R2RException) as exc_info: - await auth_service.get_user_profile(new_user.id) + result = auth_provider.db_provider.relational.get_user_by_email( + "delete_user@example.com" + ) assert exc_info.value.status_code == 404 # Try to login with deleted account with pytest.raises(R2RException) as exc_info: await auth_service.login("delete_user@example.com", "password123") - assert exc_info.value.status_code == 401 + assert exc_info.value.status_code == 404 @pytest.mark.asyncio @@ -674,12 +650,14 @@ async def test_confirm_reset_password(auth_service, auth_provider): @pytest.mark.asyncio -async def test_get_user_profile(auth_service): - new_user = await auth_service.register( +async def test_get_user_profile(auth_service, auth_provider): + await auth_service.register( email="profile@example.com", password="password123" ) - profile = await auth_service.get_user_profile(new_user.id) + profile = auth_provider.db_provider.relational.get_user_by_email( + "profile@example.com" + ) assert profile.email == "profile@example.com" diff --git a/tests/test_client.py b/tests/test_client.py index 40f029398..cb25247a7 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -8,6 +8,7 @@ from fastapi.testclient import TestClient from r2r import ( + DocumentInfo, R2RApp, R2RBuilder, R2RClient, @@ -50,6 +51,34 @@ def auth_wrapper(token: str = Depends(oauth2_scheme)): return auth_wrapper +@pytest.fixture(scope="function") +def mock_auth_wrapper(): + def auth_wrapper(token: str = Depends(oauth2_scheme)): + return UserResponse( + id=uuid.UUID("12345678-1234-5678-1234-567812345678"), + email="test@example.com", + is_active=True, + hashed_password="xxx", + is_superuser=True, + ) + + return auth_wrapper + + +@pytest.fixture(scope="function") +def mock_super_auth_wrapper(): + def auth_wrapper(token: str = Depends(oauth2_scheme)): + return UserResponse( + id=uuid.UUID("12345678-1234-5678-1234-567812345678"), + email="test@example.com", + is_active=True, + hashed_password="xxx", + is_superuser=True, + ) + + return auth_wrapper + + @pytest.fixture(scope="function") def mock_db(): db = MagicMock() @@ -70,6 +99,21 @@ def update_user(user): return updated_user db.relational.update_user.side_effect = update_user + db.relational.get_documents_in_group.return_value = [ + DocumentInfo( + user_id=uuid.uuid4(), + id=uuid.uuid4(), + title=f"Document {i}", + type="txt", + group_ids=[uuid.uuid4()], + created_at=datetime.utcnow(), + updated_at=datetime.utcnow(), + version="1", + metadata={}, + size_in_bytes=1000, + ) + for i in range(100) + ] return db @@ -255,6 +299,7 @@ async def test_password_reset_flow(r2r_client, mock_db): reset_response = r2r_client.request_password_reset( "reset_pass@example.com" ) + print("reset_response = ", reset_response) assert "message" in reset_response["results"] # Confirm password reset (we'll need to mock the reset token) @@ -308,3 +353,24 @@ async def test_user_profile(r2r_client, mock_db): updated_profile = r2r_client.update_user(name="John Doe", bio="Test bio") assert updated_profile["results"]["name"] == "John Doe" assert updated_profile["results"]["bio"] == "Test bio" + + +@pytest.mark.asyncio +async def test_get_documents_in_group(r2r_client, mock_db): + # Register and login as a superuser + user_data = {"email": "superuser@example.com", "password": "password123"} + r2r_client.register(**user_data) + + # Set the mock user as a superuser + # mock_db.relational.get_user_by_email.return_value.is_superuser = True + + r2r_client.login(**user_data) + + # Get documents in group + group_id = uuid.uuid4() + response = r2r_client.get_documents_in_group(group_id) + + assert "results" in response + assert len(response["results"]) == 100 # Default limit + assert response["results"][0]["title"] == "Document 0" + assert response["results"][0]["type"] == "txt" diff --git a/tests/test_end_to_end.py b/tests/test_end_to_end.py index 4aa0e8615..bacf0d95f 100644 --- a/tests/test_end_to_end.py +++ b/tests/test_end_to_end.py @@ -291,10 +291,7 @@ async def test_ingest_search_then_delete(app, logging_connection): delete_result = await app.adelete(filters={"author": {"$eq": "John Doe"}}) # Verify the deletion was successful - assert ( - len(delete_result) > 0 - ), f"Expected at least one document to be deleted, but got {delete_result}" - + assert delete_result is None # Search for the document again search_results_2 = await app.asearch("who was aristotle?") @@ -307,8 +304,13 @@ async def test_ingest_search_then_delete(app, logging_connection): @pytest.mark.parametrize("app", ["postgres"], indirect=True) @pytest.mark.asyncio async def test_ingest_user_documents(app, logging_connection): - user_id_0 = generate_id_from_label("user_0") - user_id_1 = generate_id_from_label("user_1") + + # user_id_0 = generate_id_from_label("user_0") + # user_id_1 = generate_id_from_label("user_1") + user_0 = app.register("user_0@test.com", "password") + user_id_0 = user_0.id + user_1 = app.register("user_1@test.com", "password") + user_id_1 = user_1.id doc_id_0 = generate_id_from_label("doc_01") doc_id_1 = generate_id_from_label("doc_11") @@ -332,9 +334,12 @@ async def test_ingest_user_documents(app, logging_connection): ), ] ) - user_id_results = await app.ausers_overview([user_id_0, user_id_1]) - assert set([stats.user_id for stats in user_id_results]) == set( - [user_id_0, user_id_1] + user_stats_results = await app.ausers_overview([user_id_0, user_id_1]) + print("user_stats_results = ", user_stats_results) + user_id_results = [stats.user_id for stats in user_stats_results] + print("user_id_results = ", user_stats_results) + assert set([user_id_0, user_id_1]) == set( + user_id_results ), f"Expected user ids {user_id_0} and {user_id_1}, but got {user_id_results}" user_0_docs = await app.adocuments_overview(user_ids=[user_id_0]) @@ -358,9 +363,7 @@ async def test_ingest_user_documents(app, logging_connection): filters={"document_id": {"$in": [doc_id_0, doc_id_1]}} ) - assert ( - len(delete_result) == 2 - ), f"Expected 2 chunks to be deleted, but got {len(delete_result)}" + assert delete_result is None @pytest.mark.parametrize("app", ["postgres"], indirect=True) @@ -383,8 +386,6 @@ async def test_delete_by_id(app, logging_connection): assert len(search_results["vector_search_results"]) > 0 delete_result = await app.adelete(filters={"document_id": {"$eq": doc_id}}) - assert ( - len(delete_result) > 0 - ), f"Expected at least one document to be deleted, but got {delete_result}" + assert delete_result is None search_results = await app.asearch("who was aristotle?") assert len(search_results["vector_search_results"]) == 0 diff --git a/tests/test_groups.py b/tests/test_groups.py index c6eb6c8a2..12e39fb14 100644 --- a/tests/test_groups.py +++ b/tests/test_groups.py @@ -212,15 +212,6 @@ def test_get_groups_by_ids(pg_db): assert any(g.group_id == group2.group_id for g in groups) -def test_get_group_count(pg_db, test_group): - initial_count = pg_db.relational.get_group_count() - - pg_db.relational.create_group("New Group", "New Description") - - new_count = pg_db.relational.get_group_count() - assert new_count == initial_count + 1 - - def test_get_groups_overview(pg_db, test_group, test_user): pg_db.relational.add_user_to_group(test_user.id, test_group.group_id) diff --git a/tests/test_groups_client.py b/tests/test_groups_client.py index a9319b9cd..b213aa906 100644 --- a/tests/test_groups_client.py +++ b/tests/test_groups_client.py @@ -148,7 +148,7 @@ def mock_list_groups(offset=0, limit=100): ) db.relational.get_groups_for_user = MagicMock(side_effect=mock_list_groups) - def mock_groups_overview(group_ids): + def mock_groups_overview(group_ids, offset=0, limit=100): return [ { "group_id": str(uuid.uuid4()), @@ -355,7 +355,9 @@ async def test_groups_overview(r2r_client, mock_db): assert "results" in response assert len(response["results"]) == 2 # assert response["results"] == mock_overview - mock_db.relational.get_groups_overview.assert_called_once_with(None) + mock_db.relational.get_groups_overview.assert_called_once_with( + None, 0, 100 + ) @pytest.mark.asyncio @@ -367,10 +369,10 @@ async def test_groups_overview_with_ids(r2r_client, mock_db): # {"id": str(group_ids[1]), "name": "Group 2", "member_count": 3}, # ] # mock_db.relational.get_groups_overview.return_value = mock_overview - response = r2r_client.groups_overview(group_ids) + response = r2r_client.groups_overview(group_ids, 10, 100) assert "results" in response assert len(response["results"]) == 2 # assert response["results"] == mock_overview mock_db.relational.get_groups_overview.assert_called_once_with( - [str(gid) for gid in group_ids] + [str(gid) for gid in group_ids], 100, 10 ) diff --git a/tests/test_kg.py b/tests/test_kg.py index 4111971ce..cb6acf3cc 100644 --- a/tests/test_kg.py +++ b/tests/test_kg.py @@ -1,139 +1,139 @@ -import json -import uuid -from unittest.mock import Mock, patch - -import pytest - -from r2r.base.abstractions.document import DocumentFragment -from r2r.base.abstractions.graph import Entity, Triple -from r2r.base.providers.kg import KGConfig -from r2r.providers.kg.neo4j.provider import Neo4jKGProvider - - -@pytest.fixture -def neo4j_kg_provider(): - extra_fields = { - "user": "neo4j", - "password": "ineedastrongerpassword", - "url": "bolt://localhost:7688", - "database": "neo4j", - } - config = KGConfig(provider="neo4j", extra_fields=extra_fields) - return Neo4jKGProvider(config) - - -@pytest.fixture(autouse=True) -def clean_graph(neo4j_kg_provider): - neo4j_kg_provider.delete_all_nodes() - yield - neo4j_kg_provider.delete_all_nodes() - - -def get_uuid(): - return str(uuid.uuid4()) - - -@pytest.fixture -def test_chunks(): - return [ - DocumentFragment( - id=get_uuid(), - data="Test chunk 1", - metadata={"testkey": "testvalue"}, - document_id=get_uuid(), - extraction_id=get_uuid(), - ), - DocumentFragment( - id=get_uuid(), - data="Test chunk 2", - metadata={"testkey": "testvalue"}, - document_id=get_uuid(), - extraction_id=get_uuid(), - ), - ] - - -@pytest.fixture -def test_entities(): - return [ - Entity( - id=get_uuid(), - category="Test category 1", - subcategory=None, - value="Test entity 1", - description="Test entity 1 description", - description_embedding=[1.0, 2.0, 3.0], - name_embedding=[1.0, 2.0, 3.0], - graph_embedding=[1.0, 2.0, 3.0], - community_ids=[get_uuid()], - text_unit_ids=[get_uuid()], - document_ids=[get_uuid(), get_uuid()], - rank=1, - attributes={"testkey": "testvalue"}, - ), - # Entity(id=get_uuid(), category="Test category 2", subcategory=None, value="Test entity 2", description="Test entity 2 description", description_embedding=[1.0, 2.0, 3.0], name_embedding=[1.0, 2.0, 3.0], graph_embedding=[1.0, 2.0, 3.0], community_ids=[get_uuid()], text_unit_ids=[get_uuid()], document_ids=[get_uuid(), get_uuid()], rank=1, attributes={"testkey": "testvalue"}) - ] - - -@pytest.fixture -def test_triples(): - return [ - Triple( - id=get_uuid(), - subject=get_uuid(), - predicate="test_predicate", - object=get_uuid(), - weight=1.0, - description="Test triple description", - predicate_embedding=[1.0, 2.0, 3.0], - text_unit_ids=[get_uuid()], - document_ids=[get_uuid()], - attributes={"testkey": "testvalue"}, - ) - ] - - -def test_upsert_chunks(neo4j_kg_provider, test_chunks, clean_graph): - neo4j_kg_provider.upsert_chunks(test_chunks) - neo4j_output = neo4j_kg_provider.get_chunks() - chunks = [record["c"]._properties for record in neo4j_output.records] - assert len(chunks) == len(test_chunks) - for chunk, test_chunk in zip(chunks, test_chunks): - assert chunk["id"] == str(test_chunk.id) - assert chunk["data"] == test_chunk.data - assert json.loads(chunk["metadata"]) == test_chunk.metadata - assert chunk["document_id"] == str(test_chunk.document_id) - assert chunk["extraction_id"] == str(test_chunk.extraction_id) - - -def test_upsert_entities(neo4j_kg_provider, test_entities): - neo4j_kg_provider.upsert_entities(test_entities) - neo4j_output = neo4j_kg_provider.get_entities() - entities = [record["e"]._properties for record in neo4j_output.records] - assert len(entities) == len(test_entities) - for entity, test_entity in zip(entities, test_entities): - assert entity["id"] == test_entity.id - assert entity["category"] == test_entity.category - assert entity["value"] == test_entity.value - assert entity["description"] == test_entity.description - - -def test_upsert_triples(neo4j_kg_provider, test_triples): - triples_count = neo4j_kg_provider.upsert_triples(test_triples) - triples = neo4j_kg_provider.get_triples() - assert len(triples) == len(test_triples) - for triple, test_triple in zip(triples, test_triples): - assert triple.id == test_triple.id - assert triple.subject == test_triple.subject - assert triple.predicate == test_triple.predicate - assert triple.object == test_triple.object - - -def test_upsert_communities(neo4j_kg_provider, test_communities): - neo4j_kg_provider.upsert_communities(test_communities) - neo4j_output = neo4j_kg_provider.get_communities() - communities = [record["c"]._properties for record in neo4j_output.records] - assert len(communities) == len(test_communities) - for community, test_community in zip(communities, test_communities): - assert community["id"] == test_community.id - assert community["name"] == test_community.name +# import json +# import uuid +# from unittest.mock import Mock, patch + +# import pytest + +# from r2r.base.abstractions.document import DocumentFragment +# from r2r.base.abstractions.graph import Entity, Triple +# from r2r.base.providers.kg import KGConfig +# from r2r.providers.kg.neo4j.provider import Neo4jKGProvider + + +# @pytest.fixture +# def neo4j_kg_provider(): +# extra_fields = { +# "user": "neo4j", +# "password": "ineedastrongerpassword", +# "url": "bolt://localhost:7688", +# "database": "neo4j", +# } +# config = KGConfig(provider="neo4j", extra_fields=extra_fields) +# return Neo4jKGProvider(config) + + +# @pytest.fixture(autouse=True) +# def clean_graph(neo4j_kg_provider): +# neo4j_kg_provider.delete_all_nodes() +# yield +# neo4j_kg_provider.delete_all_nodes() + + +# def get_uuid(): +# return str(uuid.uuid4()) + + +# @pytest.fixture +# def test_chunks(): +# return [ +# DocumentFragment( +# id=get_uuid(), +# data="Test chunk 1", +# metadata={"testkey": "testvalue"}, +# document_id=get_uuid(), +# extraction_id=get_uuid(), +# ), +# DocumentFragment( +# id=get_uuid(), +# data="Test chunk 2", +# metadata={"testkey": "testvalue"}, +# document_id=get_uuid(), +# extraction_id=get_uuid(), +# ), +# ] + + +# @pytest.fixture +# def test_entities(): +# return [ +# Entity( +# id=get_uuid(), +# category="Test category 1", +# subcategory=None, +# value="Test entity 1", +# description="Test entity 1 description", +# description_embedding=[1.0, 2.0, 3.0], +# name_embedding=[1.0, 2.0, 3.0], +# graph_embedding=[1.0, 2.0, 3.0], +# community_ids=[get_uuid()], +# text_unit_ids=[get_uuid()], +# document_ids=[get_uuid(), get_uuid()], +# rank=1, +# attributes={"testkey": "testvalue"}, +# ), +# # Entity(id=get_uuid(), category="Test category 2", subcategory=None, value="Test entity 2", description="Test entity 2 description", description_embedding=[1.0, 2.0, 3.0], name_embedding=[1.0, 2.0, 3.0], graph_embedding=[1.0, 2.0, 3.0], community_ids=[get_uuid()], text_unit_ids=[get_uuid()], document_ids=[get_uuid(), get_uuid()], rank=1, attributes={"testkey": "testvalue"}) +# ] + + +# @pytest.fixture +# def test_triples(): +# return [ +# Triple( +# id=get_uuid(), +# subject=get_uuid(), +# predicate="test_predicate", +# object=get_uuid(), +# weight=1.0, +# description="Test triple description", +# predicate_embedding=[1.0, 2.0, 3.0], +# text_unit_ids=[get_uuid()], +# document_ids=[get_uuid()], +# attributes={"testkey": "testvalue"}, +# ) +# ] + + +# def test_upsert_chunks(neo4j_kg_provider, test_chunks, clean_graph): +# neo4j_kg_provider.upsert_chunks(test_chunks) +# neo4j_output = neo4j_kg_provider.get_chunks() +# chunks = [record["c"]._properties for record in neo4j_output.records] +# assert len(chunks) == len(test_chunks) +# for chunk, test_chunk in zip(chunks, test_chunks): +# assert chunk["id"] == str(test_chunk.id) +# assert chunk["data"] == test_chunk.data +# assert json.loads(chunk["metadata"]) == test_chunk.metadata +# assert chunk["document_id"] == str(test_chunk.document_id) +# assert chunk["extraction_id"] == str(test_chunk.extraction_id) + + +# def test_upsert_entities(neo4j_kg_provider, test_entities): +# neo4j_kg_provider.upsert_entities(test_entities) +# neo4j_output = neo4j_kg_provider.get_entities() +# entities = [record["e"]._properties for record in neo4j_output.records] +# assert len(entities) == len(test_entities) +# for entity, test_entity in zip(entities, test_entities): +# assert entity["id"] == test_entity.id +# assert entity["category"] == test_entity.category +# assert entity["value"] == test_entity.value +# assert entity["description"] == test_entity.description + + +# def test_upsert_triples(neo4j_kg_provider, test_triples): +# triples_count = neo4j_kg_provider.upsert_triples(test_triples) +# triples = neo4j_kg_provider.get_triples() +# assert len(triples) == len(test_triples) +# for triple, test_triple in zip(triples, test_triples): +# assert triple.id == test_triple.id +# assert triple.subject == test_triple.subject +# assert triple.predicate == test_triple.predicate +# assert triple.object == test_triple.object + + +# def test_upsert_communities(neo4j_kg_provider, test_communities): +# neo4j_kg_provider.upsert_communities(test_communities) +# neo4j_output = neo4j_kg_provider.get_communities() +# communities = [record["c"]._properties for record in neo4j_output.records] +# assert len(communities) == len(test_communities) +# for community, test_community in zip(communities, test_communities): +# assert community["id"] == test_community.id +# assert community["name"] == test_community.name From 21cbac637578acb2b571c1b458e0e6e4860b7486 Mon Sep 17 00:00:00 2001 From: Shreyas Pimpalgaonkar Date: Sun, 18 Aug 2024 14:21:38 -0400 Subject: [PATCH 04/74] Shreyas/graphrag test (#881) * add group ids to document abstraction, first steps * extend group permissions * up * add tests for new group features * up * fixup auth * onboard extensive regression tests * adding regression tests * finish tests * rm selenium * test observability * uncomment tests * checkin first set of group tests * modify search, passing vector tests * checkin work * full delete logic * update search to use new filters * check in * Clean up * Check in * add search * tests/test_end_to_end.py::test_ingest_txt_document passing * cleanup logging * make schemas explicit * move to run logger abstraction * cleanup some test workflows * revive tests * tweak to pass tests * tweak rrf * finish hybrid search cleanup * fixup on regr tests, regen payloads * refresh payloads * refactor api model * Feature/refactor api model (#868) * cleanup imports * flake and cleanup * coherent global import / export structure * add ingestion response models * add management response models * cleanups * checkin work on routes * remove request models * last fixes * merge * add user / group gating * sync * enrich * up * fix global search * rag * remove client.py * rm configs * rm configs --------- Co-authored-by: emrgnt-cmplxty Co-authored-by: NolanTrem <34580718+NolanTrem@users.noreply.github.com> Co-authored-by: emrgnt-cmplxty <68796651+emrgnt-cmplxty@users.noreply.github.com> --- r2r/__init__.py | 3 +- r2r/base/__init__.py | 3 +- r2r/base/abstractions/__init__.py | 4 - r2r/base/abstractions/graph.py | 63 +-------- r2r/base/abstractions/search.py | 11 +- r2r/base/providers/kg.py | 6 + r2r/cli/commands/rag_operations.py | 13 +- r2r/configs/graphrag.toml | 61 --------- r2r/examples/scripts/advanced_kg_cookbook.py | 44 +++---- r2r/main/abstractions.py | 2 +- r2r/main/api/routes/base_router.py | 2 +- r2r/main/assembly/builder.py | 8 +- r2r/main/assembly/factory.py | 18 +-- r2r/main/engine.py | 4 +- r2r/main/execution.py | 12 +- r2r/main/services/management_service.py | 45 +++++-- r2r/main/services/restructure_service.py | 4 +- r2r/pipelines/ingestion_pipeline.py | 2 +- r2r/pipes/__init__.py | 4 +- r2r/pipes/ingestion/vector_storage_pipe.py | 2 +- r2r/pipes/kg/clustering.py | 75 ++--------- r2r/pipes/kg/extraction.py | 124 +++++++----------- r2r/pipes/kg/node_extraction.py | 4 +- r2r/pipes/retrieval/kg_search_search_pipe.py | 6 +- r2r/providers/kg/neo4j/graph_queries.py | 2 +- r2r/providers/kg/neo4j/provider.py | 9 +- .../graphrag_triplet_extraction_few_shot.yaml | 4 +- ...graphrag_triplet_extraction_zero_shot.yaml | 4 +- 28 files changed, 188 insertions(+), 351 deletions(-) delete mode 100644 r2r/configs/graphrag.toml diff --git a/r2r/__init__.py b/r2r/__init__.py index b31a2385b..7683ef22e 100644 --- a/r2r/__init__.py +++ b/r2r/__init__.py @@ -65,7 +65,6 @@ "Entity", "KGExtraction", "Triple", - "extract_triples", # LLM abstractions "GenerationConfig", "LLMChatCompletion", @@ -155,7 +154,6 @@ # Knowledge Graph provider "KGConfig", "KGProvider", - "extract_entities", # LLM provider "CompletionConfig", "CompletionProvider", @@ -175,6 +173,7 @@ "generate_id_from_label", "increment_version", "EntityType", + "RelationshipType", "format_entity_types", "format_relations", ## MAIN diff --git a/r2r/base/__init__.py b/r2r/base/__init__.py index edcefcf00..8c56ecf62 100644 --- a/r2r/base/__init__.py +++ b/r2r/base/__init__.py @@ -34,7 +34,6 @@ "Entity", "KGExtraction", "Triple", - "extract_triples", # LLM abstractions "GenerationConfig", "LLMChatCompletion", @@ -124,7 +123,6 @@ # Knowledge Graph provider "KGConfig", "KGProvider", - "extract_entities", # LLM provider "CompletionConfig", "CompletionProvider", @@ -144,6 +142,7 @@ "generate_id_from_label", "increment_version", "EntityType", + "RelationshipType", "format_entity_types", "format_relations", ] diff --git a/r2r/base/abstractions/__init__.py b/r2r/base/abstractions/__init__.py index ae33be385..6ea82c364 100644 --- a/r2r/base/abstractions/__init__.py +++ b/r2r/base/abstractions/__init__.py @@ -19,8 +19,6 @@ KGExtraction, RelationshipType, Triple, - extract_entities, - extract_triples, ) from .llm import ( GenerationConfig, @@ -68,8 +66,6 @@ "CommunityReport", "KGExtraction", "Triple", - "extract_entities", - "extract_triples", # LLM abstractions "GenerationConfig", "LLMChatCompletion", diff --git a/r2r/base/abstractions/graph.py b/r2r/base/abstractions/graph.py index 27300f131..762da615d 100644 --- a/r2r/base/abstractions/graph.py +++ b/r2r/base/abstractions/graph.py @@ -68,7 +68,7 @@ def __init__(self, **kwargs): try: self.attributes = json.loads(self.attributes) except Exception as e: - logger.error(f"Error loading attributes: {e}") + self.attributes = self.attributes pass @@ -105,7 +105,11 @@ class Triple(BaseModel): def __init__(self, **kwargs): super().__init__(**kwargs) if isinstance(self.attributes, str): - self.attributes = json.loads(self.attributes) + try: + self.attributes = json.loads(self.attributes) + except Exception as e: + self.attributes = self.attributes + pass @classmethod def from_dict( @@ -390,61 +394,6 @@ def from_dict( TextEmbedder = Callable[[str], list[float]] - -def extract_entities(llm_payload: list[str]) -> dict[str, Entity]: - entities = {} - for entry in llm_payload: - try: - if "], " in entry: # Check if the entry is an entity - entry_val = entry.split("], ")[0] + "]" - entry = entry.split("], ")[1] - colon_count = entry.count(":") - - if colon_count == 1: - category, value = entry.split(":") - subcategory = None - elif colon_count >= 2: - parts = entry.split(":", 2) - category, subcategory, value = ( - parts[0], - parts[1], - parts[2], - ) - else: - raise ValueError("Unexpected entry format") - - entities[entry_val] = Entity( - category=category, subcategory=subcategory, value=value - ) - except Exception as e: - logger.error(f"Error processing entity {entry}: {e}") - continue - return entities - - -def extract_triples( - llm_payload: list[str], entities: dict[str, Entity] -) -> list[Triple]: - triples = [] - for entry in llm_payload: - try: - if "], " not in entry: # Check if the entry is an entity - elements = entry.split(" ") - subject = elements[0] - predicate = elements[1] - object = " ".join(elements[2:]) - subject = entities[subject].value # Use entity.value - if "[" in object and "]" in object: - object = entities[object].value # Use entity.value - triples.append( - Triple(subject=subject, predicate=predicate, object=object) - ) - except Exception as e: - logger.error(f"Error processing triplet {entry}: {e}") - continue - return triples - - class KGExtraction(BaseModel): """An extraction from a document that is part of a knowledge graph.""" diff --git a/r2r/base/abstractions/search.py b/r2r/base/abstractions/search.py index 7c94bd02d..348530cab 100644 --- a/r2r/base/abstractions/search.py +++ b/r2r/base/abstractions/search.py @@ -1,6 +1,5 @@ """Abstractions for search functionality.""" -import json from typing import Any, Dict, List, Optional, Tuple from uuid import UUID @@ -120,16 +119,16 @@ def model_dump(self, *args, **kwargs): class KGSearchSettings(BaseModel): use_kg_search: bool = False kg_search_type: str = "global" # 'global' or 'local' - kg_search_level: Optional[int] = None + kg_search_level: Optional[str] = None kg_search_generation_config: Optional[GenerationConfig] = Field( default_factory=GenerationConfig ) entity_types: list = [] relationships: list = [] max_community_description_length: int = 4096 * 4 - max_llm_queries_for_global_search: int = 10 + max_llm_queries_for_global_search: int = 250 local_search_limits: dict[str, int] = { - "__Entity__": 10, - "__Relationship__": 10, - "__Community__": 10, + "__Entity__": 20, + "__Relationship__": 20, + "__Community__": 20, } diff --git a/r2r/base/providers/kg.py b/r2r/base/providers/kg.py index fc4c60305..574472de4 100644 --- a/r2r/base/providers/kg.py +++ b/r2r/base/providers/kg.py @@ -21,6 +21,7 @@ class KGConfig(ProviderConfig): kg_search_prompt: Optional[str] = "kg_search" kg_extraction_config: Optional[GenerationConfig] = None kg_store_path: Optional[str] = None + max_knowledge_triples: Optional[int] = 100 def validate(self) -> None: if self.provider not in self.supported_providers: @@ -144,6 +145,11 @@ def update_kg_search_prompt( pass + @abstractmethod + def create_vector_index(self, node_type: str, node_property: str, dimension: int) -> None: + """Abstract method to create a vector index.""" + pass + def escape_braces(s: str) -> str: """ Escape braces in a string. diff --git a/r2r/cli/commands/rag_operations.py b/r2r/cli/commands/rag_operations.py index fb101b5de..ceadf6bd1 100644 --- a/r2r/cli/commands/rag_operations.py +++ b/r2r/cli/commands/rag_operations.py @@ -9,11 +9,14 @@ @click.option( "--limit", default=100, help="Limit the number of relationships returned" ) +@click.option( + "--print-descriptions", is_flag=True, help="Print descriptions of entities and relationships" +) @click.pass_obj -def inspect_knowledge_graph(obj, limit): +def inspect_knowledge_graph(obj, limit, print_descriptions): """Print relationships from the knowledge graph.""" with timer(): - response = obj.inspect_knowledge_graph(limit) + response = obj.inspect_knowledge_graph(limit, print_descriptions) click.echo(response) @@ -34,6 +37,8 @@ def inspect_knowledge_graph(obj, limit): @click.option("--kg-search-model", default=None, help="Model for KG agent") @click.option("--stream", is_flag=True, help="Stream the RAG response") @click.option("--rag-model", default=None, help="Model for RAG") +@click.option("--kg-search-level", default=None, help="Level of cluster to use for Global KG search") +@click.option("--kg-search-type", default="global", help="Local or Global") @click.pass_obj def rag( obj, @@ -46,6 +51,8 @@ def rag( kg_search_model, stream, rag_model, + kg_search_type, + kg_search_level, ): """Perform a RAG query.""" kg_search_generation_config = {} @@ -66,6 +73,8 @@ def rag( kg_search_generation_config, stream, rag_generation_config, + kg_search_type, + kg_search_level, ) if stream: for chunk in response: diff --git a/r2r/configs/graphrag.toml b/r2r/configs/graphrag.toml deleted file mode 100644 index 5af5d4549..000000000 --- a/r2r/configs/graphrag.toml +++ /dev/null @@ -1,61 +0,0 @@ -[completion] -provider = "litellm" -concurrent_request_limit = 256 - - [completion.generation_config] - model = "gpt-4o-mini" - temperature = 0.1 - top_p = 1 - max_tokens_to_sample = 1_024 - stream = false - add_generation_kwargs = { } - -[embedding] -provider = "openai" -base_model = "text-embedding-3-small" -base_dimension = 1_536 -batch_size = 256 -add_title_as_prefix = true - -[ingestion] -excluded_parsers = [ "gif", "jpeg", "jpg", "png", "svg", "mp3", "mp4" ] - -[kg] -provider = "local" -batch_size = 1024 -max_entities = 10 -max_relations = 20 -kg_extraction_prompt = "graphrag_triplet_extraction_zero_shot" -kg_store_path = "/Users/shreyas/r2rr2r/graph_data" - - [kg.kg_extraction_config] - model = "gpt-4o-mini" - temperature = 1 - top_p = 1 - max_tokens_to_sample = 1_024 - stream = false - add_generation_kwargs = { } - -# [kg] -# provider = "local" -# batch_size = 256 -# kg_extraction_prompt = "graphrag_triplet_extraction_zero_shot" - - -# [kg.kg_extraction_config] -# model = "gpt-4o-mini" -# temperature = 1 -# top_p = 1 -# max_tokens_to_sample = 1_024 -# stream = false -# add_generation_kwargs = { } - -[database] -provider = "postgres" - -[agent] -system_instruction_name = "rag_agent" -tool_names = ["search"] - - [agent.generation_config] - model = "gpt-4o-mini" diff --git a/r2r/examples/scripts/advanced_kg_cookbook.py b/r2r/examples/scripts/advanced_kg_cookbook.py index e6270a46e..5411044c5 100644 --- a/r2r/examples/scripts/advanced_kg_cookbook.py +++ b/r2r/examples/scripts/advanced_kg_cookbook.py @@ -4,7 +4,7 @@ import requests from bs4 import BeautifulSoup, Comment -from r2r import EntityType, R2RClient, R2RPromptProvider, update_kg_prompt +from r2r import EntityType, R2RClient, R2RPromptProvider, RelationshipType def escape_braces(text): @@ -103,26 +103,26 @@ def main( # Specify the relations for the KG construction relations = [ # Founder Relations - Relation("EDUCATED_AT"), - Relation("WORKED_AT"), - Relation("FOUNDED"), + RelationshipType("EDUCATED_AT"), + RelationshipType("WORKED_AT"), + RelationshipType("FOUNDED"), # Company relations - Relation("RAISED"), - Relation("REVENUE"), - Relation("TEAM_SIZE"), - Relation("LOCATION"), - Relation("ACQUIRED_BY"), - Relation("ANNOUNCED"), - Relation("INDUSTRY"), + RelationshipType("RAISED"), + RelationshipType("REVENUE"), + RelationshipType("TEAM_SIZE"), + RelationshipType("LOCATION"), + RelationshipType("ACQUIRED_BY"), + RelationshipType("ANNOUNCED"), + RelationshipType("INDUSTRY"), # Product relations - Relation("PRODUCT"), - Relation("FEATURES"), - Relation("TECHNOLOGY"), + RelationshipType("PRODUCT"), + RelationshipType("FEATURES"), + RelationshipType("TECHNOLOGY"), # Additional relations - Relation("HAS"), - Relation("AS_OF"), - Relation("PARTICIPATED"), - Relation("ASSOCIATED"), + RelationshipType("HAS"), + RelationshipType("AS_OF"), + RelationshipType("PARTICIPATED"), + RelationshipType("ASSOCIATED"), ] client = R2RClient(base_url=base_url) @@ -130,8 +130,6 @@ def main( prompt = "graphrag_triplet_extraction_few_shot" - update_kg_prompt(client, r2r_prompts, prompt, entity_types, relations) - url_map = get_all_yc_co_directory_urls() i = 0 @@ -157,14 +155,10 @@ def main( continue print("Inspecting Knowledge Graph") - print(client.inspect_knowledge_graph(1000)["results"]) + print(client.inspect_knowledge_graph(1000, print_descriptions=True)["results"]) if not local_mode: - update_kg_prompt( - client, r2r_prompts, "kg_search", entity_types, relations - ) - # support local and global result = client.search( query="Find up to 10 founders that worked at Google", diff --git a/r2r/main/abstractions.py b/r2r/main/abstractions.py index fa3648a6d..c02c99f98 100644 --- a/r2r/main/abstractions.py +++ b/r2r/main/abstractions.py @@ -61,7 +61,7 @@ class R2RPipelines(BaseModel): search_pipeline: SearchPipeline rag_pipeline: RAGPipeline streaming_rag_pipeline: RAGPipeline - kg_pipeline: KGEnrichmentPipeline + kg_enrichment_pipeline: KGEnrichmentPipeline class Config: arbitrary_types_allowed = True diff --git a/r2r/main/api/routes/base_router.py b/r2r/main/api/routes/base_router.py index 6c270fdbf..1b644c8c3 100644 --- a/r2r/main/api/routes/base_router.py +++ b/r2r/main/api/routes/base_router.py @@ -48,7 +48,7 @@ async def wrapper(*args, **kwargs): key="error", value=str(e), ) - logger.error(f"{func.__name__}() - \n\n{str(e)})") + logger.error(f"Error in base endpoint {func.__name__}() - \n\n{str(e)})") raise HTTPException( status_code=500, detail={ diff --git a/r2r/main/assembly/builder.py b/r2r/main/assembly/builder.py index 1fb007bbc..67aad39ef 100644 --- a/r2r/main/assembly/builder.py +++ b/r2r/main/assembly/builder.py @@ -94,7 +94,7 @@ def __init__( self.search_pipeline: Optional[SearchPipeline] = None self.rag_pipeline: Optional[RAGPipeline] = None self.streaming_rag_pipeline: Optional[RAGPipeline] = None - self.kg_pipeline: Optional[KGEnrichmentPipeline] = None + self.kg_enrichment_pipeline: Optional[KGEnrichmentPipeline] = None # Agent overrides self.assistant_factory_override: Optional[R2RAgentFactory] = None @@ -211,8 +211,8 @@ def with_streaming_rag_pipeline(self, pipeline: RAGPipeline): self.streaming_rag_pipeline = pipeline return self - def with_kg_pipeline(self, pipeline: KGEnrichmentPipeline): - self.kg_pipeline = pipeline + def with_kg_enrichment_pipeline(self, pipeline: KGEnrichmentPipeline): + self.kg_enrichment_pipeline = pipeline return self def with_assistant_factory(self, factory: R2RAgentFactory): @@ -261,7 +261,7 @@ def build(self, *args, **kwargs) -> R2R: search_pipeline=self.search_pipeline, rag_pipeline=self.rag_pipeline, streaming_rag_pipeline=self.streaming_rag_pipeline, - kg_pipeline=self.kg_pipeline, + kg_enrichment_pipeline=self.kg_enrichment_pipeline, *args, **kwargs, ) diff --git a/r2r/main/assembly/factory.py b/r2r/main/assembly/factory.py index 178c552ae..19de04241 100644 --- a/r2r/main/assembly/factory.py +++ b/r2r/main/assembly/factory.py @@ -559,13 +559,13 @@ def create_rag_pipeline( rag_pipeline.add_pipe(rag_pipe) return rag_pipeline - def create_kg_pipeline(self, *args, **kwargs) -> KGEnrichmentPipeline: - kg_pipeline = KGEnrichmentPipeline() - kg_pipeline.add_pipe(self.pipes.kg_node_extraction_pipe) - kg_pipeline.add_pipe(self.pipes.kg_node_description_pipe) - kg_pipeline.add_pipe(self.pipes.kg_clustering_pipe) + def create_kg_enrichment_pipeline(self, *args, **kwargs) -> KGEnrichmentPipeline: + kg_enrichment_pipeline = KGEnrichmentPipeline() + kg_enrichment_pipeline.add_pipe(self.pipes.kg_node_extraction_pipe) + kg_enrichment_pipeline.add_pipe(self.pipes.kg_node_description_pipe) + kg_enrichment_pipeline.add_pipe(self.pipes.kg_clustering_pipe) - return kg_pipeline + return kg_enrichment_pipeline def create_pipelines( self, @@ -573,7 +573,7 @@ def create_pipelines( search_pipeline: Optional[SearchPipeline] = None, rag_pipeline: Optional[RAGPipeline] = None, streaming_rag_pipeline: Optional[RAGPipeline] = None, - kg_pipeline: Optional[KGEnrichmentPipeline] = None, + kg_enrichment_pipeline: Optional[KGEnrichmentPipeline] = None, *args, **kwargs, ) -> R2RPipelines: @@ -602,8 +602,8 @@ def create_pipelines( *args, **kwargs, ), - kg_pipeline=kg_pipeline - or self.create_kg_pipeline(*args, **kwargs), + kg_enrichment_pipeline=kg_enrichment_pipeline + or self.create_kg_enrichment_pipeline(*args, **kwargs), ) def configure_logging(self): diff --git a/r2r/main/engine.py b/r2r/main/engine.py index c90257cfd..e29daa77e 100644 --- a/r2r/main/engine.py +++ b/r2r/main/engine.py @@ -42,7 +42,7 @@ def __init__( logging_connection, ) - self.kg_service = RestructureService( + self.restructure_service = RestructureService( config, providers, pipelines, @@ -95,7 +95,7 @@ async def aupdate_files(self, *args, **kwargs): @syncable async def aenrich_graph(self, *args, **kwargs): - return await self.kg_service.enrich_graph(*args, **kwargs) + return await self.restructure_service.enrich_graph(*args, **kwargs) @syncable async def asearch(self, *args, **kwargs): diff --git a/r2r/main/execution.py b/r2r/main/execution.py index 9a0685c19..b1633fe79 100644 --- a/r2r/main/execution.py +++ b/r2r/main/execution.py @@ -231,7 +231,7 @@ def search( use_kg_search: bool = False, kg_search_generation_config: Optional[dict] = None, kg_search_type: str = "global", - kg_search_level: Optional[int] = None, + kg_search_level: Optional[str] = None, entity_types: list = [], relationships: list = [], ): @@ -287,6 +287,8 @@ def rag( kg_search_generation_config: Optional[dict] = None, stream: bool = False, rag_generation_config: Optional[dict] = None, + kg_search_type: str = "global", + kg_search_level: Optional[str] = None, ): if self.client_mode: response = self.client.rag( @@ -302,6 +304,8 @@ def rag( kg_search_generation_config=GenerationConfig( **(kg_search_generation_config or {}) ), + kg_search_type=kg_search_type, + kg_search_level=kg_search_level, ), rag_generation_config=GenerationConfig( **(rag_generation_config or {}) @@ -446,11 +450,11 @@ def ingest_sample_files(self, no_media: bool = True): sample_ingestor = SampleDataIngestor(self) return sample_ingestor.ingest_sample_files(no_media=no_media) - def inspect_knowledge_graph(self, limit: int = 100) -> str: + def inspect_knowledge_graph(self, limit: int = 100, print_descriptions: bool = False) -> str: if self.client_mode: - return self.client.inspect_knowledge_graph(limit)["results"] + return self.client.inspect_knowledge_graph(limit, print_descriptions)["results"] else: - return self.engine.inspect_knowledge_graph(limit) + return self.engine.inspect_knowledge_graph(limit, print_descriptions) def health(self) -> str: if self.client_mode: diff --git a/r2r/main/services/management_service.py b/r2r/main/services/management_service.py index dd8ef20bc..3dadf255c 100644 --- a/r2r/main/services/management_service.py +++ b/r2r/main/services/management_service.py @@ -320,7 +320,7 @@ async def users_overview( @telemetry_event("InspectKnowledgeGraph") async def inspect_knowledge_graph( - self, limit=10000, *args: Any, **kwargs: Any + self, limit=10000, print_descriptions: bool = False, *args: Any, **kwargs: Any ): if self.providers.kg is None: raise R2RException( @@ -329,19 +329,37 @@ async def inspect_knowledge_graph( rel_query = f""" MATCH (n1)-[r]->(n2) - RETURN n1.id AS subject, type(r) AS relation, n2.id AS object + return n1.name AS subject, n1.description AS subject_description, n2.name AS object, n2.description AS object_description, type(r) AS relation, r.description AS relation_description LIMIT {limit} """ try: - with self.providers.kg.client.session( - database=self.providers.kg._database - ) as session: - results = session.run(rel_query) - relationships = [ - (record["subject"], record["relation"], record["object"]) - for record in results - ] + neo4j_results = self.providers.kg.structured_query(rel_query).records + + relationships_raw = [{ + "subject": { + "name": record["subject"], + "description": record["subject_description"], + }, + "relation": { + "name": record["relation"], + "description": record["relation_description"], + }, + "object": { + "name": record["object"], + "description": record["object_description"], + }, + } + for record in neo4j_results + ] + + descriptions_dict = {} + relationships = [] + for relationship in relationships_raw: + descriptions_dict[relationship["subject"]["name"]] = relationship["subject"]["description"] + descriptions_dict[relationship["object"]["name"]] = relationship["object"]["description"] + descriptions_dict[relationship["relation"]["name"]] = relationship["relation"]["description"] + relationships.append((relationship["subject"]["name"], relationship["relation"]["name"], relationship["object"]["name"])) # Create graph representation and group relationships graph, grouped_relationships = self.process_relationships( @@ -349,12 +367,12 @@ async def inspect_knowledge_graph( ) # Generate output - output = self.generate_output(grouped_relationships, graph) + output = self.generate_output(grouped_relationships, graph, descriptions_dict, print_descriptions) return "\n".join(output) except Exception as e: - logger.error(f"Error printing relationships: {str(e)}") + logger.error("Error printing relationships", exc_info=True) raise R2RException( status_code=500, message=f"An error occurred while fetching relationships: {str(e)}", @@ -413,9 +431,10 @@ def generate_output( self, grouped_relationships: Dict[str, Dict[str, List[str]]], graph: Dict[str, List[str]], + descriptions_dict: Dict[str, str], + print_descriptions: bool = True ) -> List[str]: output = [] - # Print grouped relationships for subject, relations in grouped_relationships.items(): output.extend( diff --git a/r2r/main/services/restructure_service.py b/r2r/main/services/restructure_service.py index 1162ab222..b92d07fcf 100644 --- a/r2r/main/services/restructure_service.py +++ b/r2r/main/services/restructure_service.py @@ -44,13 +44,11 @@ async def enrich_graph( """ try: # Assuming there's a graph enrichment pipeline - enrichment_results = await self.pipelines.kg_pipeline.run( + return self.pipelines.kg_enrichment_pipeline.run( input=[], run_manager=self.run_manager, ) - return enrichment_results - except Exception as e: logger.error(f"Error during graph enrichment: {str(e)}") raise R2RException( diff --git a/r2r/pipelines/ingestion_pipeline.py b/r2r/pipelines/ingestion_pipeline.py index 5a1fe42e7..e6351750f 100644 --- a/r2r/pipelines/ingestion_pipeline.py +++ b/r2r/pipelines/ingestion_pipeline.py @@ -161,4 +161,4 @@ def add_pipe( pipe, add_upstream_outputs, *args, **kwargs ) else: - raise ValueError("Pipe must be a parsing, embedding, or KG pipe") + raise ValueError("Pipe must be a parsing, embedding, or KG pipe") \ No newline at end of file diff --git a/r2r/pipes/__init__.py b/r2r/pipes/__init__.py index 10f5cfaf1..4d27fe2d8 100644 --- a/r2r/pipes/__init__.py +++ b/r2r/pipes/__init__.py @@ -4,7 +4,7 @@ from .ingestion.parsing_pipe import ParsingPipe from .ingestion.vector_storage_pipe import VectorStoragePipe from .kg.clustering import KGClusteringPipe -from .kg.extraction import KGExtractionPipe +from .kg.extraction import KGTriplesExtractionPipe from .kg.node_extraction import KGNodeDescriptionPipe, KGNodeExtractionPipe from .kg.storage import KGStoragePipe from .other.web_search_pipe import WebSearchPipe @@ -18,7 +18,7 @@ __all__ = [ "SearchPipe", "EmbeddingPipe", - "KGExtractionPipe", + "KGTriplesExtractionPipe", "KGNodeExtractionPipe", "KGNodeDescriptionPipe", "ParsingPipe", diff --git a/r2r/pipes/ingestion/vector_storage_pipe.py b/r2r/pipes/ingestion/vector_storage_pipe.py index 06b3a9984..3f67d482d 100644 --- a/r2r/pipes/ingestion/vector_storage_pipe.py +++ b/r2r/pipes/ingestion/vector_storage_pipe.py @@ -12,7 +12,7 @@ ) from r2r.base.pipes.base_pipe import AsyncPipe -from ...base.abstractions.exception import R2RDocumentProcessingError +from r2r.base.abstractions.exception import R2RDocumentProcessingError logger = logging.getLogger(__name__) diff --git a/r2r/pipes/kg/clustering.py b/r2r/pipes/kg/clustering.py index 0fa51e905..5ef1648d2 100644 --- a/r2r/pipes/kg/clustering.py +++ b/r2r/pipes/kg/clustering.py @@ -7,6 +7,7 @@ import logging import uuid from typing import Any, AsyncGenerator, Optional +import json import networkx as nx from graspologic.partition import hierarchical_leiden @@ -85,25 +86,6 @@ async def cluster_kg(self, triples: list[Triple]) -> list[Community]: Clusters the knowledge graph triples into communities using hierarchical Leiden algorithm. """ - # for record in data: - # source = EntityNode( - # name=record["source_id"], - # label=record["source_type"], - # properties=remove_empty_values(record["source_properties"]), - # ) - # target = EntityNode( - # name=record["target_id"], - # label=record["target_type"], - # properties=remove_empty_values(record["target_properties"]), - # ) - # rel = Relation( - # source_id=record["source_id"], - # target_id=record["target_id"], - # label=record["type"], - # ) - # triples.append([source, rel, target]) - # return triples - G = nx.Graph() for triple in triples: G.add_edge( @@ -138,9 +120,6 @@ async def cluster_kg(self, triples: list[Triple]) -> list[Community]: community_details[f"{level}_{cluster}"].entity_ids.append(node) for neighbor in G.neighbors(node): edge_info = G.get_edge_data(node, neighbor) - logger.info(f"Node: {node}") - logger.info(f"Neighbor: {neighbor}") - logger.info(f"Edge info: {edge_info}") if edge_info and edge_info.get("id"): community_details[ f"{level}_{cluster}" @@ -196,11 +175,7 @@ async def process_community(community_key, community): ) description = description.choices[0].message.content - - logger.info(f"Community description: {description}") - community.summary = description - summary_embedding = ( await self.embedding_provider.async_get_embedding( community.summary @@ -208,7 +183,11 @@ async def process_community(community_key, community): ) community.summary_embedding = summary_embedding self.kg_provider.upsert_communities([community]) - return community + try: + summary = json.loads(community.summary) + except: + summary = {"title": "_"} + return { 'id': community.id, 'title': summary['title'] } tasks = [] async for community_key, community in async_iterate_dict( @@ -223,12 +202,6 @@ async def process_community(community_key, community): for completed_task in asyncio.as_completed(tasks): yield await completed_task - async def _process_batch(self, triples: list[Triple]) -> list[Community]: - """ - Processes a batch of triples and returns the resulting communities. - """ - return await self.cluster_kg(triples) - async def _run_logic( self, input: AsyncPipe.Input, @@ -240,43 +213,19 @@ async def _run_logic( """ Executes the KG clustering pipe: clustering entities and triples into communities. """ - # batch_tasks = [] - # triple_batch = [] - - # async for triple in input.message: - # triple_batch.append(triple) - # if len(triple_batch) >= self.cluster_batch_size: - # batch_tasks.append(self._process_batch(triple_batch.copy())) - # triple_batch.clear() - # if triple_batch: # Process any remaining triples - # batch_tasks.append(self._process_batch(triple_batch)) - - # for task in asyncio.as_completed(batch_tasks): - # communities = await task - # for community in communities: - # yield community - - # store all inputs + base_dimension = self.embedding_provider.config.base_dimension + vector_index_fn = self.kg_provider.create_vector_index + vector_index_fn("__ENTITY__", "name_embedding", base_dimension) + vector_index_fn("__ENTITY__", "description_embedding", base_dimension) + vector_index_fn("__RELATIONSHIP__", "description", base_dimension) + vector_index_fn("__Community__", "summary_embedding", base_dimension) all_nodes = [] async for node in input.message: all_nodes.append(node) triples = self.kg_provider.get_triples() - # create a networkx graph async for community in self.cluster_kg(triples): yield community - - # then finally create vector indexes for communities - self.kg_provider.create_vector_index("__ENTITY__", "name_embedding") - self.kg_provider.create_vector_index( - "__ENTITY__", "description_embedding" - ) - - self.kg_provider.create_vector_index("__RELATIONSHIP__", "description") - - self.kg_provider.create_vector_index( - "__Community__", "summary_embedding" - ) diff --git a/r2r/pipes/kg/extraction.py b/r2r/pipes/kg/extraction.py index ac00ab75c..c2d581256 100644 --- a/r2r/pipes/kg/extraction.py +++ b/r2r/pipes/kg/extraction.py @@ -19,8 +19,6 @@ R2RDocumentProcessingError, RunLoggingSingleton, Triple, - extract_entities, - extract_triples, ) from r2r.base.pipes.base_pipe import AsyncPipe @@ -33,7 +31,7 @@ class ClientError(Exception): pass -class KGExtractionPipe(AsyncPipe): +class KGTriplesExtractionPipe(AsyncPipe): """ Extracts knowledge graph information from document extractions. """ @@ -89,8 +87,7 @@ async def extract_kg( """ task_inputs = {"input": fragment.data} - if self.graph_rag: - task_inputs["max_knowledge_triplets"] = 100 + task_inputs["max_knowledge_triples"] = self.kg_provider.config.max_knowledge_triples messages = self.prompt_provider._get_message_payload( task_prompt_name=self.kg_provider.config.kg_extraction_prompt, @@ -105,87 +102,64 @@ async def extract_kg( ) kg_extraction = response.choices[0].message.content + entity_pattern = ( + r'\("entity"\${4}([^$]+)\${4}([^$]+)\${4}([^$]+)\)' + ) + relationship_pattern = r'\("relationship"\${4}([^$]+)\${4}([^$]+)\${4}([^$]+)\${4}([^$]+)\${4}(\d+(?:\.\d+)?)\)' - if self.graph_rag: - - entity_pattern = ( - r'\("entity"\${4}([^$]+)\${4}([^$]+)\${4}([^$]+)\)' + def parse_fn(response_str: str) -> Any: + entities = re.findall(entity_pattern, response_str) + relationships = re.findall( + relationship_pattern, response_str ) - relationship_pattern = r'\("relationship"\${4}([^$]+)\${4}([^$]+)\${4}([^$]+)\${4}([^$]+)\${4}(\d+(?:\.\d+)?)\)' - def parse_fn(response_str: str) -> Any: - entities = re.findall(entity_pattern, response_str) - relationships = re.findall( - relationship_pattern, response_str + entities_dict = {} + for entity in entities: + logger.info(f"Entity: {entity}") + entity_value = entity[0] + entity_category = entity[1] + entity_description = entity[2] + entities_dict[entity_value] = Entity( + category=entity_category, + description=entity_description, + name=entity_value, + document_ids=[str(fragment.document_id)], + text_unit_ids=[str(fragment.id)], + attributes={"fragment_text": fragment.data}, ) - entities_dict = {} - for entity in entities: - logger.info(f"Entity: {entity}") - entity_value = entity[0] - entity_category = entity[1] - entity_description = entity[2] - entities_dict[entity_value] = Entity( - category=entity_category, - description=entity_description, - name=entity_value, + relations_arr = [] + for relationship in relationships: + logger.info(f"Relationship: {relationship}") + subject = relationship[0] + object = relationship[1] + predicate = relationship[2] + description = relationship[3] + weight = float(relationship[4]) + + # check if subject and object are in entities_dict + relations_arr.append( + Triple( + id=str(uuid.uuid4()), + subject=subject, + predicate=predicate, + object=object, + description=description, + weight=weight, document_ids=[str(fragment.document_id)], text_unit_ids=[str(fragment.id)], - attributes={"fragment_text": fragment.data}, - ) - - relations_arr = [] - for relationship in relationships: - logger.info(f"Relationship: {relationship}") - subject = relationship[0] - object = relationship[1] - predicate = relationship[2] - description = relationship[3] - weight = float(relationship[4]) - - # check if subject and object are in entities_dict - relations_arr.append( - Triple( - id=str(uuid.uuid4()), - subject=subject, - predicate=predicate, - object=object, - description=description, - weight=weight, - document_ids=[str(fragment.document_id)], - text_unit_ids=[str(fragment.id)], - attributes={ - "fragment_text": fragment.data - }, - ) + attributes={ + "fragment_text": fragment.data + }, ) - - return entities_dict, relations_arr - - entities, triples = parse_fn(kg_extraction) - return KGExtraction( - entities=list(entities.values()), triples=triples - ) - - else: - # Parsing JSON from the response - kg_json = ( - json.loads( - kg_extraction.split("```json")[1].split("```")[0] ) - if "```json" in kg_extraction - else json.loads(kg_extraction) - ) - llm_payload = kg_json.get("entities_and_triples", {}) - # Extract triples with detailed logging - entities = extract_entities(llm_payload) - triples = extract_triples(llm_payload, entities) + return entities_dict, relations_arr - # Create KG extraction object - return KGExtraction( - entities=entities.values(), triples=triples - ) + entities, triples = parse_fn(kg_extraction) + return KGExtraction( + entities=list(entities.values()), triples=triples + ) except ( ClientError, diff --git a/r2r/pipes/kg/node_extraction.py b/r2r/pipes/kg/node_extraction.py index ffd8e7ce5..b4fda0584 100644 --- a/r2r/pipes/kg/node_extraction.py +++ b/r2r/pipes/kg/node_extraction.py @@ -3,15 +3,17 @@ import asyncio import logging import uuid -from typing import Any, AsyncGenerator, Optional +from typing import Any, AsyncGenerator, Optional, Union from r2r.base import ( AsyncState, CompletionProvider, EmbeddingProvider, + KGExtraction, KGProvider, PipeType, PromptProvider, + R2RDocumentProcessingError, RunLoggingSingleton, ) from r2r.base.abstractions.graph import Entity, Triple diff --git a/r2r/pipes/retrieval/kg_search_search_pipe.py b/r2r/pipes/retrieval/kg_search_search_pipe.py index 18aa77528..93fdf7b24 100644 --- a/r2r/pipes/retrieval/kg_search_search_pipe.py +++ b/r2r/pipes/retrieval/kg_search_search_pipe.py @@ -180,11 +180,11 @@ async def process_community(merged_report): # Use asyncio.gather to process all preprocessed community reports concurrently logger.info( - f"Processing {len(communities)} communities, {len(preprocessed_reports)} reports" + f"Processing {len(communities)} communities, {len(preprocessed_reports)} reports, Max LLM queries = {kg_search_settings.max_llm_queries_for_global_search}" ) map_responses = await asyncio.gather( - *[process_community(report) for report in preprocessed_reports] + *[process_community(report) for report in preprocessed_reports[:kg_search_settings.max_llm_queries_for_global_search]] ) # Filter only the relevant responses filtered_responses = self.filter_responses(map_responses) @@ -195,7 +195,7 @@ async def process_community(merged_report): task_prompt_name="graphrag_reduce_system_prompt", task_inputs={ "response_type": "multiple paragraphs", - "report_data": filtered_responses[:2048], + "report_data": filtered_responses, "input": message, }, ), diff --git a/r2r/providers/kg/neo4j/graph_queries.py b/r2r/providers/kg/neo4j/graph_queries.py index 4468ca9d3..6be93701f 100644 --- a/r2r/providers/kg/neo4j/graph_queries.py +++ b/r2r/providers/kg/neo4j/graph_queries.py @@ -127,7 +127,7 @@ GET_COMMUNITIES_QUERY = """ MATCH (c:__Community__) -where $level = -1 OR c.level = $level +WHERE $level IS NULL OR c.level = $level RETURN c """ diff --git a/r2r/providers/kg/neo4j/provider.py b/r2r/providers/kg/neo4j/provider.py index a8b89769c..3501b2657 100644 --- a/r2r/providers/kg/neo4j/provider.py +++ b/r2r/providers/kg/neo4j/provider.py @@ -282,15 +282,16 @@ def update_kg_search_prompt( ) -> None: pass - def get_communities(self, level: int = -1) -> List[Community]: + def get_communities(self, level: str = None) -> List[Community]: """ Get communities from the graph. """ neo4j_records = self.structured_query( GET_COMMUNITIES_QUERY, {"level": level} ) + communities = [ - Community(**record["c"]._properties) + Community(**record["c"]._properties, id=record["c"]["community"]) for record in neo4j_records.records ] return communities @@ -320,13 +321,13 @@ def get_rel_map( def client(self): return self._driver - def create_vector_index(self, node_type: str, node_property: str) -> None: + def create_vector_index(self, node_type: str, node_property: str, dimension: int) -> None: query = f""" CREATE VECTOR INDEX `{node_type}_{node_property}` IF NOT EXISTS FOR (n:{node_type}) ON n.{node_property} - OPTIONS {{indexConfig: {{`vector.similarity_function`: 'cosine', `vector.dimensions`:{self.embedding_provider.config.base_dimension}}}}}""" + OPTIONS {{indexConfig: {{`vector.similarity_function`: 'cosine', `vector.dimensions`:{dimension}}}}}""" self.structured_query(query) diff --git a/r2r/providers/prompts/defaults/graphrag_triplet_extraction_few_shot.yaml b/r2r/providers/prompts/defaults/graphrag_triplet_extraction_few_shot.yaml index 0a9b580a8..bb2e31ee4 100644 --- a/r2r/providers/prompts/defaults/graphrag_triplet_extraction_few_shot.yaml +++ b/r2r/providers/prompts/defaults/graphrag_triplet_extraction_few_shot.yaml @@ -2,7 +2,7 @@ graphrag_triplet_extraction_few_shot: template: > -Goal- Given a text document, identify all entities and their entity types from the text and all relationships among the identified entities. - Given the text, extract up to {max_knowledge_triplets} entity-relation triplets. + Given the text, extract up to {max_knowledge_triples} entity-relation triplets. -Steps- 1. Identify all entities. For each identified entity, extract the following information: - entity_name: Name of the entity, capitalized @@ -30,7 +30,7 @@ graphrag_triplet_extraction_few_shot: {relation_types} input_types: - max_knowledge_triplets: int + max_knowledge_triples: int input: str entity_types: list[str] relation_types: list[str] diff --git a/r2r/providers/prompts/defaults/graphrag_triplet_extraction_zero_shot.yaml b/r2r/providers/prompts/defaults/graphrag_triplet_extraction_zero_shot.yaml index d2d11fb2c..a1762ea68 100644 --- a/r2r/providers/prompts/defaults/graphrag_triplet_extraction_zero_shot.yaml +++ b/r2r/providers/prompts/defaults/graphrag_triplet_extraction_zero_shot.yaml @@ -2,7 +2,7 @@ graphrag_triplet_extraction_zero_shot: template: > -Goal- Given a text document, identify all entities and their entity types from the text and all relationships among the identified entities. - Given the text, extract up to {max_knowledge_triplets} entity-relation triplets. + Given the text, extract up to {max_knowledge_triples} entity-relation triplets. -Steps- 1. Identify all entities. For each identified entity, extract the following information: - entity_name: Name of the entity, capitalized @@ -24,5 +24,5 @@ graphrag_triplet_extraction_zero_shot: ###################### input_types: - max_knowledge_triplets: int + max_knowledge_triples: int input: str From d00b5a98b5cdc932184fcd747edf2e8c0dd65f2a Mon Sep 17 00:00:00 2001 From: emrgnt-cmplxty <68796651+emrgnt-cmplxty@users.noreply.github.com> Date: Mon, 19 Aug 2024 13:06:06 -0700 Subject: [PATCH 05/74] Feature/fix embedding pipe (#882) * up * fixup concurrency * fix ollama embeddings * fix batching with ollama * checkin all cleanups --- poetry.lock | 725 +++++++++--------- pyproject.toml | 2 +- r2r/base/abstractions/completion.py | 6 +- r2r/base/abstractions/graph.py | 1 + r2r/base/abstractions/search.py | 28 +- r2r/base/logging/run_manager.py | 14 +- r2r/base/pipes/base_pipe.py | 6 +- r2r/base/providers/chunking.py | 20 + r2r/base/providers/embedding.py | 39 +- r2r/base/providers/kg.py | 6 +- r2r/base/utils/__init__.py | 2 + r2r/base/utils/base_utils.py | 17 +- r2r/cli/commands/rag_operations.py | 12 +- r2r/configs/local_llm.toml | 4 +- r2r/examples/scripts/advanced_kg_cookbook.py | 6 +- r2r/examples/scripts/sample_data_ingestor.py | 4 +- r2r/main/api/client/auth.py | 4 +- r2r/main/api/client/ingestion.py | 36 +- r2r/main/api/client/management.py | 42 +- r2r/main/api/routes/auth/base.py | 6 +- r2r/main/api/routes/base_router.py | 9 +- r2r/main/api/routes/ingestion/base.py | 340 +++----- .../ingestion/ingestion_router_openapi.yml | 61 ++ r2r/main/api/routes/management/base.py | 40 +- r2r/main/assembly/factory.py | 4 +- r2r/main/execution.py | 20 +- r2r/main/services/auth_service.py | 6 +- r2r/main/services/ingestion_service.py | 337 ++++---- r2r/main/services/management_service.py | 114 +-- r2r/main/services/retrieval_service.py | 8 +- r2r/pipelines/ingestion_pipeline.py | 2 +- r2r/pipes/abstractions/generator_pipe.py | 4 +- r2r/pipes/abstractions/search_pipe.py | 4 +- r2r/pipes/ingestion/embedding_pipe.py | 74 +- r2r/pipes/ingestion/parsing_pipe.py | 7 +- r2r/pipes/ingestion/vector_storage_pipe.py | 56 +- r2r/pipes/kg/clustering.py | 8 +- r2r/pipes/kg/extraction.py | 8 +- r2r/pipes/kg/node_extraction.py | 10 +- r2r/pipes/kg/storage.py | 4 +- r2r/pipes/other/web_search_pipe.py | 6 +- r2r/pipes/retrieval/kg_search_search_pipe.py | 15 +- r2r/pipes/retrieval/multi_search.py | 4 +- r2r/pipes/retrieval/query_transform_pipe.py | 4 +- r2r/pipes/retrieval/streaming_rag_pipe.py | 4 +- r2r/pipes/retrieval/vector_search_pipe.py | 6 +- r2r/providers/database/relational.py | 1 - r2r/providers/database/vecs/adapter/base.py | 12 +- r2r/providers/database/vecs/collection.py | 10 +- r2r/providers/embeddings/litellm.py | 67 +- r2r/providers/embeddings/ollama.py | 101 ++- r2r/providers/embeddings/openai.py | 101 +-- r2r/providers/kg/neo4j/provider.py | 10 +- tests/test_ingestion_service.py | 4 +- 54 files changed, 1245 insertions(+), 1196 deletions(-) create mode 100644 r2r/main/api/routes/ingestion/ingestion_router_openapi.yml diff --git a/poetry.lock b/poetry.lock index 82c4a01ba..53e96de38 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2,98 +2,98 @@ [[package]] name = "aiohappyeyeballs" -version = "2.3.5" +version = "2.4.0" description = "Happy Eyeballs for asyncio" optional = false python-versions = ">=3.8" files = [ - {file = "aiohappyeyeballs-2.3.5-py3-none-any.whl", hash = "sha256:4d6dea59215537dbc746e93e779caea8178c866856a721c9c660d7a5a7b8be03"}, - {file = "aiohappyeyeballs-2.3.5.tar.gz", hash = "sha256:6fa48b9f1317254f122a07a131a86b71ca6946ca989ce6326fff54a99a920105"}, + {file = "aiohappyeyeballs-2.4.0-py3-none-any.whl", hash = "sha256:7ce92076e249169a13c2f49320d1967425eaf1f407522d707d59cac7628d62bd"}, + {file = "aiohappyeyeballs-2.4.0.tar.gz", hash = "sha256:55a1714f084e63d49639800f95716da97a1f173d46a16dfcfda0016abb93b6b2"}, ] [[package]] name = "aiohttp" -version = "3.10.1" +version = "3.10.4" description = "Async http client/server framework (asyncio)" optional = false python-versions = ">=3.8" files = [ - {file = "aiohttp-3.10.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:47b4c2412960e64d97258f40616efddaebcb34ff664c8a972119ed38fac2a62c"}, - {file = "aiohttp-3.10.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e7dbf637f87dd315fa1f36aaed8afa929ee2c607454fb7791e74c88a0d94da59"}, - {file = "aiohttp-3.10.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c8fb76214b5b739ce59e2236a6489d9dc3483649cfd6f563dbf5d8e40dbdd57d"}, - {file = "aiohttp-3.10.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c577cdcf8f92862363b3d598d971c6a84ed8f0bf824d4cc1ce70c2fb02acb4a"}, - {file = "aiohttp-3.10.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:777e23609899cb230ad2642b4bdf1008890f84968be78de29099a8a86f10b261"}, - {file = "aiohttp-3.10.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b07286a1090483799599a2f72f76ac396993da31f6e08efedb59f40876c144fa"}, - {file = "aiohttp-3.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b9db600a86414a9a653e3c1c7f6a2f6a1894ab8f83d11505247bd1b90ad57157"}, - {file = "aiohttp-3.10.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01c3f1eb280008e51965a8d160a108c333136f4a39d46f516c64d2aa2e6a53f2"}, - {file = "aiohttp-3.10.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f5dd109a925fee4c9ac3f6a094900461a2712df41745f5d04782ebcbe6479ccb"}, - {file = "aiohttp-3.10.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:8c81ff4afffef9b1186639506d70ea90888218f5ddfff03870e74ec80bb59970"}, - {file = "aiohttp-3.10.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:2a384dfbe8bfebd203b778a30a712886d147c61943675f4719b56725a8bbe803"}, - {file = "aiohttp-3.10.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:b9fb6508893dc31cfcbb8191ef35abd79751db1d6871b3e2caee83959b4d91eb"}, - {file = "aiohttp-3.10.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:88596384c3bec644a96ae46287bb646d6a23fa6014afe3799156aef42669c6bd"}, - {file = "aiohttp-3.10.1-cp310-cp310-win32.whl", hash = "sha256:68164d43c580c2e8bf8e0eb4960142919d304052ccab92be10250a3a33b53268"}, - {file = "aiohttp-3.10.1-cp310-cp310-win_amd64.whl", hash = "sha256:d6bbe2c90c10382ca96df33b56e2060404a4f0f88673e1e84b44c8952517e5f3"}, - {file = "aiohttp-3.10.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f6979b4f20d3e557a867da9d9227de4c156fcdcb348a5848e3e6190fd7feb972"}, - {file = "aiohttp-3.10.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:03c0c380c83f8a8d4416224aafb88d378376d6f4cadebb56b060688251055cd4"}, - {file = "aiohttp-3.10.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1c2b104e81b3c3deba7e6f5bc1a9a0e9161c380530479970766a6655b8b77c7c"}, - {file = "aiohttp-3.10.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b023b68c61ab0cd48bd38416b421464a62c381e32b9dc7b4bdfa2905807452a4"}, - {file = "aiohttp-3.10.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a07c76a82390506ca0eabf57c0540cf5a60c993c442928fe4928472c4c6e5e6"}, - {file = "aiohttp-3.10.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:41d8dab8c64ded1edf117d2a64f353efa096c52b853ef461aebd49abae979f16"}, - {file = "aiohttp-3.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:615348fab1a9ef7d0960a905e83ad39051ae9cb0d2837da739b5d3a7671e497a"}, - {file = "aiohttp-3.10.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:256ee6044214ee9d66d531bb374f065ee94e60667d6bbeaa25ca111fc3997158"}, - {file = "aiohttp-3.10.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b7d5bb926805022508b7ddeaad957f1fce7a8d77532068d7bdb431056dc630cd"}, - {file = "aiohttp-3.10.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:028faf71b338f069077af6315ad54281612705d68889f5d914318cbc2aab0d50"}, - {file = "aiohttp-3.10.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:5c12310d153b27aa630750be44e79313acc4e864c421eb7d2bc6fa3429c41bf8"}, - {file = "aiohttp-3.10.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:de1a91d5faded9054957ed0a9e01b9d632109341942fc123947ced358c5d9009"}, - {file = "aiohttp-3.10.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9c186b270979fb1dee3ababe2d12fb243ed7da08b30abc83ebac3a928a4ddb15"}, - {file = "aiohttp-3.10.1-cp311-cp311-win32.whl", hash = "sha256:4a9ce70f5e00380377aac0e568abd075266ff992be2e271765f7b35d228a990c"}, - {file = "aiohttp-3.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:a77c79bac8d908d839d32c212aef2354d2246eb9deb3e2cb01ffa83fb7a6ea5d"}, - {file = "aiohttp-3.10.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:2212296cdb63b092e295c3e4b4b442e7b7eb41e8a30d0f53c16d5962efed395d"}, - {file = "aiohttp-3.10.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:4dcb127ca3eb0a61205818a606393cbb60d93b7afb9accd2fd1e9081cc533144"}, - {file = "aiohttp-3.10.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cb8b79a65332e1a426ccb6290ce0409e1dc16b4daac1cc5761e059127fa3d134"}, - {file = "aiohttp-3.10.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68cc24f707ed9cb961f6ee04020ca01de2c89b2811f3cf3361dc7c96a14bfbcc"}, - {file = "aiohttp-3.10.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9cb54f5725b4b37af12edf6c9e834df59258c82c15a244daa521a065fbb11717"}, - {file = "aiohttp-3.10.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:51d03e948e53b3639ce4d438f3d1d8202898ec6655cadcc09ec99229d4adc2a9"}, - {file = "aiohttp-3.10.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:786299d719eb5d868f161aeec56d589396b053925b7e0ce36e983d30d0a3e55c"}, - {file = "aiohttp-3.10.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abda4009a30d51d3f06f36bc7411a62b3e647fa6cc935ef667e3e3d3a7dd09b1"}, - {file = "aiohttp-3.10.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:67f7639424c313125213954e93a6229d3a1d386855d70c292a12628f600c7150"}, - {file = "aiohttp-3.10.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:8e5a26d7aac4c0d8414a347da162696eea0629fdce939ada6aedf951abb1d745"}, - {file = "aiohttp-3.10.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:120548d89f14b76a041088b582454d89389370632ee12bf39d919cc5c561d1ca"}, - {file = "aiohttp-3.10.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:f5293726943bdcea24715b121d8c4ae12581441d22623b0e6ab12d07ce85f9c4"}, - {file = "aiohttp-3.10.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1f8605e573ed6c44ec689d94544b2c4bb1390aaa723a8b5a2cc0a5a485987a68"}, - {file = "aiohttp-3.10.1-cp312-cp312-win32.whl", hash = "sha256:e7168782621be4448d90169a60c8b37e9b0926b3b79b6097bc180c0a8a119e73"}, - {file = "aiohttp-3.10.1-cp312-cp312-win_amd64.whl", hash = "sha256:8fbf8c0ded367c5c8eaf585f85ca8dd85ff4d5b73fb8fe1e6ac9e1b5e62e11f7"}, - {file = "aiohttp-3.10.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:54b7f4a20d7cc6bfa4438abbde069d417bb7a119f870975f78a2b99890226d55"}, - {file = "aiohttp-3.10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2fa643ca990323db68911b92f3f7a0ca9ae300ae340d0235de87c523601e58d9"}, - {file = "aiohttp-3.10.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d8311d0d690487359fe2247ec5d2cac9946e70d50dced8c01ce9e72341c21151"}, - {file = "aiohttp-3.10.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:222821c60b8f6a64c5908cb43d69c0ee978a1188f6a8433d4757d39231b42cdb"}, - {file = "aiohttp-3.10.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e7b55d9ede66af7feb6de87ff277e0ccf6d51c7db74cc39337fe3a0e31b5872d"}, - {file = "aiohttp-3.10.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a95151a5567b3b00368e99e9c5334a919514f60888a6b6d2054fea5e66e527e"}, - {file = "aiohttp-3.10.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e9e9171d2fe6bfd9d3838a6fe63b1e91b55e0bf726c16edf265536e4eafed19"}, - {file = "aiohttp-3.10.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a57e73f9523e980f6101dc9a83adcd7ac0006ea8bf7937ca3870391c7bb4f8ff"}, - {file = "aiohttp-3.10.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:0df51a3d70a2bfbb9c921619f68d6d02591f24f10e9c76de6f3388c89ed01de6"}, - {file = "aiohttp-3.10.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:b0de63ff0307eac3961b4af74382d30220d4813f36b7aaaf57f063a1243b4214"}, - {file = "aiohttp-3.10.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:8db9b749f589b5af8e4993623dbda6716b2b7a5fcb0fa2277bf3ce4b278c7059"}, - {file = "aiohttp-3.10.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:6b14c19172eb53b63931d3e62a9749d6519f7c121149493e6eefca055fcdb352"}, - {file = "aiohttp-3.10.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:5cd57ad998e3038aa87c38fe85c99ed728001bf5dde8eca121cadee06ee3f637"}, - {file = "aiohttp-3.10.1-cp38-cp38-win32.whl", hash = "sha256:df31641e3f02b77eb3c5fb63c0508bee0fc067cf153da0e002ebbb0db0b6d91a"}, - {file = "aiohttp-3.10.1-cp38-cp38-win_amd64.whl", hash = "sha256:93094eba50bc2ad4c40ff4997ead1fdcd41536116f2e7d6cfec9596a8ecb3615"}, - {file = "aiohttp-3.10.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:440954ddc6b77257e67170d57b1026aa9545275c33312357472504eef7b4cc0b"}, - {file = "aiohttp-3.10.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f9f8beed277488a52ee2b459b23c4135e54d6a819eaba2e120e57311015b58e9"}, - {file = "aiohttp-3.10.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d8a8221a63602008550022aa3a4152ca357e1dde7ab3dd1da7e1925050b56863"}, - {file = "aiohttp-3.10.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a702bd3663b5cbf3916e84bf332400d24cdb18399f0877ca6b313ce6c08bfb43"}, - {file = "aiohttp-3.10.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1988b370536eb14f0ce7f3a4a5b422ab64c4e255b3f5d7752c5f583dc8c967fc"}, - {file = "aiohttp-3.10.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7ccf1f0a304352c891d124ac1a9dea59b14b2abed1704aaa7689fc90ef9c5be1"}, - {file = "aiohttp-3.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc3ea6ef2a83edad84bbdb5d96e22f587b67c68922cd7b6f9d8f24865e655bcf"}, - {file = "aiohttp-3.10.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:89b47c125ab07f0831803b88aeb12b04c564d5f07a1c1a225d4eb4d2f26e8b5e"}, - {file = "aiohttp-3.10.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:21778552ef3d44aac3278cc6f6d13a6423504fa5f09f2df34bfe489ed9ded7f5"}, - {file = "aiohttp-3.10.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:bde0693073fd5e542e46ea100aa6c1a5d36282dbdbad85b1c3365d5421490a92"}, - {file = "aiohttp-3.10.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:bf66149bb348d8e713f3a8e0b4f5b952094c2948c408e1cfef03b49e86745d60"}, - {file = "aiohttp-3.10.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:587237571a85716d6f71f60d103416c9df7d5acb55d96d3d3ced65f39bff9c0c"}, - {file = "aiohttp-3.10.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:bfe33cba6e127d0b5b417623c9aa621f0a69f304742acdca929a9fdab4593693"}, - {file = "aiohttp-3.10.1-cp39-cp39-win32.whl", hash = "sha256:9fbff00646cf8211b330690eb2fd64b23e1ce5b63a342436c1d1d6951d53d8dd"}, - {file = "aiohttp-3.10.1-cp39-cp39-win_amd64.whl", hash = "sha256:5951c328f9ac42d7bce7a6ded535879bc9ae13032818d036749631fa27777905"}, - {file = "aiohttp-3.10.1.tar.gz", hash = "sha256:8b0d058e4e425d3b45e8ec70d49b402f4d6b21041e674798b1f91ba027c73f28"}, + {file = "aiohttp-3.10.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:81037ddda8cc0a95c6d8c1b9029d0b19a62db8770c0e239e3bea0109d294ab66"}, + {file = "aiohttp-3.10.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:71944d4f4090afc07ce96b7029d5a574240e2f39570450df4af0d5b93a5ee64a"}, + {file = "aiohttp-3.10.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c774f08afecc0a617966f45a9c378456e713a999ee60654d9727617def3e4ee4"}, + {file = "aiohttp-3.10.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dc990e73613c78ab2930b60266135066f37fdfce6b32dd604f42c5c377ee880a"}, + {file = "aiohttp-3.10.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f6acd1a908740f708358d240f9a3243cec31a456e3ded65c2cb46f6043bc6735"}, + {file = "aiohttp-3.10.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6075e27e7e54fbcd1c129c5699b2d251c885c9892e26d59a0fb7705141c2d14b"}, + {file = "aiohttp-3.10.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc98d93d11d860ac823beb6131f292d82efb76f226b5e28a3eab1ec578dfd041"}, + {file = "aiohttp-3.10.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:201ddf1471567568be381b6d4701e266a768f7eaa2f99ef753f2c9c5e1e3fb5c"}, + {file = "aiohttp-3.10.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:7d202ec55e61f06b1a1eaf317fba7546855cbf803c13ce7625d462fb8c88e238"}, + {file = "aiohttp-3.10.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:96b2e7c110a941c8c1a692703b8ac1013e47f17ee03356c71d55c0a54de2ce38"}, + {file = "aiohttp-3.10.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:8ba0fbc56c44883bd757ece433f9caadbca67f565934afe9bc53ba3bd99cc368"}, + {file = "aiohttp-3.10.4-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:46cc9069da466652bb7b8b3fac1f8ce2e12a9dc0fb11551faa420c4cdbc60abf"}, + {file = "aiohttp-3.10.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:93a19cd1e9dc703257fda78b8e889c3a08eabaa09f6ff0d867850b03964f80d1"}, + {file = "aiohttp-3.10.4-cp310-cp310-win32.whl", hash = "sha256:8593040bcc8075fc0e817a602bc5d3d74c7bd717619ffc175a8ba0188edebadf"}, + {file = "aiohttp-3.10.4-cp310-cp310-win_amd64.whl", hash = "sha256:326fb5228aadfc395981d9b336d56a698da335897c4143105c73b583d7500839"}, + {file = "aiohttp-3.10.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:dfe48f477e02ef5ab247c6ac431a6109c69b5c24cb3ccbcd3e27c4fb39691fe4"}, + {file = "aiohttp-3.10.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f6fe78b51852e25d4e20be51ef88c2a0bf31432b9f2223bdbd61c01a0f9253a7"}, + {file = "aiohttp-3.10.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5cc75ff5efbd92301e63a157fddb18a6964a3f40e31c77d57e97dbb9bb3373b4"}, + {file = "aiohttp-3.10.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dca39391f45fbb28daa6412f98c625265bf6b512cc41382df61672d1b242f8f4"}, + {file = "aiohttp-3.10.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8616dd5ed8b3b4029021b560305041c62e080bb28f238c27c2e150abe3539587"}, + {file = "aiohttp-3.10.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9d7958ba22854b3f00a7bbb66cde1dc759760ce8a3e6dfe9ea53f06bccaa9aa2"}, + {file = "aiohttp-3.10.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a24ac7164a824ef2e8e4e9a9f6debb1f43c44ad7ad04efc6018a6610555666d"}, + {file = "aiohttp-3.10.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:660ad010b8fd0b26e8edb8ae5c036db5b16baac4278198ad238b11956d920b3d"}, + {file = "aiohttp-3.10.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:93ee83008d3e505db9846a5a1f48a002676d8dcc90ee431a9462541c9b81393c"}, + {file = "aiohttp-3.10.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:77071795efd6ba87f409001141fb05c94ee962b9fca6c8fa1f735c2718512de4"}, + {file = "aiohttp-3.10.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:ff371ae72a1816c3eeba5c9cff42cb739aaa293fec7d78f180d1c7ee342285b6"}, + {file = "aiohttp-3.10.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:c253e81f12da97f85d45441e8c6da0d9c12e07db4a7136b0a955df6fc5e4bf51"}, + {file = "aiohttp-3.10.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2ce101c447cf7ba4b6e5ab07bfa2c0da21cbab66922f78a601f0b84fd7710d72"}, + {file = "aiohttp-3.10.4-cp311-cp311-win32.whl", hash = "sha256:705c311ecf2d30fbcf3570d1a037c657be99095694223488140c47dee4ef2460"}, + {file = "aiohttp-3.10.4-cp311-cp311-win_amd64.whl", hash = "sha256:ebddbfea8a8d6b97f717658fa85a96681a28990072710d3de3a4eba5d6804a37"}, + {file = "aiohttp-3.10.4-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:fe4d63f42d9c604521b208b754abfafe01218af4a8f6332b43196ee8fe88bbd5"}, + {file = "aiohttp-3.10.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:fef7b7bd3a6911b4d148332136d34d3c2aee3d54d354373b1da6d96bc08089a5"}, + {file = "aiohttp-3.10.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fff8606149098935188fe1e135f7e7991e6a36d6fe394fd15939fc57d0aff889"}, + {file = "aiohttp-3.10.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9eb3df1aa83602be9a5e572c834d74c3c8e382208b59a873aabfe4c493c45ed0"}, + {file = "aiohttp-3.10.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5c4a71d4a5e0cbfd4bfadd13cb84fe2bc76c64d550dc4f22c22008c9354cffb3"}, + {file = "aiohttp-3.10.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bf61884a604c399458c4a42c8caea000fbcc44255ed89577ff50cb688a0fe8e2"}, + {file = "aiohttp-3.10.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2015e4b40bd5dedc8155c2b2d24a2b07963ae02b5772373d0b599a68e38a316b"}, + {file = "aiohttp-3.10.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b06e1a66bf0a1a2d0f12aef25843dfd2093df080d6c1acbc43914bb9c8f36ed3"}, + {file = "aiohttp-3.10.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:eb898c9ad5a1228a669ebe2e2ba3d76aebe1f7c10b78f09a36000254f049fc2b"}, + {file = "aiohttp-3.10.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:2d64a5a7539320c3cecb4bca093ea825fcc906f8461cf8b42a7bf3c706ce1932"}, + {file = "aiohttp-3.10.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:438c6e1492d060b21285f4b6675b941cf96dd9ef3dfdd59940561029b82e3e1f"}, + {file = "aiohttp-3.10.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e99bf118afb2584848dba169a685fe092b338a4fe52ae08c7243d7bc4cc204fe"}, + {file = "aiohttp-3.10.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9dc26781fb95225c6170619dece8b5c6ca7cfb1b0be97b7ee719915773d0c2a9"}, + {file = "aiohttp-3.10.4-cp312-cp312-win32.whl", hash = "sha256:45bb655cb8b3a61e19977183a4e0962051ae90f6d46588ed4addb8232128141c"}, + {file = "aiohttp-3.10.4-cp312-cp312-win_amd64.whl", hash = "sha256:347bbdc48411badc24fe3a13565820bc742db3aa2f9127cd5f48c256caf87e29"}, + {file = "aiohttp-3.10.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:4ad284cee0fdcdc0216346b849fd53d201b510aff3c48aa3622daec9ada4bf80"}, + {file = "aiohttp-3.10.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:58df59234be7d7e80548b9482ebfeafdda21948c25cb2873c7f23870c8053dfe"}, + {file = "aiohttp-3.10.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5f52225af7f91f27b633f73473e9ef0aa8e2112d57b69eaf3aa4479e3ea3bc0e"}, + {file = "aiohttp-3.10.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:93f1a0e12c321d923c024b56d7dcd8012e60bf30a4b3fb69a88be15dcb9ab80b"}, + {file = "aiohttp-3.10.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c9e9e9a51dd12f2f71fdbd7f7230dcb75ed8f77d8ac8e07c73b599b6d7027e5c"}, + {file = "aiohttp-3.10.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:38bb515f1affc36d3d97b02bf82099925a5785c4a96066ff4400a83ad09d3d5d"}, + {file = "aiohttp-3.10.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e685afb0e3b7b861d89cb3690d89eeda221b43095352efddaaa735c6baf87f3"}, + {file = "aiohttp-3.10.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abd5673e3391564871ba6753cf674dcf2051ef19dc508998fe0758a6c7b429a0"}, + {file = "aiohttp-3.10.4-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:4b34e5086e1ead3baa740e32adf35cc5e42338e44c4b07f7b62b41ca6d6a5bfd"}, + {file = "aiohttp-3.10.4-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:c3fd3b8f0164fb2866400cd6eb9e884ab0dc95f882cf8b25e560ace7350c552d"}, + {file = "aiohttp-3.10.4-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:b95e1694d234f27b4bbf5bdef56bb751974ac5dbe045b1e462bde1fe39421cbe"}, + {file = "aiohttp-3.10.4-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:c031de4dfabe7bb6565743745ab43d20588944ddfc7233360169cab4008eee2f"}, + {file = "aiohttp-3.10.4-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:03c5a3143d4a82c43a3d82ac77d9cdef527a72f1c04dcca7b14770879f33d196"}, + {file = "aiohttp-3.10.4-cp38-cp38-win32.whl", hash = "sha256:b71722b527445e02168e2d1cf435772731874671a647fa159ad000feea7933b6"}, + {file = "aiohttp-3.10.4-cp38-cp38-win_amd64.whl", hash = "sha256:0fd1f57aac7d01c9c768675d531976d20d5b79d9da67fac87e55d41b4ade05f9"}, + {file = "aiohttp-3.10.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:15b36a644d1f44ea3d94a0bbb71e75d5f394a3135dc388a209466e22b711ce64"}, + {file = "aiohttp-3.10.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:394ddf9d216cf0bd429b223239a0ab628f01a7a1799c93ce4685eedcdd51b9bc"}, + {file = "aiohttp-3.10.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:dd33f4d571b4143fc9318c3d9256423579c7d183635acc458a6db81919ae5204"}, + {file = "aiohttp-3.10.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e5991b80886655e6c785aadf3114d4f86e6bec2da436e2bb62892b9f048450a4"}, + {file = "aiohttp-3.10.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:92021bf0a4b9ad16851a6c1ca3c86e5b09aecca4f7a2576430c6bbf3114922b1"}, + {file = "aiohttp-3.10.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:938e37fd337343c67471098736deb33066d72cec7d8927b9c1b6b4ea807ade9e"}, + {file = "aiohttp-3.10.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d697023b16c62f9aeb3ffdfb8ec4ac3afd477388993b9164b47dadbd60e7062"}, + {file = "aiohttp-3.10.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c2f9f07fe6d0d51bd2a788cbb339f1570fd691449c53b5dec83ff838f117703e"}, + {file = "aiohttp-3.10.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:50ac670f3fc13ce95e4d6d5a299db9288cc84c663aa630142444ef504756fcf7"}, + {file = "aiohttp-3.10.4-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:9bcdd19398212785a9cb82a63a4b75a299998343f3f5732dfd37c1a4275463f9"}, + {file = "aiohttp-3.10.4-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:122c26f0976225aba46f381e3cabb5ef89a08af6503fc30493fb732e578cfa55"}, + {file = "aiohttp-3.10.4-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:d0665e2a346b6b66959f831ffffd8aa71dd07dd2300017d478f5b47573e66cfe"}, + {file = "aiohttp-3.10.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:625a4a9d4b9f80e7bbaaf2ace06341cf701b2fee54232843addf0bb7304597fb"}, + {file = "aiohttp-3.10.4-cp39-cp39-win32.whl", hash = "sha256:5115490112f39f16ae87c1b34dff3e2c95306cf456b1d2af5974c4ac7d2d1ec7"}, + {file = "aiohttp-3.10.4-cp39-cp39-win_amd64.whl", hash = "sha256:9b58b2ef7f28a2462ba86acbf3b20371bd80a1faa1cfd82f31968af4ac81ef25"}, + {file = "aiohttp-3.10.4.tar.gz", hash = "sha256:23a5f97e7dd22e181967fb6cb6c3b11653b0fdbbc4bb7739d9b6052890ccab96"}, ] [package.dependencies] @@ -1417,13 +1417,13 @@ socks = ["socksio (==1.*)"] [[package]] name = "huggingface-hub" -version = "0.24.5" +version = "0.24.6" description = "Client library to download and publish models, datasets and other repos on the huggingface.co hub" optional = false python-versions = ">=3.8.0" files = [ - {file = "huggingface_hub-0.24.5-py3-none-any.whl", hash = "sha256:d93fb63b1f1a919a22ce91a14518974e81fc4610bf344dfe7572343ce8d3aced"}, - {file = "huggingface_hub-0.24.5.tar.gz", hash = "sha256:7b45d6744dd53ce9cbf9880957de00e9d10a9ae837f1c9b7255fc8fa4e8264f3"}, + {file = "huggingface_hub-0.24.6-py3-none-any.whl", hash = "sha256:a990f3232aa985fe749bc9474060cbad75e8b2f115f6665a9fda5b9c97818970"}, + {file = "huggingface_hub-0.24.6.tar.gz", hash = "sha256:cc2579e761d070713eaa9c323e3debe39d5b464ae3a7261c39a9195b27bb8000"}, ] [package.dependencies] @@ -1493,13 +1493,13 @@ files = [ [[package]] name = "imageio" -version = "2.34.2" +version = "2.35.1" description = "Library for reading and writing a wide range of image, video, scientific, and volumetric data formats." optional = true python-versions = ">=3.8" files = [ - {file = "imageio-2.34.2-py3-none-any.whl", hash = "sha256:a0bb27ec9d5bab36a9f4835e51b21d2cb099e1f78451441f94687ff3404b79f8"}, - {file = "imageio-2.34.2.tar.gz", hash = "sha256:5c0c0ee8faa018a1c42f649b90395dd4d3bb6187c09053a0cd6f1fdd51bbff5e"}, + {file = "imageio-2.35.1-py3-none-any.whl", hash = "sha256:6eb2e5244e7a16b85c10b5c2fe0f7bf961b40fcb9f1a9fd1bd1d2c2f8fb3cd65"}, + {file = "imageio-2.35.1.tar.gz", hash = "sha256:4952dfeef3c3947957f6d5dedb1f4ca31c6e509a476891062396834048aeed2a"}, ] [package.dependencies] @@ -1507,19 +1507,20 @@ numpy = "*" pillow = ">=8.3.2" [package.extras] -all-plugins = ["astropy", "av", "imageio-ffmpeg", "pillow-heif", "psutil", "tifffile"] -all-plugins-pypy = ["av", "imageio-ffmpeg", "pillow-heif", "psutil", "tifffile"] +all-plugins = ["astropy", "av", "imageio-ffmpeg", "psutil", "tifffile"] +all-plugins-pypy = ["av", "imageio-ffmpeg", "psutil", "tifffile"] build = ["wheel"] dev = ["black", "flake8", "fsspec[github]", "pytest", "pytest-cov"] docs = ["numpydoc", "pydata-sphinx-theme", "sphinx (<6)"] ffmpeg = ["imageio-ffmpeg", "psutil"] fits = ["astropy"] -full = ["astropy", "av", "black", "flake8", "fsspec[github]", "gdal", "imageio-ffmpeg", "itk", "numpydoc", "pillow-heif", "psutil", "pydata-sphinx-theme", "pytest", "pytest-cov", "sphinx (<6)", "tifffile", "wheel"] +full = ["astropy", "av", "black", "flake8", "fsspec[github]", "gdal", "imageio-ffmpeg", "itk", "numpy (>2)", "numpydoc", "pillow-heif", "psutil", "pydata-sphinx-theme", "pytest", "pytest-cov", "rawpy", "sphinx (<6)", "tifffile", "wheel"] gdal = ["gdal"] itk = ["itk"] linting = ["black", "flake8"] pillow-heif = ["pillow-heif"] pyav = ["av"] +rawpy = ["numpy (>2)", "rawpy"] test = ["fsspec[github]", "pytest", "pytest-cov"] tifffile = ["tifffile"] @@ -1562,13 +1563,13 @@ test = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "p [[package]] name = "importlib-resources" -version = "6.4.2" +version = "6.4.3" description = "Read resources from Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "importlib_resources-6.4.2-py3-none-any.whl", hash = "sha256:8bba8c54a8a3afaa1419910845fa26ebd706dc716dd208d9b158b4b6966f5c5c"}, - {file = "importlib_resources-6.4.2.tar.gz", hash = "sha256:6cbfbefc449cc6e2095dd184691b7a12a04f40bc75dd4c55d31c34f174cdf57a"}, + {file = "importlib_resources-6.4.3-py3-none-any.whl", hash = "sha256:2d6dfe3b9e055f72495c2085890837fc8c758984e209115c8792bddcb762cd93"}, + {file = "importlib_resources-6.4.3.tar.gz", hash = "sha256:4a202b9b9d38563b46da59221d77bb73862ab5d79d461307bcb826d725448b98"}, ] [package.dependencies] @@ -1854,13 +1855,13 @@ files = [ [[package]] name = "litellm" -version = "1.43.1" +version = "1.43.18" description = "Library to easily interface with LLM API providers" optional = false python-versions = "!=2.7.*,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,!=3.7.*,>=3.8" files = [ - {file = "litellm-1.43.1-py3-none-any.whl", hash = "sha256:57a3ce38889782f014f371cd794a1cad4e7d9b97412d75ff8b051bc8fc4f4e4d"}, - {file = "litellm-1.43.1.tar.gz", hash = "sha256:f7132938b6e2120e40b01b2210087ca05c51f2f90cebf33495adb53e7f9aaaab"}, + {file = "litellm-1.43.18-py3-none-any.whl", hash = "sha256:68d853b4a0198a16e2260e4406a20f8d2e59bd903e019b7f3ba5a9f35ecc3e62"}, + {file = "litellm-1.43.18.tar.gz", hash = "sha256:e22b20065b62663dd060be9da1e84ca05903931c41c49d35a98649ed09e79d29"}, ] [package.dependencies] @@ -1869,7 +1870,7 @@ click = "*" importlib-metadata = ">=6.8.0" jinja2 = ">=3.1.2,<4.0.0" jsonschema = ">=4.22.0,<5.0.0" -openai = ">=1.27.0" +openai = ">=1.40.0" pydantic = ">=2.0.0,<3.0.0" python-dotenv = ">=0.2.0" requests = ">=2.31.0,<3.0.0" @@ -1912,153 +1913,149 @@ files = [ [[package]] name = "lxml" -version = "5.2.2" +version = "5.3.0" description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API." optional = false python-versions = ">=3.6" files = [ - {file = "lxml-5.2.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:364d03207f3e603922d0d3932ef363d55bbf48e3647395765f9bfcbdf6d23632"}, - {file = "lxml-5.2.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:50127c186f191b8917ea2fb8b206fbebe87fd414a6084d15568c27d0a21d60db"}, - {file = "lxml-5.2.2-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:74e4f025ef3db1c6da4460dd27c118d8cd136d0391da4e387a15e48e5c975147"}, - {file = "lxml-5.2.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:981a06a3076997adf7c743dcd0d7a0415582661e2517c7d961493572e909aa1d"}, - {file = "lxml-5.2.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aef5474d913d3b05e613906ba4090433c515e13ea49c837aca18bde190853dff"}, - {file = "lxml-5.2.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1e275ea572389e41e8b039ac076a46cb87ee6b8542df3fff26f5baab43713bca"}, - {file = "lxml-5.2.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5b65529bb2f21ac7861a0e94fdbf5dc0daab41497d18223b46ee8515e5ad297"}, - {file = "lxml-5.2.2-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:bcc98f911f10278d1daf14b87d65325851a1d29153caaf146877ec37031d5f36"}, - {file = "lxml-5.2.2-cp310-cp310-manylinux_2_28_ppc64le.whl", hash = "sha256:b47633251727c8fe279f34025844b3b3a3e40cd1b198356d003aa146258d13a2"}, - {file = "lxml-5.2.2-cp310-cp310-manylinux_2_28_s390x.whl", hash = "sha256:fbc9d316552f9ef7bba39f4edfad4a734d3d6f93341232a9dddadec4f15d425f"}, - {file = "lxml-5.2.2-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:13e69be35391ce72712184f69000cda04fc89689429179bc4c0ae5f0b7a8c21b"}, - {file = "lxml-5.2.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3b6a30a9ab040b3f545b697cb3adbf3696c05a3a68aad172e3fd7ca73ab3c835"}, - {file = "lxml-5.2.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:a233bb68625a85126ac9f1fc66d24337d6e8a0f9207b688eec2e7c880f012ec0"}, - {file = "lxml-5.2.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:dfa7c241073d8f2b8e8dbc7803c434f57dbb83ae2a3d7892dd068d99e96efe2c"}, - {file = "lxml-5.2.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1a7aca7964ac4bb07680d5c9d63b9d7028cace3e2d43175cb50bba8c5ad33316"}, - {file = "lxml-5.2.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ae4073a60ab98529ab8a72ebf429f2a8cc612619a8c04e08bed27450d52103c0"}, - {file = "lxml-5.2.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:ffb2be176fed4457e445fe540617f0252a72a8bc56208fd65a690fdb1f57660b"}, - {file = "lxml-5.2.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:e290d79a4107d7d794634ce3e985b9ae4f920380a813717adf61804904dc4393"}, - {file = "lxml-5.2.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:96e85aa09274955bb6bd483eaf5b12abadade01010478154b0ec70284c1b1526"}, - {file = "lxml-5.2.2-cp310-cp310-win32.whl", hash = "sha256:f956196ef61369f1685d14dad80611488d8dc1ef00be57c0c5a03064005b0f30"}, - {file = "lxml-5.2.2-cp310-cp310-win_amd64.whl", hash = "sha256:875a3f90d7eb5c5d77e529080d95140eacb3c6d13ad5b616ee8095447b1d22e7"}, - {file = "lxml-5.2.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:45f9494613160d0405682f9eee781c7e6d1bf45f819654eb249f8f46a2c22545"}, - {file = "lxml-5.2.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b0b3f2df149efb242cee2ffdeb6674b7f30d23c9a7af26595099afaf46ef4e88"}, - {file = "lxml-5.2.2-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d28cb356f119a437cc58a13f8135ab8a4c8ece18159eb9194b0d269ec4e28083"}, - {file = "lxml-5.2.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:657a972f46bbefdbba2d4f14413c0d079f9ae243bd68193cb5061b9732fa54c1"}, - {file = "lxml-5.2.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b74b9ea10063efb77a965a8d5f4182806fbf59ed068b3c3fd6f30d2ac7bee734"}, - {file = "lxml-5.2.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:07542787f86112d46d07d4f3c4e7c760282011b354d012dc4141cc12a68cef5f"}, - {file = "lxml-5.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:303f540ad2dddd35b92415b74b900c749ec2010e703ab3bfd6660979d01fd4ed"}, - {file = "lxml-5.2.2-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:2eb2227ce1ff998faf0cd7fe85bbf086aa41dfc5af3b1d80867ecfe75fb68df3"}, - {file = "lxml-5.2.2-cp311-cp311-manylinux_2_28_ppc64le.whl", hash = "sha256:1d8a701774dfc42a2f0b8ccdfe7dbc140500d1049e0632a611985d943fcf12df"}, - {file = "lxml-5.2.2-cp311-cp311-manylinux_2_28_s390x.whl", hash = "sha256:56793b7a1a091a7c286b5f4aa1fe4ae5d1446fe742d00cdf2ffb1077865db10d"}, - {file = "lxml-5.2.2-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:eb00b549b13bd6d884c863554566095bf6fa9c3cecb2e7b399c4bc7904cb33b5"}, - {file = "lxml-5.2.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1a2569a1f15ae6c8c64108a2cd2b4a858fc1e13d25846be0666fc144715e32ab"}, - {file = "lxml-5.2.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:8cf85a6e40ff1f37fe0f25719aadf443686b1ac7652593dc53c7ef9b8492b115"}, - {file = "lxml-5.2.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:d237ba6664b8e60fd90b8549a149a74fcc675272e0e95539a00522e4ca688b04"}, - {file = "lxml-5.2.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0b3f5016e00ae7630a4b83d0868fca1e3d494c78a75b1c7252606a3a1c5fc2ad"}, - {file = "lxml-5.2.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:23441e2b5339bc54dc949e9e675fa35efe858108404ef9aa92f0456929ef6fe8"}, - {file = "lxml-5.2.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:2fb0ba3e8566548d6c8e7dd82a8229ff47bd8fb8c2da237607ac8e5a1b8312e5"}, - {file = "lxml-5.2.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:79d1fb9252e7e2cfe4de6e9a6610c7cbb99b9708e2c3e29057f487de5a9eaefa"}, - {file = "lxml-5.2.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6dcc3d17eac1df7859ae01202e9bb11ffa8c98949dcbeb1069c8b9a75917e01b"}, - {file = "lxml-5.2.2-cp311-cp311-win32.whl", hash = "sha256:4c30a2f83677876465f44c018830f608fa3c6a8a466eb223535035fbc16f3438"}, - {file = "lxml-5.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:49095a38eb333aaf44c06052fd2ec3b8f23e19747ca7ec6f6c954ffea6dbf7be"}, - {file = "lxml-5.2.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:7429e7faa1a60cad26ae4227f4dd0459efde239e494c7312624ce228e04f6391"}, - {file = "lxml-5.2.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:50ccb5d355961c0f12f6cf24b7187dbabd5433f29e15147a67995474f27d1776"}, - {file = "lxml-5.2.2-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dc911208b18842a3a57266d8e51fc3cfaccee90a5351b92079beed912a7914c2"}, - {file = "lxml-5.2.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:33ce9e786753743159799fdf8e92a5da351158c4bfb6f2db0bf31e7892a1feb5"}, - {file = "lxml-5.2.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ec87c44f619380878bd49ca109669c9f221d9ae6883a5bcb3616785fa8f94c97"}, - {file = "lxml-5.2.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08ea0f606808354eb8f2dfaac095963cb25d9d28e27edcc375d7b30ab01abbf6"}, - {file = "lxml-5.2.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75a9632f1d4f698b2e6e2e1ada40e71f369b15d69baddb8968dcc8e683839b18"}, - {file = "lxml-5.2.2-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:74da9f97daec6928567b48c90ea2c82a106b2d500f397eeb8941e47d30b1ca85"}, - {file = "lxml-5.2.2-cp312-cp312-manylinux_2_28_ppc64le.whl", hash = "sha256:0969e92af09c5687d769731e3f39ed62427cc72176cebb54b7a9d52cc4fa3b73"}, - {file = "lxml-5.2.2-cp312-cp312-manylinux_2_28_s390x.whl", hash = "sha256:9164361769b6ca7769079f4d426a41df6164879f7f3568be9086e15baca61466"}, - {file = "lxml-5.2.2-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:d26a618ae1766279f2660aca0081b2220aca6bd1aa06b2cf73f07383faf48927"}, - {file = "lxml-5.2.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab67ed772c584b7ef2379797bf14b82df9aa5f7438c5b9a09624dd834c1c1aaf"}, - {file = "lxml-5.2.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:3d1e35572a56941b32c239774d7e9ad724074d37f90c7a7d499ab98761bd80cf"}, - {file = "lxml-5.2.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:8268cbcd48c5375f46e000adb1390572c98879eb4f77910c6053d25cc3ac2c67"}, - {file = "lxml-5.2.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e282aedd63c639c07c3857097fc0e236f984ceb4089a8b284da1c526491e3f3d"}, - {file = "lxml-5.2.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6dfdc2bfe69e9adf0df4915949c22a25b39d175d599bf98e7ddf620a13678585"}, - {file = "lxml-5.2.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4aefd911793b5d2d7a921233a54c90329bf3d4a6817dc465f12ffdfe4fc7b8fe"}, - {file = "lxml-5.2.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:8b8df03a9e995b6211dafa63b32f9d405881518ff1ddd775db4e7b98fb545e1c"}, - {file = "lxml-5.2.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f11ae142f3a322d44513de1018b50f474f8f736bc3cd91d969f464b5bfef8836"}, - {file = "lxml-5.2.2-cp312-cp312-win32.whl", hash = "sha256:16a8326e51fcdffc886294c1e70b11ddccec836516a343f9ed0f82aac043c24a"}, - {file = "lxml-5.2.2-cp312-cp312-win_amd64.whl", hash = "sha256:bbc4b80af581e18568ff07f6395c02114d05f4865c2812a1f02f2eaecf0bfd48"}, - {file = "lxml-5.2.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e3d9d13603410b72787579769469af730c38f2f25505573a5888a94b62b920f8"}, - {file = "lxml-5.2.2-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:38b67afb0a06b8575948641c1d6d68e41b83a3abeae2ca9eed2ac59892b36706"}, - {file = "lxml-5.2.2-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c689d0d5381f56de7bd6966a4541bff6e08bf8d3871bbd89a0c6ab18aa699573"}, - {file = "lxml-5.2.2-cp36-cp36m-manylinux_2_28_x86_64.whl", hash = "sha256:cf2a978c795b54c539f47964ec05e35c05bd045db5ca1e8366988c7f2fe6b3ce"}, - {file = "lxml-5.2.2-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:739e36ef7412b2bd940f75b278749106e6d025e40027c0b94a17ef7968d55d56"}, - {file = "lxml-5.2.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:d8bbcd21769594dbba9c37d3c819e2d5847656ca99c747ddb31ac1701d0c0ed9"}, - {file = "lxml-5.2.2-cp36-cp36m-musllinux_1_2_x86_64.whl", hash = "sha256:2304d3c93f2258ccf2cf7a6ba8c761d76ef84948d87bf9664e14d203da2cd264"}, - {file = "lxml-5.2.2-cp36-cp36m-win32.whl", hash = "sha256:02437fb7308386867c8b7b0e5bc4cd4b04548b1c5d089ffb8e7b31009b961dc3"}, - {file = "lxml-5.2.2-cp36-cp36m-win_amd64.whl", hash = "sha256:edcfa83e03370032a489430215c1e7783128808fd3e2e0a3225deee278585196"}, - {file = "lxml-5.2.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:28bf95177400066596cdbcfc933312493799382879da504633d16cf60bba735b"}, - {file = "lxml-5.2.2-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3a745cc98d504d5bd2c19b10c79c61c7c3df9222629f1b6210c0368177589fb8"}, - {file = "lxml-5.2.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b590b39ef90c6b22ec0be925b211298e810b4856909c8ca60d27ffbca6c12e6"}, - {file = "lxml-5.2.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b336b0416828022bfd5a2e3083e7f5ba54b96242159f83c7e3eebaec752f1716"}, - {file = "lxml-5.2.2-cp37-cp37m-manylinux_2_28_aarch64.whl", hash = "sha256:c2faf60c583af0d135e853c86ac2735ce178f0e338a3c7f9ae8f622fd2eb788c"}, - {file = "lxml-5.2.2-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:4bc6cb140a7a0ad1f7bc37e018d0ed690b7b6520ade518285dc3171f7a117905"}, - {file = "lxml-5.2.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7ff762670cada8e05b32bf1e4dc50b140790909caa8303cfddc4d702b71ea184"}, - {file = "lxml-5.2.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:57f0a0bbc9868e10ebe874e9f129d2917750adf008fe7b9c1598c0fbbfdde6a6"}, - {file = "lxml-5.2.2-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:a6d2092797b388342c1bc932077ad232f914351932353e2e8706851c870bca1f"}, - {file = "lxml-5.2.2-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:60499fe961b21264e17a471ec296dcbf4365fbea611bf9e303ab69db7159ce61"}, - {file = "lxml-5.2.2-cp37-cp37m-win32.whl", hash = "sha256:d9b342c76003c6b9336a80efcc766748a333573abf9350f4094ee46b006ec18f"}, - {file = "lxml-5.2.2-cp37-cp37m-win_amd64.whl", hash = "sha256:b16db2770517b8799c79aa80f4053cd6f8b716f21f8aca962725a9565ce3ee40"}, - {file = "lxml-5.2.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7ed07b3062b055d7a7f9d6557a251cc655eed0b3152b76de619516621c56f5d3"}, - {file = "lxml-5.2.2-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f60fdd125d85bf9c279ffb8e94c78c51b3b6a37711464e1f5f31078b45002421"}, - {file = "lxml-5.2.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a7e24cb69ee5f32e003f50e016d5fde438010c1022c96738b04fc2423e61706"}, - {file = "lxml-5.2.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23cfafd56887eaed93d07bc4547abd5e09d837a002b791e9767765492a75883f"}, - {file = "lxml-5.2.2-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:19b4e485cd07b7d83e3fe3b72132e7df70bfac22b14fe4bf7a23822c3a35bff5"}, - {file = "lxml-5.2.2-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:7ce7ad8abebe737ad6143d9d3bf94b88b93365ea30a5b81f6877ec9c0dee0a48"}, - {file = "lxml-5.2.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:e49b052b768bb74f58c7dda4e0bdf7b79d43a9204ca584ffe1fb48a6f3c84c66"}, - {file = "lxml-5.2.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d14a0d029a4e176795cef99c056d58067c06195e0c7e2dbb293bf95c08f772a3"}, - {file = "lxml-5.2.2-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:be49ad33819d7dcc28a309b86d4ed98e1a65f3075c6acd3cd4fe32103235222b"}, - {file = "lxml-5.2.2-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:a6d17e0370d2516d5bb9062c7b4cb731cff921fc875644c3d751ad857ba9c5b1"}, - {file = "lxml-5.2.2-cp38-cp38-win32.whl", hash = "sha256:5b8c041b6265e08eac8a724b74b655404070b636a8dd6d7a13c3adc07882ef30"}, - {file = "lxml-5.2.2-cp38-cp38-win_amd64.whl", hash = "sha256:f61efaf4bed1cc0860e567d2ecb2363974d414f7f1f124b1df368bbf183453a6"}, - {file = "lxml-5.2.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:fb91819461b1b56d06fa4bcf86617fac795f6a99d12239fb0c68dbeba41a0a30"}, - {file = "lxml-5.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d4ed0c7cbecde7194cd3228c044e86bf73e30a23505af852857c09c24e77ec5d"}, - {file = "lxml-5.2.2-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54401c77a63cc7d6dc4b4e173bb484f28a5607f3df71484709fe037c92d4f0ed"}, - {file = "lxml-5.2.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:625e3ef310e7fa3a761d48ca7ea1f9d8718a32b1542e727d584d82f4453d5eeb"}, - {file = "lxml-5.2.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:519895c99c815a1a24a926d5b60627ce5ea48e9f639a5cd328bda0515ea0f10c"}, - {file = "lxml-5.2.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c7079d5eb1c1315a858bbf180000757db8ad904a89476653232db835c3114001"}, - {file = "lxml-5.2.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:343ab62e9ca78094f2306aefed67dcfad61c4683f87eee48ff2fd74902447726"}, - {file = "lxml-5.2.2-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:cd9e78285da6c9ba2d5c769628f43ef66d96ac3085e59b10ad4f3707980710d3"}, - {file = "lxml-5.2.2-cp39-cp39-manylinux_2_28_ppc64le.whl", hash = "sha256:546cf886f6242dff9ec206331209db9c8e1643ae642dea5fdbecae2453cb50fd"}, - {file = "lxml-5.2.2-cp39-cp39-manylinux_2_28_s390x.whl", hash = "sha256:02f6a8eb6512fdc2fd4ca10a49c341c4e109aa6e9448cc4859af5b949622715a"}, - {file = "lxml-5.2.2-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:339ee4a4704bc724757cd5dd9dc8cf4d00980f5d3e6e06d5847c1b594ace68ab"}, - {file = "lxml-5.2.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0a028b61a2e357ace98b1615fc03f76eb517cc028993964fe08ad514b1e8892d"}, - {file = "lxml-5.2.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:f90e552ecbad426eab352e7b2933091f2be77115bb16f09f78404861c8322981"}, - {file = "lxml-5.2.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:d83e2d94b69bf31ead2fa45f0acdef0757fa0458a129734f59f67f3d2eb7ef32"}, - {file = "lxml-5.2.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a02d3c48f9bb1e10c7788d92c0c7db6f2002d024ab6e74d6f45ae33e3d0288a3"}, - {file = "lxml-5.2.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:6d68ce8e7b2075390e8ac1e1d3a99e8b6372c694bbe612632606d1d546794207"}, - {file = "lxml-5.2.2-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:453d037e09a5176d92ec0fd282e934ed26d806331a8b70ab431a81e2fbabf56d"}, - {file = "lxml-5.2.2-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:3b019d4ee84b683342af793b56bb35034bd749e4cbdd3d33f7d1107790f8c472"}, - {file = "lxml-5.2.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:cb3942960f0beb9f46e2a71a3aca220d1ca32feb5a398656be934320804c0df9"}, - {file = "lxml-5.2.2-cp39-cp39-win32.whl", hash = "sha256:ac6540c9fff6e3813d29d0403ee7a81897f1d8ecc09a8ff84d2eea70ede1cdbf"}, - {file = "lxml-5.2.2-cp39-cp39-win_amd64.whl", hash = "sha256:610b5c77428a50269f38a534057444c249976433f40f53e3b47e68349cca1425"}, - {file = "lxml-5.2.2-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:b537bd04d7ccd7c6350cdaaaad911f6312cbd61e6e6045542f781c7f8b2e99d2"}, - {file = "lxml-5.2.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4820c02195d6dfb7b8508ff276752f6b2ff8b64ae5d13ebe02e7667e035000b9"}, - {file = "lxml-5.2.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a09f6184f17a80897172863a655467da2b11151ec98ba8d7af89f17bf63dae"}, - {file = "lxml-5.2.2-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:76acba4c66c47d27c8365e7c10b3d8016a7da83d3191d053a58382311a8bf4e1"}, - {file = "lxml-5.2.2-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:b128092c927eaf485928cec0c28f6b8bead277e28acf56800e972aa2c2abd7a2"}, - {file = "lxml-5.2.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:ae791f6bd43305aade8c0e22f816b34f3b72b6c820477aab4d18473a37e8090b"}, - {file = "lxml-5.2.2-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a2f6a1bc2460e643785a2cde17293bd7a8f990884b822f7bca47bee0a82fc66b"}, - {file = "lxml-5.2.2-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e8d351ff44c1638cb6e980623d517abd9f580d2e53bfcd18d8941c052a5a009"}, - {file = "lxml-5.2.2-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bec4bd9133420c5c52d562469c754f27c5c9e36ee06abc169612c959bd7dbb07"}, - {file = "lxml-5.2.2-pp37-pypy37_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:55ce6b6d803890bd3cc89975fca9de1dff39729b43b73cb15ddd933b8bc20484"}, - {file = "lxml-5.2.2-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:8ab6a358d1286498d80fe67bd3d69fcbc7d1359b45b41e74c4a26964ca99c3f8"}, - {file = "lxml-5.2.2-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:06668e39e1f3c065349c51ac27ae430719d7806c026fec462e5693b08b95696b"}, - {file = "lxml-5.2.2-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9cd5323344d8ebb9fb5e96da5de5ad4ebab993bbf51674259dbe9d7a18049525"}, - {file = "lxml-5.2.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89feb82ca055af0fe797a2323ec9043b26bc371365847dbe83c7fd2e2f181c34"}, - {file = "lxml-5.2.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e481bba1e11ba585fb06db666bfc23dbe181dbafc7b25776156120bf12e0d5a6"}, - {file = "lxml-5.2.2-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:9d6c6ea6a11ca0ff9cd0390b885984ed31157c168565702959c25e2191674a14"}, - {file = "lxml-5.2.2-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:3d98de734abee23e61f6b8c2e08a88453ada7d6486dc7cdc82922a03968928db"}, - {file = "lxml-5.2.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:69ab77a1373f1e7563e0fb5a29a8440367dec051da6c7405333699d07444f511"}, - {file = "lxml-5.2.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:34e17913c431f5ae01d8658dbf792fdc457073dcdfbb31dc0cc6ab256e664a8d"}, - {file = "lxml-5.2.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:05f8757b03208c3f50097761be2dea0aba02e94f0dc7023ed73a7bb14ff11eb0"}, - {file = "lxml-5.2.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6a520b4f9974b0a0a6ed73c2154de57cdfd0c8800f4f15ab2b73238ffed0b36e"}, - {file = "lxml-5.2.2-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:5e097646944b66207023bc3c634827de858aebc226d5d4d6d16f0b77566ea182"}, - {file = "lxml-5.2.2-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:b5e4ef22ff25bfd4ede5f8fb30f7b24446345f3e79d9b7455aef2836437bc38a"}, - {file = "lxml-5.2.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:ff69a9a0b4b17d78170c73abe2ab12084bdf1691550c5629ad1fe7849433f324"}, - {file = "lxml-5.2.2.tar.gz", hash = "sha256:bb2dc4898180bea79863d5487e5f9c7c34297414bad54bcd0f0852aee9cfdb87"}, + {file = "lxml-5.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:dd36439be765e2dde7660212b5275641edbc813e7b24668831a5c8ac91180656"}, + {file = "lxml-5.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ae5fe5c4b525aa82b8076c1a59d642c17b6e8739ecf852522c6321852178119d"}, + {file = "lxml-5.3.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:501d0d7e26b4d261fca8132854d845e4988097611ba2531408ec91cf3fd9d20a"}, + {file = "lxml-5.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb66442c2546446944437df74379e9cf9e9db353e61301d1a0e26482f43f0dd8"}, + {file = "lxml-5.3.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9e41506fec7a7f9405b14aa2d5c8abbb4dbbd09d88f9496958b6d00cb4d45330"}, + {file = "lxml-5.3.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f7d4a670107d75dfe5ad080bed6c341d18c4442f9378c9f58e5851e86eb79965"}, + {file = "lxml-5.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41ce1f1e2c7755abfc7e759dc34d7d05fd221723ff822947132dc934d122fe22"}, + {file = "lxml-5.3.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:44264ecae91b30e5633013fb66f6ddd05c006d3e0e884f75ce0b4755b3e3847b"}, + {file = "lxml-5.3.0-cp310-cp310-manylinux_2_28_ppc64le.whl", hash = "sha256:3c174dc350d3ec52deb77f2faf05c439331d6ed5e702fc247ccb4e6b62d884b7"}, + {file = "lxml-5.3.0-cp310-cp310-manylinux_2_28_s390x.whl", hash = "sha256:2dfab5fa6a28a0b60a20638dc48e6343c02ea9933e3279ccb132f555a62323d8"}, + {file = "lxml-5.3.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:b1c8c20847b9f34e98080da785bb2336ea982e7f913eed5809e5a3c872900f32"}, + {file = "lxml-5.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:2c86bf781b12ba417f64f3422cfc302523ac9cd1d8ae8c0f92a1c66e56ef2e86"}, + {file = "lxml-5.3.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:c162b216070f280fa7da844531169be0baf9ccb17263cf5a8bf876fcd3117fa5"}, + {file = "lxml-5.3.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:36aef61a1678cb778097b4a6eeae96a69875d51d1e8f4d4b491ab3cfb54b5a03"}, + {file = "lxml-5.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f65e5120863c2b266dbcc927b306c5b78e502c71edf3295dfcb9501ec96e5fc7"}, + {file = "lxml-5.3.0-cp310-cp310-win32.whl", hash = "sha256:ef0c1fe22171dd7c7c27147f2e9c3e86f8bdf473fed75f16b0c2e84a5030ce80"}, + {file = "lxml-5.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:052d99051e77a4f3e8482c65014cf6372e61b0a6f4fe9edb98503bb5364cfee3"}, + {file = "lxml-5.3.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:74bcb423462233bc5d6066e4e98b0264e7c1bed7541fff2f4e34fe6b21563c8b"}, + {file = "lxml-5.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a3d819eb6f9b8677f57f9664265d0a10dd6551d227afb4af2b9cd7bdc2ccbf18"}, + {file = "lxml-5.3.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b8f5db71b28b8c404956ddf79575ea77aa8b1538e8b2ef9ec877945b3f46442"}, + {file = "lxml-5.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c3406b63232fc7e9b8783ab0b765d7c59e7c59ff96759d8ef9632fca27c7ee4"}, + {file = "lxml-5.3.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2ecdd78ab768f844c7a1d4a03595038c166b609f6395e25af9b0f3f26ae1230f"}, + {file = "lxml-5.3.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:168f2dfcfdedf611eb285efac1516c8454c8c99caf271dccda8943576b67552e"}, + {file = "lxml-5.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa617107a410245b8660028a7483b68e7914304a6d4882b5ff3d2d3eb5948d8c"}, + {file = "lxml-5.3.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:69959bd3167b993e6e710b99051265654133a98f20cec1d9b493b931942e9c16"}, + {file = "lxml-5.3.0-cp311-cp311-manylinux_2_28_ppc64le.whl", hash = "sha256:bd96517ef76c8654446fc3db9242d019a1bb5fe8b751ba414765d59f99210b79"}, + {file = "lxml-5.3.0-cp311-cp311-manylinux_2_28_s390x.whl", hash = "sha256:ab6dd83b970dc97c2d10bc71aa925b84788c7c05de30241b9e96f9b6d9ea3080"}, + {file = "lxml-5.3.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:eec1bb8cdbba2925bedc887bc0609a80e599c75b12d87ae42ac23fd199445654"}, + {file = "lxml-5.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a7095eeec6f89111d03dabfe5883a1fd54da319c94e0fb104ee8f23616b572d"}, + {file = "lxml-5.3.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:6f651ebd0b21ec65dfca93aa629610a0dbc13dbc13554f19b0113da2e61a4763"}, + {file = "lxml-5.3.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:f422a209d2455c56849442ae42f25dbaaba1c6c3f501d58761c619c7836642ec"}, + {file = "lxml-5.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:62f7fdb0d1ed2065451f086519865b4c90aa19aed51081979ecd05a21eb4d1be"}, + {file = "lxml-5.3.0-cp311-cp311-win32.whl", hash = "sha256:c6379f35350b655fd817cd0d6cbeef7f265f3ae5fedb1caae2eb442bbeae9ab9"}, + {file = "lxml-5.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:9c52100e2c2dbb0649b90467935c4b0de5528833c76a35ea1a2691ec9f1ee7a1"}, + {file = "lxml-5.3.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:e99f5507401436fdcc85036a2e7dc2e28d962550afe1cbfc07c40e454256a859"}, + {file = "lxml-5.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:384aacddf2e5813a36495233b64cb96b1949da72bef933918ba5c84e06af8f0e"}, + {file = "lxml-5.3.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:874a216bf6afaf97c263b56371434e47e2c652d215788396f60477540298218f"}, + {file = "lxml-5.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:65ab5685d56914b9a2a34d67dd5488b83213d680b0c5d10b47f81da5a16b0b0e"}, + {file = "lxml-5.3.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aac0bbd3e8dd2d9c45ceb82249e8bdd3ac99131a32b4d35c8af3cc9db1657179"}, + {file = "lxml-5.3.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b369d3db3c22ed14c75ccd5af429086f166a19627e84a8fdade3f8f31426e52a"}, + {file = "lxml-5.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c24037349665434f375645fa9d1f5304800cec574d0310f618490c871fd902b3"}, + {file = "lxml-5.3.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:62d172f358f33a26d6b41b28c170c63886742f5b6772a42b59b4f0fa10526cb1"}, + {file = "lxml-5.3.0-cp312-cp312-manylinux_2_28_ppc64le.whl", hash = "sha256:c1f794c02903c2824fccce5b20c339a1a14b114e83b306ff11b597c5f71a1c8d"}, + {file = "lxml-5.3.0-cp312-cp312-manylinux_2_28_s390x.whl", hash = "sha256:5d6a6972b93c426ace71e0be9a6f4b2cfae9b1baed2eed2006076a746692288c"}, + {file = "lxml-5.3.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:3879cc6ce938ff4eb4900d901ed63555c778731a96365e53fadb36437a131a99"}, + {file = "lxml-5.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:74068c601baff6ff021c70f0935b0c7bc528baa8ea210c202e03757c68c5a4ff"}, + {file = "lxml-5.3.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:ecd4ad8453ac17bc7ba3868371bffb46f628161ad0eefbd0a855d2c8c32dd81a"}, + {file = "lxml-5.3.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:7e2f58095acc211eb9d8b5771bf04df9ff37d6b87618d1cbf85f92399c98dae8"}, + {file = "lxml-5.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e63601ad5cd8f860aa99d109889b5ac34de571c7ee902d6812d5d9ddcc77fa7d"}, + {file = "lxml-5.3.0-cp312-cp312-win32.whl", hash = "sha256:17e8d968d04a37c50ad9c456a286b525d78c4a1c15dd53aa46c1d8e06bf6fa30"}, + {file = "lxml-5.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:c1a69e58a6bb2de65902051d57fde951febad631a20a64572677a1052690482f"}, + {file = "lxml-5.3.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8c72e9563347c7395910de6a3100a4840a75a6f60e05af5e58566868d5eb2d6a"}, + {file = "lxml-5.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e92ce66cd919d18d14b3856906a61d3f6b6a8500e0794142338da644260595cd"}, + {file = "lxml-5.3.0-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d04f064bebdfef9240478f7a779e8c5dc32b8b7b0b2fc6a62e39b928d428e51"}, + {file = "lxml-5.3.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c2fb570d7823c2bbaf8b419ba6e5662137f8166e364a8b2b91051a1fb40ab8b"}, + {file = "lxml-5.3.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0c120f43553ec759f8de1fee2f4794452b0946773299d44c36bfe18e83caf002"}, + {file = "lxml-5.3.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:562e7494778a69086f0312ec9689f6b6ac1c6b65670ed7d0267e49f57ffa08c4"}, + {file = "lxml-5.3.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:423b121f7e6fa514ba0c7918e56955a1d4470ed35faa03e3d9f0e3baa4c7e492"}, + {file = "lxml-5.3.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:c00f323cc00576df6165cc9d21a4c21285fa6b9989c5c39830c3903dc4303ef3"}, + {file = "lxml-5.3.0-cp313-cp313-manylinux_2_28_ppc64le.whl", hash = "sha256:1fdc9fae8dd4c763e8a31e7630afef517eab9f5d5d31a278df087f307bf601f4"}, + {file = "lxml-5.3.0-cp313-cp313-manylinux_2_28_s390x.whl", hash = "sha256:658f2aa69d31e09699705949b5fc4719cbecbd4a97f9656a232e7d6c7be1a367"}, + {file = "lxml-5.3.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:1473427aff3d66a3fa2199004c3e601e6c4500ab86696edffdbc84954c72d832"}, + {file = "lxml-5.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a87de7dd873bf9a792bf1e58b1c3887b9264036629a5bf2d2e6579fe8e73edff"}, + {file = "lxml-5.3.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:0d7b36afa46c97875303a94e8f3ad932bf78bace9e18e603f2085b652422edcd"}, + {file = "lxml-5.3.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:cf120cce539453ae086eacc0130a324e7026113510efa83ab42ef3fcfccac7fb"}, + {file = "lxml-5.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:df5c7333167b9674aa8ae1d4008fa4bc17a313cc490b2cca27838bbdcc6bb15b"}, + {file = "lxml-5.3.0-cp313-cp313-win32.whl", hash = "sha256:c802e1c2ed9f0c06a65bc4ed0189d000ada8049312cfeab6ca635e39c9608957"}, + {file = "lxml-5.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:406246b96d552e0503e17a1006fd27edac678b3fcc9f1be71a2f94b4ff61528d"}, + {file = "lxml-5.3.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:8f0de2d390af441fe8b2c12626d103540b5d850d585b18fcada58d972b74a74e"}, + {file = "lxml-5.3.0-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1afe0a8c353746e610bd9031a630a95bcfb1a720684c3f2b36c4710a0a96528f"}, + {file = "lxml-5.3.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56b9861a71575f5795bde89256e7467ece3d339c9b43141dbdd54544566b3b94"}, + {file = "lxml-5.3.0-cp36-cp36m-manylinux_2_28_x86_64.whl", hash = "sha256:9fb81d2824dff4f2e297a276297e9031f46d2682cafc484f49de182aa5e5df99"}, + {file = "lxml-5.3.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:2c226a06ecb8cdef28845ae976da407917542c5e6e75dcac7cc33eb04aaeb237"}, + {file = "lxml-5.3.0-cp36-cp36m-musllinux_1_2_x86_64.whl", hash = "sha256:7d3d1ca42870cdb6d0d29939630dbe48fa511c203724820fc0fd507b2fb46577"}, + {file = "lxml-5.3.0-cp36-cp36m-win32.whl", hash = "sha256:094cb601ba9f55296774c2d57ad68730daa0b13dc260e1f941b4d13678239e70"}, + {file = "lxml-5.3.0-cp36-cp36m-win_amd64.whl", hash = "sha256:eafa2c8658f4e560b098fe9fc54539f86528651f61849b22111a9b107d18910c"}, + {file = "lxml-5.3.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:cb83f8a875b3d9b458cada4f880fa498646874ba4011dc974e071a0a84a1b033"}, + {file = "lxml-5.3.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:25f1b69d41656b05885aa185f5fdf822cb01a586d1b32739633679699f220391"}, + {file = "lxml-5.3.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23e0553b8055600b3bf4a00b255ec5c92e1e4aebf8c2c09334f8368e8bd174d6"}, + {file = "lxml-5.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ada35dd21dc6c039259596b358caab6b13f4db4d4a7f8665764d616daf9cc1d"}, + {file = "lxml-5.3.0-cp37-cp37m-manylinux_2_28_aarch64.whl", hash = "sha256:81b4e48da4c69313192d8c8d4311e5d818b8be1afe68ee20f6385d0e96fc9512"}, + {file = "lxml-5.3.0-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:2bc9fd5ca4729af796f9f59cd8ff160fe06a474da40aca03fcc79655ddee1a8b"}, + {file = "lxml-5.3.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:07da23d7ee08577760f0a71d67a861019103e4812c87e2fab26b039054594cc5"}, + {file = "lxml-5.3.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:ea2e2f6f801696ad7de8aec061044d6c8c0dd4037608c7cab38a9a4d316bfb11"}, + {file = "lxml-5.3.0-cp37-cp37m-win32.whl", hash = "sha256:5c54afdcbb0182d06836cc3d1be921e540be3ebdf8b8a51ee3ef987537455f84"}, + {file = "lxml-5.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:f2901429da1e645ce548bf9171784c0f74f0718c3f6150ce166be39e4dd66c3e"}, + {file = "lxml-5.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c56a1d43b2f9ee4786e4658c7903f05da35b923fb53c11025712562d5cc02753"}, + {file = "lxml-5.3.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ee8c39582d2652dcd516d1b879451500f8db3fe3607ce45d7c5957ab2596040"}, + {file = "lxml-5.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fdf3a3059611f7585a78ee10399a15566356116a4288380921a4b598d807a22"}, + {file = "lxml-5.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:146173654d79eb1fc97498b4280c1d3e1e5d58c398fa530905c9ea50ea849b22"}, + {file = "lxml-5.3.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:0a7056921edbdd7560746f4221dca89bb7a3fe457d3d74267995253f46343f15"}, + {file = "lxml-5.3.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:9e4b47ac0f5e749cfc618efdf4726269441014ae1d5583e047b452a32e221920"}, + {file = "lxml-5.3.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:f914c03e6a31deb632e2daa881fe198461f4d06e57ac3d0e05bbcab8eae01945"}, + {file = "lxml-5.3.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:213261f168c5e1d9b7535a67e68b1f59f92398dd17a56d934550837143f79c42"}, + {file = "lxml-5.3.0-cp38-cp38-win32.whl", hash = "sha256:218c1b2e17a710e363855594230f44060e2025b05c80d1f0661258142b2add2e"}, + {file = "lxml-5.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:315f9542011b2c4e1d280e4a20ddcca1761993dda3afc7a73b01235f8641e903"}, + {file = "lxml-5.3.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:1ffc23010330c2ab67fac02781df60998ca8fe759e8efde6f8b756a20599c5de"}, + {file = "lxml-5.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2b3778cb38212f52fac9fe913017deea2fdf4eb1a4f8e4cfc6b009a13a6d3fcc"}, + {file = "lxml-5.3.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b0c7a688944891086ba192e21c5229dea54382f4836a209ff8d0a660fac06be"}, + {file = "lxml-5.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:747a3d3e98e24597981ca0be0fd922aebd471fa99d0043a3842d00cdcad7ad6a"}, + {file = "lxml-5.3.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86a6b24b19eaebc448dc56b87c4865527855145d851f9fc3891673ff97950540"}, + {file = "lxml-5.3.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b11a5d918a6216e521c715b02749240fb07ae5a1fefd4b7bf12f833bc8b4fe70"}, + {file = "lxml-5.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:68b87753c784d6acb8a25b05cb526c3406913c9d988d51f80adecc2b0775d6aa"}, + {file = "lxml-5.3.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:109fa6fede314cc50eed29e6e56c540075e63d922455346f11e4d7a036d2b8cf"}, + {file = "lxml-5.3.0-cp39-cp39-manylinux_2_28_ppc64le.whl", hash = "sha256:02ced472497b8362c8e902ade23e3300479f4f43e45f4105c85ef43b8db85229"}, + {file = "lxml-5.3.0-cp39-cp39-manylinux_2_28_s390x.whl", hash = "sha256:6b038cc86b285e4f9fea2ba5ee76e89f21ed1ea898e287dc277a25884f3a7dfe"}, + {file = "lxml-5.3.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:7437237c6a66b7ca341e868cda48be24b8701862757426852c9b3186de1da8a2"}, + {file = "lxml-5.3.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:7f41026c1d64043a36fda21d64c5026762d53a77043e73e94b71f0521939cc71"}, + {file = "lxml-5.3.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:482c2f67761868f0108b1743098640fbb2a28a8e15bf3f47ada9fa59d9fe08c3"}, + {file = "lxml-5.3.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:1483fd3358963cc5c1c9b122c80606a3a79ee0875bcac0204149fa09d6ff2727"}, + {file = "lxml-5.3.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dec2d1130a9cda5b904696cec33b2cfb451304ba9081eeda7f90f724097300a"}, + {file = "lxml-5.3.0-cp39-cp39-win32.whl", hash = "sha256:a0eabd0a81625049c5df745209dc7fcef6e2aea7793e5f003ba363610aa0a3ff"}, + {file = "lxml-5.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:89e043f1d9d341c52bf2af6d02e6adde62e0a46e6755d5eb60dc6e4f0b8aeca2"}, + {file = "lxml-5.3.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7b1cd427cb0d5f7393c31b7496419da594fe600e6fdc4b105a54f82405e6626c"}, + {file = "lxml-5.3.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:51806cfe0279e06ed8500ce19479d757db42a30fd509940b1701be9c86a5ff9a"}, + {file = "lxml-5.3.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee70d08fd60c9565ba8190f41a46a54096afa0eeb8f76bd66f2c25d3b1b83005"}, + {file = "lxml-5.3.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:8dc2c0395bea8254d8daebc76dcf8eb3a95ec2a46fa6fae5eaccee366bfe02ce"}, + {file = "lxml-5.3.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:6ba0d3dcac281aad8a0e5b14c7ed6f9fa89c8612b47939fc94f80b16e2e9bc83"}, + {file = "lxml-5.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:6e91cf736959057f7aac7adfc83481e03615a8e8dd5758aa1d95ea69e8931dba"}, + {file = "lxml-5.3.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:94d6c3782907b5e40e21cadf94b13b0842ac421192f26b84c45f13f3c9d5dc27"}, + {file = "lxml-5.3.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c300306673aa0f3ed5ed9372b21867690a17dba38c68c44b287437c362ce486b"}, + {file = "lxml-5.3.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78d9b952e07aed35fe2e1a7ad26e929595412db48535921c5013edc8aa4a35ce"}, + {file = "lxml-5.3.0-pp37-pypy37_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:01220dca0d066d1349bd6a1726856a78f7929f3878f7e2ee83c296c69495309e"}, + {file = "lxml-5.3.0-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:2d9b8d9177afaef80c53c0a9e30fa252ff3036fb1c6494d427c066a4ce6a282f"}, + {file = "lxml-5.3.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:20094fc3f21ea0a8669dc4c61ed7fa8263bd37d97d93b90f28fc613371e7a875"}, + {file = "lxml-5.3.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ace2c2326a319a0bb8a8b0e5b570c764962e95818de9f259ce814ee666603f19"}, + {file = "lxml-5.3.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:92e67a0be1639c251d21e35fe74df6bcc40cba445c2cda7c4a967656733249e2"}, + {file = "lxml-5.3.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd5350b55f9fecddc51385463a4f67a5da829bc741e38cf689f38ec9023f54ab"}, + {file = "lxml-5.3.0-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:4c1fefd7e3d00921c44dc9ca80a775af49698bbfd92ea84498e56acffd4c5469"}, + {file = "lxml-5.3.0-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:71a8dd38fbd2f2319136d4ae855a7078c69c9a38ae06e0c17c73fd70fc6caad8"}, + {file = "lxml-5.3.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:97acf1e1fd66ab53dacd2c35b319d7e548380c2e9e8c54525c6e76d21b1ae3b1"}, + {file = "lxml-5.3.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:68934b242c51eb02907c5b81d138cb977b2129a0a75a8f8b60b01cb8586c7b21"}, + {file = "lxml-5.3.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b710bc2b8292966b23a6a0121f7a6c51d45d2347edcc75f016ac123b8054d3f2"}, + {file = "lxml-5.3.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18feb4b93302091b1541221196a2155aa296c363fd233814fa11e181adebc52f"}, + {file = "lxml-5.3.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:3eb44520c4724c2e1a57c0af33a379eee41792595023f367ba3952a2d96c2aab"}, + {file = "lxml-5.3.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:609251a0ca4770e5a8768ff902aa02bf636339c5a93f9349b48eb1f606f7f3e9"}, + {file = "lxml-5.3.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:516f491c834eb320d6c843156440fe7fc0d50b33e44387fcec5b02f0bc118a4c"}, + {file = "lxml-5.3.0.tar.gz", hash = "sha256:4e109ca30d1edec1ac60cdbe341905dc3b8f55b16855e03a54aaf59e51ec8c6f"}, ] [package.extras] @@ -2066,7 +2063,7 @@ cssselect = ["cssselect (>=0.7)"] html-clean = ["lxml-html-clean"] html5 = ["html5lib"] htmlsoup = ["BeautifulSoup4"] -source = ["Cython (>=3.0.10)"] +source = ["Cython (>=3.0.11)"] [[package]] name = "mako" @@ -2089,13 +2086,13 @@ testing = ["pytest"] [[package]] name = "markdown" -version = "3.6" +version = "3.7" description = "Python implementation of John Gruber's Markdown." optional = false python-versions = ">=3.8" files = [ - {file = "Markdown-3.6-py3-none-any.whl", hash = "sha256:48f276f4d8cfb8ce6527c8f79e2ee29708508bf4d40aa410fbc3b4ee832c850f"}, - {file = "Markdown-3.6.tar.gz", hash = "sha256:ed4f41f6daecbeeb96e576ce414c41d2d876daa9a16cb35fa8ed8c2ddfad0224"}, + {file = "Markdown-3.7-py3-none-any.whl", hash = "sha256:7eb6df5690b81a1d7942992c97fad2938e956e79df20cbc6186e9c3a77b1c803"}, + {file = "markdown-3.7.tar.gz", hash = "sha256:2ae2471477cfd02dbbf038d5d9bc226d40def84b4fe2986e49b59b6b472bbed2"}, ] [package.dependencies] @@ -2581,13 +2578,13 @@ files = [ [[package]] name = "ollama" -version = "0.2.1" +version = "0.3.1" description = "The official Python client for Ollama." optional = false python-versions = "<4.0,>=3.8" files = [ - {file = "ollama-0.2.1-py3-none-any.whl", hash = "sha256:b6e2414921c94f573a903d1069d682ba2fb2607070ea9e19ca4a7872f2a460ec"}, - {file = "ollama-0.2.1.tar.gz", hash = "sha256:fa316baa9a81eac3beb4affb0a17deb3008fdd6ed05b123c26306cfbe4c349b6"}, + {file = "ollama-0.3.1-py3-none-any.whl", hash = "sha256:db50034c73d6350349bdfba19c3f0d54a3cea73eb97b35f9d7419b2fc7206454"}, + {file = "ollama-0.3.1.tar.gz", hash = "sha256:032572fb494a4fba200c65013fe937a65382c846b5f358d9e8918ecbc9ac44b5"}, ] [package.dependencies] @@ -2595,13 +2592,13 @@ httpx = ">=0.27.0,<0.28.0" [[package]] name = "openai" -version = "1.40.1" +version = "1.41.0" description = "The official Python library for the openai API" optional = false python-versions = ">=3.7.1" files = [ - {file = "openai-1.40.1-py3-none-any.whl", hash = "sha256:cf5929076c6ca31c26f1ed207e9fd19eb05404cc9104f64c9d29bb0ac0c5bcd4"}, - {file = "openai-1.40.1.tar.gz", hash = "sha256:cb1294ac1f8c6a1acbb07e090698eb5ad74a7a88484e77126612a4f22579673d"}, + {file = "openai-1.41.0-py3-none-any.whl", hash = "sha256:3b6cca4571667f3e0800442ef8f2bfa6a6f3301c51776bc7626159a4d81c242c"}, + {file = "openai-1.41.0.tar.gz", hash = "sha256:26b81f39b49dce92ff5d30c373625ddb212c2f1050e1574e456d18423730cdd0"}, ] [package.dependencies] @@ -2636,11 +2633,11 @@ files = [ [package.dependencies] numpy = [ {version = ">=1.21.0", markers = "python_version == \"3.9\" and platform_system == \"Darwin\" and platform_machine == \"arm64\""}, - {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, - {version = ">=1.23.5", markers = "python_version >= \"3.11\" and python_version < \"3.12\""}, {version = ">=1.21.4", markers = "python_version >= \"3.10\" and platform_system == \"Darwin\" and python_version < \"3.11\""}, {version = ">=1.21.2", markers = "platform_system != \"Darwin\" and python_version >= \"3.10\" and python_version < \"3.11\""}, {version = ">=1.19.3", markers = "platform_system == \"Linux\" and platform_machine == \"aarch64\" and python_version >= \"3.8\" and python_version < \"3.10\" or python_version > \"3.9\" and python_version < \"3.10\" or python_version >= \"3.9\" and platform_system != \"Darwin\" and python_version < \"3.10\" or python_version >= \"3.9\" and platform_machine != \"arm64\" and python_version < \"3.10\""}, + {version = ">=1.23.5", markers = "python_version >= \"3.11\" and python_version < \"3.12\""}, + {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, ] [[package]] @@ -2723,8 +2720,8 @@ files = [ [package.dependencies] numpy = [ {version = ">=1.22.4", markers = "python_version < \"3.11\""}, - {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, {version = ">=1.23.2", markers = "python_version == \"3.11\""}, + {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, ] python-dateutil = ">=2.8.2" pytz = ">=2020.1" @@ -4000,18 +3997,18 @@ stats = ["scipy (>=1.7)", "statsmodels (>=0.12)"] [[package]] name = "setuptools" -version = "72.1.0" +version = "72.2.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-72.1.0-py3-none-any.whl", hash = "sha256:5a03e1860cf56bb6ef48ce186b0e557fdba433237481a9a625176c2831be15d1"}, - {file = "setuptools-72.1.0.tar.gz", hash = "sha256:8d243eff56d095e5817f796ede6ae32941278f542e0f941867cc05ae52b162ec"}, + {file = "setuptools-72.2.0-py3-none-any.whl", hash = "sha256:f11dd94b7bae3a156a95ec151f24e4637fb4fa19c878e4d191bfb8b2d82728c4"}, + {file = "setuptools-72.2.0.tar.gz", hash = "sha256:80aacbf633704e9c8bfa1d99fa5dd4dc59573efcf9e4042c13d3bcef91ac2ef9"}, ] [package.extras] core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.text (>=3.7)", "more-itertools (>=8.8)", "ordered-set (>=3.1.1)", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.11.*)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (<0.4)", "pytest-ruff (>=0.2.1)", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] [[package]] @@ -4063,13 +4060,13 @@ files = [ [[package]] name = "soupsieve" -version = "2.5" +version = "2.6" description = "A modern CSS selector implementation for Beautiful Soup." optional = false python-versions = ">=3.8" files = [ - {file = "soupsieve-2.5-py3-none-any.whl", hash = "sha256:eaa337ff55a1579b6549dc679565eac1e3d000563bcb1c8ab0d0fefbc0c2cdc7"}, - {file = "soupsieve-2.5.tar.gz", hash = "sha256:5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690"}, + {file = "soupsieve-2.6-py3-none-any.whl", hash = "sha256:e72c4ff06e4fb6e4b5a9f0f55fe6e81514581fca1515028625d0f299c602ccc9"}, + {file = "soupsieve-2.6.tar.gz", hash = "sha256:e2e68417777af359ec65daac1057404a3c8a5455bb8abc36f1a9866ab1a51abb"}, ] [[package]] @@ -4301,111 +4298,111 @@ blobfile = ["blobfile (>=2)"] [[package]] name = "tokenizers" -version = "0.19.1" +version = "0.20.0" description = "" optional = false python-versions = ">=3.7" files = [ - {file = "tokenizers-0.19.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:952078130b3d101e05ecfc7fc3640282d74ed26bcf691400f872563fca15ac97"}, - {file = "tokenizers-0.19.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:82c8b8063de6c0468f08e82c4e198763e7b97aabfe573fd4cf7b33930ca4df77"}, - {file = "tokenizers-0.19.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f03727225feaf340ceeb7e00604825addef622d551cbd46b7b775ac834c1e1c4"}, - {file = "tokenizers-0.19.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:453e4422efdfc9c6b6bf2eae00d5e323f263fff62b29a8c9cd526c5003f3f642"}, - {file = "tokenizers-0.19.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:02e81bf089ebf0e7f4df34fa0207519f07e66d8491d963618252f2e0729e0b46"}, - {file = "tokenizers-0.19.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b07c538ba956843833fee1190cf769c60dc62e1cf934ed50d77d5502194d63b1"}, - {file = "tokenizers-0.19.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e28cab1582e0eec38b1f38c1c1fb2e56bce5dc180acb1724574fc5f47da2a4fe"}, - {file = "tokenizers-0.19.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b01afb7193d47439f091cd8f070a1ced347ad0f9144952a30a41836902fe09e"}, - {file = "tokenizers-0.19.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7fb297edec6c6841ab2e4e8f357209519188e4a59b557ea4fafcf4691d1b4c98"}, - {file = "tokenizers-0.19.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2e8a3dd055e515df7054378dc9d6fa8c8c34e1f32777fb9a01fea81496b3f9d3"}, - {file = "tokenizers-0.19.1-cp310-none-win32.whl", hash = "sha256:7ff898780a155ea053f5d934925f3902be2ed1f4d916461e1a93019cc7250837"}, - {file = "tokenizers-0.19.1-cp310-none-win_amd64.whl", hash = "sha256:bea6f9947e9419c2fda21ae6c32871e3d398cba549b93f4a65a2d369662d9403"}, - {file = "tokenizers-0.19.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:5c88d1481f1882c2e53e6bb06491e474e420d9ac7bdff172610c4f9ad3898059"}, - {file = "tokenizers-0.19.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ddf672ed719b4ed82b51499100f5417d7d9f6fb05a65e232249268f35de5ed14"}, - {file = "tokenizers-0.19.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:dadc509cc8a9fe460bd274c0e16ac4184d0958117cf026e0ea8b32b438171594"}, - {file = "tokenizers-0.19.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dfedf31824ca4915b511b03441784ff640378191918264268e6923da48104acc"}, - {file = "tokenizers-0.19.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ac11016d0a04aa6487b1513a3a36e7bee7eec0e5d30057c9c0408067345c48d2"}, - {file = "tokenizers-0.19.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:76951121890fea8330d3a0df9a954b3f2a37e3ec20e5b0530e9a0044ca2e11fe"}, - {file = "tokenizers-0.19.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b342d2ce8fc8d00f376af068e3274e2e8649562e3bc6ae4a67784ded6b99428d"}, - {file = "tokenizers-0.19.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d16ff18907f4909dca9b076b9c2d899114dd6abceeb074eca0c93e2353f943aa"}, - {file = "tokenizers-0.19.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:706a37cc5332f85f26efbe2bdc9ef8a9b372b77e4645331a405073e4b3a8c1c6"}, - {file = "tokenizers-0.19.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:16baac68651701364b0289979ecec728546133e8e8fe38f66fe48ad07996b88b"}, - {file = "tokenizers-0.19.1-cp311-none-win32.whl", hash = "sha256:9ed240c56b4403e22b9584ee37d87b8bfa14865134e3e1c3fb4b2c42fafd3256"}, - {file = "tokenizers-0.19.1-cp311-none-win_amd64.whl", hash = "sha256:ad57d59341710b94a7d9dbea13f5c1e7d76fd8d9bcd944a7a6ab0b0da6e0cc66"}, - {file = "tokenizers-0.19.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:621d670e1b1c281a1c9698ed89451395d318802ff88d1fc1accff0867a06f153"}, - {file = "tokenizers-0.19.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d924204a3dbe50b75630bd16f821ebda6a5f729928df30f582fb5aade90c818a"}, - {file = "tokenizers-0.19.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:4f3fefdc0446b1a1e6d81cd4c07088ac015665d2e812f6dbba4a06267d1a2c95"}, - {file = "tokenizers-0.19.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9620b78e0b2d52ef07b0d428323fb34e8ea1219c5eac98c2596311f20f1f9266"}, - {file = "tokenizers-0.19.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:04ce49e82d100594715ac1b2ce87d1a36e61891a91de774755f743babcd0dd52"}, - {file = "tokenizers-0.19.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c5c2ff13d157afe413bf7e25789879dd463e5a4abfb529a2d8f8473d8042e28f"}, - {file = "tokenizers-0.19.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3174c76efd9d08f836bfccaca7cfec3f4d1c0a4cf3acbc7236ad577cc423c840"}, - {file = "tokenizers-0.19.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7c9d5b6c0e7a1e979bec10ff960fae925e947aab95619a6fdb4c1d8ff3708ce3"}, - {file = "tokenizers-0.19.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:a179856d1caee06577220ebcfa332af046d576fb73454b8f4d4b0ba8324423ea"}, - {file = "tokenizers-0.19.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:952b80dac1a6492170f8c2429bd11fcaa14377e097d12a1dbe0ef2fb2241e16c"}, - {file = "tokenizers-0.19.1-cp312-none-win32.whl", hash = "sha256:01d62812454c188306755c94755465505836fd616f75067abcae529c35edeb57"}, - {file = "tokenizers-0.19.1-cp312-none-win_amd64.whl", hash = "sha256:b70bfbe3a82d3e3fb2a5e9b22a39f8d1740c96c68b6ace0086b39074f08ab89a"}, - {file = "tokenizers-0.19.1-cp37-cp37m-macosx_10_12_x86_64.whl", hash = "sha256:bb9dfe7dae85bc6119d705a76dc068c062b8b575abe3595e3c6276480e67e3f1"}, - {file = "tokenizers-0.19.1-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:1f0360cbea28ea99944ac089c00de7b2e3e1c58f479fb8613b6d8d511ce98267"}, - {file = "tokenizers-0.19.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:71e3ec71f0e78780851fef28c2a9babe20270404c921b756d7c532d280349214"}, - {file = "tokenizers-0.19.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b82931fa619dbad979c0ee8e54dd5278acc418209cc897e42fac041f5366d626"}, - {file = "tokenizers-0.19.1-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e8ff5b90eabdcdaa19af697885f70fe0b714ce16709cf43d4952f1f85299e73a"}, - {file = "tokenizers-0.19.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e742d76ad84acbdb1a8e4694f915fe59ff6edc381c97d6dfdd054954e3478ad4"}, - {file = "tokenizers-0.19.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d8c5d59d7b59885eab559d5bc082b2985555a54cda04dda4c65528d90ad252ad"}, - {file = "tokenizers-0.19.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b2da5c32ed869bebd990c9420df49813709e953674c0722ff471a116d97b22d"}, - {file = "tokenizers-0.19.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:638e43936cc8b2cbb9f9d8dde0fe5e7e30766a3318d2342999ae27f68fdc9bd6"}, - {file = "tokenizers-0.19.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:78e769eb3b2c79687d9cb0f89ef77223e8e279b75c0a968e637ca7043a84463f"}, - {file = "tokenizers-0.19.1-cp37-none-win32.whl", hash = "sha256:72791f9bb1ca78e3ae525d4782e85272c63faaef9940d92142aa3eb79f3407a3"}, - {file = "tokenizers-0.19.1-cp37-none-win_amd64.whl", hash = "sha256:f3bbb7a0c5fcb692950b041ae11067ac54826204318922da754f908d95619fbc"}, - {file = "tokenizers-0.19.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:07f9295349bbbcedae8cefdbcfa7f686aa420be8aca5d4f7d1ae6016c128c0c5"}, - {file = "tokenizers-0.19.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:10a707cc6c4b6b183ec5dbfc5c34f3064e18cf62b4a938cb41699e33a99e03c1"}, - {file = "tokenizers-0.19.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6309271f57b397aa0aff0cbbe632ca9d70430839ca3178bf0f06f825924eca22"}, - {file = "tokenizers-0.19.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ad23d37d68cf00d54af184586d79b84075ada495e7c5c0f601f051b162112dc"}, - {file = "tokenizers-0.19.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:427c4f0f3df9109314d4f75b8d1f65d9477033e67ffaec4bca53293d3aca286d"}, - {file = "tokenizers-0.19.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e83a31c9cf181a0a3ef0abad2b5f6b43399faf5da7e696196ddd110d332519ee"}, - {file = "tokenizers-0.19.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c27b99889bd58b7e301468c0838c5ed75e60c66df0d4db80c08f43462f82e0d3"}, - {file = "tokenizers-0.19.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bac0b0eb952412b0b196ca7a40e7dce4ed6f6926489313414010f2e6b9ec2adf"}, - {file = "tokenizers-0.19.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8a6298bde623725ca31c9035a04bf2ef63208d266acd2bed8c2cb7d2b7d53ce6"}, - {file = "tokenizers-0.19.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:08a44864e42fa6d7d76d7be4bec62c9982f6f6248b4aa42f7302aa01e0abfd26"}, - {file = "tokenizers-0.19.1-cp38-none-win32.whl", hash = "sha256:1de5bc8652252d9357a666e609cb1453d4f8e160eb1fb2830ee369dd658e8975"}, - {file = "tokenizers-0.19.1-cp38-none-win_amd64.whl", hash = "sha256:0bcce02bf1ad9882345b34d5bd25ed4949a480cf0e656bbd468f4d8986f7a3f1"}, - {file = "tokenizers-0.19.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:0b9394bd204842a2a1fd37fe29935353742be4a3460b6ccbaefa93f58a8df43d"}, - {file = "tokenizers-0.19.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4692ab92f91b87769d950ca14dbb61f8a9ef36a62f94bad6c82cc84a51f76f6a"}, - {file = "tokenizers-0.19.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6258c2ef6f06259f70a682491c78561d492e885adeaf9f64f5389f78aa49a051"}, - {file = "tokenizers-0.19.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c85cf76561fbd01e0d9ea2d1cbe711a65400092bc52b5242b16cfd22e51f0c58"}, - {file = "tokenizers-0.19.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:670b802d4d82bbbb832ddb0d41df7015b3e549714c0e77f9bed3e74d42400fbe"}, - {file = "tokenizers-0.19.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:85aa3ab4b03d5e99fdd31660872249df5e855334b6c333e0bc13032ff4469c4a"}, - {file = "tokenizers-0.19.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cbf001afbbed111a79ca47d75941e9e5361297a87d186cbfc11ed45e30b5daba"}, - {file = "tokenizers-0.19.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4c89aa46c269e4e70c4d4f9d6bc644fcc39bb409cb2a81227923404dd6f5227"}, - {file = "tokenizers-0.19.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:39c1ec76ea1027438fafe16ecb0fb84795e62e9d643444c1090179e63808c69d"}, - {file = "tokenizers-0.19.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c2a0d47a89b48d7daa241e004e71fb5a50533718897a4cd6235cb846d511a478"}, - {file = "tokenizers-0.19.1-cp39-none-win32.whl", hash = "sha256:61b7fe8886f2e104d4caf9218b157b106207e0f2a4905c9c7ac98890688aabeb"}, - {file = "tokenizers-0.19.1-cp39-none-win_amd64.whl", hash = "sha256:f97660f6c43efd3e0bfd3f2e3e5615bf215680bad6ee3d469df6454b8c6e8256"}, - {file = "tokenizers-0.19.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3b11853f17b54c2fe47742c56d8a33bf49ce31caf531e87ac0d7d13d327c9334"}, - {file = "tokenizers-0.19.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d26194ef6c13302f446d39972aaa36a1dda6450bc8949f5eb4c27f51191375bd"}, - {file = "tokenizers-0.19.1-pp310-pypy310_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:e8d1ed93beda54bbd6131a2cb363a576eac746d5c26ba5b7556bc6f964425594"}, - {file = "tokenizers-0.19.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca407133536f19bdec44b3da117ef0d12e43f6d4b56ac4c765f37eca501c7bda"}, - {file = "tokenizers-0.19.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce05fde79d2bc2e46ac08aacbc142bead21614d937aac950be88dc79f9db9022"}, - {file = "tokenizers-0.19.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:35583cd46d16f07c054efd18b5d46af4a2f070a2dd0a47914e66f3ff5efb2b1e"}, - {file = "tokenizers-0.19.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:43350270bfc16b06ad3f6f07eab21f089adb835544417afda0f83256a8bf8b75"}, - {file = "tokenizers-0.19.1-pp37-pypy37_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b4399b59d1af5645bcee2072a463318114c39b8547437a7c2d6a186a1b5a0e2d"}, - {file = "tokenizers-0.19.1-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6852c5b2a853b8b0ddc5993cd4f33bfffdca4fcc5d52f89dd4b8eada99379285"}, - {file = "tokenizers-0.19.1-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bcd266ae85c3d39df2f7e7d0e07f6c41a55e9a3123bb11f854412952deacd828"}, - {file = "tokenizers-0.19.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ecb2651956eea2aa0a2d099434134b1b68f1c31f9a5084d6d53f08ed43d45ff2"}, - {file = "tokenizers-0.19.1-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:b279ab506ec4445166ac476fb4d3cc383accde1ea152998509a94d82547c8e2a"}, - {file = "tokenizers-0.19.1-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:89183e55fb86e61d848ff83753f64cded119f5d6e1f553d14ffee3700d0a4a49"}, - {file = "tokenizers-0.19.1-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b2edbc75744235eea94d595a8b70fe279dd42f3296f76d5a86dde1d46e35f574"}, - {file = "tokenizers-0.19.1-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:0e64bfde9a723274e9a71630c3e9494ed7b4c0f76a1faacf7fe294cd26f7ae7c"}, - {file = "tokenizers-0.19.1-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0b5ca92bfa717759c052e345770792d02d1f43b06f9e790ca0a1db62838816f3"}, - {file = "tokenizers-0.19.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f8a20266e695ec9d7a946a019c1d5ca4eddb6613d4f466888eee04f16eedb85"}, - {file = "tokenizers-0.19.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63c38f45d8f2a2ec0f3a20073cccb335b9f99f73b3c69483cd52ebc75369d8a1"}, - {file = "tokenizers-0.19.1-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:dd26e3afe8a7b61422df3176e06664503d3f5973b94f45d5c45987e1cb711876"}, - {file = "tokenizers-0.19.1-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:eddd5783a4a6309ce23432353cdb36220e25cbb779bfa9122320666508b44b88"}, - {file = "tokenizers-0.19.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:56ae39d4036b753994476a1b935584071093b55c7a72e3b8288e68c313ca26e7"}, - {file = "tokenizers-0.19.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:f9939ca7e58c2758c01b40324a59c034ce0cebad18e0d4563a9b1beab3018243"}, - {file = "tokenizers-0.19.1-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6c330c0eb815d212893c67a032e9dc1b38a803eccb32f3e8172c19cc69fbb439"}, - {file = "tokenizers-0.19.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec11802450a2487cdf0e634b750a04cbdc1c4d066b97d94ce7dd2cb51ebb325b"}, - {file = "tokenizers-0.19.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2b718f316b596f36e1dae097a7d5b91fc5b85e90bf08b01ff139bd8953b25af"}, - {file = "tokenizers-0.19.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:ed69af290c2b65169f0ba9034d1dc39a5db9459b32f1dd8b5f3f32a3fcf06eab"}, - {file = "tokenizers-0.19.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f8a9c828277133af13f3859d1b6bf1c3cb6e9e1637df0e45312e6b7c2e622b1f"}, - {file = "tokenizers-0.19.1.tar.gz", hash = "sha256:ee59e6680ed0fdbe6b724cf38bd70400a0c1dd623b07ac729087270caeac88e3"}, + {file = "tokenizers-0.20.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:6cff5c5e37c41bc5faa519d6f3df0679e4b37da54ea1f42121719c5e2b4905c0"}, + {file = "tokenizers-0.20.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:62a56bf75c27443432456f4ca5ca055befa95e25be8a28141cc495cac8ae4d6d"}, + {file = "tokenizers-0.20.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68cc7de6a63f09c4a86909c2597b995aa66e19df852a23aea894929c74369929"}, + {file = "tokenizers-0.20.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:053c37ecee482cc958fdee53af3c6534286a86f5d35aac476f7c246830e53ae5"}, + {file = "tokenizers-0.20.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3d7074aaabc151a6363fa03db5493fc95b423b2a1874456783989e96d541c7b6"}, + {file = "tokenizers-0.20.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a11435780f2acd89e8fefe5e81cecf01776f6edb9b3ac95bcb76baee76b30b90"}, + {file = "tokenizers-0.20.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9a81cd2712973b007d84268d45fc3f6f90a79c31dfe7f1925e6732f8d2959987"}, + {file = "tokenizers-0.20.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7dfd796ab9d909f76fb93080e1c7c8309f196ecb316eb130718cd5e34231c69"}, + {file = "tokenizers-0.20.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:8029ad2aa8cb00605c9374566034c1cc1b15130713e0eb5afcef6cface8255c9"}, + {file = "tokenizers-0.20.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ca4d54260ebe97d59dfa9a30baa20d0c4dd9137d99a8801700055c561145c24e"}, + {file = "tokenizers-0.20.0-cp310-none-win32.whl", hash = "sha256:95ee16b57cec11b86a7940174ec5197d506439b0f415ab3859f254b1dffe9df0"}, + {file = "tokenizers-0.20.0-cp310-none-win_amd64.whl", hash = "sha256:0a61a11e93eeadbf02aea082ffc75241c4198e0608bbbac4f65a9026851dcf37"}, + {file = "tokenizers-0.20.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:6636b798b3c4d6c9b1af1a918bd07c867808e5a21c64324e95318a237e6366c3"}, + {file = "tokenizers-0.20.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5ec603e42eaf499ffd58b9258162add948717cf21372458132f14e13a6bc7172"}, + {file = "tokenizers-0.20.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cce124264903a8ea6f8f48e1cc7669e5ef638c18bd4ab0a88769d5f92debdf7f"}, + {file = "tokenizers-0.20.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:07bbeba0231cf8de07aa6b9e33e9779ff103d47042eeeb859a8c432e3292fb98"}, + {file = "tokenizers-0.20.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:06c0ca8397b35d38b83a44a9c6929790c1692957d88541df061cb34d82ebbf08"}, + {file = "tokenizers-0.20.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ca6557ac3b83d912dfbb1f70ab56bd4b0594043916688e906ede09f42e192401"}, + {file = "tokenizers-0.20.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2a5ad94c9e80ac6098328bee2e3264dbced4c6faa34429994d473f795ec58ef4"}, + {file = "tokenizers-0.20.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b5c7f906ee6bec30a9dc20268a8b80f3b9584de1c9f051671cb057dc6ce28f6"}, + {file = "tokenizers-0.20.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:31e087e9ee1b8f075b002bfee257e858dc695f955b43903e1bb4aa9f170e37fe"}, + {file = "tokenizers-0.20.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c3124fb6f3346cb3d8d775375d3b429bf4dcfc24f739822702009d20a4297990"}, + {file = "tokenizers-0.20.0-cp311-none-win32.whl", hash = "sha256:a4bb8b40ba9eefa621fdcabf04a74aa6038ae3be0c614c6458bd91a4697a452f"}, + {file = "tokenizers-0.20.0-cp311-none-win_amd64.whl", hash = "sha256:2b709d371f1fe60a28ef0c5c67815952d455ca7f34dbe7197eaaed3cc54b658e"}, + {file = "tokenizers-0.20.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:15c81a17d0d66f4987c6ca16f4bea7ec253b8c7ed1bb00fdc5d038b1bb56e714"}, + {file = "tokenizers-0.20.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6a531cdf1fb6dc41c984c785a3b299cb0586de0b35683842a3afbb1e5207f910"}, + {file = "tokenizers-0.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:06caabeb4587f8404e0cd9d40f458e9cba3e815c8155a38e579a74ff3e2a4301"}, + {file = "tokenizers-0.20.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8768f964f23f5b9f50546c0369c75ab3262de926983888bbe8b98be05392a79c"}, + {file = "tokenizers-0.20.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:626403860152c816f97b649fd279bd622c3d417678c93b4b1a8909b6380b69a8"}, + {file = "tokenizers-0.20.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9c1b88fa9e5ff062326f4bf82681da5a96fca7104d921a6bd7b1e6fcf224af26"}, + {file = "tokenizers-0.20.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d7e559436a07dc547f22ce1101f26d8b2fad387e28ec8e7e1e3b11695d681d8"}, + {file = "tokenizers-0.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e48afb75e50449848964e4a67b0da01261dd3aa8df8daecf10db8fd7f5b076eb"}, + {file = "tokenizers-0.20.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:baf5d0e1ff44710a95eefc196dd87666ffc609fd447c5e5b68272a7c3d342a1d"}, + {file = "tokenizers-0.20.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e5e56df0e8ed23ba60ae3848c3f069a0710c4b197218fe4f89e27eba38510768"}, + {file = "tokenizers-0.20.0-cp312-none-win32.whl", hash = "sha256:ec53e5ecc142a82432f9c6c677dbbe5a2bfee92b8abf409a9ecb0d425ee0ce75"}, + {file = "tokenizers-0.20.0-cp312-none-win_amd64.whl", hash = "sha256:f18661ece72e39c0dfaa174d6223248a15b457dbd4b0fc07809b8e6d3ca1a234"}, + {file = "tokenizers-0.20.0-cp37-cp37m-macosx_10_12_x86_64.whl", hash = "sha256:f7065b1084d8d1a03dc89d9aad69bcbc8415d4bc123c367063eb32958cd85054"}, + {file = "tokenizers-0.20.0-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:e5d4069e4714e3f7ba0a4d3d44f9d84a432cd4e4aa85c3d7dd1f51440f12e4a1"}, + {file = "tokenizers-0.20.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:799b808529e54b7e1a36350bda2aeb470e8390e484d3e98c10395cee61d4e3c6"}, + {file = "tokenizers-0.20.0-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7f9baa027cc8a281ad5f7725a93c204d7a46986f88edbe8ef7357f40a23fb9c7"}, + {file = "tokenizers-0.20.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:010ec7f3f7a96adc4c2a34a3ada41fa14b4b936b5628b4ff7b33791258646c6b"}, + {file = "tokenizers-0.20.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:98d88f06155335b14fd78e32ee28ca5b2eb30fced4614e06eb14ae5f7fba24ed"}, + {file = "tokenizers-0.20.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e13eb000ef540c2280758d1b9cfa5fe424b0424ae4458f440e6340a4f18b2638"}, + {file = "tokenizers-0.20.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fab3cf066ff426f7e6d70435dc28a9ff01b2747be83810e397cba106f39430b0"}, + {file = "tokenizers-0.20.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:39fa3761b30a89368f322e5daf4130dce8495b79ad831f370449cdacfb0c0d37"}, + {file = "tokenizers-0.20.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:c8da0fba4d179ddf2607821575998df3c294aa59aa8df5a6646dc64bc7352bce"}, + {file = "tokenizers-0.20.0-cp37-none-win32.whl", hash = "sha256:fada996d6da8cf213f6e3c91c12297ad4f6cdf7a85c2fadcd05ec32fa6846fcd"}, + {file = "tokenizers-0.20.0-cp37-none-win_amd64.whl", hash = "sha256:7d29aad702279e0760c265fcae832e89349078e3418dd329732d4503259fd6bd"}, + {file = "tokenizers-0.20.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:099c68207f3ef0227ecb6f80ab98ea74de559f7b124adc7b17778af0250ee90a"}, + {file = "tokenizers-0.20.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:68012d8a8cddb2eab3880870d7e2086cb359c7f7a2b03f5795044f5abff4e850"}, + {file = "tokenizers-0.20.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9253bdd209c6aee168deca7d0e780581bf303e0058f268f9bb06859379de19b6"}, + {file = "tokenizers-0.20.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8f868600ddbcb0545905ed075eb7218a0756bf6c09dae7528ea2f8436ebd2c93"}, + {file = "tokenizers-0.20.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a9643d9c8c5f99b6aba43fd10034f77cc6c22c31f496d2f0ee183047d948fa0"}, + {file = "tokenizers-0.20.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c375c6a889aeab44734028bc65cc070acf93ccb0f9368be42b67a98e1063d3f6"}, + {file = "tokenizers-0.20.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e359f852328e254f070bbd09a19a568421d23388f04aad9f2fb7da7704c7228d"}, + {file = "tokenizers-0.20.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d98b01a309d4387f3b1c1dd68a8b8136af50376cf146c1b7e8d8ead217a5be4b"}, + {file = "tokenizers-0.20.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:459f7537119554c2899067dec1ac74a00d02beef6558f4ee2e99513bf6d568af"}, + {file = "tokenizers-0.20.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:392b87ec89452628c045c9f2a88bc2a827f4c79e7d84bc3b72752b74c2581f70"}, + {file = "tokenizers-0.20.0-cp38-none-win32.whl", hash = "sha256:55a393f893d2ed4dd95a1553c2e42d4d4086878266f437b03590d3f81984c4fe"}, + {file = "tokenizers-0.20.0-cp38-none-win_amd64.whl", hash = "sha256:30ffe33c5c2f2aab8e9a3340d0110dd9f7ace7eec7362e20a697802306bd8068"}, + {file = "tokenizers-0.20.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:aa2d4a6fed2a7e3f860c7fc9d48764bb30f2649d83915d66150d6340e06742b8"}, + {file = "tokenizers-0.20.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b5ef0f814084a897e9071fc4a868595f018c5c92889197bdc4bf19018769b148"}, + {file = "tokenizers-0.20.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc1e1b791e8c3bf4c4f265f180dadaff1c957bf27129e16fdd5e5d43c2d3762c"}, + {file = "tokenizers-0.20.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2b69e55e481459c07885263743a0d3c18d52db19bae8226a19bcca4aaa213fff"}, + {file = "tokenizers-0.20.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4806b4d82e27a2512bc23057b2986bc8b85824914286975b84d8105ff40d03d9"}, + {file = "tokenizers-0.20.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9859e9ef13adf5a473ccab39d31bff9c550606ae3c784bf772b40f615742a24f"}, + {file = "tokenizers-0.20.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ef703efedf4c20488a8eb17637b55973745b27997ff87bad88ed499b397d1144"}, + {file = "tokenizers-0.20.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6eec0061bab94b1841ab87d10831fdf1b48ebaed60e6d66d66dbe1d873f92bf5"}, + {file = "tokenizers-0.20.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:980f3d0d7e73f845b69087f29a63c11c7eb924c4ad6b358da60f3db4cf24bdb4"}, + {file = "tokenizers-0.20.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7c157550a2f3851b29d7fdc9dc059fcf81ff0c0fc49a1e5173a89d533ed043fa"}, + {file = "tokenizers-0.20.0-cp39-none-win32.whl", hash = "sha256:8a3d2f4d08608ec4f9895ec25b4b36a97f05812543190a5f2c3cd19e8f041e5a"}, + {file = "tokenizers-0.20.0-cp39-none-win_amd64.whl", hash = "sha256:d90188d12afd0c75e537f9a1d92f9c7375650188ee4f48fdc76f9e38afbd2251"}, + {file = "tokenizers-0.20.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:d68e15f1815357b059ec266062340c343ea7f98f7f330602df81ffa3474b6122"}, + {file = "tokenizers-0.20.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:23f9ecec637b9bc80da5f703808d29ed5329e56b5aa8d791d1088014f48afadc"}, + {file = "tokenizers-0.20.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f830b318ee599e3d0665b3e325f85bc75ee2d2ca6285f52e439dc22b64691580"}, + {file = "tokenizers-0.20.0-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3dc750def789cb1de1b5a37657919545e1d9ffa667658b3fa9cb7862407a1b8"}, + {file = "tokenizers-0.20.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e26e6c755ae884c2ea6135cd215bdd0fccafe4ee62405014b8c3cd19954e3ab9"}, + {file = "tokenizers-0.20.0-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:a1158c7174f427182e08baa2a8ded2940f2b4a3e94969a85cc9cfd16004cbcea"}, + {file = "tokenizers-0.20.0-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:6324826287a3fc198898d3dcf758fe4a8479e42d6039f4c59e2cedd3cf92f64e"}, + {file = "tokenizers-0.20.0-pp37-pypy37_pp73-macosx_10_12_x86_64.whl", hash = "sha256:7d8653149405bb0c16feaf9cfee327fdb6aaef9dc2998349fec686f35e81c4e2"}, + {file = "tokenizers-0.20.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b8a2dc1e402a155e97309287ca085c80eb1b7fab8ae91527d3b729181639fa51"}, + {file = "tokenizers-0.20.0-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07bef67b20aa6e5f7868c42c7c5eae4d24f856274a464ae62e47a0f2cccec3da"}, + {file = "tokenizers-0.20.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da06e397182ff53789c506c7833220c192952c57e1581a53f503d8d953e2d67e"}, + {file = "tokenizers-0.20.0-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:302f7e11a14814028b7fc88c45a41f1bbe9b5b35fd76d6869558d1d1809baa43"}, + {file = "tokenizers-0.20.0-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:055ec46e807b875589dfbe3d9259f9a6ee43394fb553b03b3d1e9541662dbf25"}, + {file = "tokenizers-0.20.0-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:e3144b8acebfa6ae062e8f45f7ed52e4b50fb6c62f93afc8871b525ab9fdcab3"}, + {file = "tokenizers-0.20.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:b52aa3fd14b2a07588c00a19f66511cff5cca8f7266ca3edcdd17f3512ad159f"}, + {file = "tokenizers-0.20.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2b8cf52779ffc5d4d63a0170fbeb512372bad0dd014ce92bbb9149756c831124"}, + {file = "tokenizers-0.20.0-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:983a45dd11a876124378dae71d6d9761822199b68a4c73f32873d8cdaf326a5b"}, + {file = "tokenizers-0.20.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:df6b819c9a19831ebec581e71a7686a54ab45d90faf3842269a10c11d746de0c"}, + {file = "tokenizers-0.20.0-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:e738cfd80795fcafcef89c5731c84b05638a4ab3f412f97d5ed7765466576eb1"}, + {file = "tokenizers-0.20.0-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:c8842c7be2fadb9c9edcee233b1b7fe7ade406c99b0973f07439985c1c1d0683"}, + {file = "tokenizers-0.20.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:e47a82355511c373a4a430c4909dc1e518e00031207b1fec536c49127388886b"}, + {file = "tokenizers-0.20.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:9afbf359004551179a5db19424180c81276682773cff2c5d002f6eaaffe17230"}, + {file = "tokenizers-0.20.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a07eaa8799a92e6af6f472c21a75bf71575de2af3c0284120b7a09297c0de2f3"}, + {file = "tokenizers-0.20.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0994b2e5fc53a301071806bc4303e4bc3bdc3f490e92a21338146a36746b0872"}, + {file = "tokenizers-0.20.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b6466e0355b603d10e3cc3d282d350b646341b601e50969464a54939f9848d0"}, + {file = "tokenizers-0.20.0-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:1e86594c2a433cb1ea09cfbe596454448c566e57ee8905bd557e489d93e89986"}, + {file = "tokenizers-0.20.0-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:3e14cdef1efa96ecead6ea64a891828432c3ebba128bdc0596e3059fea104ef3"}, + {file = "tokenizers-0.20.0.tar.gz", hash = "sha256:39d7acc43f564c274085cafcd1dae9d36f332456de1a31970296a6b8da4eac8d"}, ] [package.dependencies] @@ -4791,13 +4788,13 @@ multidict = ">=4.0" [[package]] name = "zipp" -version = "3.19.2" +version = "3.20.0" description = "Backport of pathlib-compatible object wrapper for zip files" optional = false python-versions = ">=3.8" files = [ - {file = "zipp-3.19.2-py3-none-any.whl", hash = "sha256:f091755f667055f2d02b32c53771a7a6c8b47e1fdbc4b72a8b9072b3eef8015c"}, - {file = "zipp-3.19.2.tar.gz", hash = "sha256:bf1dcf6450f873a13e952a29504887c89e6de7506209e5b1bcc3460135d4de19"}, + {file = "zipp-3.20.0-py3-none-any.whl", hash = "sha256:58da6168be89f0be59beb194da1250516fdaa062ccebd30127ac65d30045e10d"}, + {file = "zipp-3.20.0.tar.gz", hash = "sha256:0145e43d89664cfe1a2e533adc75adafed82fe2da404b4bbb6b026c0157bdb31"}, ] [package.extras] @@ -4811,4 +4808,4 @@ ingest-movies = ["moviepy", "opencv-python"] [metadata] lock-version = "2.0" python-versions = ">=3.9,<3.13" -content-hash = "d6fe35a821e98c4721de40e75b1e3d743ed67f078ea0babb7cd4b00e679bc8d5" +content-hash = "df92f12a9cb37e0c8ae9ff29eb41b7fe4028acc04364639374bd4ef738b3718a" diff --git a/pyproject.toml b/pyproject.toml index a22f2ba98..248772265 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -57,7 +57,7 @@ openai = "^1.11.1" fsspec = "^2024.6.0" posthog = "^3.5.0" sqlalchemy = "^2.0.30" -ollama = "^0.2.1" +ollama = "^0.3.1" neo4j = "^5.21.0" passlib = "^1.7.4" bcrypt = "^4.1.3" diff --git a/r2r/base/abstractions/completion.py b/r2r/base/abstractions/completion.py index e0f5f43ca..9c22d5508 100644 --- a/r2r/base/abstractions/completion.py +++ b/r2r/base/abstractions/completion.py @@ -3,10 +3,10 @@ """ import json -import uuid from datetime import datetime from enum import Enum from typing import List, Optional +from uuid import UUID from pydantic import BaseModel @@ -25,7 +25,7 @@ def __str__(self): class CompletionRecord(BaseModel): - message_id: uuid.UUID + message_id: UUID message_type: MessageType timestamp: datetime = datetime.now() feedback: Optional[List[str]] = None @@ -41,7 +41,7 @@ class Config: def to_dict(self): def serialize(obj): - if isinstance(obj, uuid.UUID): + if isinstance(obj, UUID): return str(obj) elif isinstance(obj, datetime): return obj.isoformat() diff --git a/r2r/base/abstractions/graph.py b/r2r/base/abstractions/graph.py index 762da615d..597aefbaf 100644 --- a/r2r/base/abstractions/graph.py +++ b/r2r/base/abstractions/graph.py @@ -394,6 +394,7 @@ def from_dict( TextEmbedder = Callable[[str], list[float]] + class KGExtraction(BaseModel): """An extraction from a document that is part of a knowledge graph.""" diff --git a/r2r/base/abstractions/search.py b/r2r/base/abstractions/search.py index 348530cab..269a4b47d 100644 --- a/r2r/base/abstractions/search.py +++ b/r2r/base/abstractions/search.py @@ -39,21 +39,19 @@ def dict(self) -> dict: } class Config: - json_schema_extra = [ - { - "fragment_id": "c68dc72e-fc23-5452-8f49-d7bd46088a96", - "extraction_id": "3f3d47f3-8baf-58eb-8bc2-0171fb1c6e09", - "document_id": "3e157b3a-8469-51db-90d9-52e7d896b49b", - "user_id": "2acb499e-8428-543b-bd85-0d9098718220", - "group_ids": [], - "score": 0.23943702876567796, - "text": "Example text from the document", - "metadata": { - "title": "example_document.pdf", - "associatedQuery": "What is the capital of France?", - }, - } - ] + json_schema_extra = { + "fragment_id": "c68dc72e-fc23-5452-8f49-d7bd46088a96", + "extraction_id": "3f3d47f3-8baf-58eb-8bc2-0171fb1c6e09", + "document_id": "3e157b3a-8469-51db-90d9-52e7d896b49b", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "score": 0.23943702876567796, + "text": "Example text from the document", + "metadata": { + "title": "example_document.pdf", + "associatedQuery": "What is the capital of France?", + }, + } KGSearchResult = List[Tuple[str, List[Dict[str, Any]]]] diff --git a/r2r/base/logging/run_manager.py b/r2r/base/logging/run_manager.py index 389c1c5e3..9d1e55e69 100644 --- a/r2r/base/logging/run_manager.py +++ b/r2r/base/logging/run_manager.py @@ -1,10 +1,11 @@ import contextvars -import uuid from contextlib import asynccontextmanager from typing import Optional +from uuid import UUID from r2r.base.api.models.auth.responses import UserResponse from r2r.base.logging.base import RunType +from r2r.base.utils import generate_run_id from .run_logger import RunLoggingSingleton @@ -16,15 +17,10 @@ def __init__(self, logger: RunLoggingSingleton): self.logger = logger self.run_info = {} - def generate_run_id(self) -> uuid.UUID: - return uuid.uuid4() - - async def set_run_info( - self, run_type: str, run_id: Optional[uuid.UUID] = None - ): + async def set_run_info(self, run_type: str, run_id: Optional[UUID] = None): run_id = run_id or run_id_var.get() if run_id is None: - run_id = self.generate_run_id() + run_id = generate_run_id() token = run_id_var.set(run_id) self.run_info[run_id] = {"run_type": run_type} else: @@ -60,7 +56,7 @@ async def clear_run_info(self, token: contextvars.Token): async def manage_run( run_manager: RunManager, run_type: RunType = RunType.UNSPECIFIED, - run_id: Optional[uuid.UUID] = None, + run_id: Optional[UUID] = None, ): run_id, token = await run_manager.set_run_info(run_type, run_id) try: diff --git a/r2r/base/pipes/base_pipe.py b/r2r/base/pipes/base_pipe.py index 5cddea982..18ced8581 100644 --- a/r2r/base/pipes/base_pipe.py +++ b/r2r/base/pipes/base_pipe.py @@ -1,9 +1,9 @@ import asyncio import logging -import uuid from abc import abstractmethod from enum import Enum from typing import Any, AsyncGenerator, Optional +from uuid import UUID from pydantic import BaseModel @@ -117,7 +117,7 @@ async def log_worker(self): await self.pipe_logger.log(run_id, key, value) self.log_queue.task_done() - async def enqueue_log(self, run_id: uuid.UUID, key: str, value: str): + async def enqueue_log(self, run_id: UUID, key: str, value: str): if self.log_queue.qsize() < self.config.max_log_queue_size: await self.log_queue.put((run_id, key, value)) @@ -155,7 +155,7 @@ async def _run_logic( self, input: Input, state: AsyncState, - run_id: uuid.UUID, + run_id: UUID, *args: Any, **kwargs: Any, ) -> AsyncGenerator[Any, None]: diff --git a/r2r/base/providers/chunking.py b/r2r/base/providers/chunking.py index 57fc5a510..6b2bab04b 100644 --- a/r2r/base/providers/chunking.py +++ b/r2r/base/providers/chunking.py @@ -30,6 +30,26 @@ def validate(self) -> None: def supported_providers(self) -> list[str]: return ["r2r", "unstructured", None] + class Config: + json_schema_extra = { + "type": "object", + "properties": { + "provider": {"type": "string"}, + "method": {"type": "string"}, + "chunk_size": {"type": "integer"}, + "chunk_overlap": {"type": "integer"}, + "max_chunk_size": {"type": "integer"}, + }, + "required": ["provider", "method", "chunk_size", "chunk_overlap"], + "example": { + "provider": "r2r", + "method": "recursive", + "chunk_size": 512, + "chunk_overlap": 20, + "max_chunk_size": 1024, + }, + } + class ChunkingProvider(Provider, ABC): def __init__(self, config: ChunkingConfig): diff --git a/r2r/base/providers/embedding.py b/r2r/base/providers/embedding.py index e213b44da..25725914d 100644 --- a/r2r/base/providers/embedding.py +++ b/r2r/base/providers/embedding.py @@ -2,7 +2,6 @@ import logging import time from abc import abstractmethod -from concurrent.futures import ThreadPoolExecutor from enum import Enum from typing import Any, Optional @@ -52,9 +51,7 @@ def __init__(self, config: EmbeddingConfig): super().__init__(config) self.config: EmbeddingConfig = config self.semaphore = asyncio.Semaphore(config.concurrent_request_limit) - self.thread_pool = ThreadPoolExecutor( - max_workers=config.concurrent_request_limit - ) + self.current_requests = 0 async def _execute_with_backoff_async(self, task: dict[str, Any]): retries = 0 @@ -129,33 +126,25 @@ async def async_get_embeddings( stage: PipeStage = PipeStage.BASE, purpose: EmbeddingPurpose = EmbeddingPurpose.INDEX, ): - tasks = [ - { - "text": text, - "stage": stage, - "purpose": purpose, - } - for text in texts - ] - return await asyncio.gather( - *[self._execute_with_backoff_async(task) for task in tasks] - ) + task = { + "texts": texts, + "stage": stage, + "purpose": purpose, + } + return await self._execute_with_backoff_async(task) def get_embeddings( self, texts: list[str], stage: PipeStage = PipeStage.BASE, purpose: EmbeddingPurpose = EmbeddingPurpose.INDEX, - ): - tasks = [ - { - "text": text, - "stage": stage, - "purpose": purpose, - } - for text in texts - ] - return [self._execute_with_backoff_sync(task) for task in tasks] + ) -> list[list[float]]: + task = { + "texts": texts, + "stage": stage, + "purpose": purpose, + } + return self._execute_with_backoff_sync(task) @abstractmethod def rerank( diff --git a/r2r/base/providers/kg.py b/r2r/base/providers/kg.py index 574472de4..9093b22b2 100644 --- a/r2r/base/providers/kg.py +++ b/r2r/base/providers/kg.py @@ -144,12 +144,14 @@ def update_kg_search_prompt( """Abstract method to update the KG agent prompt.""" pass - @abstractmethod - def create_vector_index(self, node_type: str, node_property: str, dimension: int) -> None: + def create_vector_index( + self, node_type: str, node_property: str, dimension: int + ) -> None: """Abstract method to create a vector index.""" pass + def escape_braces(s: str) -> str: """ Escape braces in a string. diff --git a/r2r/base/utils/__init__.py b/r2r/base/utils/__init__.py index 591054546..a097314a0 100644 --- a/r2r/base/utils/__init__.py +++ b/r2r/base/utils/__init__.py @@ -3,6 +3,7 @@ format_relations, generate_id_from_label, generate_run_id, + generate_user_document_id, increment_version, run_pipeline, to_async_generator, @@ -14,6 +15,7 @@ "format_relations", "generate_id_from_label", "generate_run_id", + "generate_user_document_id", "increment_version", "run_pipeline", "to_async_generator", diff --git a/r2r/base/utils/base_utils.py b/r2r/base/utils/base_utils.py index a1aa48590..8d621774d 100644 --- a/r2r/base/utils/base_utils.py +++ b/r2r/base/utils/base_utils.py @@ -1,6 +1,6 @@ import asyncio -import uuid from typing import TYPE_CHECKING, Any, AsyncGenerator, Iterable +from uuid import NAMESPACE_DNS, UUID, uuid4, uuid5 from ..abstractions.graph import EntityType, RelationshipType @@ -8,12 +8,19 @@ from ..pipeline.base_pipeline import AsyncPipeline -def generate_run_id() -> uuid.UUID: - return uuid.uuid4() +def generate_run_id() -> UUID: + return uuid5(NAMESPACE_DNS, str(uuid4())) -def generate_id_from_label(label: str) -> uuid.UUID: - return uuid.uuid5(uuid.NAMESPACE_DNS, label) +def generate_id_from_label(label: str) -> UUID: + return uuid5(NAMESPACE_DNS, label) + + +def generate_user_document_id(filename: str, user_id: UUID) -> UUID: + """ + Generates a unique document id from a given filename and user id + """ + return generate_id_from_label(f'{filename.split("/")[-1]}-{str(user_id)}') async def to_async_generator( diff --git a/r2r/cli/commands/rag_operations.py b/r2r/cli/commands/rag_operations.py index ceadf6bd1..ffed98c38 100644 --- a/r2r/cli/commands/rag_operations.py +++ b/r2r/cli/commands/rag_operations.py @@ -10,7 +10,9 @@ "--limit", default=100, help="Limit the number of relationships returned" ) @click.option( - "--print-descriptions", is_flag=True, help="Print descriptions of entities and relationships" + "--print-descriptions", + is_flag=True, + help="Print descriptions of entities and relationships", ) @click.pass_obj def inspect_knowledge_graph(obj, limit, print_descriptions): @@ -37,7 +39,11 @@ def inspect_knowledge_graph(obj, limit, print_descriptions): @click.option("--kg-search-model", default=None, help="Model for KG agent") @click.option("--stream", is_flag=True, help="Stream the RAG response") @click.option("--rag-model", default=None, help="Model for RAG") -@click.option("--kg-search-level", default=None, help="Level of cluster to use for Global KG search") +@click.option( + "--kg-search-level", + default=None, + help="Level of cluster to use for Global KG search", +) @click.option("--kg-search-type", default="global", help="Local or Global") @click.pass_obj def rag( @@ -51,7 +57,7 @@ def rag( kg_search_model, stream, rag_model, - kg_search_type, + kg_search_type, kg_search_level, ): """Perform a RAG query.""" diff --git a/r2r/configs/local_llm.toml b/r2r/configs/local_llm.toml index 4802ebd73..532e3f1bd 100644 --- a/r2r/configs/local_llm.toml +++ b/r2r/configs/local_llm.toml @@ -17,9 +17,9 @@ provider = "postgres" provider = "ollama" base_model = "mxbai-embed-large" base_dimension = 1_024 -batch_size = 32 +batch_size = 128 add_title_as_prefix = true -concurrent_request_limit = 32 +concurrent_request_limit = 2 [parsing] excluded_parsers = [ "gif", "jpeg", "jpg", "png", "svg", "mp3", "mp4" ] diff --git a/r2r/examples/scripts/advanced_kg_cookbook.py b/r2r/examples/scripts/advanced_kg_cookbook.py index 5411044c5..be52ed529 100644 --- a/r2r/examples/scripts/advanced_kg_cookbook.py +++ b/r2r/examples/scripts/advanced_kg_cookbook.py @@ -155,7 +155,11 @@ def main( continue print("Inspecting Knowledge Graph") - print(client.inspect_knowledge_graph(1000, print_descriptions=True)["results"]) + print( + client.inspect_knowledge_graph(1000, print_descriptions=True)[ + "results" + ] + ) if not local_mode: diff --git a/r2r/examples/scripts/sample_data_ingestor.py b/r2r/examples/scripts/sample_data_ingestor.py index b245a1c11..4fe9590cf 100644 --- a/r2r/examples/scripts/sample_data_ingestor.py +++ b/r2r/examples/scripts/sample_data_ingestor.py @@ -31,8 +31,8 @@ def get_sample_files(no_media: bool = True) -> list[str]: os.path.join(examples_dir, "data", "pg_essay_5.html"), os.path.join(examples_dir, "data", "lyft_2021.pdf"), os.path.join(examples_dir, "data", "uber_2021.pdf"), - # os.path.join(examples_dir, "data", "sample.mp3"), - # os.path.join(examples_dir, "data", "sample2.mp3"), + os.path.join(examples_dir, "data", "sample.mp3"), + os.path.join(examples_dir, "data", "sample2.mp3"), ] if no_media: excluded_types = ["jpeg", "jpg", "png", "svg", "mp3", "mp4"] diff --git a/r2r/main/api/client/auth.py b/r2r/main/api/client/auth.py index 151753310..5631bbd8f 100644 --- a/r2r/main/api/client/auth.py +++ b/r2r/main/api/client/auth.py @@ -1,5 +1,5 @@ -import uuid from typing import Optional +from uuid import UUID from r2r.base import Token from r2r.base.api.models.auth.responses import UserResponse @@ -90,7 +90,7 @@ async def update_user( @staticmethod async def delete_user( - client, user_id: uuid.UUID, password: Optional[str] = None + client, user_id: UUID, password: Optional[str] = None ) -> dict: data = {"user_id": str(user_id), "password": password} response = await client._make_request("DELETE", "user", json=data) diff --git a/r2r/main/api/client/ingestion.py b/r2r/main/api/client/ingestion.py index 061f410cb..cb68c47b3 100644 --- a/r2r/main/api/client/ingestion.py +++ b/r2r/main/api/client/ingestion.py @@ -1,8 +1,8 @@ import json import os -import uuid from contextlib import ExitStack -from typing import List, Optional, Union +from typing import Optional, Union +from uuid import UUID from r2r.base import ChunkingConfig @@ -12,10 +12,10 @@ class IngestionMethods: @staticmethod async def ingest_files( client, - file_paths: List[str], - metadatas: Optional[List[dict]] = None, - document_ids: Optional[List[Union[uuid.UUID, str]]] = None, - versions: Optional[List[str]] = None, + file_paths: list[str], + document_ids: Optional[list[UUID]] = None, + versions: Optional[list[str]] = None, + metadatas: Optional[list[dict]] = None, chunking_config_override: Optional[Union[dict, ChunkingConfig]] = None, ) -> dict: """ @@ -24,7 +24,7 @@ async def ingest_files( Args: file_paths (List[str]): List of file paths to ingest. metadatas (Optional[List[dict]]): List of metadata dictionaries for each file. - document_ids (Optional[List[Union[uuid.UUID, str]]]): List of document IDs. + document_ids (Optional[List[Union[UUID, str]]]): List of document IDs. versions (Optional[List[str]]): List of version strings for each file. chunking_config_override (Optional[Union[dict, ChunkingConfig]]): Custom chunking configuration. @@ -64,7 +64,7 @@ async def ingest_files( "versions": json.dumps(versions) if versions else None, "chunking_config_override": ( json.dumps( - chunking_config_override.dict() + chunking_config_override.model_dump() if isinstance(chunking_config_override, ChunkingConfig) else chunking_config_override ) @@ -72,7 +72,6 @@ async def ingest_files( else None ), } - return await client._make_request( "POST", "ingest_files", data=data, files=files ) @@ -80,9 +79,9 @@ async def ingest_files( @staticmethod async def update_files( client, - file_paths: List[str], - document_ids: List[str], - metadatas: Optional[List[dict]] = None, + file_paths: list[str], + document_ids: Optional[list[UUID]] = None, + metadatas: Optional[list[dict]] = None, chunking_config_override: Optional[Union[dict, ChunkingConfig]] = None, ) -> dict: """ @@ -90,14 +89,14 @@ async def update_files( Args: file_paths (List[str]): List of file paths to update. - document_ids (List[str]): List of document IDs to update. + document_ids (Optional[List[str]): An optional list of document IDs to update. metadatas (Optional[List[dict]]): List of updated metadata dictionaries for each file. chunking_config_override (Optional[Union[dict, ChunkingConfig]]): Custom chunking configuration. Returns: dict: Update results containing processed, failed, and skipped documents. """ - if len(file_paths) != len(document_ids): + if document_ids and len(file_paths) != len(document_ids): raise ValueError( "Number of file paths must match number of document IDs." ) @@ -116,11 +115,15 @@ async def update_files( ] data = { - "document_ids": json.dumps(document_ids), "metadatas": json.dumps(metadatas) if metadatas else None, + "document_ids": ( + json.dumps([str(doc_id) for doc_id in document_ids]) + if document_ids + else None + ), "chunking_config_override": ( json.dumps( - chunking_config_override.dict() + chunking_config_override.model_dump() if isinstance(chunking_config_override, ChunkingConfig) else chunking_config_override ) @@ -128,7 +131,6 @@ async def update_files( else None ), } - return await client._make_request( "POST", "update_files", data=data, files=files ) diff --git a/r2r/main/api/client/management.py b/r2r/main/api/client/management.py index b42bb3f13..ea80e1081 100644 --- a/r2r/main/api/client/management.py +++ b/r2r/main/api/client/management.py @@ -1,6 +1,6 @@ import json -import uuid -from typing import Any, Optional, Union +from typing import Optional, Union +from uuid import UUID from r2r.base import VectorDBFilterValue @@ -43,7 +43,7 @@ async def app_settings(client) -> dict: @staticmethod async def score_completion( client, - message_id: uuid.UUID, + message_id: UUID, score: float = 0.0, ) -> dict: data = { @@ -57,7 +57,7 @@ async def score_completion( @staticmethod async def users_overview( client, - user_ids: Optional[list[uuid.UUID]] = None, + user_ids: Optional[list[UUID]] = None, ) -> dict: params = { "user_ids": [str(uid) for uid in user_ids] if user_ids else None @@ -80,9 +80,9 @@ async def delete( @staticmethod async def documents_overview( client, - user_ids: Optional[list[uuid.UUID]] = None, - group_ids: Optional[list[uuid.UUID]] = None, - document_ids: Optional[list[uuid.UUID]] = None, + user_ids: Optional[list[UUID]] = None, + group_ids: Optional[list[UUID]] = None, + document_ids: Optional[list[UUID]] = None, ) -> dict: params = { "user_ids": [str(uid) for uid in user_ids] if user_ids else None, @@ -100,7 +100,7 @@ async def documents_overview( @staticmethod async def document_chunks( client, - document_id: uuid.UUID, + document_id: UUID, ) -> dict: return await client._make_request( "GET", "document_chunks", params={"document_id": document_id} @@ -120,7 +120,7 @@ async def inspect_knowledge_graph( async def assign_document_to_group( client, document_id: str, - group_id: uuid.UUID, + group_id: UUID, ) -> dict: data = { "document_id": document_id, @@ -134,7 +134,7 @@ async def assign_document_to_group( async def remove_document_from_group( client, document_id: str, - group_id: uuid.UUID, + group_id: UUID, ) -> dict: data = { "document_id": document_id, @@ -168,14 +168,14 @@ async def create_group( @staticmethod async def get_group( client, - group_id: uuid.UUID, + group_id: UUID, ) -> dict: return await client._make_request("GET", f"get_group/{group_id}") @staticmethod async def update_group( client, - group_id: uuid.UUID, + group_id: UUID, name: Optional[str] = None, description: Optional[str] = None, ) -> dict: @@ -189,7 +189,7 @@ async def update_group( @staticmethod async def delete_group( client, - group_id: uuid.UUID, + group_id: UUID, ) -> dict: return await client._make_request("DELETE", f"delete_group/{group_id}") @@ -208,8 +208,8 @@ async def list_groups( @staticmethod async def add_user_to_group( client, - user_id: uuid.UUID, - group_id: uuid.UUID, + user_id: UUID, + group_id: UUID, ) -> dict: data = { "user_id": str(user_id), @@ -222,8 +222,8 @@ async def add_user_to_group( @staticmethod async def remove_user_from_group( client, - user_id: uuid.UUID, - group_id: uuid.UUID, + user_id: UUID, + group_id: UUID, ) -> dict: data = { "user_id": str(user_id), @@ -236,7 +236,7 @@ async def remove_user_from_group( @staticmethod async def get_users_in_group( client, - group_id: uuid.UUID, + group_id: UUID, offset: int = 0, limit: int = 100, ) -> dict: @@ -251,7 +251,7 @@ async def get_users_in_group( @staticmethod async def get_groups_for_user( client, - user_id: uuid.UUID, + user_id: UUID, ) -> dict: return await client._make_request( "GET", f"get_groups_for_user/{user_id}" @@ -260,7 +260,7 @@ async def get_groups_for_user( @staticmethod async def groups_overview( client, - group_ids: Optional[list[uuid.UUID]] = None, + group_ids: Optional[list[UUID]] = None, limit: int = 100, offset: int = 0, ) -> dict: @@ -277,7 +277,7 @@ async def groups_overview( @staticmethod async def get_documents_in_group( client, - group_id: uuid.UUID, + group_id: UUID, offset: int = 0, limit: int = 100, ) -> dict: diff --git a/r2r/main/api/routes/auth/base.py b/r2r/main/api/routes/auth/base.py index 62a6c7285..a9a330910 100644 --- a/r2r/main/api/routes/auth/base.py +++ b/r2r/main/api/routes/auth/base.py @@ -1,5 +1,5 @@ -import uuid from typing import TYPE_CHECKING +from uuid import UUID from fastapi import Body, Depends, Path from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm @@ -204,9 +204,7 @@ async def logout_app( ) @self.base_endpoint async def delete_user_app( - user_id: uuid.UUID = Body( - ..., description="ID of the user to delete" - ), + user_id: UUID = Body(..., description="ID of the user to delete"), password: str | None = Body( None, description="User's current password" ), diff --git a/r2r/main/api/routes/base_router.py b/r2r/main/api/routes/base_router.py index 1b644c8c3..56dd9560f 100644 --- a/r2r/main/api/routes/base_router.py +++ b/r2r/main/api/routes/base_router.py @@ -1,5 +1,6 @@ import functools import logging +from abc import abstractmethod from fastapi import APIRouter, HTTPException from fastapi.responses import StreamingResponse @@ -16,6 +17,10 @@ def __init__(self, engine, run_type: RunType = RunType.UNSPECIFIED): self.run_type = run_type self.router = APIRouter() + @abstractmethod + def load_openapi_extras(self): + pass + def base_endpoint(self, func: callable): @functools.wraps(func) async def wrapper(*args, **kwargs): @@ -48,7 +53,9 @@ async def wrapper(*args, **kwargs): key="error", value=str(e), ) - logger.error(f"Error in base endpoint {func.__name__}() - \n\n{str(e)})") + logger.error( + f"Error in base endpoint {func.__name__}() - \n\n{str(e)})" + ) raise HTTPException( status_code=500, detail={ diff --git a/r2r/main/api/routes/ingestion/base.py b/r2r/main/api/routes/ingestion/base.py index 8da142dca..c2082f264 100644 --- a/r2r/main/api/routes/ingestion/base.py +++ b/r2r/main/api/routes/ingestion/base.py @@ -1,13 +1,16 @@ import json import logging -import uuid +from pathlib import Path from typing import List, Optional +from uuid import UUID +import yaml from fastapi import Depends, File, Form, UploadFile from fastapi.openapi.models import Example from r2r.base import ChunkingConfig, R2RException from r2r.base.api.models.ingestion.responses import WrappedIngestionResponse +from r2r.base.utils import generate_user_document_id from ....assembly.factory import R2RProviderFactory from ....engine import R2REngine @@ -19,143 +22,76 @@ class IngestionRouter(BaseRouter): def __init__(self, engine: R2REngine): super().__init__(engine) + self.openapi_extras = self.load_openapi_extras() self.setup_routes() - def setup_routes(self): + def load_openapi_extras(self): + yaml_path = Path(__file__).parent / "ingestion_router_openapi.yml" + with open(yaml_path, "r") as yaml_file: + yaml_content = yaml.safe_load(yaml_file) + return yaml_content + + # paths = yaml_content.get("paths", {}) + + # def extract_descriptions(endpoint): + # params = endpoint.get("requestBody", {}).get("content", {}).get("multipart/form-data", {}).get("schema", {}).get("properties", {}) + # return {k: v.get("description", "") for k, v in params.items()} + # ingest_files = paths.get("/v1/ingest_files", {}) + # # update_files = paths.get("/v1/update_files", {}).get("post", {}) + + # return { + # "ingest_files": { + # # "descriptions": extract_descriptions(ingest_files), + # # "operation": ingest_files + # }, + # # "update_files": { + # # "descriptions": extract_descriptions(update_files), + # # "operation": update_files + # # } + # } + + def setup_routes(self): # Note, we use the following verbose input parameters because FastAPI struggles to handle `File` input and `Body` inputs # at the same time. Therefore, we must ues `Form` inputs for the metadata, document_ids, and versions inputs. + ingest_files_extras = self.openapi_extras.get("ingest_files", {}) + ingest_files_descriptions = ingest_files_extras.get( + "input_descriptions", {} + ) + @self.router.post( "/ingest_files", - openapi_extra={ - "x-codeSamples": [ - { - "lang": "Python", - "source": """from r2r import R2RClient - -client = R2RClient("http://localhost:8000") -# when using auth, do client.login(...) - -result = client.ingest_files( - files=["pg_essay_1.html", "got.txt"], - metadatas=[{"metadata_1":"some random metadata"}, {"metadata_2": "some other random metadata"}], - document_ids=None, - versions=None -) -""", - }, - { - "lang": "Shell", - "source": """curl -X POST "https://api.example.com/ingest_files" \\ - -H "Content-Type: multipart/form-data" \\ - -H "Authorization: Bearer YOUR_API_KEY" \\ - -F "file=@pg_essay_1.html;type=text/html" \\ - -F "file=@got.txt;type=text/plain" \\ - -F 'metadatas=[{},{}]' \\ - -F 'document_ids=null' \\ - -F 'versions=null' -""", - }, - ] - }, - responses={ - 200: { - "description": "Successful Response", - "content": { - "application/json": { - "example": { - "results": { - "processed_documents": [ - { - "id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", - "title": "pg_essay_1.html", - }, - { - "id": "716fea3a-826b-5b27-8e59-ffbd1a35455a", - "title": "got.txt", - }, - ], - "failed_documents": [], - "skipped_documents": [], - } - } - } - }, - }, - 422: { - "description": "Validation Error", - "content": { - "application/json": { - "example": { - "detail": [ - { - "message": "All documents were already successfully processed", - "error_type": "R2RException", - } - ] - } - } - }, - }, - }, - response_model=WrappedIngestionResponse, + openapi_extra=ingest_files_extras.get("openapi_extra"), ) @self.base_endpoint async def ingest_files_app( files: List[UploadFile] = File( - ..., - description="A list of file paths to be ingested. E.g. `file1.txt`, `file2.txt`", + ..., description=ingest_files_descriptions.get("files") ), - metadatas: Optional[str] = Form( + document_ids: Optional[list[UUID]] = Form( None, - description="JSON string containing metadata for each file, e.g. `{'title': 'Document 1', 'author': 'John Doe'}`", - examples=[ - Example( - summary="Sample metadata", - description="JSON string with metadata for two documents", - value='[{"title": "Document 1", "author": "John Doe"}, {"title": "Document 2", "author": "Jane Smith"}]', - ) - ], + description=ingest_files_descriptions.get("document_ids"), ), - document_ids: Optional[str] = Form( - None, - description="Comma-separated list of document IDs, e.g. `3e157b3a-8469-51db-90d9-52e7d896b49b,223e4567-e89b-12d3-a456-426614174000`", - examples=[ - Example( - summary="Sample document IDs", - description="Comma-separated list of document IDs", - value="3e157b3a-8469-51db-90d9-52e7d896b49b,223e4567-e89b-12d3-a456-426614174000", - ) - ], + versions: Optional[list[str]] = Form( + None, description=ingest_files_descriptions.get("versions") ), - versions: Optional[str] = Form( - None, - description="Comma-separated list of versions, e.g. `1.0,1.1`", - examples=[ - Example( - summary="Sample versions", - description="Comma-separated list of versions", - value="1.0,1.1", - ) - ], + metadatas: Optional[list[dict]] = Form( + None, description=ingest_files_descriptions.get("metadatas") ), - chunking_config_override: Optional[str] = Form( + chunking_config_override: Optional[ChunkingConfig] = Form( None, - description="JSON string for chunking configuration override", - examples=[ - Example( - summary="Sample chunking config override", - description="JSON string for chunking configuration override", - value='{"chunk_size": 1000, "chunk_overlap": 200}', - ) - ], + description=ingest_files_descriptions.get( + "chunking_config_override" + ), ), auth_user=Depends(self.engine.providers.auth.auth_wrapper), - ): + ) -> WrappedIngestionResponse: """ Ingest files into the system. - This endpoint supports multipart/form-data requests, enabling you to update files along with their inside of R2R. A valid user authentication token is required to access this endpoint. Regular users can only update documents they have permission to access. + This endpoint supports multipart/form-data requests, enabling you to ingest files and their associated metadatas into R2R. + + A valid user authentication token is required to access this endpoint, as regular users can only ingest files for their own access. More expansive group permissioning is under development. """ try: parsed_data = self.parse_ingest_files_form_data( @@ -164,12 +100,13 @@ async def ingest_files_app( except R2RException as e: raise e - kwargs = {} + chunking_provider = None if chunking_config_override: - config = ChunkingConfig(**chunking_config_override) - config.validate() - kwargs["chunking_provider"] = ( - R2RProviderFactory.create_chunking_provider(config) + chunking_config_override.validate() + chunking_provider = ( + R2RProviderFactory.create_chunking_provider( + chunking_config_override + ) ) else: logger.info( @@ -206,7 +143,7 @@ async def ingest_files_app( document_ids=parsed_data["document_ids"], versions=parsed_data["versions"], user=auth_user, - **kwargs, + chunking_provider=chunking_provider, ) # If superuser, assign documents to groups @@ -223,130 +160,60 @@ async def ingest_files_app( return ingestion_result + update_files_extras = self.openapi_extras.get("update_files", {}) + update_files_descriptions = update_files_extras.get( + "input_descriptions", {} + ) + @self.router.post( "/update_files", - openapi_extra={ - "x-codeSamples": [ - { - "lang": "Python", - "source": """from r2r import R2RClient - -client = R2RClient("http://localhost:8000") -# when using auth, do client.login(...) - -result = client.update_files( - files=["pg_essay_1_v2.txt"], - document_ids=["b4ac4dd6-5f27-596e-a55b-7cf242ca30aa"] -) -""", - }, - { - "lang": "Shell", - "source": """curl -X POST "https://api.example.com/update_files" \\ - -H "Content-Type: multipart/form-data" \\ - -H "Authorization: Bearer YOUR_API_KEY" \\ - -F "file=@pg_essay_1_v2.txt;type=text/plain" \\ - -F 'document_ids=["b4ac4dd6-5f27-596e-a55b-7cf242ca30aa"]' -""", - }, - ] - }, - responses={ - 200: { - "description": "Successful Response", - "content": { - "application/json": { - "example": { - "results": { - "processed_documents": [ - { - "id": "b4ac4dd6-5f27-596e-a55b-7cf242ca30aa", - "title": "pg_essay_1_v2.html", - }, - ], - "failed_documents": [], - "skipped_documents": [], - } - } - } - }, - }, - 422: { - "description": "Validation Error", - "content": { - "application/json": { - "example": { - "detail": [ - { - "message": "Document 'b4ac4dd6-5f27-596e-a55b-7cf242ca30aa' does not exist.", - "error_type": "R2RException", - } - ] - } - } - }, - }, - }, - response_model=WrappedIngestionResponse, + openapi_extra=update_files_extras.get("openapi_extra"), ) @self.base_endpoint async def update_files_app( files: List[UploadFile] = File( - ..., - description="List of files to update", + ..., description=update_files_descriptions.get("files") ), - metadatas: Optional[str] = Form( - None, - description="JSON string containing updated metadata for each file", - examples=[ - Example( - summary="Sample updated metadata", - description="JSON string with updated metadata for two documents", - value='[{"title": "Updated Document 1", "version": "1.1"}, {"title": "Updated Document 2", "version": "1.2"}]', - ) - ], + document_ids: Optional[list[UUID]] = Form( + None, description=update_files_descriptions.get("document_ids") ), - document_ids: Optional[str] = Form( - None, - description="Comma-separated list of document IDs to update", - examples=[ - Example( - summary="Sample document IDs", - description="Comma-separated list of document IDs to update", - value="3e157b3a-8469-51db-90d9-52e7d896b49b,223e4567-e89b-12d3-a456-426614174000", - ) - ], + metadatas: Optional[list[dict]] = Form( + None, description=update_files_descriptions.get("metadatas") ), chunking_config_override: Optional[str] = Form( None, - description="JSON string for chunking configuration override", - examples=[ - Example( - summary="Sample chunking config override", - description="JSON string for chunking configuration override", - value='{"chunk_size": 1200, "chunk_overlap": 250}', - ) - ], + description=update_files_descriptions.get( + "chunking_config_override" + ), ), auth_user=Depends(self.engine.providers.auth.auth_wrapper), - ): + ) -> WrappedIngestionResponse: """ Update existing files in the system. - This endpoint supports multipart/form-data requests, enabling you to update files along with their inside of R2R. A valid user authentication token is required to access this endpoint. Regular users can only update documents they have permission to access. + This endpoint supports multipart/form-data requests, enabling you to update files and their associated metadatas into R2R. + + + + + A valid user authentication token is required to access this endpoint, as regular users can only update their own files. More expansive group permissioning is under development. """ try: parsed_data = self.parse_update_files_form_data( - metadatas, document_ids, chunking_config_override + metadatas, + document_ids, + chunking_config_override, + [file.filename for file in files], + auth_user.id, ) except R2RException as e: raise e - chunking_config_override = None + chunking_provider = None if chunking_config_override: config = ChunkingConfig(**chunking_config_override) - chunking_config_override = ( + chunking_provider = ( R2RProviderFactory.create_chunking_provider(config) ) @@ -354,7 +221,7 @@ async def update_files_app( files=files, metadatas=parsed_data["metadatas"], document_ids=parsed_data["document_ids"], - chunking_config_override=chunking_config_override, + chunking_provider=chunking_provider, user=auth_user, ) @@ -383,7 +250,7 @@ def parse_ingest_files_form_data( ) if parsed_document_ids is not None: parsed_document_ids = [ - uuid.UUID(doc_id) for doc_id in parsed_document_ids + UUID(doc_id) for doc_id in parsed_document_ids ] parsed_versions = ( @@ -418,9 +285,11 @@ def parse_ingest_files_form_data( @staticmethod def parse_update_files_form_data( - metadatas: Optional[str], - document_ids: str, + metadatas: Optional[list[dict]], + document_ids: Optional[list[UUID]], chunking_config_override: Optional[str], + filenames: list[str], + user_id: UUID, ): try: parsed_metadatas = ( @@ -433,15 +302,20 @@ def parse_update_files_form_data( ): raise ValueError("metadatas must be a list of dictionaries") - if not document_ids or document_ids == "null": - raise ValueError("document_ids is required and cannot be null") - - parsed_document_ids = json.loads(document_ids) - if not isinstance(parsed_document_ids, list): - raise ValueError("document_ids must be a list") - parsed_document_ids = [ - uuid.UUID(doc_id) for doc_id in parsed_document_ids - ] + parsed_document_ids = ( + json.loads(document_ids) + if document_ids and document_ids != "null" + else None + ) + if parsed_document_ids is not None: + parsed_document_ids = [ + UUID(doc_id) for doc_id in parsed_document_ids + ] + else: + parsed_document_ids = [ + generate_user_document_id(filename, user_id) + for filename in filenames + ] parsed_chunking_config = ( json.loads(chunking_config_override) diff --git a/r2r/main/api/routes/ingestion/ingestion_router_openapi.yml b/r2r/main/api/routes/ingestion/ingestion_router_openapi.yml new file mode 100644 index 000000000..31e81c784 --- /dev/null +++ b/r2r/main/api/routes/ingestion/ingestion_router_openapi.yml @@ -0,0 +1,61 @@ +ingest_files: + openapi_extra: + x-codeSamples: + - lang: Python + source: | + from r2r import R2RClient + + client = R2RClient("http://localhost:8000") + # when using auth, do client.login(...) + + result = client.ingest_files( + files=["pg_essay_1.html", "got.txt"], + metadatas=[{"metadata_1":"some random metadata"}, {"metadata_2": "some other random metadata"}], + document_ids=None, + versions=None + ) + - lang: Shell + source: | + curl -X POST "https://api.example.com/ingest_files" \ + -H "Content-Type: multipart/form-data" \ + -H "Authorization: Bearer YOUR_API_KEY" \ + -F "file=@pg_essay_1.html;type=text/html" \ + -F "file=@got.txt;type=text/plain" \ + -F 'metadatas=[{},{}]' \ + -F 'document_ids=null' \ + -F 'versions=null' + + input_descriptions: + files: "The list of paths of input files to ingest into the system." + metadatas: "An optional list of JSON metadata to affix to each file" + document_ids: "An optional list of document ids for each file. If not provided, the system will generate a unique document id via the `generate_user_document_id` method." + versions: "An optional list of versions for each file. If not provided, the system will default to the tag `v1`." + chunking_config_override: "An optional dictionary to override the default chunking configuration for the ingestion process. If not provided, the system will use the default server-side chunking configuration." + +update_files: + openapi_extra: + x-codeSamples: + - lang: Python + source: | + from r2r import R2RClient + + client = R2RClient("http://localhost:8000") + # when using auth, do client.login(...) + + result = client.update_files( + files=["pg_essay_1_v2.txt"], + document_ids=["b4ac4dd6-5f27-596e-a55b-7cf242ca30aa"] + ) + - lang: Shell + source: | + curl -X POST "https://api.example.com/update_files" \ + -H "Content-Type: multipart/form-data" \ + -H "Authorization: Bearer YOUR_API_KEY" \ + -F "file=@pg_essay_1_v2.txt;type=text/plain" \ + -F 'document_ids=["b4ac4dd6-5f27-596e-a55b-7cf242ca30aa"]' + + input_descriptions: + files: "The list of paths of input files to update in the system." + document_ids: "An optional list of document ids for each file. If not provided, the system will attempt to generate the corresponding unique from the `generate_user_document_id` method." + metadatas: "An optional list of JSON metadata to affix to each file" + chunking_config_override: "JSON string for chunking configuration override" diff --git a/r2r/main/api/routes/management/base.py b/r2r/main/api/routes/management/base.py index 8b1435991..aa4176357 100644 --- a/r2r/main/api/routes/management/base.py +++ b/r2r/main/api/routes/management/base.py @@ -1,8 +1,8 @@ # TODO - Cleanup the handling for non-auth configurations import json -import uuid from datetime import datetime, timezone from typing import Optional +from uuid import UUID import psutil from fastapi import Body, Depends, Path, Query @@ -147,7 +147,7 @@ async def delete_app( @self.router.get("/document_chunks") @self.base_endpoint async def document_chunks_app( - document_id: uuid.UUID = Query(...), + document_id: UUID = Query(...), auth_user=Depends(self.engine.providers.auth.auth_wrapper), ) -> WrappedDocumentChunkResponse: chunks = await self.engine.adocument_chunks(document_id) @@ -171,7 +171,7 @@ async def document_chunks_app( @self.router.get("/users_overview") @self.base_endpoint async def users_overview_app( - user_ids: list[uuid.UUID] = Query([]), + user_ids: list[UUID] = Query([]), auth_user=Depends(self.engine.providers.auth.auth_wrapper), ) -> WrappedUserOverviewResponse: if not auth_user.is_superuser: @@ -185,7 +185,7 @@ async def users_overview_app( @self.router.get("/documents_overview") @self.base_endpoint async def documents_overview_app( - document_id: list[uuid.UUID] = Query([]), + document_id: list[UUID] = Query([]), auth_user=Depends(self.engine.providers.auth.auth_wrapper), ) -> WrappedDocumentOverviewResponse: request_user_ids = ( @@ -238,7 +238,7 @@ async def create_group_app( @self.router.get("/get_group/{group_id}") @self.base_endpoint async def get_group_app( - group_id: uuid.UUID = Path(..., description="Group ID"), + group_id: UUID = Path(..., description="Group ID"), auth_user=Depends(self.engine.providers.auth.auth_wrapper), ) -> WrappedGroupResponse: if not auth_user.is_superuser: @@ -252,7 +252,7 @@ async def get_group_app( @self.router.put("/update_group") @self.base_endpoint async def update_group_app( - group_id: uuid.UUID = Body(..., description="Group ID"), + group_id: UUID = Body(..., description="Group ID"), name: Optional[str] = Body(None, description="Updated group name"), description: Optional[str] = Body( None, description="Updated group description" @@ -266,7 +266,7 @@ async def update_group_app( @self.router.delete("/delete_group/{group_id}") @self.base_endpoint async def delete_group_app( - group_id: uuid.UUID = Path(..., description="Group ID"), + group_id: UUID = Path(..., description="Group ID"), auth_user=Depends(self.engine.providers.auth.auth_wrapper), ) -> WrappedGroupResponse: if not auth_user.is_superuser: @@ -289,8 +289,8 @@ async def list_groups_app( @self.router.post("/add_user_to_group") @self.base_endpoint async def add_user_to_group_app( - user_id: uuid.UUID = Body(..., description="User ID"), - group_id: uuid.UUID = Body(..., description="Group ID"), + user_id: UUID = Body(..., description="User ID"), + group_id: UUID = Body(..., description="Group ID"), auth_user=Depends(self.engine.providers.auth.auth_wrapper), ) -> WrappedAddUserResponse: if not auth_user.is_superuser: @@ -303,8 +303,8 @@ async def add_user_to_group_app( @self.router.post("/remove_user_from_group") @self.base_endpoint async def remove_user_from_group_app( - user_id: uuid.UUID = Body(..., description="User ID"), - group_id: uuid.UUID = Body(..., description="Group ID"), + user_id: UUID = Body(..., description="User ID"), + group_id: UUID = Body(..., description="Group ID"), auth_user=Depends(self.engine.providers.auth.auth_wrapper), ) -> WrappedGroupResponse: if not auth_user.is_superuser: @@ -317,7 +317,7 @@ async def remove_user_from_group_app( @self.router.get("/get_users_in_group/{group_id}") @self.base_endpoint async def get_users_in_group_app( - group_id: uuid.UUID = Path(..., description="Group ID"), + group_id: UUID = Path(..., description="Group ID"), offset: int = Query(..., description="Offset"), limit: int = Query(..., description="limit"), auth_user=Depends(self.engine.providers.auth.auth_wrapper), @@ -333,7 +333,7 @@ async def get_users_in_group_app( @self.router.get("/get_groups_for_user/{user_id}") @self.base_endpoint async def get_groups_for_user_app( - user_id: uuid.UUID = Path(..., description="User ID"), + user_id: UUID = Path(..., description="User ID"), auth_user=Depends(self.engine.providers.auth.auth_wrapper), ) -> WrappedGroupListResponse: if not auth_user.is_superuser and auth_user.id != user_id: @@ -346,7 +346,7 @@ async def get_groups_for_user_app( @self.router.get("/groups_overview") @self.base_endpoint async def groups_overview_app( - group_ids: Optional[list[uuid.UUID]] = Query(None), + group_ids: Optional[list[UUID]] = Query(None), limit: Optional[int] = Query(100, ge=1, le=1000), offset: Optional[int] = Query(0, ge=0), auth_user=Depends(self.engine.providers.auth.auth_wrapper), @@ -365,7 +365,7 @@ async def groups_overview_app( @self.router.post("/score_completion") @self.base_endpoint async def score_completion( - message_id: uuid.UUID = Body(..., description="Message ID"), + message_id: UUID = Body(..., description="Message ID"), score: float = Body(..., description="Completion score"), auth_user=Depends(self.engine.providers.auth.auth_wrapper), ) -> WrappedScoreCompletionResponse: @@ -377,7 +377,7 @@ async def score_completion( @self.base_endpoint async def assign_document_to_group_app( document_id: str = Body(..., description="Document ID"), - group_id: uuid.UUID = Body(..., description="Group ID"), + group_id: UUID = Body(..., description="Group ID"), auth_user=Depends(self.engine.providers.auth.auth_wrapper), ) -> WrappedGroupResponse: if not auth_user.is_superuser: @@ -392,7 +392,7 @@ async def assign_document_to_group_app( @self.base_endpoint async def remove_document_from_group_app( document_id: str = Body(..., description="Document ID"), - group_id: uuid.UUID = Body(..., description="Group ID"), + group_id: UUID = Body(..., description="Group ID"), auth_user=Depends(self.engine.providers.auth.auth_wrapper), ) -> WrappedGroupResponse: if not auth_user.is_superuser: @@ -414,7 +414,7 @@ async def get_document_groups_app( @self.router.get("/group/{group_id}/documents") @self.base_endpoint async def get_documents_in_group_app( - group_id: uuid.UUID = Path(..., description="Group ID"), + group_id: UUID = Path(..., description="Group ID"), offset: int = Query(0, ge=0), limit: int = Query(100, ge=1, le=1000), auth_user=Depends(self.engine.providers.auth.auth_wrapper), @@ -431,7 +431,7 @@ async def get_documents_in_group_app( @self.base_endpoint async def assign_document_to_group_app( document_id: str = Body(..., description="Document ID"), - group_id: uuid.UUID = Body(..., description="Group ID"), + group_id: UUID = Body(..., description="Group ID"), auth_user=Depends(self.engine.providers.auth.auth_wrapper), ) -> WrappedGroupResponse: if not auth_user.is_superuser: @@ -446,7 +446,7 @@ async def assign_document_to_group_app( @self.base_endpoint async def remove_document_from_group_app( document_id: str = Body(..., description="Document ID"), - group_id: uuid.UUID = Body(..., description="Group ID"), + group_id: UUID = Body(..., description="Group ID"), auth_user=Depends(self.engine.providers.auth.auth_wrapper), ) -> WrappedGroupResponse: if not auth_user.is_superuser: diff --git a/r2r/main/assembly/factory.py b/r2r/main/assembly/factory.py index 19de04241..3f6971110 100644 --- a/r2r/main/assembly/factory.py +++ b/r2r/main/assembly/factory.py @@ -559,7 +559,9 @@ def create_rag_pipeline( rag_pipeline.add_pipe(rag_pipe) return rag_pipeline - def create_kg_enrichment_pipeline(self, *args, **kwargs) -> KGEnrichmentPipeline: + def create_kg_enrichment_pipeline( + self, *args, **kwargs + ) -> KGEnrichmentPipeline: kg_enrichment_pipeline = KGEnrichmentPipeline() kg_enrichment_pipeline.add_pipe(self.pipes.kg_node_extraction_pipe) kg_enrichment_pipeline.add_pipe(self.pipes.kg_node_description_pipe) diff --git a/r2r/main/execution.py b/r2r/main/execution.py index b1633fe79..74045d4c9 100644 --- a/r2r/main/execution.py +++ b/r2r/main/execution.py @@ -4,8 +4,8 @@ import os import threading import time -import uuid from typing import Any, Dict, Optional, Union +from uuid import UUID import click from fastapi import UploadFile @@ -111,7 +111,7 @@ def ingest_files( self, file_paths: list[str], metadatas: Optional[list[dict]] = None, - document_ids: Optional[list[Union[uuid.UUID, str]]] = None, + document_ids: Optional[list[Union[UUID, str]]] = None, versions: Optional[list[str]] = None, ): if isinstance(file_paths, str): @@ -395,7 +395,7 @@ def logs( return self.app.logs(run_type_filter, max_runs) def document_chunks(self, document_id: str): - doc_uuid = uuid.UUID(document_id) + doc_uuid = UUID(document_id) if self.client_mode: return self.client.document_chunks(doc_uuid)["results"] else: @@ -407,7 +407,7 @@ def app_settings(self): else: return self.app.app_settings() - def users_overview(self, user_ids: Optional[list[uuid.UUID]] = None): + def users_overview(self, user_ids: Optional[list[UUID]] = None): if self.client_mode: return self.client.users_overview(user_ids)["results"] else: @@ -450,11 +450,17 @@ def ingest_sample_files(self, no_media: bool = True): sample_ingestor = SampleDataIngestor(self) return sample_ingestor.ingest_sample_files(no_media=no_media) - def inspect_knowledge_graph(self, limit: int = 100, print_descriptions: bool = False) -> str: + def inspect_knowledge_graph( + self, limit: int = 100, print_descriptions: bool = False + ) -> str: if self.client_mode: - return self.client.inspect_knowledge_graph(limit, print_descriptions)["results"] + return self.client.inspect_knowledge_graph( + limit, print_descriptions + )["results"] else: - return self.engine.inspect_knowledge_graph(limit, print_descriptions) + return self.engine.inspect_knowledge_graph( + limit, print_descriptions + ) def health(self) -> str: if self.client_mode: diff --git a/r2r/main/services/auth_service.py b/r2r/main/services/auth_service.py index f99941478..1677ce8f8 100644 --- a/r2r/main/services/auth_service.py +++ b/r2r/main/services/auth_service.py @@ -1,6 +1,6 @@ -import uuid from datetime import datetime from typing import Optional +from uuid import UUID from r2r.base import R2RException, RunLoggingSingleton, RunManager, Token from r2r.base.api.models.auth.responses import UserResponse @@ -109,7 +109,7 @@ async def logout(self, token: str) -> dict[str, str]: @telemetry_event("UpdateUserProfile") async def update_user( self, - user_id: uuid.UUID, + user_id: UUID, email: Optional[str] = None, name: Optional[str] = None, bio: Optional[str] = None, @@ -131,7 +131,7 @@ async def update_user( @telemetry_event("DeleteUserAccount") async def delete_user( self, - user_id: uuid.UUID, + user_id: UUID, password: Optional[str] = None, is_superuser: bool = False, ) -> dict[str, str]: diff --git a/r2r/main/services/ingestion_service.py b/r2r/main/services/ingestion_service.py index da58d8b5a..71e5c0f28 100644 --- a/r2r/main/services/ingestion_service.py +++ b/r2r/main/services/ingestion_service.py @@ -1,8 +1,8 @@ import logging -import uuid from collections import defaultdict from datetime import datetime from typing import Any, Optional +from uuid import UUID from fastapi import UploadFile @@ -14,11 +14,12 @@ R2RException, RunLoggingSingleton, RunManager, - generate_id_from_label, + generate_user_document_id, increment_version, to_async_generator, ) from r2r.base.api.models import IngestionResponse +from r2r.base.providers import ChunkingProvider from r2r.telemetry.telemetry_decorator import telemetry_event from ...base.api.models.auth.responses import UserResponse @@ -49,37 +50,161 @@ def __init__( logging_connection, ) - def _file_to_document( + @telemetry_event("IngestFiles") + async def ingest_files( self, - file: UploadFile, + files: list[UploadFile], user: UserResponse, - document_id: uuid.UUID, - metadata: dict, - ) -> Document: - file_extension = file.filename.split(".")[-1].lower() - if file_extension.upper() not in DocumentType.__members__: + metadatas: Optional[list[dict]] = None, + document_ids: Optional[list[UUID]] = None, + versions: Optional[list[str]] = None, + chunking_provider: Optional[ChunkingProvider] = None, + *args: Any, + **kwargs: Any, + ) -> IngestionResponse: + if not files: raise R2RException( - status_code=415, - message=f"'{file_extension}' is not a valid DocumentType.", + status_code=400, message="No files provided for ingestion." ) - document_title = metadata.get("title") or file.filename.split("/")[-1] - metadata["title"] = document_title + try: + documents = [] + for iteration, file in enumerate(files): + if not file.filename: + raise R2RException( + status_code=400, message="File name not provided." + ) - return Document( - id=document_id, - group_ids=metadata.get("group_ids", []), - user_id=user.id, - type=DocumentType[file_extension.upper()], - data=file.file.read(), - metadata=metadata, - ) + document_metadata = metadatas[iteration] if metadatas else {} + + # document id is dynamically generated from the filename and user id, unless explicitly provided + document_id = ( + document_ids[iteration] + if document_ids + else generate_user_document_id(file.filename, user.id) + ) + document = self._file_to_document( + file, user, document_id, document_metadata + ) + documents.append(document) + # ingests all documents in parallel + return await self.ingest_documents( + documents, + versions, + user=user, + chunking_provider=chunking_provider, + *args, + **kwargs, + ) + + finally: + for file in files: + file.file.close() + + @telemetry_event("UpdateFiles") + async def update_files( + self, + files: list[UploadFile], + user: UserResponse, + document_ids: list[UUID], + metadatas: Optional[list[dict]] = None, + chunking_provider: Optional[ChunkingProvider] = None, + *args: Any, + **kwargs: Any, + ) -> IngestionResponse: + if not files: + raise R2RException( + status_code=400, message="No files provided for update." + ) + if not self.providers.database: + raise R2RException( + status_code=501, + message="Database provider is not available for updating documents.", + ) + try: + if len(document_ids) != len(files): + raise R2RException( + status_code=400, + message="Number of ids does not match number of files.", + ) + + # Only superusers can modify arbitrary document ids, which this gate guarantees in conjuction with the check that follows + documents_overview = ( + ( + self.providers.database.relational.get_documents_overview( + filter_document_ids=document_ids, + ) + ) + if user.is_superuser + else self.providers.database.relational.get_documents_overview( + filter_document_ids=document_ids, filter_user_ids=[user.id] + ) + ) + + if len(documents_overview) != len(files): + raise R2RException( + status_code=404, + message="One or more documents was not found.", + ) + + documents = [] + new_versions = [] + + for it, (file, doc_id, doc_info) in enumerate( + zip(files, document_ids, documents_overview) + ): + if not doc_info: + raise R2RException( + status_code=404, + message=f"Document with id {doc_id} not found.", + ) + + new_version = increment_version(doc_info.version) + new_versions.append(new_version) + + updated_metadata = ( + metadatas[it] if metadatas else doc_info.metadata + ) + updated_metadata["title"] = ( + updated_metadata.get("title", None) + or file.filename.split("/")[-1] + ) + + document = self._file_to_document( + file, user, doc_id, updated_metadata + ) + documents.append(document) + + ingestion_results = await self.ingest_documents( + documents, + versions=new_versions, + chunking_provider=chunking_provider, + *args, + **kwargs, + ) + + for doc_id, old_version in zip( + document_ids, + [doc_info.version for doc_info in documents_overview], + ): + self.providers.database.vector.delete( + filters={"document_id": {"$eq": doc_id}} + ) + self.providers.database.relational.delete_from_documents_overview( + doc_id, old_version + ) + + return ingestion_results + + finally: + for file in files: + file.file.close() - @telemetry_event("IngestDocuments") async def ingest_documents( self, documents: list[Document], versions: Optional[list[str]] = None, + chunking_provider: Optional[ChunkingProvider] = None, *args: Any, **kwargs: Any, ): @@ -88,7 +213,6 @@ async def ingest_documents( status_code=400, message="No documents provided for ingestion." ) - chunking_provider = kwargs.get("chunking_provider") if chunking_provider is None: logger.info("No chunking provider specified. Using default.") else: @@ -212,162 +336,37 @@ async def ingest_documents( **kwargs, ) - # enrich using graphrag - # get triples from the graph - - # self.graph_rag = True - # if self.graph_rag: - - # graphrag_results = await self.pipelines.kg_cluster_pipeline.run( - # input = to_async_generator() - # ) - return await self._process_ingestion_results( ingestion_results, document_infos, skipped_documents, ) - @telemetry_event("IngestFiles") - async def ingest_files( - self, - files: list[UploadFile], - user: UserResponse, - metadatas: Optional[list[dict]] = None, - document_ids: Optional[list[uuid.UUID]] = None, - versions: Optional[list[str]] = None, - *args: Any, - **kwargs: Any, - ) -> IngestionResponse: - if not files: - raise R2RException( - status_code=400, message="No files provided for ingestion." - ) - - try: - documents = [] - for iteration, file in enumerate(files): - if not file.filename: - raise R2RException( - status_code=400, message="File name not provided." - ) - - document_metadata = metadatas[iteration] if metadatas else {} - - id_label = f'{file.filename.split("/")[-1]}-{user.id}' - - document_id = ( - document_ids[iteration] - if document_ids - else generate_id_from_label(id_label) - ) - - print("user.id = ", user.id) - print("document_id = ", document_id) - - document = self._file_to_document( - file, user, document_id, document_metadata - ) - documents.append(document) - return await self.ingest_documents( - documents, - versions, - user=user, - *args, - **kwargs, - ) - - finally: - for file in files: - file.file.close() - - @telemetry_event("UpdateFiles") - async def update_files( + def _file_to_document( self, - files: list[UploadFile], - document_ids: list[uuid.UUID], + file: UploadFile, user: UserResponse, - metadatas: Optional[list[dict]] = None, - *args: Any, - **kwargs: Any, - ) -> IngestionResponse: - print("UpdateFiles") - if not files: - raise R2RException( - status_code=400, message="No files provided for update." - ) - if not self.providers.database: + document_id: UUID, + metadata: dict, + ) -> Document: + file_extension = file.filename.split(".")[-1].lower() + if file_extension.upper() not in DocumentType.__members__: raise R2RException( - status_code=501, - message="Database provider is not available for updating documents.", - ) - try: - if len(document_ids) != len(files): - raise R2RException( - status_code=400, - message="Number of ids does not match number of files.", - ) - - documents_overview = ( - self.providers.database.relational.get_documents_overview( - filter_document_ids=document_ids - ) - ) - - if len(documents_overview) != len(files): - raise R2RException( - status_code=404, - message="One or more documents was not found.", - ) - - documents = [] - new_versions = [] - - for it, (file, doc_id, doc_info) in enumerate( - zip(files, document_ids, documents_overview) - ): - if not doc_info: - raise R2RException( - status_code=404, - message=f"Document with id {doc_id} not found.", - ) - - new_version = increment_version(doc_info.version) - new_versions.append(new_version) - - updated_metadata = ( - metadatas[it] if metadatas else doc_info.metadata - ) - updated_metadata["title"] = ( - updated_metadata.get("title", None) - or file.filename.split("/")[-1] - ) - - document = self._file_to_document( - file, user, doc_id, updated_metadata - ) - documents.append(document) - - ingestion_results = await self.ingest_documents( - documents, versions=new_versions, *args, **kwargs + status_code=415, + message=f"'{file_extension}' is not a valid DocumentType.", ) - for doc_id, old_version in zip( - document_ids, - [doc_info.version for doc_info in documents_overview], - ): - self.providers.database.vector.delete( - filters={"document_id": {"$eq": doc_id}} - ) - self.providers.database.relational.delete_from_documents_overview( - doc_id, old_version - ) - - return ingestion_results + document_title = metadata.get("title") or file.filename.split("/")[-1] + metadata["title"] = document_title - finally: - for file in files: - file.file.close() + return Document( + id=document_id, + group_ids=metadata.get("group_ids", []), + user_id=user.id, + type=DocumentType[file_extension.upper()], + data=file.file.read(), + metadata=metadata, + ) async def _process_ingestion_results( self, @@ -407,7 +406,9 @@ async def _process_ingestion_results( self.providers.database.relational.upsert_documents_overview( documents_to_upsert ) - # TODO - modify ingestion service so that at end we write out number of vectors produced or the error message + + # TODO - modify ingestion service so that at end we write out number + # of vectors produced or the error message to document info # THEN, return updated document infos here results = { "processed_documents": [ diff --git a/r2r/main/services/management_service.py b/r2r/main/services/management_service.py index 3dadf255c..462d3cd2f 100644 --- a/r2r/main/services/management_service.py +++ b/r2r/main/services/management_service.py @@ -1,8 +1,10 @@ import json import logging -import uuid from collections import defaultdict from typing import Any, Dict, List, Optional, Tuple +from uuid import UUID + +import toml from r2r.base import ( AnalysisTypes, @@ -189,7 +191,7 @@ async def aapp_settings(self, *args: Any, **kwargs: Any): @telemetry_event("ScoreCompletion") async def ascore_completion( self, - message_id: uuid.UUID, + message_id: UUID, score: float = 0.0, run_type_filter: str = None, max_runs: int = 100, @@ -238,7 +240,7 @@ async def ascore_completion( @telemetry_event("UsersOverview") async def ausers_overview( self, - user_ids: Optional[list[uuid.UUID]] = None, + user_ids: Optional[list[UUID]] = None, *args, **kwargs, ): @@ -286,9 +288,9 @@ async def delete( @telemetry_event("DocumentsOverview") async def adocuments_overview( self, - user_ids: Optional[list[uuid.UUID]] = None, - group_ids: Optional[list[uuid.UUID]] = None, - document_ids: Optional[list[uuid.UUID]] = None, + user_ids: Optional[list[UUID]] = None, + group_ids: Optional[list[UUID]] = None, + document_ids: Optional[list[UUID]] = None, *args: Any, **kwargs: Any, ): @@ -301,7 +303,7 @@ async def adocuments_overview( @telemetry_event("DocumentChunks") async def document_chunks( self, - document_id: uuid.UUID, + document_id: UUID, *args, **kwargs, ): @@ -310,7 +312,7 @@ async def document_chunks( @telemetry_event("UsersOverview") async def users_overview( self, - user_ids: Optional[list[uuid.UUID]], + user_ids: Optional[list[UUID]], *args, **kwargs, ): @@ -320,7 +322,11 @@ async def users_overview( @telemetry_event("InspectKnowledgeGraph") async def inspect_knowledge_graph( - self, limit=10000, print_descriptions: bool = False, *args: Any, **kwargs: Any + self, + limit=10000, + print_descriptions: bool = False, + *args: Any, + **kwargs: Any, ): if self.providers.kg is None: raise R2RException( @@ -334,20 +340,23 @@ async def inspect_knowledge_graph( """ try: - neo4j_results = self.providers.kg.structured_query(rel_query).records - - relationships_raw = [{ - "subject": { - "name": record["subject"], - "description": record["subject_description"], - }, - "relation": { - "name": record["relation"], - "description": record["relation_description"], - }, - "object": { - "name": record["object"], - "description": record["object_description"], + neo4j_results = self.providers.kg.structured_query( + rel_query + ).records + + relationships_raw = [ + { + "subject": { + "name": record["subject"], + "description": record["subject_description"], + }, + "relation": { + "name": record["relation"], + "description": record["relation_description"], + }, + "object": { + "name": record["object"], + "description": record["object_description"], }, } for record in neo4j_results @@ -356,10 +365,22 @@ async def inspect_knowledge_graph( descriptions_dict = {} relationships = [] for relationship in relationships_raw: - descriptions_dict[relationship["subject"]["name"]] = relationship["subject"]["description"] - descriptions_dict[relationship["object"]["name"]] = relationship["object"]["description"] - descriptions_dict[relationship["relation"]["name"]] = relationship["relation"]["description"] - relationships.append((relationship["subject"]["name"], relationship["relation"]["name"], relationship["object"]["name"])) + descriptions_dict[relationship["subject"]["name"]] = ( + relationship["subject"]["description"] + ) + descriptions_dict[relationship["object"]["name"]] = ( + relationship["object"]["description"] + ) + descriptions_dict[relationship["relation"]["name"]] = ( + relationship["relation"]["description"] + ) + relationships.append( + ( + relationship["subject"]["name"], + relationship["relation"]["name"], + relationship["object"]["name"], + ) + ) # Create graph representation and group relationships graph, grouped_relationships = self.process_relationships( @@ -367,7 +388,12 @@ async def inspect_knowledge_graph( ) # Generate output - output = self.generate_output(grouped_relationships, graph, descriptions_dict, print_descriptions) + output = self.generate_output( + grouped_relationships, + graph, + descriptions_dict, + print_descriptions, + ) return "\n".join(output) @@ -380,7 +406,7 @@ async def inspect_knowledge_graph( @telemetry_event("AssignDocumentToGroup") async def aassign_document_to_group( - self, document_id: str, group_id: uuid.UUID + self, document_id: str, group_id: UUID ): success = self.providers.database.vector.assign_document_to_group( @@ -396,7 +422,7 @@ async def aassign_document_to_group( @telemetry_event("RemoveDocumentFromGroup") async def aremove_document_from_group( - self, document_id: str, group_id: uuid.UUID + self, document_id: str, group_id: UUID ): success = self.providers.database.vector.remove_document_from_group( document_id, group_id @@ -431,8 +457,8 @@ def generate_output( self, grouped_relationships: Dict[str, Dict[str, List[str]]], graph: Dict[str, List[str]], - descriptions_dict: Dict[str, str], - print_descriptions: bool = True + descriptions_dict: Dict[str, str], + print_descriptions: bool = True, ) -> List[str]: output = [] # Print grouped relationships @@ -515,27 +541,25 @@ async def app_settings( } @telemetry_event("CreateGroup") - async def acreate_group( - self, name: str, description: str = "" - ) -> uuid.UUID: + async def acreate_group(self, name: str, description: str = "") -> UUID: return self.providers.database.relational.create_group( name, description ) @telemetry_event("GetGroup") - async def aget_group(self, group_id: uuid.UUID) -> Optional[dict]: + async def aget_group(self, group_id: UUID) -> Optional[dict]: return self.providers.database.relational.get_group(group_id) @telemetry_event("UpdateGroup") async def aupdate_group( - self, group_id: uuid.UUID, name: str = None, description: str = None + self, group_id: UUID, name: str = None, description: str = None ) -> bool: return self.providers.database.relational.update_group( group_id, name, description ) @telemetry_event("DeleteGroup") - async def adelete_group(self, group_id: uuid.UUID) -> bool: + async def adelete_group(self, group_id: UUID) -> bool: return self.providers.database.relational.delete_group(group_id) @telemetry_event("ListGroups") @@ -547,16 +571,14 @@ async def alist_groups( ) @telemetry_event("AddUserToGroup") - async def aadd_user_to_group( - self, user_id: uuid.UUID, group_id: uuid.UUID - ) -> bool: + async def aadd_user_to_group(self, user_id: UUID, group_id: UUID) -> bool: return self.providers.database.relational.add_user_to_group( user_id, group_id ) @telemetry_event("RemoveUserFromGroup") async def aremove_user_from_group( - self, user_id: uuid.UUID, group_id: uuid.UUID + self, user_id: UUID, group_id: UUID ) -> bool: return self.providers.database.relational.remove_user_from_group( user_id, group_id @@ -564,20 +586,20 @@ async def aremove_user_from_group( @telemetry_event("GetUsersInGroup") async def aget_users_in_group( - self, group_id: uuid.UUID, offset: int = 0, limit: int = 100 + self, group_id: UUID, offset: int = 0, limit: int = 100 ) -> list[dict]: return self.providers.database.relational.get_users_in_group( group_id, offset, limit ) @telemetry_event("GetGroupsForUser") - async def aget_groups_for_user(self, user_id: uuid.UUID) -> list[dict]: + async def aget_groups_for_user(self, user_id: UUID) -> list[dict]: return self.providers.database.relational.get_groups_for_user(user_id) @telemetry_event("GroupsOverview") async def agroups_overview( self, - group_ids: Optional[list[uuid.UUID]] = None, + group_ids: Optional[list[UUID]] = None, offset: int = 0, limit: int = 100, *args, @@ -591,7 +613,7 @@ async def agroups_overview( @telemetry_event("GetDocumentsInGroup") async def aget_documents_in_group( - self, group_id: uuid.UUID, offset: int = 0, limit: int = 100 + self, group_id: UUID, offset: int = 0, limit: int = 100 ) -> list[dict]: return self.providers.database.relational.get_documents_in_group( group_id, offset, limit diff --git a/r2r/main/services/retrieval_service.py b/r2r/main/services/retrieval_service.py index ca75d9c27..5b50de002 100644 --- a/r2r/main/services/retrieval_service.py +++ b/r2r/main/services/retrieval_service.py @@ -1,8 +1,8 @@ import logging import time -import uuid from datetime import datetime from typing import Optional +from uuid import UUID from r2r.base import ( CompletionRecord, @@ -81,7 +81,7 @@ async def search( # TODO - Remove these transforms once we have a better way to handle this for filter, value in vector_search_settings.filters.items(): - if isinstance(value, uuid.UUID): + if isinstance(value, UUID): vector_search_settings.filters[filter] = str(value) results = await self.pipelines.search_pipeline.run( @@ -122,7 +122,7 @@ async def rag( filter, value, ) in vector_search_settings.filters.items(): - if isinstance(value, uuid.UUID): + if isinstance(value, UUID): vector_search_settings.filters[filter] = str(value) completion_start_time = datetime.now() @@ -253,7 +253,7 @@ async def agent( filter, value, ) in vector_search_settings.filters.items(): - if isinstance(value, uuid.UUID): + if isinstance(value, UUID): vector_search_settings.filters[filter] = str(value) if rag_generation_config.stream: diff --git a/r2r/pipelines/ingestion_pipeline.py b/r2r/pipelines/ingestion_pipeline.py index e6351750f..5a1fe42e7 100644 --- a/r2r/pipelines/ingestion_pipeline.py +++ b/r2r/pipelines/ingestion_pipeline.py @@ -161,4 +161,4 @@ def add_pipe( pipe, add_upstream_outputs, *args, **kwargs ) else: - raise ValueError("Pipe must be a parsing, embedding, or KG pipe") \ No newline at end of file + raise ValueError("Pipe must be a parsing, embedding, or KG pipe") diff --git a/r2r/pipes/abstractions/generator_pipe.py b/r2r/pipes/abstractions/generator_pipe.py index 1237948e9..38d2aafa8 100644 --- a/r2r/pipes/abstractions/generator_pipe.py +++ b/r2r/pipes/abstractions/generator_pipe.py @@ -1,6 +1,6 @@ -import uuid from abc import abstractmethod from typing import Any, AsyncGenerator, Optional +from uuid import UUID from r2r.base import ( AsyncState, @@ -44,7 +44,7 @@ async def _run_logic( self, input: AsyncPipe.Input, state: AsyncState, - run_id: uuid.UUID, + run_id: UUID, rag_generation_config: GenerationConfig, *args: Any, **kwargs: Any, diff --git a/r2r/pipes/abstractions/search_pipe.py b/r2r/pipes/abstractions/search_pipe.py index 2f6d2d8c0..76f0b23bb 100644 --- a/r2r/pipes/abstractions/search_pipe.py +++ b/r2r/pipes/abstractions/search_pipe.py @@ -1,7 +1,7 @@ import logging -import uuid from abc import abstractmethod from typing import Any, AsyncGenerator, Optional, Union +from uuid import UUID from r2r.base import ( AsyncPipe, @@ -55,7 +55,7 @@ async def _run_logic( self, input: Input, state: AsyncState, - run_id: uuid.UUID, + run_id: UUID, *args: Any, **kwargs, ) -> AsyncGenerator[VectorSearchResult, None]: diff --git a/r2r/pipes/ingestion/embedding_pipe.py b/r2r/pipes/ingestion/embedding_pipe.py index 19890091f..013c3a5fa 100644 --- a/r2r/pipes/ingestion/embedding_pipe.py +++ b/r2r/pipes/ingestion/embedding_pipe.py @@ -1,3 +1,4 @@ +import asyncio import logging from typing import Any, AsyncGenerator, Optional, Union @@ -78,8 +79,16 @@ async def _run_logic( run_id: Any, *args: Any, **kwargs: Any, - ) -> AsyncGenerator[Union[R2RDocumentProcessingError, VectorEntry], None]: + ): fragment_batch = [] + batch_size = self.embedding_batch_size + concurrent_limit = ( + self.embedding_provider.config.concurrent_request_limit + ) + tasks = set() + + async def process_batch(batch): + return await self._process_batch(batch) async for item in input.message: if isinstance(item, R2RDocumentProcessingError): @@ -87,28 +96,47 @@ async def _run_logic( continue fragment_batch.append(item) - if len(fragment_batch) >= self.embedding_batch_size: - try: - for vector_entry in await self._process_batch( - fragment_batch - ): + + if len(fragment_batch) >= batch_size: + tasks.add(asyncio.create_task(process_batch(fragment_batch))) + fragment_batch = [] + + while len(tasks) >= concurrent_limit: + done, tasks = await asyncio.wait( + tasks, return_when=asyncio.FIRST_COMPLETED + ) + for task in done: + for vector_entry in await task: yield vector_entry - except Exception as e: - logger.error(f"Error processing batch: {e}") - yield R2RDocumentProcessingError( - error_message=str(e), - document_id=fragment_batch[0].document_id, - ) - finally: - fragment_batch.clear() if fragment_batch: - try: - for vector_entry in await self._process_batch(fragment_batch): - yield vector_entry - except Exception as e: - logger.error(f"Error processing final batch: {e}") - yield R2RDocumentProcessingError( - error_message=str(e), - document_id=fragment_batch[0].document_id, - ) + tasks.add(asyncio.create_task(process_batch(fragment_batch))) + + for task in asyncio.as_completed(tasks): + for vector_entry in await task: + yield vector_entry + + async def _process_fragment( + self, fragment: DocumentFragment + ) -> Union[VectorEntry, R2RDocumentProcessingError]: + try: + vectors = await self.embedding_provider.async_get_embeddings( + [fragment.data], + EmbeddingProvider.PipeStage.BASE, + ) + return VectorEntry( + fragment_id=fragment.id, + extraction_id=fragment.extraction_id, + document_id=fragment.document_id, + user_id=fragment.user_id, + group_ids=fragment.group_ids, + vector=Vector(data=vectors[0]), + text=fragment.data, + metadata={**fragment.metadata}, + ) + except Exception as e: + logger.error(f"Error processing fragment: {e}") + return R2RDocumentProcessingError( + error_message=str(e), + document_id=fragment.document_id, + ) diff --git a/r2r/pipes/ingestion/parsing_pipe.py b/r2r/pipes/ingestion/parsing_pipe.py index e8fc3ff21..03ceab6aa 100644 --- a/r2r/pipes/ingestion/parsing_pipe.py +++ b/r2r/pipes/ingestion/parsing_pipe.py @@ -3,8 +3,8 @@ """ import logging -import uuid from typing import AsyncGenerator, Optional, Union +from uuid import UUID from r2r.base import ( AsyncState, @@ -47,7 +47,7 @@ def __init__( async def _parse( self, document: Document, - run_id: uuid.UUID, + run_id: UUID, version: str, ) -> AsyncGenerator[ Union[R2RDocumentProcessingError, DocumentExtraction], None @@ -69,7 +69,7 @@ async def _run_logic( self, input: Input, state: AsyncState, - run_id: uuid.UUID, + run_id: UUID, versions: Optional[list[str]] = None, *args, **kwargs, @@ -77,5 +77,4 @@ async def _run_logic( async for document in input.message: version = versions[0] if versions else "v0" async for result in self._parse(document, run_id, version): - logger.info(f"Parsing pipe result for document, {document.id}") yield result diff --git a/r2r/pipes/ingestion/vector_storage_pipe.py b/r2r/pipes/ingestion/vector_storage_pipe.py index 3f67d482d..af516350b 100644 --- a/r2r/pipes/ingestion/vector_storage_pipe.py +++ b/r2r/pipes/ingestion/vector_storage_pipe.py @@ -1,7 +1,7 @@ import asyncio import logging -import uuid from typing import Any, AsyncGenerator, Optional, Tuple, Union +from uuid import UUID from r2r.base import ( AsyncState, @@ -10,9 +10,8 @@ RunLoggingSingleton, VectorEntry, ) -from r2r.base.pipes.base_pipe import AsyncPipe - from r2r.base.abstractions.exception import R2RDocumentProcessingError +from r2r.base.pipes.base_pipe import AsyncPipe logger = logging.getLogger(__name__) @@ -67,51 +66,44 @@ async def _run_logic( self, input: Input, state: AsyncState, - run_id: uuid.UUID, + run_id: UUID, *args: Any, **kwargs: Any, ) -> AsyncGenerator[ - Tuple[uuid.UUID, Union[str, R2RDocumentProcessingError]], None + Tuple[UUID, Union[str, R2RDocumentProcessingError]], None ]: - """ - Executes the async vector storage pipe: storing embeddings in the vector database. - """ - batch_tasks = [] vector_batch = [] document_counts = {} - i = 0 + connection_attempts = 0 + last_vector_received = None + async for msg in input.message: - i += 1 + last_vector_received = asyncio.get_event_loop().time() if isinstance(msg, R2RDocumentProcessingError): yield (msg.document_id, msg) continue - if msg.document_id not in document_counts: - document_counts[msg.document_id] = 1 - else: - document_counts[msg.document_id] += 1 - vector_batch.append(msg) + document_counts[msg.document_id] = ( + document_counts.get(msg.document_id, 0) + 1 + ) + if len(vector_batch) >= self.storage_batch_size: - # Schedule the storage task - batch_tasks.append( - asyncio.create_task( - self.store(vector_batch.copy()), - name=f"vector-store-{self.config.name}", - ) - ) + connection_attempts += 1 + try: + await self.store(vector_batch) + except Exception as e: + logger.error(f"Failed to store vector batch: {e}") vector_batch.clear() - if vector_batch: # Process any remaining vectors - batch_tasks.append( - asyncio.create_task( - self.store(vector_batch.copy()), - name=f"vector-store-{self.config.name}", - ) - ) + if vector_batch: + connection_attempts += 1 + try: + await self.store(vector_batch) + except Exception as e: + logger.error(f"Failed to store final vector batch: {e}") - # Wait for all storage tasks to complete - await asyncio.gather(*batch_tasks) + logger.info(f"Total connection attempts: {connection_attempts}") for document_id, count in document_counts.items(): yield ( diff --git a/r2r/pipes/kg/clustering.py b/r2r/pipes/kg/clustering.py index 5ef1648d2..a0d6c0248 100644 --- a/r2r/pipes/kg/clustering.py +++ b/r2r/pipes/kg/clustering.py @@ -4,10 +4,10 @@ """A module for clustering entities and triples into communities using hierarchical Leiden algorithm.""" import asyncio +import json import logging -import uuid from typing import Any, AsyncGenerator, Optional -import json +from uuid import UUID import networkx as nx from graspologic.partition import hierarchical_leiden @@ -187,7 +187,7 @@ async def process_community(community_key, community): summary = json.loads(community.summary) except: summary = {"title": "_"} - return { 'id': community.id, 'title': summary['title'] } + return {"id": community.id, "title": summary["title"]} tasks = [] async for community_key, community in async_iterate_dict( @@ -206,7 +206,7 @@ async def _run_logic( self, input: AsyncPipe.Input, state: AsyncState, - run_id: uuid.UUID, + run_id: UUID, *args: Any, **kwargs: Any, ) -> AsyncGenerator[Community, None]: diff --git a/r2r/pipes/kg/extraction.py b/r2r/pipes/kg/extraction.py index c2d581256..4d2043c32 100644 --- a/r2r/pipes/kg/extraction.py +++ b/r2r/pipes/kg/extraction.py @@ -87,7 +87,9 @@ async def extract_kg( """ task_inputs = {"input": fragment.data} - task_inputs["max_knowledge_triples"] = self.kg_provider.config.max_knowledge_triples + task_inputs["max_knowledge_triples"] = ( + self.kg_provider.config.max_knowledge_triples + ) messages = self.prompt_provider._get_message_payload( task_prompt_name=self.kg_provider.config.kg_extraction_prompt, @@ -148,9 +150,7 @@ def parse_fn(response_str: str) -> Any: weight=weight, document_ids=[str(fragment.document_id)], text_unit_ids=[str(fragment.id)], - attributes={ - "fragment_text": fragment.data - }, + attributes={"fragment_text": fragment.data}, ) ) diff --git a/r2r/pipes/kg/node_extraction.py b/r2r/pipes/kg/node_extraction.py index b4fda0584..9f85fa3b8 100644 --- a/r2r/pipes/kg/node_extraction.py +++ b/r2r/pipes/kg/node_extraction.py @@ -2,18 +2,16 @@ import asyncio import logging -import uuid -from typing import Any, AsyncGenerator, Optional, Union +from typing import Any, AsyncGenerator, Optional +from uuid import UUID from r2r.base import ( AsyncState, CompletionProvider, EmbeddingProvider, - KGExtraction, KGProvider, PipeType, PromptProvider, - R2RDocumentProcessingError, RunLoggingSingleton, ) from r2r.base.abstractions.graph import Entity, Triple @@ -56,7 +54,7 @@ async def _run_logic( self, input: Input, state: AsyncState, - run_id: uuid.UUID, + run_id: UUID, *args, **kwargs, ) -> AsyncGenerator[Any, None]: @@ -103,7 +101,7 @@ async def _run_logic( self, input: Input, state: AsyncState, - run_id: uuid.UUID, + run_id: UUID, *args: Any, **kwargs: Any, ) -> AsyncGenerator[Any, None]: diff --git a/r2r/pipes/kg/storage.py b/r2r/pipes/kg/storage.py index ab7e10e15..1663856b5 100644 --- a/r2r/pipes/kg/storage.py +++ b/r2r/pipes/kg/storage.py @@ -1,7 +1,7 @@ import asyncio import logging -import uuid from typing import Any, AsyncGenerator, Optional +from uuid import UUID from r2r.base import ( AsyncState, @@ -67,7 +67,7 @@ async def _run_logic( self, input: Input, state: AsyncState, - run_id: uuid.UUID, + run_id: UUID, *args: Any, **kwargs: Any, ) -> AsyncGenerator[None, None]: diff --git a/r2r/pipes/other/web_search_pipe.py b/r2r/pipes/other/web_search_pipe.py index 4ef1b47d1..1e0c5a768 100644 --- a/r2r/pipes/other/web_search_pipe.py +++ b/r2r/pipes/other/web_search_pipe.py @@ -1,7 +1,7 @@ import json import logging -import uuid from typing import Any, AsyncGenerator, Optional +from uuid import UUID from r2r.base import ( AsyncPipe, @@ -37,7 +37,7 @@ def __init__( async def search( self, message: str, - run_id: uuid.UUID, + run_id: UUID, *args: Any, **kwargs: Any, ) -> AsyncGenerator[VectorSearchResult, None]: @@ -81,7 +81,7 @@ async def _run_logic( self, input: AsyncPipe.Input, state: AsyncState, - run_id: uuid.UUID, + run_id: UUID, *args: Any, **kwargs, ) -> AsyncGenerator[VectorSearchResult, None]: diff --git a/r2r/pipes/retrieval/kg_search_search_pipe.py b/r2r/pipes/retrieval/kg_search_search_pipe.py index 93fdf7b24..24eb16d4d 100644 --- a/r2r/pipes/retrieval/kg_search_search_pipe.py +++ b/r2r/pipes/retrieval/kg_search_search_pipe.py @@ -1,8 +1,8 @@ import asyncio import json import logging -import uuid from typing import Any, Optional +from uuid import UUID from r2r.base import ( AsyncState, @@ -98,7 +98,7 @@ async def local_search( self, input: GeneratorPipe.Input, state: AsyncState, - run_id: uuid.UUID, + run_id: UUID, kg_search_settings: KGSearchSettings, *args: Any, **kwargs: Any, @@ -133,7 +133,7 @@ async def global_search( self, input: GeneratorPipe.Input, state: AsyncState, - run_id: uuid.UUID, + run_id: UUID, kg_search_settings: KGSearchSettings, *args: Any, **kwargs: Any, @@ -184,7 +184,12 @@ async def process_community(merged_report): ) map_responses = await asyncio.gather( - *[process_community(report) for report in preprocessed_reports[:kg_search_settings.max_llm_queries_for_global_search]] + *[ + process_community(report) + for report in preprocessed_reports[ + : kg_search_settings.max_llm_queries_for_global_search + ] + ] ) # Filter only the relevant responses filtered_responses = self.filter_responses(map_responses) @@ -210,7 +215,7 @@ async def _run_logic( self, input: GeneratorPipe.Input, state: AsyncState, - run_id: uuid.UUID, + run_id: UUID, kg_search_settings: KGSearchSettings, *args: Any, **kwargs: Any, diff --git a/r2r/pipes/retrieval/multi_search.py b/r2r/pipes/retrieval/multi_search.py index 6da2c34b5..74cf9f40a 100644 --- a/r2r/pipes/retrieval/multi_search.py +++ b/r2r/pipes/retrieval/multi_search.py @@ -1,6 +1,6 @@ -import uuid from copy import copy from typing import Any, AsyncGenerator, Optional +from uuid import UUID from r2r.base.abstractions.llm import GenerationConfig from r2r.base.abstractions.search import VectorSearchResult @@ -49,7 +49,7 @@ async def _run_logic( self, input: Any, state: Any, - run_id: uuid.UUID, + run_id: UUID, query_transform_generation_config: Optional[GenerationConfig] = None, *args: Any, **kwargs: Any, diff --git a/r2r/pipes/retrieval/query_transform_pipe.py b/r2r/pipes/retrieval/query_transform_pipe.py index b14a44223..98f1bfd2f 100644 --- a/r2r/pipes/retrieval/query_transform_pipe.py +++ b/r2r/pipes/retrieval/query_transform_pipe.py @@ -1,6 +1,6 @@ import logging -import uuid from typing import Any, AsyncGenerator, Optional +from uuid import UUID from r2r.base import ( AsyncPipe, @@ -48,7 +48,7 @@ async def _run_logic( self, input: AsyncPipe.Input, state: AsyncState, - run_id: uuid.UUID, + run_id: UUID, query_transform_generation_config: GenerationConfig, num_query_xf_outputs: int = 3, *args: Any, diff --git a/r2r/pipes/retrieval/streaming_rag_pipe.py b/r2r/pipes/retrieval/streaming_rag_pipe.py index 686e9f758..68ef1f01c 100644 --- a/r2r/pipes/retrieval/streaming_rag_pipe.py +++ b/r2r/pipes/retrieval/streaming_rag_pipe.py @@ -1,8 +1,8 @@ import json import logging -import uuid from datetime import datetime from typing import Any, AsyncGenerator, Generator, Optional +from uuid import UUID from r2r.base import ( AsyncState, @@ -108,7 +108,7 @@ def _process_chunk(chunk: LLMChatCompletionChunk) -> str: return chunk.choices[0].delta.content or "" async def log_completion_record( - self, run_id: uuid.UUID, completion_record: CompletionRecord + self, run_id: UUID, completion_record: CompletionRecord ): await self.enqueue_log( run_id=run_id, diff --git a/r2r/pipes/retrieval/vector_search_pipe.py b/r2r/pipes/retrieval/vector_search_pipe.py index d1c97ede6..1029ccafc 100644 --- a/r2r/pipes/retrieval/vector_search_pipe.py +++ b/r2r/pipes/retrieval/vector_search_pipe.py @@ -1,7 +1,7 @@ import json import logging -import uuid from typing import Any, AsyncGenerator, Optional +from uuid import UUID from r2r.base import ( AsyncPipe, @@ -41,7 +41,7 @@ def __init__( async def search( self, message: str, - run_id: uuid.UUID, + run_id: UUID, vector_search_settings: VectorSearchSettings, *args: Any, **kwargs: Any, @@ -99,7 +99,7 @@ async def _run_logic( self, input: AsyncPipe.Input, state: AsyncState, - run_id: uuid.UUID, + run_id: UUID, vector_search_settings: VectorSearchSettings = VectorSearchSettings(), *args: Any, **kwargs: Any, diff --git a/r2r/providers/database/relational.py b/r2r/providers/database/relational.py index 0fb2769e3..b2b23a829 100644 --- a/r2r/providers/database/relational.py +++ b/r2r/providers/database/relational.py @@ -40,7 +40,6 @@ def _initialize_relational_db(self): # Call create_table for each mixin for base_class in self.__class__.__bases__: - print("base_class", base_class) if issubclass(base_class, DatabaseMixin): base_class.create_table(self) diff --git a/r2r/providers/database/vecs/adapter/base.py b/r2r/providers/database/vecs/adapter/base.py index 6634f35a5..7559d9e27 100644 --- a/r2r/providers/database/vecs/adapter/base.py +++ b/r2r/providers/database/vecs/adapter/base.py @@ -6,10 +6,10 @@ All public classes, enums, and functions are re-exported by `vecs.adapters` module. """ -import uuid from abc import ABC, abstractmethod from enum import Enum from typing import Any, Dict, Generator, Iterable, Optional, Tuple, Union +from uuid import UUID from vecs.exc import ArgError @@ -18,11 +18,11 @@ Numeric = Union[int, float, complex] Record = Tuple[ - uuid.UUID, - uuid.UUID, - uuid.UUID, - uuid.UUID, - list[uuid.UUID], + UUID, + UUID, + UUID, + UUID, + list[UUID], Iterable[Numeric], str, Metadata, diff --git a/r2r/providers/database/vecs/collection.py b/r2r/providers/database/vecs/collection.py index 8bacee9c1..96c499ff0 100644 --- a/r2r/providers/database/vecs/collection.py +++ b/r2r/providers/database/vecs/collection.py @@ -8,7 +8,6 @@ from __future__ import annotations import math -import uuid import warnings from dataclasses import dataclass from enum import Enum @@ -22,6 +21,7 @@ Tuple, Union, ) +from uuid import UUID import psycopg2 from flupy import flu @@ -447,7 +447,7 @@ def upsert( sess.execute(stmt) return None - def fetch(self, fragment_ids: Iterable[uuid.UUID]) -> List[Record]: + def fetch(self, fragment_ids: Iterable[UUID]) -> List[Record]: """ Fetches vectors from the collection by their fragment identifiers. @@ -460,7 +460,7 @@ def fetch(self, fragment_ids: Iterable[uuid.UUID]) -> List[Record]: Raises: ArgError: If fragment_ids is not an iterable of UUIDs. """ - if isinstance(fragment_ids, (str, uuid.UUID)): + if isinstance(fragment_ids, (str, UUID)): raise ArgError("fragment_ids must be an iterable of UUIDs") chunk_size = 12 @@ -477,7 +477,7 @@ def fetch(self, fragment_ids: Iterable[uuid.UUID]) -> List[Record]: def delete( self, - fragment_ids: Optional[Iterable[uuid.UUID]] = None, + fragment_ids: Optional[Iterable[UUID]] = None, filters: Optional[Dict[str, Any]] = None, ) -> Dict[str, Dict[str, str]]: """ @@ -502,7 +502,7 @@ def delete( "Either fragment_ids or filters must be provided, not both." ) - if isinstance(fragment_ids, (str, uuid.UUID)): + if isinstance(fragment_ids, (str, UUID)): raise ArgError("fragment_ids must be an iterable of UUIDs") deleted_records = {} diff --git a/r2r/providers/embeddings/litellm.py b/r2r/providers/embeddings/litellm.py index 9ebb45876..a2eaa54ce 100644 --- a/r2r/providers/embeddings/litellm.py +++ b/r2r/providers/embeddings/litellm.py @@ -43,7 +43,6 @@ def __init__( self.base_model = config.base_model self.base_dimension = config.base_dimension - self.semaphore = asyncio.Semaphore(config.concurrent_request_limit) def _get_embedding_kwargs(self, **kwargs): embedding_kwargs = { @@ -53,30 +52,30 @@ def _get_embedding_kwargs(self, **kwargs): embedding_kwargs.update(kwargs) return embedding_kwargs - async def _execute_task(self, task: dict[str, Any]) -> List[float]: - text = task["text"] + async def _execute_task(self, task: dict[str, Any]) -> List[List[float]]: + texts = task["texts"] kwargs = self._get_embedding_kwargs(**task.get("kwargs", {})) + try: response = await self.litellm_aembedding( - input=[text], + input=texts, **kwargs, ) - return response.data[0]["embedding"] + return [data["embedding"] for data in response.data] except Exception as e: error_msg = f"Error getting embeddings: {str(e)}" logger.error(error_msg) raise R2RException(error_msg, 400) - def _execute_task_sync(self, task: dict[str, Any]) -> List[float]: - text = task["text"] + def _execute_task_sync(self, task: dict[str, Any]) -> List[List[float]]: + texts = task["texts"] kwargs = self._get_embedding_kwargs(**task.get("kwargs", {})) try: - return self.litellm_embedding( - input=[text], + response = self.litellm_embedding( + input=texts, **kwargs, - ).data[ - 0 - ]["embedding"] + ) + return [data["embedding"] for data in response.data] except Exception as e: error_msg = f"Error getting embeddings: {str(e)}" logger.error(error_msg) @@ -95,12 +94,12 @@ async def async_get_embedding( ) task = { - "text": text, + "texts": [text], "stage": stage, "purpose": purpose, "kwargs": kwargs, } - return await self._execute_with_backoff_async(task) + return (await self._execute_with_backoff_async(task))[0] def get_embedding( self, @@ -115,12 +114,12 @@ def get_embedding( ) task = { - "text": text, + "texts": [text], "stage": stage, "purpose": purpose, "kwargs": kwargs, } - return self._execute_with_backoff_sync(task) + return self._execute_with_backoff_sync(task)[0] async def async_get_embeddings( self, @@ -134,18 +133,13 @@ async def async_get_embeddings( "LiteLLMEmbeddingProvider only supports search stage." ) - tasks = [ - { - "text": text, - "stage": stage, - "purpose": purpose, - "kwargs": kwargs, - } - for text in texts - ] - return await asyncio.gather( - *[self._execute_with_backoff_async(task) for task in tasks] - ) + task = { + "texts": texts, + "stage": stage, + "purpose": purpose, + "kwargs": kwargs, + } + return await self._execute_with_backoff_async(task) def get_embeddings( self, @@ -159,16 +153,13 @@ def get_embeddings( "LiteLLMEmbeddingProvider only supports search stage." ) - tasks = [ - { - "text": text, - "stage": stage, - "purpose": purpose, - "kwargs": kwargs, - } - for text in texts - ] - return [self._execute_with_backoff_sync(task) for task in tasks] + task = { + "texts": texts, + "stage": stage, + "purpose": purpose, + "kwargs": kwargs, + } + return self._execute_with_backoff_sync(task) def rerank( self, diff --git a/r2r/providers/embeddings/ollama.py b/r2r/providers/embeddings/ollama.py index 2577a6c91..e4cde4bc2 100644 --- a/r2r/providers/embeddings/ollama.py +++ b/r2r/providers/embeddings/ollama.py @@ -1,4 +1,3 @@ -import asyncio import logging import os from typing import Any, List @@ -43,32 +42,54 @@ def __init__(self, config: EmbeddingConfig): self.aclient = AsyncClient(host=self.base_url) self.set_prefixes(config.prefixes or {}, self.base_model) + self.batch_size = config.batch_size or 32 - async def _execute_task(self, task: dict[str, Any]) -> List[float]: - text = task["text"] + def _get_embedding_kwargs(self, **kwargs): + embedding_kwargs = { + "model": self.base_model, + } + embedding_kwargs.update(kwargs) + return embedding_kwargs + + async def _execute_task(self, task: dict[str, Any]) -> List[List[float]]: + texts = task["texts"] purpose = task.get("purpose", EmbeddingPurpose.INDEX) - text = self.prefixes.get(purpose, "") + text + kwargs = self._get_embedding_kwargs(**task.get("kwargs", {})) try: - response = await self.aclient.embeddings( - prompt=text, model=self.base_model - ) - return response["embedding"] + embeddings = [] + for i in range(0, len(texts), self.batch_size): + batch = texts[i : i + self.batch_size] + prefixed_batch = [ + self.prefixes.get(purpose, "") + text for text in batch + ] + response = await self.aclient.embed( + input=prefixed_batch, **kwargs + ) + embeddings.extend(response["embeddings"]) + return embeddings except Exception as e: error_msg = f"Error getting embeddings: {str(e)}" logger.error(error_msg) raise R2RException(error_msg, 400) - def _execute_task_sync(self, task: dict[str, Any]) -> List[float]: - text = task["text"] + def _execute_task_sync(self, task: dict[str, Any]) -> List[List[float]]: + texts = task["texts"] purpose = task.get("purpose", EmbeddingPurpose.INDEX) - text = self.prefixes.get(purpose, "") + text + kwargs = self._get_embedding_kwargs(**task.get("kwargs", {})) try: - response = self.client.embeddings( - prompt=text, model=self.base_model - ) - return response["embedding"] + embeddings = [] + for i in range(0, len(texts), self.batch_size): + batch = texts[i : i + self.batch_size] + prefixed_batch = [ + self.prefixes.get(purpose, "") + text for text in batch + ] + response = self.client.embed( + model=kwargs["model"], input=prefixed_batch, **kwargs + ) + embeddings.extend(response["embeddings"]) + return embeddings except Exception as e: error_msg = f"Error getting embeddings: {str(e)}" logger.error(error_msg) @@ -79,6 +100,7 @@ async def async_get_embedding( text: str, stage: EmbeddingProvider.PipeStage = EmbeddingProvider.PipeStage.BASE, purpose: EmbeddingPurpose = EmbeddingPurpose.INDEX, + **kwargs, ) -> List[float]: if stage != EmbeddingProvider.PipeStage.BASE: raise ValueError( @@ -86,17 +108,20 @@ async def async_get_embedding( ) task = { - "text": text, + "texts": [text], "stage": stage, "purpose": purpose, + "kwargs": kwargs, } - return await self._execute_with_backoff_async(task) + result = await self._execute_with_backoff_async(task) + return result[0] def get_embedding( self, text: str, stage: EmbeddingProvider.PipeStage = EmbeddingProvider.PipeStage.BASE, purpose: EmbeddingPurpose = EmbeddingPurpose.INDEX, + **kwargs, ) -> List[float]: if stage != EmbeddingProvider.PipeStage.BASE: raise ValueError( @@ -104,55 +129,53 @@ def get_embedding( ) task = { - "text": text, + "texts": [text], "stage": stage, "purpose": purpose, + "kwargs": kwargs, } - return self._execute_with_backoff_sync(task) + result = self._execute_with_backoff_sync(task) + return result[0] async def async_get_embeddings( self, texts: List[str], stage: EmbeddingProvider.PipeStage = EmbeddingProvider.PipeStage.BASE, purpose: EmbeddingPurpose = EmbeddingPurpose.INDEX, + **kwargs, ) -> List[List[float]]: if stage != EmbeddingProvider.PipeStage.BASE: raise ValueError( "OllamaEmbeddingProvider only supports search stage." ) - tasks = [ - { - "text": text, - "stage": stage, - "purpose": purpose, - } - for text in texts - ] - return await asyncio.gather( - *[self._execute_with_backoff_async(task) for task in tasks] - ) + task = { + "texts": texts, + "stage": stage, + "purpose": purpose, + "kwargs": kwargs, + } + return await self._execute_with_backoff_async(task) def get_embeddings( self, texts: List[str], stage: EmbeddingProvider.PipeStage = EmbeddingProvider.PipeStage.BASE, purpose: EmbeddingPurpose = EmbeddingPurpose.INDEX, + **kwargs, ) -> List[List[float]]: if stage != EmbeddingProvider.PipeStage.BASE: raise ValueError( "OllamaEmbeddingProvider only supports search stage." ) - tasks = [ - { - "text": text, - "stage": stage, - "purpose": purpose, - } - for text in texts - ] - return [self._execute_with_backoff_sync(task) for task in tasks] + task = { + "texts": texts, + "stage": stage, + "purpose": purpose, + "kwargs": kwargs, + } + return self._execute_with_backoff_sync(task) def rerank( self, diff --git a/r2r/providers/embeddings/openai.py b/r2r/providers/embeddings/openai.py index 627a3eeaa..68ebb7e84 100644 --- a/r2r/providers/embeddings/openai.py +++ b/r2r/providers/embeddings/openai.py @@ -51,7 +51,10 @@ def __init__(self, config: EmbeddingConfig): "OpenAIEmbeddingProvider does not support separate reranking." ) - self.base_model = config.base_model + if config.base_model and "openai/" in config.base_model: + self.base_model = config.base_model.split("/")[-1] + else: + self.base_model = config.base_model self.base_dimension = config.base_dimension if not self.base_model: @@ -88,46 +91,57 @@ def _get_dimensions(self): or OpenAIEmbeddingProvider.MODEL_TO_DIMENSIONS[self.base_model][-1] ) - async def _execute_task(self, task: dict[str, Any]) -> List[float]: - text = task["text"] + def _get_embedding_kwargs(self, **kwargs): + embedding_kwargs = { + "model": self.base_model, + "dimensions": self._get_dimensions(), + } + embedding_kwargs.update(kwargs) + return embedding_kwargs + + async def _execute_task(self, task: dict[str, Any]) -> List[List[float]]: + texts = task["texts"] + kwargs = self._get_embedding_kwargs(**task.get("kwargs", {})) + try: response = await self.async_client.embeddings.create( - input=[text], - model=self.base_model, - dimensions=self._get_dimensions(), + input=texts, + **kwargs, ) - return response.data[0].embedding + return [data.embedding for data in response.data] except AuthenticationError as e: raise ValueError( "Invalid OpenAI API key provided. Please check your OPENAI_API_KEY environment variable." ) from e except Exception as e: - raise ValueError(f"Error getting embedding: {str(e)}") + error_msg = f"Error getting embeddings: {str(e)}" + logger.error(error_msg) + raise ValueError(error_msg) - def _execute_task_sync(self, task: dict[str, Any]) -> List[float]: - text = task["text"] + def _execute_task_sync(self, task: dict[str, Any]) -> List[List[float]]: + texts = task["texts"] + kwargs = self._get_embedding_kwargs(**task.get("kwargs", {})) try: - return ( - self.client.embeddings.create( - input=[text], - model=self.base_model, - dimensions=self._get_dimensions(), - ) - .data[0] - .embedding + response = self.client.embeddings.create( + input=texts, + **kwargs, ) + return [data.embedding for data in response.data] except AuthenticationError as e: raise ValueError( "Invalid OpenAI API key provided. Please check your OPENAI_API_KEY environment variable." ) from e except Exception as e: - raise ValueError(f"Error getting embedding: {str(e)}") + error_msg = f"Error getting embeddings: {str(e)}" + logger.error(error_msg) + raise ValueError(error_msg) async def async_get_embedding( self, text: str, stage: EmbeddingProvider.PipeStage = EmbeddingProvider.PipeStage.BASE, purpose: EmbeddingPurpose = EmbeddingPurpose.INDEX, + **kwargs, ) -> List[float]: if stage != EmbeddingProvider.PipeStage.BASE: raise ValueError( @@ -135,17 +149,20 @@ async def async_get_embedding( ) task = { - "text": text, + "texts": [text], "stage": stage, "purpose": purpose, + "kwargs": kwargs, } - return await self._execute_with_backoff_async(task) + result = await self._execute_with_backoff_async(task) + return result[0] def get_embedding( self, text: str, stage: EmbeddingProvider.PipeStage = EmbeddingProvider.PipeStage.BASE, purpose: EmbeddingPurpose = EmbeddingPurpose.INDEX, + **kwargs, ) -> List[float]: if stage != EmbeddingProvider.PipeStage.BASE: raise ValueError( @@ -153,55 +170,53 @@ def get_embedding( ) task = { - "text": text, + "texts": [text], "stage": stage, "purpose": purpose, + "kwargs": kwargs, } - return self._execute_with_backoff_sync(task) + result = self._execute_with_backoff_sync(task) + return result[0] async def async_get_embeddings( self, texts: List[str], stage: EmbeddingProvider.PipeStage = EmbeddingProvider.PipeStage.BASE, purpose: EmbeddingPurpose = EmbeddingPurpose.INDEX, + **kwargs, ) -> List[List[float]]: if stage != EmbeddingProvider.PipeStage.BASE: raise ValueError( "OpenAIEmbeddingProvider only supports search stage." ) - tasks = [ - { - "text": text, - "stage": stage, - "purpose": purpose, - } - for text in texts - ] - return await asyncio.gather( - *[self._execute_with_backoff_async(task) for task in tasks] - ) + task = { + "texts": texts, + "stage": stage, + "purpose": purpose, + "kwargs": kwargs, + } + return await self._execute_with_backoff_async(task) def get_embeddings( self, texts: List[str], stage: EmbeddingProvider.PipeStage = EmbeddingProvider.PipeStage.BASE, purpose: EmbeddingPurpose = EmbeddingPurpose.INDEX, + **kwargs, ) -> List[List[float]]: if stage != EmbeddingProvider.PipeStage.BASE: raise ValueError( "OpenAIEmbeddingProvider only supports search stage." ) - tasks = [ - { - "text": text, - "stage": stage, - "purpose": purpose, - } - for text in texts - ] - return [self._execute_with_backoff_sync(task) for task in tasks] + task = { + "texts": texts, + "stage": stage, + "purpose": purpose, + "kwargs": kwargs, + } + return self._execute_with_backoff_sync(task) def rerank( self, diff --git a/r2r/providers/kg/neo4j/provider.py b/r2r/providers/kg/neo4j/provider.py index 3501b2657..a4f2b48a8 100644 --- a/r2r/providers/kg/neo4j/provider.py +++ b/r2r/providers/kg/neo4j/provider.py @@ -1,10 +1,10 @@ import json import os import time -import uuid from datetime import date, datetime from decimal import Decimal from typing import Any, Dict, List, Optional +from uuid import UUID from r2r.base import ( KGConfig, @@ -97,7 +97,7 @@ def convert_to_neo4j_compatible(self, value): return value elif isinstance(value, (datetime, date)): return value.isoformat() - elif isinstance(value, uuid.UUID): + elif isinstance(value, UUID): return str(value) elif isinstance(value, Decimal): return float(value) @@ -289,7 +289,7 @@ def get_communities(self, level: str = None) -> List[Community]: neo4j_records = self.structured_query( GET_COMMUNITIES_QUERY, {"level": level} ) - + communities = [ Community(**record["c"]._properties, id=record["c"]["community"]) for record in neo4j_records.records @@ -321,7 +321,9 @@ def get_rel_map( def client(self): return self._driver - def create_vector_index(self, node_type: str, node_property: str, dimension: int) -> None: + def create_vector_index( + self, node_type: str, node_property: str, dimension: int + ) -> None: query = f""" CREATE VECTOR INDEX `{node_type}_{node_property}` IF NOT EXISTS diff --git a/tests/test_ingestion_service.py b/tests/test_ingestion_service.py index e76973643..13b79d499 100644 --- a/tests/test_ingestion_service.py +++ b/tests/test_ingestion_service.py @@ -331,7 +331,9 @@ async def test_version_increment(ingestion_service, mock_vector_db): file_mock = UploadFile( filename="test.txt", file=io.BytesIO(b"Updated content") ) - await ingestion_service.update_files([file_mock], [document.id], user=user) + await ingestion_service.update_files( + files=[file_mock], document_ids=[document.id], user=user + ) calls = mock_vector_db.relational.upsert_documents_overview.call_args_list assert len(calls) == 2 From 9c8ff3aed0f7ec15b0cfb7f048f35c5e48cef83d Mon Sep 17 00:00:00 2001 From: emrgnt-cmplxty <68796651+emrgnt-cmplxty@users.noreply.github.com> Date: Mon, 19 Aug 2024 13:34:45 -0700 Subject: [PATCH 06/74] rm kg cruft (#884) * rm kg cruft * tweaks --- r2r/main/api/client/restructure.py | 28 +------------------------ r2r/main/api/routes/kg/__init__.py | 0 r2r/main/api/routes/kg/base.py | 23 -------------------- r2r/main/api/routes/kg/requests.py | 10 --------- r2r/main/api/routes/restructure/base.py | 3 --- 5 files changed, 1 insertion(+), 63 deletions(-) delete mode 100644 r2r/main/api/routes/kg/__init__.py delete mode 100644 r2r/main/api/routes/kg/base.py delete mode 100644 r2r/main/api/routes/kg/requests.py diff --git a/r2r/main/api/client/restructure.py b/r2r/main/api/client/restructure.py index 0fcbc9f82..801fdb5c3 100644 --- a/r2r/main/api/client/restructure.py +++ b/r2r/main/api/client/restructure.py @@ -22,30 +22,4 @@ async def enrich_graph( [doc.model_dump() for doc in documents] if documents else None ) } - return await client._make_request("POST", "kg/enrich_graph", json=data) - - @staticmethod - async def query_graph(client, query: str) -> Dict[str, Any]: - """ - Query the knowledge graph. - - Args: - query (str): The query to run against the knowledge graph. - - Returns: - Dict[str, Any]: Results of the graph query. - """ - params = {"query": query} - return await client._make_request( - "GET", "kg/query_graph", params=params - ) - - @staticmethod - async def get_graph_statistics(client) -> Dict[str, Any]: - """ - Get statistics about the knowledge graph. - - Returns: - Dict[str, Any]: Statistics about the knowledge graph. - """ - return await client._make_request("GET", "kg/graph_statistics") + return await client._make_request("POST", "enrich_graph", json=data) diff --git a/r2r/main/api/routes/kg/__init__.py b/r2r/main/api/routes/kg/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/r2r/main/api/routes/kg/base.py b/r2r/main/api/routes/kg/base.py deleted file mode 100644 index 1dd1e400f..000000000 --- a/r2r/main/api/routes/kg/base.py +++ /dev/null @@ -1,23 +0,0 @@ -from fastapi import Depends - -from r2r.main.api.routes.base_router import BaseRouter -from r2r.main.engine import R2REngine - - -class KGRouter(BaseRouter): - def __init__(self, engine: R2REngine): - super().__init__(engine) - self.setup_routes() - - def setup_routes(self): - @self.router.post("/enrich_graph") - @self.base_endpoint - async def enrich_graph( - request: dict, - auth_user=( - Depends(self.engine.providers.auth.auth_wrapper) - if self.engine.providers.auth - else None - ), - ): - return await self.engine.enrich_graph() diff --git a/r2r/main/api/routes/kg/requests.py b/r2r/main/api/routes/kg/requests.py deleted file mode 100644 index 213227768..000000000 --- a/r2r/main/api/routes/kg/requests.py +++ /dev/null @@ -1,10 +0,0 @@ -from typing import List, Optional - -from pydantic import BaseModel - - -class KGEnrichGraphRequest(BaseModel): - query: str - entity_types: Optional[List[str]] = None - relationships: Optional[List[str]] = None - generation_config: Optional[dict] = None diff --git a/r2r/main/api/routes/restructure/base.py b/r2r/main/api/routes/restructure/base.py index 142c0ded8..9660c21de 100644 --- a/r2r/main/api/routes/restructure/base.py +++ b/r2r/main/api/routes/restructure/base.py @@ -32,6 +32,3 @@ async def enrich_graph( "generation_config": generation_config, } return await self.engine.enrich_graph(request) - - -# ... existing code ... From 600781fe80b47e3600d44dfa3a7cefdd23207287 Mon Sep 17 00:00:00 2001 From: emrgnt-cmplxty <68796651+emrgnt-cmplxty@users.noreply.github.com> Date: Mon, 19 Aug 2024 13:43:55 -0700 Subject: [PATCH 07/74] tweak 2 (#885) --- r2r/main/api/routes/ingestion/base.py | 21 ------------ r2r/main/api/routes/restructure/base.py | 20 +++++------ r2r/main/services/restructure_service.py | 43 +----------------------- 3 files changed, 9 insertions(+), 75 deletions(-) diff --git a/r2r/main/api/routes/ingestion/base.py b/r2r/main/api/routes/ingestion/base.py index c2082f264..e49e37d2c 100644 --- a/r2r/main/api/routes/ingestion/base.py +++ b/r2r/main/api/routes/ingestion/base.py @@ -6,7 +6,6 @@ import yaml from fastapi import Depends, File, Form, UploadFile -from fastapi.openapi.models import Example from r2r.base import ChunkingConfig, R2RException from r2r.base.api.models.ingestion.responses import WrappedIngestionResponse @@ -31,26 +30,6 @@ def load_openapi_extras(self): yaml_content = yaml.safe_load(yaml_file) return yaml_content - # paths = yaml_content.get("paths", {}) - - # def extract_descriptions(endpoint): - # params = endpoint.get("requestBody", {}).get("content", {}).get("multipart/form-data", {}).get("schema", {}).get("properties", {}) - # return {k: v.get("description", "") for k, v in params.items()} - - # ingest_files = paths.get("/v1/ingest_files", {}) - # # update_files = paths.get("/v1/update_files", {}).get("post", {}) - - # return { - # "ingest_files": { - # # "descriptions": extract_descriptions(ingest_files), - # # "operation": ingest_files - # }, - # # "update_files": { - # # "descriptions": extract_descriptions(update_files), - # # "operation": update_files - # # } - # } - def setup_routes(self): # Note, we use the following verbose input parameters because FastAPI struggles to handle `File` input and `Body` inputs # at the same time. Therefore, we must ues `Form` inputs for the metadata, document_ids, and versions inputs. diff --git a/r2r/main/api/routes/restructure/base.py b/r2r/main/api/routes/restructure/base.py index 9660c21de..747d5ed7e 100644 --- a/r2r/main/api/routes/restructure/base.py +++ b/r2r/main/api/routes/restructure/base.py @@ -1,6 +1,6 @@ from typing import List, Optional -from fastapi import Depends +from fastapi import Depends, Form from r2r.main.api.routes.base_router import BaseRouter from r2r.main.engine import R2REngine @@ -15,20 +15,16 @@ def setup_routes(self): @self.router.post("/enrich_graph") @self.base_endpoint async def enrich_graph( - query: str, - entity_types: Optional[List[str]] = None, - relationships: Optional[List[str]] = None, - generation_config: Optional[dict] = None, auth_user=( Depends(self.engine.providers.auth.auth_wrapper) if self.engine.providers.auth else None ), ): - request = { - "query": query, - "entity_types": entity_types, - "relationships": relationships, - "generation_config": generation_config, - } - return await self.engine.enrich_graph(request) + """ + Perform graph enrichment, e.g. GraphRAG, over the ingested documents. + + Returns: + Dict[str, Any]: Results of the graph enrichment process. + """ + return await self.engine.aenrich_graph() diff --git a/r2r/main/services/restructure_service.py b/r2r/main/services/restructure_service.py index b92d07fcf..ab98182da 100644 --- a/r2r/main/services/restructure_service.py +++ b/r2r/main/services/restructure_service.py @@ -30,15 +30,10 @@ def __init__( logging_connection, ) - async def enrich_graph( - self, documents: List[Document] = None - ) -> Dict[str, Any]: + async def enrich_graph(self) -> Dict[str, Any]: """ Perform graph enrichment on the given documents. - Args: - documents (List[Document]): List of documents to enrich. - Returns: Dict[str, Any]: Results of the graph enrichment process. """ @@ -54,39 +49,3 @@ async def enrich_graph( raise R2RException( status_code=500, message=f"Graph enrichment failed: {str(e)}" ) - - async def query_graph(self, query: str) -> Dict[str, Any]: - """ - Query the knowledge graph. - - Args: - query (str): The query to run against the knowledge graph. - - Returns: - Dict[str, Any]: Results of the graph query. - """ - try: - results = self.providers.database.graph.query(query) - return {"results": results} - except Exception as e: - logger.error(f"Error querying graph: {str(e)}") - raise R2RException( - status_code=500, message=f"Graph query failed: {str(e)}" - ) - - async def get_graph_statistics(self) -> Dict[str, Any]: - """ - Get statistics about the knowledge graph. - - Returns: - Dict[str, Any]: Statistics about the knowledge graph. - """ - try: - stats = self.providers.database.graph.get_statistics() - return stats - except Exception as e: - logger.error(f"Error getting graph statistics: {str(e)}") - raise R2RException( - status_code=500, - message=f"Failed to retrieve graph statistics: {str(e)}", - ) From 284ab7f4b3febc4bc038a7748d03f3ee30c42588 Mon Sep 17 00:00:00 2001 From: emrgnt-cmplxty <68796651+emrgnt-cmplxty@users.noreply.github.com> Date: Mon, 19 Aug 2024 13:54:14 -0700 Subject: [PATCH 08/74] Feature/fix retrieval endpoint cruft (#887) * tweak 2 * fix retrieval endpoint descriptions --- r2r/main/api/routes/restructure/base.py | 4 +- r2r/main/api/routes/retrieval/base.py | 477 ++---------------- .../retrieval/retrieval_router_openapi.yml | 151 ++++++ r2r/main/app.py | 9 +- 4 files changed, 207 insertions(+), 434 deletions(-) create mode 100644 r2r/main/api/routes/retrieval/retrieval_router_openapi.yml diff --git a/r2r/main/api/routes/restructure/base.py b/r2r/main/api/routes/restructure/base.py index 747d5ed7e..bf07fdc05 100644 --- a/r2r/main/api/routes/restructure/base.py +++ b/r2r/main/api/routes/restructure/base.py @@ -1,6 +1,4 @@ -from typing import List, Optional - -from fastapi import Depends, Form +from fastapi import Depends from r2r.main.api.routes.base_router import BaseRouter from r2r.main.engine import R2REngine diff --git a/r2r/main/api/routes/retrieval/base.py b/r2r/main/api/routes/retrieval/base.py index f52a69748..b5c4f6e2e 100644 --- a/r2r/main/api/routes/retrieval/base.py +++ b/r2r/main/api/routes/retrieval/base.py @@ -1,5 +1,7 @@ +from pathlib import Path from typing import Optional +import yaml from fastapi import Body, Depends from fastapi.responses import StreamingResponse @@ -10,7 +12,11 @@ RunType, VectorSearchSettings, ) -from r2r.base.api.models import WrappedRAGResponse, WrappedSearchResponse +from r2r.base.api.models import ( + WrappedRAGAgentResponse, + WrappedRAGResponse, + WrappedSearchResponse, +) from ....engine import R2REngine from ..base_router import BaseRouter @@ -19,138 +25,34 @@ class RetrievalRouter(BaseRouter): def __init__(self, engine: R2REngine): super().__init__(engine) + self.openapi_extras = self.load_openapi_extras() self.setup_routes() + def load_openapi_extras(self): + yaml_path = Path(__file__).parent / "retrieval_router_openapi.yml" + with open(yaml_path, "r") as yaml_file: + yaml_content = yaml.safe_load(yaml_file) + return yaml_content + def retrieval_endpoint(self, run_type: RunType = RunType.RETRIEVAL): return self.base_endpoint(run_type) def setup_routes(self): + search_extras = self.openapi_extras.get("search", {}) + search_descriptions = search_extras.get("input_descriptions", {}) + @self.router.post( "/search", - responses={ - 200: { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "results": { - "type": "object", - "properties": { - "vector_search_results": { - "type": "array", - "items": { - "type": "object", - "properties": { - "fragment_id": { - "type": "string" - }, - "extraction_id": { - "type": "string" - }, - "document_id": { - "type": "string" - }, - "user_id": { - "type": "string" - }, - "group_ids": { - "type": "array", - "items": { - "type": "string" - }, - }, - "score": { - "type": "number" - }, - "text": { - "type": "string" - }, - "metadata": { - "type": "object" - }, - }, - }, - }, - "kg_search_results": { - "type": "object", - "nullable": True, - }, - }, - } - }, - }, - "example": { - "results": { - "vector_search_results": [ - { - "fragment_id": "c68dc72e-fc23-5452-8f49-d7bd46088a96", - "extraction_id": "3f3d47f3-8baf-58eb-8bc2-0171fb1c6e09", - "document_id": "3e157b3a-8469-51db-90d9-52e7d896b49b", - "user_id": "2acb499e-8428-543b-bd85-0d9098718220", - "group_ids": [], - "score": 0.93943702876567796, - "text": "The capital of France is Paris.", - "metadata": { - "title": "france_information.pdf", - "associatedQuery": "What is the capital of France?", - }, - }, - "... Results continued ...", - ], - "kg_search_results": None, - } - }, - } - }, - } - }, - openapi_extra={ - "x-codeSamples": [ - { - "lang": "Python", - "source": """from r2r import R2RClient - -client = R2RClient("http://localhost:8000") -# when using auth, do client.login(...) - -result = client.search( - query="What is the capital of France?", - vector_search_settings={ - "use_vector_search": True, - "filters": {"document_id": {"eq": "3e157b3a-8469-51db-90d9-52e7d896b49b"}}, - "search_limit": 20, - "do_hybrid_search": True - } -) -""", - }, - { - "lang": "Shell", - "source": """curl -X POST "https://api.example.com/search" \\ - -H "Content-Type: application/json" \\ - -H "Authorization: Bearer YOUR_API_KEY" \\ - -d '{ - "query": "What is the capital of France?", - "vector_search_settings": { - "use_vector_search": true, - "filters": {"document_id": {"eq": "3e157b3a-8469-51db-90d9-52e7d896b49b"}}, - "search_limit": 20, - "do_hybrid_search": true - } - }' -""", - }, - ] - }, + openapi_extra=search_extras.get("openapi_extra"), ) @self.retrieval_endpoint async def search_app( - query: str = Body(..., description="Search query"), + query: str = Body( + ..., description=search_descriptions.get("query") + ), vector_search_settings: VectorSearchSettings = Body( default_factory=VectorSearchSettings, - description="Vector search settings", + description=search_descriptions.get("vector_search_settings"), example={ "use_vector_search": True, "filters": {"category": "technology"}, @@ -160,7 +62,7 @@ async def search_app( ), kg_search_settings: KGSearchSettings = Body( default_factory=KGSearchSettings, - description="Knowledge graph search settings", + description=search_descriptions.get("kg_search_settings"), ), auth_user=Depends(self.engine.providers.auth.auth_wrapper), ) -> WrappedSearchResponse: @@ -169,16 +71,15 @@ async def search_app( This endpoint allows for complex filtering of search results using PostgreSQL-based queries. Filters can be applied to various fields such as document_id, and internal metadata values. - Allowed operators include eq, neq, gt, gte, lt, lte, like, ilike, in, and nin. + + + Allowed filtered operators include `eq`, `neq`, `gt`, `gte`, `lt`, `lte`, `like`, `ilike`, `in`, and `nin`. """ user_groups = set(auth_user.group_ids) - print("user_groups = ", user_groups) selected_groups = set(vector_search_settings.selected_group_ids) - print("selected_groups = ", selected_groups) allowed_groups = user_groups.intersection(selected_groups) - print("allowed_groups = ", allowed_groups) if selected_groups - allowed_groups != set(): raise ValueError( "User does not have access to the specified group(s): " @@ -192,173 +93,38 @@ async def search_app( ], "$and": vector_search_settings.filters, } - print("filters = ", vector_search_settings) - results = await self.engine.asearch( query=query, vector_search_settings=vector_search_settings, kg_search_settings=kg_search_settings, user=auth_user, ) - print("Returning Results:", results) return results + rag_extras = self.openapi_extras.get("rag", {}) + rag_descriptions = rag_extras.get("input_descriptions", {}) + @self.router.post( "/rag", - responses={ - 200: { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "results": { - "type": "object", - "properties": { - "completion": { - "type": "object", - "properties": { - "id": {"type": "string"}, - "choices": { - "type": "array", - "items": { - "type": "object", - "properties": { - "finish_reason": { - "type": "string" - }, - "index": { - "type": "integer" - }, - "message": { - "type": "object", - "properties": { - "content": { - "type": "string" - }, - "role": { - "type": "string" - }, - }, - }, - }, - }, - }, - }, - }, - "search_results": { - "$ref": "#/components/schemas/SearchResponse" - }, - }, - } - }, - }, - "example": { - "results": { - "completion": { - "id": "chatcmpl-123", - "choices": [ - { - "finish_reason": "stop", - "index": 0, - "message": { - "content": "The capital of France is Paris. It is known for its iconic landmarks such as the Eiffel Tower, the Louvre Museum, and Notre-Dame Cathedral.", - "role": "assistant", - }, - } - ], - }, - "search_results": { - "vector_search_results": [ - { - "fragment_id": "c68dc72e-fc23-5452-8f49-d7bd46088a96", - "extraction_id": "3f3d47f3-8baf-58eb-8bc2-0171fb1c6e09", - "document_id": "3e157b3a-8469-51db-90d9-52e7d896b49b", - "user_id": "2acb499e-8428-543b-bd85-0d9098718220", - "group_ids": [], - "score": 0.93943702876567796, - "text": "Paris is the capital of France and is famous for its landmarks.", - "metadata": { - "title": "france_information.pdf", - "associatedQuery": "What is the capital of France?", - }, - } - ], - "kg_search_results": None, - }, - } - }, - } - }, - } - }, - openapi_extra={ - "x-codeSamples": [ - { - "lang": "Python", - "source": """from r2r import R2RClient - -client = R2RClient("http://localhost:8000") -# when using auth, do client.login(...) - -result = client.rag( - query="What is the capital of France?", - vector_search_settings={ - "use_vector_search": True, - "filters": {"document_id": {"eq": "3e157b3a-8469-51db-90d9-52e7d896b49b"}}, - "search_limit": 20, - "do_hybrid_search": True - }, - rag_generation_config={ - "stream": False, - "temperature": 0.7, - "max_tokens": 150 - } -) -""", - }, - { - "lang": "Shell", - "source": """curl -X POST "https://api.example.com/rag" \\ - -H "Content-Type: application/json" \\ - -H "Authorization: Bearer YOUR_API_KEY" \\ - -d '{ - "query": "What is the capital of France?", - "vector_search_settings": { - "use_vector_search": true, - "filters": {"document_id": {"eq": "3e157b3a-8469-51db-90d9-52e7d896b49b"}}, - "search_limit": 20, - "do_hybrid_search": true - }, - "rag_generation_config": { - "stream": false, - "temperature": 0.7, - "max_tokens": 150 - } - }' -""", - }, - ] - }, + openapi_extra=rag_extras.get("openapi_extra"), ) @self.retrieval_endpoint async def rag_app( - query: str = Body(..., description="RAG query"), + query: str = Body(..., description=rag_descriptions.get("query")), vector_search_settings: VectorSearchSettings = Body( default_factory=VectorSearchSettings, - description="Vector search settings", + description=rag_descriptions.get("vector_search_settings"), ), kg_search_settings: KGSearchSettings = Body( default_factory=KGSearchSettings, - description="Knowledge graph search settings", + description=rag_descriptions.get("kg_search_settings"), ), rag_generation_config: GenerationConfig = Body( default_factory=GenerationConfig, - description="RAG generation configuration", + description=rag_descriptions.get("rag_generation_config"), ), task_prompt_override: Optional[str] = Body( - None, description="Task prompt override" + None, description=rag_descriptions.get("task_prompt_override") ), auth_user=Depends(self.engine.providers.auth.auth_wrapper), ) -> WrappedRAGResponse: @@ -401,184 +167,42 @@ async def stream_generator(): else: return response + agent_extras = self.openapi_extras.get("agent", {}) + agent_descriptions = agent_extras.get("input_descriptions", {}) + @self.router.post( "/agent", - responses={ - 200: { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "results": { - "type": "array", - "items": { - "type": "object", - "properties": { - "role": {"type": "string"}, - "content": {"type": "string"}, - "name": { - "type": "string", - "nullable": True, - }, - "function_call": { - "type": "object", - "nullable": True, - }, - "tool_calls": { - "type": "array", - "nullable": True, - }, - }, - }, - } - }, - }, - "example": { - "results": [ - { - "role": "system", - "content": "## You are a helpful assistant that can search for information.\n\nWhen asked a question, perform a search to find relevant information and provide a response.\n\nThe response should contain line-item attributions to relevent search results, and be as informative if possible.\nIf no relevant results are found, then state that no results were found.\nIf no obvious question is present, then do not carry out a search, and instead ask for clarification.", - "name": None, - "function_call": None, - "tool_calls": None, - }, - { - "role": "user", - "content": "Who is the greatest philospher of all time?", - "name": None, - "function_call": None, - "tool_calls": None, - }, - { - "role": "assistant", - "content": "Aristotle is widely considered the greatest philospher of all time.", - "name": None, - "function_call": None, - "tool_calls": None, - }, - { - "role": "user", - "content": "Can you tell me more about him?", - "name": None, - "function_call": None, - "tool_calls": None, - }, - { - "role": "assistant", - "content": None, - "name": None, - "function_call": { - "name": "search", - "arguments": '{"query":"Aristotle biography"}', - }, - "tool_calls": None, - }, - { - "role": "function", - "content": "1. Aristotle[A] (Greek: Ἀριστοτέλης Aristotélēs, pronounced [aristotélɛːs]; 384–322 BC) was an Ancient Greek philosopher and polymath. His writings cover a broad range of subjects spanning the natural sciences, philosophy, linguistics, economics, politics, psychology, and the arts. As the founder of the Peripatetic school of philosophy in the Lyceum in Athens, he began the wider Aristotelian tradition that followed, which set the groundwork for the development of modern science.\n2. Aristotle[A] (Greek: Ἀριστοτέλης Aristotélēs, pronounced [aristotélɛːs]; 384–322 BC) was an Ancient Greek philosopher and polymath. His writings cover a broad range of subjects spanning the natural sciences, philosophy, linguistics, economics, politics, psychology, and the arts. As the founder of the Peripatetic school of philosophy in the Lyceum in Athens, he began the wider Aristotelian tradition that followed, which set the groundwork for the development of modern science.\n3. Aristotle was born in 384 BC[C] in Stagira, Chalcidice,[2] about 55 km (34 miles) east of modern-day Thessaloniki.[3][4] His father, Nicomachus, was the personal physician to King Amyntas of Macedon. While he was young, Aristotle learned about biology and medical information, which was taught by his father.[5] Both of Aristotle's parents died when he was about thirteen, and Proxenus of Atarneus became his guardian.[6] Although little information about Aristotle's childhood has survived, he probably spent\n4. Aristotle was born in 384 BC[C] in Stagira, Chalcidice,[2] about 55 km (34 miles) east of modern-day Thessaloniki.[3][4] His father, Nicomachus, was the personal physician to King Amyntas of Macedon. While he was young, Aristotle learned about biology and medical information, which was taught by his father.[5] Both of Aristotle's parents died when he was about thirteen, and Proxenus of Atarneus became his guardian.[6] Although little information about Aristotle's childhood has survived, he probably spent\n5. Life\nIn general, the details of Aristotle's life are not well-established. The biographies written in ancient times are often speculative and historians only agree on a few salient points.[B]\n", - "name": "search", - "function_call": None, - "tool_calls": None, - }, - { - "role": "assistant", - "content": "Aristotle (384–322 BC) was an Ancient Greek philosopher and polymath whose contributions have had a profound impact on various fields of knowledge. Here are some key points about his life and work:\n\n1. **Early Life**: Aristotle was born in 384 BC in Stagira, Chalcidice, which is near modern-day Thessaloniki, Greece. His father, Nicomachus, was the personal physician to King Amyntas of Macedon, which exposed Aristotle to medical and biological knowledge from a young age [C].\n\n2. **Education and Career**: After the death of his parents, Aristotle was sent to Athens to study at Plato's Academy, where he remained for about 20 years. After Plato's death, Aristotle left Athens and eventually became the tutor of Alexander the Great [C].\n\n3. **Philosophical Contributions**: Aristotle founded the Lyceum in Athens, where he established the Peripatetic school of philosophy. His works cover a wide range of subjects, including metaphysics, ethics, politics, logic, biology, and aesthetics. His writings laid the groundwork for many modern scientific and philosophical inquiries [A].\n\n4. **Legacy**: Aristotle's influence extends beyond philosophy to the natural sciences, linguistics, economics, and psychology. His method of systematic observation and analysis has been foundational to the development of modern science [A].\n\nAristotle's comprehensive approach to knowledge and his systematic methodology have earned him a lasting legacy as one of the greatest philosophers of all time.\n\nSources:\n- [A] Aristotle's broad range of writings and influence on modern science.\n- [C] Details about Aristotle's early life and education.", - "name": None, - "function_call": None, - "tool_calls": None, - }, - ] - }, - } - }, - } - }, - openapi_extra={ - "x-codeSamples": [ - { - "lang": "Python", - "source": """from r2r import R2RClient - -client = R2RClient("http://localhost:8000") -# when using auth, do client.login(...) - -result = client.agent( - messages=[ - {"role": "user", "content": "Who is the greatest philospher of all time?"}, - {"role": "assistant", "content": "Aristotle is widely considered the greatest philospher of all time."}, - {"role": "user", "content": "Can you tell me more about him?"} - ], - vector_search_settings={ - "use_vector_search": True, - "filters": {"document_id": {"eq": "5e157b3a-8469-51db-90d9-52e7d896b49b"}}, - "search_limit": 20, - "do_hybrid_search": True - }, - rag_generation_config={ - "stream": False, - "temperature": 0.7, - "max_tokens": 200 - }, - include_title_if_available=True -) -""", - }, - { - "lang": "Shell", - "source": """curl -X POST "https://api.example.com/agent" \\ - -H "Content-Type: application/json" \\ - -H "Authorization: Bearer YOUR_API_KEY" \\ - -d '{ - "messages": [ - {"role": "user", "content": "Who is the greatest philospher of all time?"}, - {"role": "assistant", "content": "Aristotle is widely considered the greatest philospher of all time."}, - {"role": "user", "content": "Can you tell me more about him?"} - ], - "vector_search_settings": { - "use_vector_search": true, - "filters": {"document_id": {"eq": "5e157b3a-8469-51db-90d9-52e7d896b49b"}}, - "search_limit": 20, - "do_hybrid_search": true - }, - "rag_generation_config": { - "stream": false, - "temperature": 0.7, - "max_tokens": 200 - }, - "include_title_if_available": true - }' -""", - }, - ] - }, + openapi_extra=agent_extras.get("openapi_extra"), ) @self.retrieval_endpoint async def agent_app( messages: list[Message] = Body( - ..., description="List of message objects" + ..., description=agent_descriptions.get("messages") ), vector_search_settings: VectorSearchSettings = Body( default_factory=VectorSearchSettings, - description="Vector search settings", + description=agent_descriptions.get("vector_search_settings"), ), kg_search_settings: KGSearchSettings = Body( default_factory=KGSearchSettings, - description="Knowledge graph search settings", + description=agent_descriptions.get("kg_search_settings"), ), rag_generation_config: GenerationConfig = Body( default_factory=GenerationConfig, - description="RAG generation configuration", + description=agent_descriptions.get("rag_generation_config"), ), task_prompt_override: Optional[str] = Body( - None, description="Task prompt override" + None, + description=agent_descriptions.get("task_prompt_override"), ), include_title_if_available: bool = Body( - True, description="Include title if available" + True, + description=agent_descriptions.get( + "include_title_if_available" + ), ), auth_user=Depends(self.engine.providers.auth.auth_wrapper), - ): + ) -> WrappedRAGAgentResponse: """ Implement an agent-based interaction for complex query processing. @@ -597,7 +221,6 @@ async def agent_app( ], "$and": vector_search_settings.filters, } - print("filters = ", vector_search_settings) response = await self.engine.arag_agent( messages=messages, vector_search_settings=vector_search_settings, diff --git a/r2r/main/api/routes/retrieval/retrieval_router_openapi.yml b/r2r/main/api/routes/retrieval/retrieval_router_openapi.yml new file mode 100644 index 000000000..7faa8c0b2 --- /dev/null +++ b/r2r/main/api/routes/retrieval/retrieval_router_openapi.yml @@ -0,0 +1,151 @@ +search: + openapi_extra: + x-codeSamples: + - lang: Python + source: | + from r2r import R2RClient + + client = R2RClient("http://localhost:8000") + # when using auth, do client.login(...) + + result = client.search( + query="What is the capital of France?", + vector_search_settings={ + "use_vector_search": True, + "filters": {"document_id": {"eq": "3e157b3a-8469-51db-90d9-52e7d896b49b"}}, + "search_limit": 20, + "do_hybrid_search": True + } + ) + - lang: Shell + source: | + curl -X POST "https://api.example.com/search" \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer YOUR_API_KEY" \ + -d '{ + "query": "What is the capital of France?", + "vector_search_settings": { + "use_vector_search": true, + "filters": {"document_id": {"eq": "3e157b3a-8469-51db-90d9-52e7d896b49b"}}, + "search_limit": 20, + "do_hybrid_search": true + } + }' + + input_descriptions: + query: "Search query" + vector_search_settings: "Vector search settings" + kg_search_settings: "Knowledge graph search settings" + +rag: + openapi_extra: + x-codeSamples: + - lang: Python + source: | + from r2r import R2RClient + + client = R2RClient("http://localhost:8000") + # when using auth, do client.login(...) + + result = client.rag( + query="What is the capital of France?", + vector_search_settings={ + "use_vector_search": True, + "filters": {"document_id": {"eq": "3e157b3a-8469-51db-90d9-52e7d896b49b"}}, + "search_limit": 20, + "do_hybrid_search": True + }, + rag_generation_config={ + "stream": False, + "temperature": 0.7, + "max_tokens": 150 + } + ) + - lang: Shell + source: | + curl -X POST "https://api.example.com/rag" \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer YOUR_API_KEY" \ + -d '{ + "query": "What is the capital of France?", + "vector_search_settings": { + "use_vector_search": true, + "filters": {"document_id": {"eq": "3e157b3a-8469-51db-90d9-52e7d896b49b"}}, + "search_limit": 20, + "do_hybrid_search": true + }, + "rag_generation_config": { + "stream": false, + "temperature": 0.7, + "max_tokens": 150 + } + }' + + input_descriptions: + query: "RAG query" + vector_search_settings: "Vector search settings" + kg_search_settings: "Knowledge graph search settings" + rag_generation_config: "RAG generation configuration" + task_prompt_override: "Task prompt override" + +agent: + openapi_extra: + x-codeSamples: + - lang: Python + source: | + from r2r import R2RClient + + client = R2RClient("http://localhost:8000") + # when using auth, do client.login(...) + + result = client.agent( + messages=[ + {"role": "user", "content": "Who is the greatest philospher of all time?"}, + {"role": "assistant", "content": "Aristotle is widely considered the greatest philospher of all time."}, + {"role": "user", "content": "Can you tell me more about him?"} + ], + vector_search_settings={ + "use_vector_search": True, + "filters": {"document_id": {"eq": "5e157b3a-8469-51db-90d9-52e7d896b49b"}}, + "search_limit": 20, + "do_hybrid_search": True + }, + rag_generation_config={ + "stream": False, + "temperature": 0.7, + "max_tokens": 200 + }, + include_title_if_available=True + ) + - lang: Shell + source: | + curl -X POST "https://api.example.com/agent" \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer YOUR_API_KEY" \ + -d '{ + "messages": [ + {"role": "user", "content": "Who is the greatest philospher of all time?"}, + {"role": "assistant", "content": "Aristotle is widely considered the greatest philospher of all time."}, + {"role": "user", "content": "Can you tell me more about him?"} + ], + "vector_search_settings": { + "use_vector_search": true, + "filters": {"document_id": {"eq": "5e157b3a-8469-51db-90d9-52e7d896b49b"}}, + "search_limit": 20, + "do_hybrid_search": true + }, + "rag_generation_config": { + "stream": false, + "temperature": 0.7, + "max_tokens": 200 + }, + "include_title_if_available": true + }' + + input_descriptions: + messages: "List of message objects" + vector_search_settings: "Vector search settings" + kg_search_settings: "Knowledge graph search settings" + rag_generation_config: "RAG generation configuration" + task_prompt_override: "Task prompt override" + include_title_if_available: "Include title if available" diff --git a/r2r/main/app.py b/r2r/main/app.py index 0727d81c1..2dd61787c 100644 --- a/r2r/main/app.py +++ b/r2r/main/app.py @@ -20,9 +20,8 @@ def serve(self, host: str = "0.0.0.0", port: int = 8000): def _setup_routes(self): from .api.routes.auth import base as auth_base from .api.routes.ingestion import base as ingestion_base - from .api.routes.kg import base as kg_base from .api.routes.management import base as management_base - from .api.routes.restructure import base as kg_base + from .api.routes.restructure import base as restructure_base from .api.routes.retrieval import base as retrieval_base self.app = FastAPI() @@ -39,14 +38,16 @@ def _setup_routes(self): ) auth_router = auth_base.AuthRouter.build_router(self.engine) - kg_router = kg_base.RestructureRouter.build_router(self.engine) + restructure_router = restructure_base.RestructureRouter.build_router( + self.engine + ) # Include routers in the app self.app.include_router(ingestion_router, prefix="/v1") self.app.include_router(management_router, prefix="/v1") self.app.include_router(retrieval_router, prefix="/v1") self.app.include_router(auth_router, prefix="/v1") - self.app.include_router(kg_router, prefix="/v1") + self.app.include_router(restructure_router, prefix="/v1") @self.app.router.get("/v1/openapi_spec") async def openapi_spec(): From 21701f2801abee0a59adaef74c8f9b67fd9e037f Mon Sep 17 00:00:00 2001 From: Nolan Tremelling <34580718+NolanTrem@users.noreply.github.com> Date: Mon, 19 Aug 2024 14:24:39 -0700 Subject: [PATCH 09/74] Python SDK (#886) Clean up Python SDK and routes --- r2r/__init__.py | 1 - r2r/base/__init__.py | 1 - r2r/base/providers/__init__.py | 2 - r2r/base/providers/database.py | 2 - r2r/main/api/client/auth.py | 151 +++++-- r2r/main/api/client/client.py | 1 - r2r/main/api/client/ingestion.py | 13 +- r2r/main/api/client/management.py | 505 +++++++++++++++++------ r2r/main/api/client/restructure.py | 23 +- r2r/main/api/client/retrieval.py | 62 ++- r2r/main/api/routes/auth/base.py | 39 +- r2r/main/api/routes/ingestion/base.py | 44 +- r2r/main/api/routes/management/base.py | 292 +++++++------ r2r/main/api/routes/restructure/base.py | 1 + r2r/main/execution.py | 7 +- r2r/main/services/management_service.py | 16 +- r2r/main/services/restructure_service.py | 4 +- 17 files changed, 749 insertions(+), 415 deletions(-) diff --git a/r2r/__init__.py b/r2r/__init__.py index 7683ef22e..b668bda9e 100644 --- a/r2r/__init__.py +++ b/r2r/__init__.py @@ -147,7 +147,6 @@ "DatabaseProvider", "RelationalDBProvider", "VectorDBProvider", - "VectorDBFilterValue", # Embedding provider "EmbeddingConfig", "EmbeddingProvider", diff --git a/r2r/base/__init__.py b/r2r/base/__init__.py index 8c56ecf62..09f9e00e3 100644 --- a/r2r/base/__init__.py +++ b/r2r/base/__init__.py @@ -116,7 +116,6 @@ "DatabaseProvider", "RelationalDBProvider", "VectorDBProvider", - "VectorDBFilterValue", # Embedding provider "EmbeddingConfig", "EmbeddingProvider", diff --git a/r2r/base/providers/__init__.py b/r2r/base/providers/__init__.py index 487756f6b..87fe0e698 100644 --- a/r2r/base/providers/__init__.py +++ b/r2r/base/providers/__init__.py @@ -6,7 +6,6 @@ DatabaseConfig, DatabaseProvider, RelationalDBProvider, - VectorDBFilterValue, VectorDBProvider, ) from .embedding import EmbeddingConfig, EmbeddingProvider @@ -34,7 +33,6 @@ "DatabaseProvider", "RelationalDBProvider", "VectorDBProvider", - "VectorDBFilterValue", # Embedding provider "EmbeddingConfig", "EmbeddingProvider", diff --git a/r2r/base/providers/database.py b/r2r/base/providers/database.py index a286e3151..354c7a2da 100644 --- a/r2r/base/providers/database.py +++ b/r2r/base/providers/database.py @@ -10,8 +10,6 @@ logger = logging.getLogger(__name__) -VectorDBFilterValue = Union[str, UUID] - class DatabaseConfig(ProviderConfig): def __post_init__(self): diff --git a/r2r/main/api/client/auth.py b/r2r/main/api/client/auth.py index 5631bbd8f..27b8ad71b 100644 --- a/r2r/main/api/client/auth.py +++ b/r2r/main/api/client/auth.py @@ -1,5 +1,4 @@ from typing import Optional -from uuid import UUID from r2r.base import Token from r2r.base.api.models.auth.responses import UserResponse @@ -8,11 +7,28 @@ class AuthMethods: @staticmethod async def register(client, email: str, password: str) -> UserResponse: + """ + Registers a new user with the given email and password. + + Args: + email (str): The email of the user to register. + password (str): The password of the user to register. + + Returns: + UserResponse: The response from the server. + """ data = {"email": email, "password": password} return await client._make_request("POST", "register", json=data) @staticmethod async def verify_email(client, verification_code: str) -> dict: + """ + Verifies the email of a user with the given verification code. + + Args: + verification_code (str): The verification code to verify the email with. + + """ return await client._make_request( "POST", "verify_email", @@ -21,18 +37,82 @@ async def verify_email(client, verification_code: str) -> dict: @staticmethod async def login(client, email: str, password: str) -> dict[str, Token]: + """ + Attempts to log in a user with the given email and password. + + Args: + email (str): The email of the user to log in. + password (str): The password of the user to log in. + + Returns: + dict[str, Token]: The access and refresh tokens from the server. + """ data = {"username": email, "password": password} response = await client._make_request("POST", "login", data=data) client.access_token = response["results"]["access_token"]["token"] client._refresh_token = response["results"]["refresh_token"]["token"] return response + @staticmethod + async def logout(client) -> dict: + """ + Logs out the currently authenticated user. + + Returns: + dict: The response from the server. + """ + response = await client._make_request("POST", "logout") + client.access_token = None + client._refresh_token = None + return response + @staticmethod async def user(client) -> UserResponse: + """ + Retrieves the user information for the currently authenticated user. + + Returns: + UserResponse: The response from the server. + """ return await client._make_request("GET", "user") + @staticmethod + async def update_user( + client, + email: Optional[str] = None, + name: Optional[str] = None, + bio: Optional[str] = None, + profile_picture: Optional[str] = None, + ) -> UserResponse: + """ + Updates the profile information for the currently authenticated user. + + Args: + email (str, optional): The updated email for the user. + name (str, optional): The updated name for the user. + bio (str, optional): The updated bio for the user. + profile_picture (str, optional): The updated profile picture URL for the user. + + Returns: + UserResponse: The response from the server. + """ + data = { + "email": email, + "name": name, + "bio": bio, + "profile_picture": profile_picture, + } + data = {k: v for k, v in data.items() if v is not None} + return await client._make_request("PUT", "user", json=data) + @staticmethod async def refresh_access_token(client) -> dict[str, Token]: + """ + Refreshes the access token for the currently authenticated user. + + Returns: + dict[str, Token]: The access and refresh tokens from the server. + """ data = {"refresh_token": client._refresh_token} response = await client._make_request( "POST", "refresh_access_token", json=data @@ -45,6 +125,16 @@ async def refresh_access_token(client) -> dict[str, Token]: async def change_password( client, current_password: str, new_password: str ) -> dict: + """ + Changes the password of the currently authenticated user. + + Args: + current_password (str): The current password of the user. + new_password (str): The new password to set for the user. + + Returns: + dict: The response from the server. + """ data = { "current_password": current_password, "new_password": new_password, @@ -53,6 +143,15 @@ async def change_password( @staticmethod async def request_password_reset(client, email: str) -> dict: + """ + Requests a password reset for the user with the given email. + + Args: + email (str): The email of the user to request a password reset for. + + Returns: + dict: The response from the server. + """ return await client._make_request( "POST", "request_password_reset", json={"email": email} ) @@ -61,38 +160,36 @@ async def request_password_reset(client, email: str) -> dict: async def confirm_password_reset( client, reset_token: str, new_password: str ) -> dict: - data = {"reset_token": reset_token, "new_password": new_password} - return await client._make_request("POST", "reset_password", json=data) + """ + Confirms a password reset for the user with the given reset token. - @staticmethod - async def logout(client) -> dict: - response = await client._make_request("POST", "logout") - client.access_token = None - client._refresh_token = None - return response + Args: + reset_token (str): The reset token to confirm the password reset with. + new_password (str): The new password to set for the user. - @staticmethod - async def update_user( - client, - email: Optional[str] = None, - name: Optional[str] = None, - bio: Optional[str] = None, - profile_picture: Optional[str] = None, - ) -> UserResponse: - data = { - "email": email, - "name": name, - "bio": bio, - "profile_picture": profile_picture, - } - data = {k: v for k, v in data.items() if v is not None} - return await client._make_request("PUT", "user", json=data) + Returns: + dict: The response from the server. + """ + data = {"reset_token": reset_token, "new_password": new_password} + return await client._make_request("POST", "reset_password", json=data) @staticmethod async def delete_user( - client, user_id: UUID, password: Optional[str] = None + client, user_id: str, password: Optional[str] = None ) -> dict: - data = {"user_id": str(user_id), "password": password} + """ + Deletes the user with the given user ID. + + Args: + user_id (str): The ID of the user to delete. + password (str, optional): The password of the user to delete. + + Returns: + dict: The response from the server. + """ + data = {"user_id": user_id} + if password: + data["password"] = password response = await client._make_request("DELETE", "user", json=data) client.access_token = None client._refresh_token = None diff --git a/r2r/main/api/client/client.py b/r2r/main/api/client/client.py index a6935c1b2..9e44267e6 100644 --- a/r2r/main/api/client/client.py +++ b/r2r/main/api/client/client.py @@ -8,7 +8,6 @@ from r2r.base import R2RException -# Import the new client modules from .auth import AuthMethods from .ingestion import IngestionMethods from .management import ManagementMethods diff --git a/r2r/main/api/client/ingestion.py b/r2r/main/api/client/ingestion.py index cb68c47b3..796e57e8a 100644 --- a/r2r/main/api/client/ingestion.py +++ b/r2r/main/api/client/ingestion.py @@ -2,7 +2,6 @@ import os from contextlib import ExitStack from typing import Optional, Union -from uuid import UUID from r2r.base import ChunkingConfig @@ -13,18 +12,18 @@ class IngestionMethods: async def ingest_files( client, file_paths: list[str], - document_ids: Optional[list[UUID]] = None, - versions: Optional[list[str]] = None, metadatas: Optional[list[dict]] = None, + document_ids: Optional[list[str]] = None, + versions: Optional[list[str]] = None, chunking_config_override: Optional[Union[dict, ChunkingConfig]] = None, ) -> dict: """ - Ingest files into the system. + Ingest files into your R2R deployment Args: file_paths (List[str]): List of file paths to ingest. metadatas (Optional[List[dict]]): List of metadata dictionaries for each file. - document_ids (Optional[List[Union[UUID, str]]]): List of document IDs. + document_ids (Optional[List[str]]): List of document IDs. versions (Optional[List[str]]): List of version strings for each file. chunking_config_override (Optional[Union[dict, ChunkingConfig]]): Custom chunking configuration. @@ -80,12 +79,12 @@ async def ingest_files( async def update_files( client, file_paths: list[str], - document_ids: Optional[list[UUID]] = None, + document_ids: Optional[list[str]] = None, metadatas: Optional[list[dict]] = None, chunking_config_override: Optional[Union[dict, ChunkingConfig]] = None, ) -> dict: """ - Update existing files in the system. + Update existing files in your R2R deployment. Args: file_paths (List[str]): List of file paths to update. diff --git a/r2r/main/api/client/management.py b/r2r/main/api/client/management.py index ea80e1081..40d62d406 100644 --- a/r2r/main/api/client/management.py +++ b/r2r/main/api/client/management.py @@ -1,13 +1,16 @@ import json from typing import Optional, Union -from uuid import UUID - -from r2r.base import VectorDBFilterValue class ManagementMethods: @staticmethod async def server_stats(client) -> dict: + """ + Get statistics about the server, including the start time, uptime, CPU usage, and memory usage. + + Returns: + dict: The server statistics. + """ return await client._make_request("GET", "server_stats") @staticmethod @@ -15,41 +18,107 @@ async def update_prompt( client, name: str, template: Optional[str] = None, - input_types: Optional[dict[str, str]] = {}, + input_types: Optional[dict[str, str]] = None, ) -> dict: - data = { - "name": name, - "template": template, - "input_types": input_types, - } + """ + Update a prompt in the database. + + Args: + name (str): The name of the prompt to update. + template (Optional[str]): The new template for the prompt. + input_types (Optional[dict[str, str]]): The new input types for the prompt. + + Returns: + dict: The response from the server. + """ + data = {name: name} + if template is not None: + data["template"] = template + if input_types is not None: + data["input_types"] = input_types + return await client._make_request("POST", "update_prompt", json=data) + @staticmethod + async def analytics( + client, + filter_criteria: Optional[Union[dict, str]] = None, + analysis_types: Optional[Union[dict, str]] = None, + ) -> dict: + """ + Get analytics data from the server. + + Args: + filter_criteria (Optional[Union[dict, str]]): The filter criteria to use. + analysis_types (Optional[Union[dict, str]]): The types of analysis to perform. + + Returns: + dict: The analytics data from the server. + """ + params = {} + if filter_criteria: + if isinstance(filter_criteria, dict): + params["filter_criteria"] = json.dumps(filter_criteria) + else: + params["filter_criteria"] = filter_criteria + if analysis_types: + if isinstance(analysis_types, dict): + params["analysis_types"] = json.dumps(analysis_types) + else: + params["analysis_types"] = analysis_types + + return await client._make_request("GET", "analytics", params=params) + @staticmethod async def logs( client, run_type_filter: Optional[str] = None, - max_runs: int = 100, + max_runs: int = None, ) -> dict: - params = { - "run_type_filter": run_type_filter, - "max_runs": max_runs, - } + """ + Get logs from the server. + + Args: + run_type_filter (Optional[str]): The run type to filter by. + max_runs (int): Specifies the maximum number of runs to return. Values outside the range of 1 to 1000 will be adjusted to the nearest valid value with a default of 100. + + Returns: + dict: The logs from the server. + """ + params = {} + if run_type_filter is not None: + params["run_type_filter"] = run_type_filter + if max_runs is not None: + params["max_runs"] = max_runs return await client._make_request("GET", "logs", params=params) @staticmethod async def app_settings(client) -> dict: + """ + Get the configuration settings for the app. + + Returns: + dict: The app settings. + """ return await client._make_request("GET", "app_settings") @staticmethod async def score_completion( client, - message_id: UUID, + message_id: str, score: float = 0.0, ) -> dict: - data = { - "message_id": str(message_id), - "score": score, - } + """ + Assign a score to a message from an LLM completion. The score should be a float between -1.0 and 1.0. + + Args: + message_id (str): The ID of the message to score. + score (float): The score to assign to the message. + + Returns: + dict: The response from the server. + """ + data = {"message_id": message_id, "score": score} return await client._make_request( "POST", "score_completion", json=data ) @@ -57,8 +126,17 @@ async def score_completion( @staticmethod async def users_overview( client, - user_ids: Optional[list[UUID]] = None, + user_ids: Optional[list[str]] = None, ) -> dict: + """ + An overview of users in the R2R deployment. + + Args: + user_ids (Optional[list[str]]): List of user IDs to get an overview for. + + Returns: + dict: The overview of users in the system. + """ params = { "user_ids": [str(uid) for uid in user_ids] if user_ids else None } @@ -69,8 +147,17 @@ async def users_overview( @staticmethod async def delete( client, - filters: dict[str, VectorDBFilterValue], + filters: dict[str, str], ) -> dict: + """ + Delete data from the database given a set of filters. + + Args: + filters (dict[str, str]): The filters to delete by. + + Returns: + dict: The results of the deletion. + """ filters_json = json.dumps(filters) return await client._make_request( @@ -80,19 +167,21 @@ async def delete( @staticmethod async def documents_overview( client, - user_ids: Optional[list[UUID]] = None, - group_ids: Optional[list[UUID]] = None, - document_ids: Optional[list[UUID]] = None, + document_ids: Optional[list[str]] = None, ) -> dict: - params = { - "user_ids": [str(uid) for uid in user_ids] if user_ids else None, - "group_ids": ( - [str(gid) for gid in group_ids] if group_ids else None - ), - "document_ids": ( - [str(did) for did in document_ids] if document_ids else None - ), - } + """ + Get an overview of documents in the R2R deployment. + + Args: + document_ids (Optional[list[str]]): List of document IDs to get an overview for. + + Returns: + dict: The overview of documents in the system. + """ + params = {} + if document_ids: + params["document_ids"] = document_ids + return await client._make_request( "GET", "documents_overview", params=params ) @@ -100,120 +189,193 @@ async def documents_overview( @staticmethod async def document_chunks( client, - document_id: UUID, + document_id: str, ) -> dict: + """ + Get the chunks for a document. + + Args: + document_id (str): The ID of the document to get chunks for. + + Returns: + dict: The chunks for the document. + """ return await client._make_request( - "GET", "document_chunks", params={"document_id": document_id} + "GET", f"document_chunks/{document_id}" ) @staticmethod async def inspect_knowledge_graph( client, - limit: int = 10000, - ) -> str: - params = {"limit": limit} + limit: Optional[int] = None, + ) -> dict: + """ + Inspect the knowledge graph associated with your R2R deployment. + + Args: + limit (Optional[int]): The maximum number of nodes to return. Defaults to 100. + + Returns: + dict: The knowledge graph inspection results. + """ + params = {} + if limit is not None: + params["limit"] = limit return await client._make_request( "GET", "inspect_knowledge_graph", params=params ) @staticmethod - async def assign_document_to_group( + async def groups_overview( client, - document_id: str, - group_id: UUID, + group_ids: Optional[list[str]] = None, + limit: Optional[int] = None, + offset: Optional[int] = None, ) -> dict: - data = { - "document_id": document_id, - "group_id": str(group_id), - } - return await client._make_request( - "POST", "assign_document_to_group", json=data - ) + """ + Get an overview of existing groups. - @staticmethod - async def remove_document_from_group( - client, - document_id: str, - group_id: UUID, - ) -> dict: - data = { - "document_id": document_id, - "group_id": str(group_id), - } - return await client._make_request( - "POST", "remove_document_from_group", json=data - ) + Args: + group_ids (Optional[list[str]]): List of group IDs to get an overview for. + limit (Optional[int]): The maximum number of groups to return. + offset (Optional[int]): The offset to start listing groups from. - @staticmethod - async def get_document_groups( - client, - document_id: str, - ) -> dict: + Returns: + dict: The overview of groups in the system. + """ + params = {} + if group_ids: + params["group_ids"] = group_ids + if limit: + params["limit"] = limit + if offset: + params["offset"] = offset return await client._make_request( - "GET", f"get_document_groups/{document_id}" + "GET", "groups_overview", params=params ) @staticmethod async def create_group( client, name: str, - description: str = "", + description: Optional[str] = None, ) -> dict: - data = { - "name": name, - "description": description, - } + """ + Create a new group. + + Args: + name (str): The name of the group. + description (Optional[str]): The description of the group. + + Returns: + dict: The response from the server. + """ + data = {"name": name} + if description is not None: + data["description"] = description + return await client._make_request("POST", "create_group", json=data) @staticmethod async def get_group( client, - group_id: UUID, + group_id: str, ) -> dict: + """ + Get a group by its ID. + + Args: + group_id (str): The ID of the group to get. + + Returns: + dict: The group data. + """ return await client._make_request("GET", f"get_group/{group_id}") @staticmethod async def update_group( client, - group_id: UUID, + group_id: str, name: Optional[str] = None, description: Optional[str] = None, ) -> dict: - data = { - "group_id": str(group_id), - "name": name, - "description": description, - } + """ + Updates the name and description of a group. + + Args: + group_id (str): The ID of the group to update. + name (Optional[str]): The new name for the group. + description (Optional[str]): The new description of the group. + + Returns: + dict: The response from the server. + """ + data = {"group_id": group_id} + if name is not None: + data["name"] = name + if description is not None: + data["description"] = description + return await client._make_request("PUT", "update_group", json=data) @staticmethod async def delete_group( client, - group_id: UUID, + group_id: str, ) -> dict: + """ + Delete a group by its ID. + + Args: + group_id (str): The ID of the group to delete. + + Returns: + dict: The response from the server. + """ return await client._make_request("DELETE", f"delete_group/{group_id}") @staticmethod async def list_groups( client, - offset: int = 0, - limit: int = 100, + offset: Optional[int] = None, + limit: Optional[int] = None, ) -> dict: - params = { - "offset": offset, - "limit": limit, - } + """ + List all groups in the R2R deployment. + + Args: + offset (Optional[int]): The offset to start listing groups from. + limit (Optional[int]): The maximum number of groups to return. + + Returns: + dict: The list of groups. + """ + params = {} + if offset is not None: + params["offset"] = offset + if limit is not None: + params["limit"] = limit return await client._make_request("GET", "list_groups", params=params) @staticmethod async def add_user_to_group( client, - user_id: UUID, - group_id: UUID, + user_id: str, + group_id: str, ) -> dict: + """ + Add a user to a group. + + Args: + user_id (str): The ID of the user to add. + group_id (str): The ID of the group to add the user to. + + Returns: + dict: The response from the server. + """ data = { - "user_id": str(user_id), - "group_id": str(group_id), + "user_id": user_id, + "group_id": group_id, } return await client._make_request( "POST", "add_user_to_group", json=data @@ -222,12 +384,22 @@ async def add_user_to_group( @staticmethod async def remove_user_from_group( client, - user_id: UUID, - group_id: UUID, + user_id: str, + group_id: str, ) -> dict: + """ + Remove a user from a group. + + Args: + user_id (str): The ID of the user to remove. + group_id (str): The ID of the group to remove the user from. + + Returns: + dict: The response from the server. + """ data = { - "user_id": str(user_id), - "group_id": str(group_id), + "user_id": user_id, + "group_id": group_id, } return await client._make_request( "POST", "remove_user_from_group", json=data @@ -236,14 +408,26 @@ async def remove_user_from_group( @staticmethod async def get_users_in_group( client, - group_id: UUID, - offset: int = 0, - limit: int = 100, + group_id: str, + offset: Optional[int] = None, + limit: Optional[int] = None, ) -> dict: - params = { - "offset": offset, - "limit": limit, - } + """ + Get all users in a group. + + Args: + group_id (str): The ID of the group to get users for. + offset (Optional[int]): The offset to start listing users from. + limit (Optional[int]): The maximum number of users to return. + + Returns: + dict: The list of users in the group. + """ + params = {} + if offset is not None: + params["offset"] = offset + if limit is not None: + params["limit"] = limit return await client._make_request( "GET", f"get_users_in_group/{group_id}", params=params ) @@ -251,60 +435,111 @@ async def get_users_in_group( @staticmethod async def get_groups_for_user( client, - user_id: UUID, + user_id: str, ) -> dict: + """ + Get all groups that a user is a member of. + + Args: + user_id (str): The ID of the user to get groups for. + + Returns: + dict: The list of groups that the user is a member of. + """ return await client._make_request( "GET", f"get_groups_for_user/{user_id}" ) @staticmethod - async def groups_overview( + async def assign_document_to_group( client, - group_ids: Optional[list[UUID]] = None, - limit: int = 100, - offset: int = 0, + document_id: str, + group_id: str, ) -> dict: - params = { - "limit": limit, - "offset": offset, + """ + Assign a document to a group. + + Args: + document_id (str): The ID of the document to assign. + group_id (str): The ID of the group to assign the document to. + + Returns: + dict: The response from the server. + """ + data = { + "document_id": document_id, + "group_id": group_id, } - if group_ids is not None: - params["group_ids"] = [str(gid) for gid in group_ids] return await client._make_request( - "GET", "groups_overview", params=params + "POST", "assign_document_to_group", json=data ) + # TODO: Verify that this method is implemented, also, should be a PUT request @staticmethod - async def get_documents_in_group( + async def remove_document_from_group( client, - group_id: UUID, - offset: int = 0, - limit: int = 100, + document_id: str, + group_id: str, ) -> dict: - params = { - "offset": offset, - "limit": limit, + """ + Remove a document from a group. + + Args: + document_id (str): The ID of the document to remove. + group_id (str): The ID of the group to remove the document from. + + Returns: + dict: The response from the server. + """ + data = { + "document_id": document_id, + "group_id": group_id, } return await client._make_request( - "GET", f"group/{group_id}/documents", params=params + "POST", "remove_document_from_group", json=data ) @staticmethod - async def analytics( + async def get_document_groups( client, - filter_criteria: Optional[Union[dict, str]] = None, - analysis_types: Optional[Union[dict, str]] = None, + document_id: str, ) -> dict: - params = {} - if filter_criteria: - if isinstance(filter_criteria, dict): - params["filter_criteria"] = json.dumps(filter_criteria) - else: - params["filter_criteria"] = filter_criteria - if analysis_types: - if isinstance(analysis_types, dict): - params["analysis_types"] = json.dumps(analysis_types) - else: - params["analysis_types"] = analysis_types + """ + Get all groups that a document is assigned to. - return await client._make_request("GET", "analytics", params=params) + Args: + document_id (str): The ID of the document to get groups for. + + Returns: + dict: The list of groups that the document is assigned to. + """ + return await client._make_request( + "GET", f"get_document_groups/{document_id}" + ) + + @staticmethod + async def get_documents_in_group( + client, + group_id: str, + offset: Optional[int] = None, + limit: Optional[int] = None, + ) -> dict: + """ + Get all documents in a group. + + Args: + group_id (str): The ID of the group to get documents for. + offset (Optional[int]): The offset to start listing documents from. + limit (Optional[int]): The maximum number of documents to return. + + Returns: + dict: The list of documents in the group. + """ + params = {} + if offset is not None: + params["offset"] = offset + if limit is not None: + params["limit"] = limit + return await client._make_request( + "GET", f"group/{group_id}/documents", params=params + ) diff --git a/r2r/main/api/client/restructure.py b/r2r/main/api/client/restructure.py index 801fdb5c3..251c1667f 100644 --- a/r2r/main/api/client/restructure.py +++ b/r2r/main/api/client/restructure.py @@ -1,25 +1,10 @@ -from typing import Any, Dict, List, Optional - -from r2r.base import Document - - class RestructureMethods: @staticmethod - async def enrich_graph( - client, documents: Optional[List[Document]] = None - ) -> Dict[str, Any]: + async def enrich_graph(client) -> dict: """ - Perform graph enrichment on the given documents. - - Args: - documents (Optional[List[Document]]): List of documents to enrich. If None, enriches the entire graph. + Perform graph enrichment over the entire graph. Returns: - Dict[str, Any]: Results of the graph enrichment process. + dict: Results of the graph enrichment process. """ - data = { - "documents": ( - [doc.model_dump() for doc in documents] if documents else None - ) - } - return await client._make_request("POST", "enrich_graph", json=data) + return await client._make_request("POST", "enrich_graph") diff --git a/r2r/main/api/client/retrieval.py b/r2r/main/api/client/retrieval.py index c28d1d2b2..8255c444b 100644 --- a/r2r/main/api/client/retrieval.py +++ b/r2r/main/api/client/retrieval.py @@ -21,6 +21,17 @@ async def search( *args, **kwargs ) -> SearchResponse: + """ + Conduct a vector and/or KG search. + + Args: + query (str): The query to search for. + vector_search_settings (Optional[Union[dict, VectorSearchSettings]]): Vector search settings. + kg_search_settings (Optional[Union[dict, KGSearchSettings]]): KG search settings. + + Returns: + SearchResponse: The search response. + """ if isinstance(vector_search_settings, dict): vector_search_settings = VectorSearchSettings( **vector_search_settings @@ -31,16 +42,15 @@ async def search( data = { "query": query, "vector_search_settings": ( - vector_search_settings.dict() + vector_search_settings.model_dump() if vector_search_settings else None ), "kg_search_settings": ( - kg_search_settings.dict() if kg_search_settings else None + kg_search_settings.model_dump() if kg_search_settings else None ), } - response = await client._make_request("POST", "search", json=data) - return response + return await client._make_request("POST", "search", json=data) @staticmethod async def rag( @@ -54,6 +64,18 @@ async def rag( *args, **kwargs ) -> Union[RAGResponse, AsyncGenerator[RAGResponse, None]]: + """ + Conducts a Retrieval Augmented Generation (RAG) search with the given query. + + Args: + query (str): The query to search for. + rag_generation_config (Union[dict, GenerationConfig]): RAG generation configuration. + vector_search_settings (Optional[Union[dict, VectorSearchSettings]]): Vector search settings. + kg_search_settings (Optional[Union[dict, KGSearchSettings]]): KG search settings. + + Returns: + Union[RAGResponse, AsyncGenerator[RAGResponse, None]]: The RAG response + """ if isinstance(rag_generation_config, dict): rag_generation_config = GenerationConfig(**rag_generation_config) if isinstance(vector_search_settings, dict): @@ -65,14 +87,14 @@ async def rag( data = { "query": query, - "rag_generation_config": rag_generation_config.dict(), + "rag_generation_config": rag_generation_config.model_dump(), "vector_search_settings": ( - vector_search_settings.dict() + vector_search_settings.model_dump() if vector_search_settings else None ), "kg_search_settings": ( - kg_search_settings.dict() if kg_search_settings else None + kg_search_settings.model_dump() if kg_search_settings else None ), } @@ -86,8 +108,7 @@ async def stream_response(): return stream_response() else: - response = await client._make_request("POST", "rag", json=data) - return response + return await client._make_request("POST", "rag", json=data) @staticmethod async def agent( @@ -103,6 +124,20 @@ async def agent( *args, **kwargs ) -> Union[list[Message], AsyncGenerator[Message, None]]: + """ + Performs a single turn in a conversation with a RAG agent. + + Args: + messages (List[Union[dict, Message]]): The messages to send to the agent. + rag_generation_config (Union[dict, GenerationConfig]): RAG generation configuration. + vector_search_settings (Optional[Union[dict, VectorSearchSettings]]): Vector search settings. + kg_search_settings (Optional[Union[dict, KGSearchSettings]]): KG search settings. + task_prompt_override (Optional[str]): Task prompt override. + include_title_if_available (Optional[bool]): Include the title if available. + + Returns: + Union[List[Message], AsyncGenerator[Message, None]]: The agent response. + """ if isinstance(rag_generation_config, dict): rag_generation_config = GenerationConfig(**rag_generation_config) if isinstance(vector_search_settings, dict): @@ -119,14 +154,14 @@ async def agent( data = { "messages": [msg.model_dump() for msg in messages], - "rag_generation_config": rag_generation_config.dict(), + "rag_generation_config": rag_generation_config.model_dump(), "vector_search_settings": ( - vector_search_settings.dict() + vector_search_settings.model_dump() if vector_search_settings else None ), "kg_search_settings": ( - kg_search_settings.dict() if kg_search_settings else None + kg_search_settings.model_dump() if kg_search_settings else None ), "task_prompt_override": task_prompt_override, "include_title_if_available": include_title_if_available, @@ -142,5 +177,4 @@ async def stream_response(): return stream_response() else: - response = await client._make_request("POST", "agent", json=data) - return response + return await client._make_request("POST", "agent", json=data) diff --git a/r2r/main/api/routes/auth/base.py b/r2r/main/api/routes/auth/base.py index a9a330910..587effdaf 100644 --- a/r2r/main/api/routes/auth/base.py +++ b/r2r/main/api/routes/auth/base.py @@ -33,7 +33,7 @@ async def register_app( password: str = Body(..., description="User's password"), ): """ - Register a new user. + Register a new user with the given email and password. """ result = await self.engine.aregister(email, password) return result @@ -72,6 +72,22 @@ async def login_app( ) return login_result + @self.router.post( + "/logout", response_model=WrappedGenericMessageResponse + ) + @self.base_endpoint + async def logout_app( + token: str = Depends(oauth2_scheme), + auth_user=Depends(self.engine.providers.auth.auth_wrapper), + ): + """ + Log out the current user. + + This endpoint invalidates the user's current access token, effectively logging them out. + """ + result = await self.engine.alogout(token) + return GenericMessageResponse(message=result["message"]) + @self.router.get("/user", response_model=WrappedUserResponse) @self.base_endpoint async def get_user_app( @@ -183,28 +199,12 @@ async def reset_password_app( ) return GenericMessageResponse(message=result["message"]) - @self.router.post( - "/logout", response_model=WrappedGenericMessageResponse - ) - @self.base_endpoint - async def logout_app( - token: str = Depends(oauth2_scheme), - auth_user=Depends(self.engine.providers.auth.auth_wrapper), - ): - """ - Log out the current user. - - This endpoint invalidates the user's current access token, effectively logging them out. - """ - result = await self.engine.alogout(token) - return GenericMessageResponse(message=result["message"]) - @self.router.delete( "/user", response_model=WrappedGenericMessageResponse ) @self.base_endpoint async def delete_user_app( - user_id: UUID = Body(..., description="ID of the user to delete"), + user_id: str = Body(..., description="ID of the user to delete"), password: str | None = Body( None, description="User's current password" ), @@ -218,5 +218,6 @@ async def delete_user_app( """ if auth_user.id != user_id and not auth_user.is_superuser: raise Exception("User ID does not match authenticated user") - result = await self.engine.adelete_user(user_id, password) + user_uuid = uuid.UUID(user_id) + result = await self.engine.adelete_user(user_uuid, password) return GenericMessageResponse(message=result["message"]) diff --git a/r2r/main/api/routes/ingestion/base.py b/r2r/main/api/routes/ingestion/base.py index e49e37d2c..ca7c8e649 100644 --- a/r2r/main/api/routes/ingestion/base.py +++ b/r2r/main/api/routes/ingestion/base.py @@ -47,7 +47,7 @@ async def ingest_files_app( files: List[UploadFile] = File( ..., description=ingest_files_descriptions.get("files") ), - document_ids: Optional[list[UUID]] = Form( + document_ids: Optional[list[str]] = Form( None, description=ingest_files_descriptions.get("document_ids"), ), @@ -98,20 +98,14 @@ async def ingest_files_app( # Handle user management logic at the request level if not auth_user: for metadata in metadatas or []: - if "user_id" in metadata: - if not is_superuser and metadata["user_id"] != str( - auth_user.id - ): - raise R2RException( - status_code=403, - message="Non-superusers cannot set user_id in metadata.", - ) - if "group_ids" in metadata: - if not is_superuser: - raise R2RException( - status_code=403, - message="Non-superusers cannot set group_ids in metadata.", - ) + if "user_id" in metadata and ( + not is_superuser + and metadata["user_id"] != str(auth_user.id) + ): + raise R2RException( + status_code=403, + message="Non-superusers cannot set user_id in metadata.", + ) # If user is not a superuser, set user_id in metadata metadata["user_id"] = str(auth_user.id) @@ -153,7 +147,7 @@ async def update_files_app( files: List[UploadFile] = File( ..., description=update_files_descriptions.get("files") ), - document_ids: Optional[list[UUID]] = Form( + document_ids: Optional[list[str]] = Form( None, description=update_files_descriptions.get("document_ids") ), metadatas: Optional[list[dict]] = Form( @@ -254,21 +248,21 @@ def parse_ingest_files_form_data( except json.JSONDecodeError as e: raise R2RException( status_code=400, message=f"Invalid JSON in form data: {e}" - ) + ) from e except ValueError as e: - raise R2RException(status_code=400, message=str(e)) + raise R2RException(status_code=400, message=str(e)) from e except Exception as e: raise R2RException( status_code=400, message=f"Error processing form data: {e}" - ) + ) from e @staticmethod def parse_update_files_form_data( metadatas: Optional[list[dict]], - document_ids: Optional[list[UUID]], + document_ids: Optional[list[str]], chunking_config_override: Optional[str], filenames: list[str], - user_id: UUID, + user_id: str, ): try: parsed_metadatas = ( @@ -292,7 +286,7 @@ def parse_update_files_form_data( ] else: parsed_document_ids = [ - generate_user_document_id(filename, user_id) + generate_user_document_id(filename, UUID(user_id)) for filename in filenames ] @@ -311,10 +305,10 @@ def parse_update_files_form_data( except json.JSONDecodeError as e: raise R2RException( status_code=400, message=f"Invalid JSON in form data: {e}" - ) + ) from e except ValueError as e: - raise R2RException(status_code=400, message=str(e)) + raise R2RException(status_code=400, message=str(e)) from e except Exception as e: raise R2RException( status_code=400, message=f"Error processing form data: {e}" - ) + ) from e diff --git a/r2r/main/api/routes/management/base.py b/r2r/main/api/routes/management/base.py index aa4176357..c21150dcd 100644 --- a/r2r/main/api/routes/management/base.py +++ b/r2r/main/api/routes/management/base.py @@ -6,7 +6,6 @@ import psutil from fastapi import Body, Depends, Path, Query -from pydantic import BaseModel from r2r.base import R2RException from r2r.base.api.models.management.responses import ( @@ -36,6 +35,7 @@ def __init__(self, engine: R2REngine): self.start_time = datetime.now(timezone.utc) self.setup_routes() + # TODO: remove this from the management route, it should be at the base of the server def setup_routes(self): @self.router.get("/health") @self.base_endpoint @@ -84,23 +84,6 @@ async def update_prompt_app( ) return result - @self.router.get("/logs") - @self.base_endpoint - async def logs_app( - run_type_filter: Optional[str] = Query(""), - max_runs: int = Query(100, ge=1, le=1000), - auth_user=Depends(self.engine.providers.auth.auth_wrapper), - ) -> WrappedLogResponse: - if not auth_user.is_superuser: - raise R2RException( - "Only a superuser can call the `logs` endpoint.", 403 - ) - - return await self.engine.alogs( - run_type_filter=run_type_filter, - max_runs=max_runs, - ) - @self.router.get("/analytics") @self.base_endpoint async def get_analytics_app( @@ -135,43 +118,52 @@ async def get_analytics_app( f"Invalid data in query parameters: {str(e)}", 400 ) - @self.router.delete("/delete", status_code=204) - @self.base_endpoint - async def delete_app( - filters: str = Query(..., description="JSON-encoded filters"), - auth_user=Depends(self.engine.providers.auth.auth_wrapper), - ) -> None: - filters_dict = json.loads(filters) if filters else None - return await self.engine.adelete(filters=filters_dict) - - @self.router.get("/document_chunks") + # TODO: should we add a message to the response model with warnings i.e. if the max_runs passed in violates the max_runs limit? + @self.router.get("/logs") @self.base_endpoint - async def document_chunks_app( - document_id: UUID = Query(...), + async def logs_app( + run_type_filter: Optional[str] = Query(""), + max_runs: int = Query(100, ge=1, le=1000), auth_user=Depends(self.engine.providers.auth.auth_wrapper), - ) -> WrappedDocumentChunkResponse: - chunks = await self.engine.adocument_chunks(document_id) - - if not chunks: + ) -> WrappedLogResponse: + if not auth_user.is_superuser: raise R2RException( - "No chunks found for the given document ID.", - 404, + "Only a superuser can call the `logs` endpoint.", 403 ) - is_owner = str(chunks[0].get("user_id")) == str(auth_user.id) + return await self.engine.alogs( + run_type_filter=run_type_filter, + max_runs=min(max(max_runs, 1), 1000), + ) - if not is_owner and not auth_user.is_superuser: + @self.router.get("/app_settings") + @self.base_endpoint + async def app_settings( + auth_user=Depends(self.engine.providers.auth.auth_wrapper), + ) -> WrappedAppSettingsResponse: + if not auth_user.is_superuser: raise R2RException( - "Only a superuser can arbitrarily call document_chunks.", + "Only a superuser can call the `app_settings` endpoint.", 403, ) + return await self.engine.aapp_settings() - return chunks + @self.router.post("/score_completion") + @self.base_endpoint + async def score_completion( + message_id: str = Body(..., description="Message ID"), + score: float = Body(..., description="Completion score"), + auth_user=Depends(self.engine.providers.auth.auth_wrapper), + ) -> WrappedScoreCompletionResponse: + message_uuid = UUID(message_id) + return await self.engine.ascore_completion( + message_id=message_uuid, score=score + ) @self.router.get("/users_overview") @self.base_endpoint async def users_overview_app( - user_ids: list[UUID] = Query([]), + user_ids: list[str] = Query([]), auth_user=Depends(self.engine.providers.auth.auth_wrapper), ) -> WrappedUserOverviewResponse: if not auth_user.is_superuser: @@ -180,23 +172,62 @@ async def users_overview_app( 403, ) - return await self.engine.ausers_overview(user_ids=user_ids) + user_uuids = [UUID(user_id) for user_id in user_ids] + + return await self.engine.ausers_overview(user_ids=user_uuids) + + @self.router.delete("/delete", status_code=204) + @self.base_endpoint + async def delete_app( + filters: str = Query(..., description="JSON-encoded filters"), + auth_user=Depends(self.engine.providers.auth.auth_wrapper), + ) -> None: + filters_dict = json.loads(filters) if filters else None + return await self.engine.adelete(filters=filters_dict) @self.router.get("/documents_overview") @self.base_endpoint async def documents_overview_app( - document_id: list[UUID] = Query([]), + document_ids: list[str] = Query([]), auth_user=Depends(self.engine.providers.auth.auth_wrapper), ) -> WrappedDocumentOverviewResponse: request_user_ids = ( - [auth_user.id] if not auth_user.is_superuser else None + None if auth_user.is_superuser else [auth_user.id] ) + document_uuids = [ + UUID(document_id) for document_id in document_ids + ] return await self.engine.adocuments_overview( user_ids=request_user_ids, group_ids=auth_user.group_ids, - document_ids=document_id, + document_ids=document_uuids, ) + @self.router.get("/document_chunks") + @self.base_endpoint + async def document_chunks_app( + document_id: str = Query(...), + auth_user=Depends(self.engine.providers.auth.auth_wrapper), + ) -> WrappedDocumentChunkResponse: + document_uuid = UUID(document_id) + chunks = await self.engine.adocument_chunks(document_uuid) + + if not chunks: + raise R2RException( + "No chunks found for the given document ID.", + 404, + ) + + is_owner = str(chunks[0].get("user_id")) == str(auth_user.id) + + if not is_owner and not auth_user.is_superuser: + raise R2RException( + "Only a superuser can arbitrarily call document_chunks.", + 403, + ) + + return chunks + @self.router.get("/inspect_knowledge_graph") @self.base_endpoint async def inspect_knowledge_graph( @@ -210,17 +241,28 @@ async def inspect_knowledge_graph( ) return await self.engine.ainspect_knowledge_graph(limit=limit) - @self.router.get("/app_settings") + @self.router.get("/groups_overview") @self.base_endpoint - async def app_settings( + async def groups_overview_app( + group_ids: Optional[list[str]] = Query(None), + limit: Optional[int] = Query(100, ge=1, le=1000), + offset: Optional[int] = Query(0, ge=0), auth_user=Depends(self.engine.providers.auth.auth_wrapper), - ) -> WrappedAppSettingsResponse: + ) -> WrappedGroupOverviewResponse: if not auth_user.is_superuser: raise R2RException( - "Only a superuser can call the `app_settings` endpoint.", + "Only a superuser can call the `groups_overview` endpoint.", 403, ) - return await self.engine.aapp_settings() + + group_uuids = ( + [UUID(group_id) for group_id in group_ids] + if group_ids + else None + ) + return await self.engine.agroups_overview( + group_ids=group_uuids, limit=limit, offset=offset + ) @self.router.post("/create_group") @self.base_endpoint @@ -238,21 +280,21 @@ async def create_group_app( @self.router.get("/get_group/{group_id}") @self.base_endpoint async def get_group_app( - group_id: UUID = Path(..., description="Group ID"), + group_id: str = Path(..., description="Group ID"), auth_user=Depends(self.engine.providers.auth.auth_wrapper), ) -> WrappedGroupResponse: if not auth_user.is_superuser: raise R2RException( "Only a superuser can get group details.", 403 ) - result = await self.engine.aget_group(group_id) - print(result) + group_uuid = UUID(group_id) + result = await self.engine.aget_group(group_uuid) return result @self.router.put("/update_group") @self.base_endpoint async def update_group_app( - group_id: UUID = Body(..., description="Group ID"), + group_id: str = Body(..., description="Group ID"), name: Optional[str] = Body(None, description="Updated group name"), description: Optional[str] = Body( None, description="Updated group description" @@ -261,17 +303,21 @@ async def update_group_app( ) -> WrappedGroupResponse: if not auth_user.is_superuser: raise R2RException("Only a superuser can update groups.", 403) - return await self.engine.aupdate_group(group_id, name, description) + group_uuid = UUID(group_id) + return await self.engine.aupdate_group( + group_uuid, name, description + ) @self.router.delete("/delete_group/{group_id}") @self.base_endpoint async def delete_group_app( - group_id: UUID = Path(..., description="Group ID"), + group_id: str = Path(..., description="Group ID"), auth_user=Depends(self.engine.providers.auth.auth_wrapper), ) -> WrappedGroupResponse: if not auth_user.is_superuser: raise R2RException("Only a superuser can delete groups.", 403) - return await self.engine.adelete_group(group_id) + group_uuid = UUID(group_id) + return await self.engine.adelete_group(group_uuid) @self.router.get("/list_groups") @self.base_endpoint @@ -284,123 +330,112 @@ async def list_groups_app( raise R2RException( "Only a superuser can list all groups.", 403 ) - return await self.engine.alist_groups(offset, limit) + return await self.engine.alist_groups( + offset=offset, limit=min(max(limit, 1), 1000) + ) @self.router.post("/add_user_to_group") @self.base_endpoint async def add_user_to_group_app( - user_id: UUID = Body(..., description="User ID"), - group_id: UUID = Body(..., description="Group ID"), + user_id: str = Body(..., description="User ID"), + group_id: str = Body(..., description="Group ID"), auth_user=Depends(self.engine.providers.auth.auth_wrapper), ) -> WrappedAddUserResponse: if not auth_user.is_superuser: raise R2RException( "Only a superuser can add users to groups.", 403 ) - result = await self.engine.aadd_user_to_group(user_id, group_id) + user_uuid = UUID(user_id) + group_uuid = UUID(group_id) + result = await self.engine.aadd_user_to_group( + user_uuid, group_uuid + ) return {"result": result} @self.router.post("/remove_user_from_group") @self.base_endpoint async def remove_user_from_group_app( - user_id: UUID = Body(..., description="User ID"), - group_id: UUID = Body(..., description="Group ID"), + user_id: str = Body(..., description="User ID"), + group_id: str = Body(..., description="Group ID"), auth_user=Depends(self.engine.providers.auth.auth_wrapper), ) -> WrappedGroupResponse: if not auth_user.is_superuser: raise R2RException( "Only a superuser can remove users from groups.", 403 ) - return await self.engine.aremove_user_from_group(user_id, group_id) + user_uuid = UUID(user_id) + group_uuid = UUID(group_id) + return await self.engine.aremove_user_from_group( + user_uuid, group_uuid + ) # TODO - Proivde response model @self.router.get("/get_users_in_group/{group_id}") @self.base_endpoint async def get_users_in_group_app( - group_id: UUID = Path(..., description="Group ID"), - offset: int = Query(..., description="Offset"), - limit: int = Query(..., description="limit"), + group_id: str = Path(..., description="Group ID"), + offset: int = Query(0, ge=0, description="Pagination offset"), + limit: int = Query( + 100, ge=1, le=1000, description="Pagination limit" + ), auth_user=Depends(self.engine.providers.auth.auth_wrapper), ): if not auth_user.is_superuser: raise R2RException( "Only a superuser can get users in a group.", 403 ) + group_uuid = UUID(group_id) return await self.engine.aget_users_in_group( - group_id, offset, limit + group_id=group_uuid, + offset=offset, + limit=min(max(limit, 1), 1000), ) @self.router.get("/get_groups_for_user/{user_id}") @self.base_endpoint async def get_groups_for_user_app( - user_id: UUID = Path(..., description="User ID"), - auth_user=Depends(self.engine.providers.auth.auth_wrapper), - ) -> WrappedGroupListResponse: - if not auth_user.is_superuser and auth_user.id != user_id: - raise R2RException( - "You can only get groups for yourself unless you're a superuser.", - 403, - ) - return await self.engine.aget_groups_for_user(user_id) - - @self.router.get("/groups_overview") - @self.base_endpoint - async def groups_overview_app( - group_ids: Optional[list[UUID]] = Query(None), - limit: Optional[int] = Query(100, ge=1, le=1000), - offset: Optional[int] = Query(0, ge=0), + user_id: str = Path(..., description="User ID"), auth_user=Depends(self.engine.providers.auth.auth_wrapper), - ) -> WrappedGroupOverviewResponse: - print("... group_ids = ", group_ids) + ): if not auth_user.is_superuser: raise R2RException( - "Only a superuser can call the `groups_overview` endpoint.", - 403, + "Only a superuser can get groups for a user.", 403 ) - - return await self.engine.agroups_overview( - group_ids=group_ids, limit=limit, offset=offset - ) - - @self.router.post("/score_completion") - @self.base_endpoint - async def score_completion( - message_id: UUID = Body(..., description="Message ID"), - score: float = Body(..., description="Completion score"), - auth_user=Depends(self.engine.providers.auth.auth_wrapper), - ) -> WrappedScoreCompletionResponse: - return await self.engine.ascore_completion( - message_id=message_id, score=score - ) + user_uuid = UUID(user_id) + return await self.engine.aget_groups_for_user(user_uuid) @self.router.post("/assign_document_to_group") @self.base_endpoint async def assign_document_to_group_app( document_id: str = Body(..., description="Document ID"), - group_id: UUID = Body(..., description="Group ID"), + group_id: str = Body(..., description="Group ID"), auth_user=Depends(self.engine.providers.auth.auth_wrapper), ) -> WrappedGroupResponse: if not auth_user.is_superuser: raise R2RException( "Only a superuser can assign documents to groups.", 403 ) + document_uuid = UUID(document_id) + group_uuid = UUID(group_id) return await self.engine.aassign_document_to_group( - document_id, group_id + document_uuid, group_uuid ) @self.router.post("/remove_document_from_group") @self.base_endpoint async def remove_document_from_group_app( document_id: str = Body(..., description="Document ID"), - group_id: UUID = Body(..., description="Group ID"), + group_id: str = Body(..., description="Group ID"), auth_user=Depends(self.engine.providers.auth.auth_wrapper), ) -> WrappedGroupResponse: if not auth_user.is_superuser: raise R2RException( "Only a superuser can remove documents from groups.", 403 ) + document_uuid = UUID(document_id) + group_uuid = UUID(group_id) return await self.engine.aremove_document_from_group( - document_id, group_id + document_uuid, group_uuid ) @self.router.get("/get_document_groups/{document_id}") @@ -414,7 +449,7 @@ async def get_document_groups_app( @self.router.get("/group/{group_id}/documents") @self.base_endpoint async def get_documents_in_group_app( - group_id: UUID = Path(..., description="Group ID"), + group_id: str = Path(..., description="Group ID"), offset: int = Query(0, ge=0), limit: int = Query(100, ge=1, le=1000), auth_user=Depends(self.engine.providers.auth.auth_wrapper), @@ -423,44 +458,7 @@ async def get_documents_in_group_app( raise R2RException( "Only a superuser can get documents in a group.", 403 ) + group_uuid = UUID(group_id) return await self.engine.aget_documents_in_group( - group_id, offset, limit - ) - - @self.router.post("/assign_document_to_group") - @self.base_endpoint - async def assign_document_to_group_app( - document_id: str = Body(..., description="Document ID"), - group_id: UUID = Body(..., description="Group ID"), - auth_user=Depends(self.engine.providers.auth.auth_wrapper), - ) -> WrappedGroupResponse: - if not auth_user.is_superuser: - raise R2RException( - "Only a superuser can assign documents to groups.", 403 - ) - return await self.engine.aassign_document_to_group( - document_id, group_id + group_uuid, offset, limit ) - - @self.router.post("/remove_document_from_group") - @self.base_endpoint - async def remove_document_from_group_app( - document_id: str = Body(..., description="Document ID"), - group_id: UUID = Body(..., description="Group ID"), - auth_user=Depends(self.engine.providers.auth.auth_wrapper), - ) -> WrappedGroupResponse: - if not auth_user.is_superuser: - raise R2RException( - "Only a superuser can remove documents from groups.", 403 - ) - return await self.engine.aremove_document_from_group( - document_id, group_id - ) - - @self.router.get("/get_document_groups/{document_id}") - @self.base_endpoint - async def get_document_groups_app( - document_id: str = Path(..., description="Document ID"), - auth_user=Depends(self.engine.providers.auth.auth_wrapper), - ) -> WrappedGroupListResponse: - return await self.engine.aget_document_groups(document_id) diff --git a/r2r/main/api/routes/restructure/base.py b/r2r/main/api/routes/restructure/base.py index bf07fdc05..470d92a32 100644 --- a/r2r/main/api/routes/restructure/base.py +++ b/r2r/main/api/routes/restructure/base.py @@ -4,6 +4,7 @@ from r2r.main.engine import R2REngine +# TODO: Botched by Claude class RestructureRouter(BaseRouter): def __init__(self, engine: R2REngine): super().__init__(engine) diff --git a/r2r/main/execution.py b/r2r/main/execution.py index 74045d4c9..91c97bc4e 100644 --- a/r2r/main/execution.py +++ b/r2r/main/execution.py @@ -15,7 +15,6 @@ GenerationConfig, KGSearchSettings, LogFilterCriteria, - VectorDBFilterValue, VectorSearchSettings, ) @@ -225,7 +224,7 @@ def search( self, query: str, use_vector_search: bool = True, - filters: Optional[dict[str, VectorDBFilterValue]] = None, + filters: Optional[dict[str, str]] = None, search_limit: int = 10, do_hybrid_search: bool = False, use_kg_search: bool = False, @@ -280,7 +279,7 @@ def rag( self, query: str, use_vector_search: bool = True, - filters: Optional[dict[str, VectorDBFilterValue]] = None, + filters: Optional[dict[str, str]] = None, search_limit: int = 10, do_hybrid_search: bool = False, use_kg_search: bool = False, @@ -377,7 +376,7 @@ def enrich_graph(self): def delete( self, - filters: Optional[dict[str, VectorDBFilterValue]] = None, + filters: Optional[dict[str, str]] = None, ): if self.client_mode: return self.client.delete(filters)["results"] diff --git a/r2r/main/services/management_service.py b/r2r/main/services/management_service.py index 462d3cd2f..9e8337b45 100644 --- a/r2r/main/services/management_service.py +++ b/r2r/main/services/management_service.py @@ -1,5 +1,6 @@ import json import logging +import uuid from collections import defaultdict from typing import Any, Dict, List, Optional, Tuple from uuid import UUID @@ -13,7 +14,6 @@ R2RException, RunLoggingSingleton, RunManager, - VectorDBFilterValue, ) from r2r.telemetry.telemetry_decorator import telemetry_event @@ -57,7 +57,7 @@ async def alogs( run_type_filter=run_type_filter, ) run_ids = [run.run_id for run in run_info] - if len(run_ids) == 0: + if not run_ids: return [] logs = await self.logging_connection.get_logs(run_ids) @@ -251,7 +251,7 @@ async def ausers_overview( @telemetry_event("Delete") async def delete( self, - filters: dict[str, VectorDBFilterValue], + filters: dict[str, str], *args, **kwargs, ): @@ -409,10 +409,9 @@ async def aassign_document_to_group( self, document_id: str, group_id: UUID ): - success = self.providers.database.vector.assign_document_to_group( + if self.providers.database.vector.assign_document_to_group( document_id, group_id - ) - if success: + ): return {"message": "Document assigned to group successfully"} else: raise R2RException( @@ -424,10 +423,9 @@ async def aassign_document_to_group( async def aremove_document_from_group( self, document_id: str, group_id: UUID ): - success = self.providers.database.vector.remove_document_from_group( + if self.providers.database.vector.remove_document_from_group( document_id, group_id - ) - if success: + ): return {"message": "Document removed from group successfully"} else: raise R2RException( diff --git a/r2r/main/services/restructure_service.py b/r2r/main/services/restructure_service.py index ab98182da..a68151310 100644 --- a/r2r/main/services/restructure_service.py +++ b/r2r/main/services/restructure_service.py @@ -1,7 +1,7 @@ import logging from typing import Any, Dict, List -from r2r.base import Document, R2RException, RunLoggingSingleton, RunManager +from r2r.base import R2RException, RunLoggingSingleton, RunManager from ..abstractions import R2RAgents, R2RPipelines, R2RProviders from ..assembly.config import R2RConfig @@ -32,7 +32,7 @@ def __init__( async def enrich_graph(self) -> Dict[str, Any]: """ - Perform graph enrichment on the given documents. + Perform graph enrichment. Returns: Dict[str, Any]: Results of the graph enrichment process. From 735375f1ec114902dfd8f743d2b0a1f3a76b75dc Mon Sep 17 00:00:00 2001 From: Nolan Tremelling <34580718+NolanTrem@users.noreply.github.com> Date: Mon, 19 Aug 2024 18:27:09 -0700 Subject: [PATCH 10/74] Separate out SDK, add js and go sdk to monorepo (#888) * Add r2r-js sdk * Add go sdk * Pull out python sdk * remove venv * Update packages * Check in fixes * Remove alembic dependencies --- .github/workflows/r2r-js-sdk-ci.yml | 38 + .../r2r-js-sdk-integration-tests.yml | 68 + .gitignore | 13 + .pre-commit-config.yaml | 4 +- poetry.lock | 231 +- pyproject.toml | 24 +- r2r/main/api/client/__init__.py | 3 - r2r_cli/go.mod | 15 + r2r_cli/go.sum | 10 + r2r_cli/main.go | 21 + r2r_cli/rag_operations.go | 181 + r2r_cli/server_operations.go | 91 + r2r_cli/utils.go | 17 + {r2r => r2r_core}/__init__.py | 2 - {r2r => r2r_core}/agent/__init__.py | 0 {r2r => r2r_core}/agent/base.py | 4 +- {r2r => r2r_core}/agent/rag.py | 12 +- {r2r => r2r_core}/base/__init__.py | 0 .../base/abstractions/__init__.py | 0 {r2r => r2r_core}/base/abstractions/base.py | 0 .../base/abstractions/completion.py | 0 .../base/abstractions/document.py | 0 .../base/abstractions/embedding.py | 0 .../base/abstractions/exception.py | 0 {r2r => r2r_core}/base/abstractions/graph.py | 0 {r2r => r2r_core}/base/abstractions/llm.py | 0 {r2r => r2r_core}/base/abstractions/prompt.py | 0 {r2r => r2r_core}/base/abstractions/search.py | 10 +- {r2r => r2r_core}/base/abstractions/user.py | 0 {r2r => r2r_core}/base/abstractions/vector.py | 0 {r2r => r2r_core}/base/agent/__init__.py | 0 {r2r => r2r_core}/base/agent/agent.py | 4 +- {r2r => r2r_core}/base/agent/base.py | 6 +- {r2r => r2r_core}/base/api/models/__init__.py | 0 .../base/api/models/auth/__init__.py | 0 .../base/api/models/auth/responses.py | 4 +- {r2r => r2r_core}/base/api/models/base.py | 0 .../base/api/models/ingestion/__init__.py | 0 .../base/api/models/ingestion/responses.py | 2 +- .../base/api/models/management/__init__.py | 0 .../base/api/models/management/responses.py | 2 +- .../base/api/models/retrieval/__init__.py | 0 .../base/api/models/retrieval/responses.py | 7 +- {r2r => r2r_core}/base/logging/__init__.py | 0 {r2r => r2r_core}/base/logging/base.py | 0 .../base/logging/log_processor.py | 0 {r2r => r2r_core}/base/logging/run_logger.py | 0 {r2r => r2r_core}/base/logging/run_manager.py | 6 +- {r2r => r2r_core}/base/parsers/__init__.py | 0 {r2r => r2r_core}/base/parsers/base_parser.py | 0 {r2r => r2r_core}/base/pipeline/__init__.py | 0 .../base/pipeline/base_pipeline.py | 0 {r2r => r2r_core}/base/pipes/__init__.py | 0 {r2r => r2r_core}/base/pipes/base_pipe.py | 4 +- {r2r => r2r_core}/base/providers/__init__.py | 0 {r2r => r2r_core}/base/providers/auth.py | 0 {r2r => r2r_core}/base/providers/base.py | 6 +- {r2r => r2r_core}/base/providers/chunking.py | 0 {r2r => r2r_core}/base/providers/crypto.py | 0 {r2r => r2r_core}/base/providers/database.py | 0 {r2r => r2r_core}/base/providers/embedding.py | 0 {r2r => r2r_core}/base/providers/kg.py | 0 {r2r => r2r_core}/base/providers/llm.py | 2 +- {r2r => r2r_core}/base/providers/parsing.py | 0 {r2r => r2r_core}/base/providers/prompt.py | 0 {r2r => r2r_core}/base/utils/__init__.py | 0 {r2r => r2r_core}/base/utils/base_utils.py | 0 .../base/utils/splitter/__init__.py | 0 {r2r => r2r_core}/base/utils/splitter/text.py | 0 {r2r => r2r_core}/cli/__init__.py | 0 {r2r => r2r_core}/cli/cli.py | 4 +- {r2r => r2r_core}/cli/command_group.py | 2 +- {r2r => r2r_core}/cli/commands/__init__.py | 0 .../cli/commands/auth_operations.py | 2 +- .../cli/commands/document_operations.py | 4 +- .../cli/commands/kg_operations.py | 4 +- .../commands/oberservability_operations.py | 6 +- .../cli/commands/rag_operations.py | 6 +- .../cli/commands/server_operations.py | 6 +- {r2r => r2r_core}/cli/utils/__init__.py | 0 {r2r => r2r_core}/cli/utils/docker_utils.py | 4 +- {r2r => r2r_core}/cli/utils/param_types.py | 0 {r2r => r2r_core}/cli/utils/timer.py | 0 {r2r => r2r_core}/configs/auth.toml | 0 {r2r => r2r_core}/configs/local_llm.toml | 0 .../configs/local_llm_neo4j_kg.toml | 0 {r2r => r2r_core}/configs/neo4j_kg.toml | 0 .../configs/neo4j_kg_no_vector_postgres.toml | 0 .../configs/postgres_logging.toml | 0 {r2r => r2r_core}/examples/__init__.py | 0 {r2r => r2r_core}/examples/data/aristotle.txt | 0 .../examples/data/aristotle_v2.txt | 0 {r2r => r2r_core}/examples/data/got.txt | 0 {r2r => r2r_core}/examples/data/lyft_2021.pdf | Bin .../examples/data/pg_essay_1.html | 0 .../examples/data/pg_essay_2.html | 0 .../examples/data/pg_essay_3.html | 0 .../examples/data/pg_essay_4.html | 0 .../examples/data/pg_essay_5.html | 0 {r2r => r2r_core}/examples/data/sample.mp3 | Bin {r2r => r2r_core}/examples/data/sample2.mp3 | Bin .../examples/data/screen_shot.png | Bin {r2r => r2r_core}/examples/data/test.txt | 0 {r2r => r2r_core}/examples/data/uber_2021.pdf | Bin .../examples/data/yc_companies.txt | 0 {r2r => r2r_core}/examples/hello_r2r.py | 2 +- .../examples/scripts/advanced_kg_cookbook.py | 1 - .../examples/scripts/run_auth_workflow.py | 3 +- .../examples/scripts/run_hyde.py | 8 +- .../examples/scripts/run_web_multi_rag.py | 8 +- .../examples/scripts/run_web_rag.py | 4 +- .../examples/scripts/sample_data_ingestor.py | 2 +- {r2r => r2r_core}/integrations/__init__.py | 0 {r2r => r2r_core}/integrations/serper.py | 0 {r2r => r2r_core}/main/__init__.py | 2 - {r2r => r2r_core}/main/abstractions.py | 8 +- {r2r => r2r_core}/main/api/__init__.py | 3 - {r2r => r2r_core}/main/api/routes/__init__.py | 0 .../main/api/routes/auth/__init__.py | 0 .../main/api/routes/auth/base.py | 6 +- .../main/api/routes/base_router.py | 4 +- .../main/api/routes/ingestion/__init__.py | 0 .../main/api/routes/ingestion/base.py | 8 +- .../ingestion/ingestion_router_openapi.yml | 0 .../main/api/routes/management/__init__.py | 0 .../main/api/routes/management/base.py | 4 +- .../main/api/routes/restructure/__init__.py | 0 .../main/api/routes/restructure/base.py | 4 +- .../main/api/routes/retrieval/__init__.py | 0 .../main/api/routes/retrieval/base.py | 4 +- .../retrieval/retrieval_router_openapi.yml | 0 {r2r => r2r_core}/main/app.py | 0 {r2r => r2r_core}/main/app_entry.py | 0 {r2r => r2r_core}/main/assembly/__init__.py | 0 {r2r => r2r_core}/main/assembly/builder.py | 6 +- {r2r => r2r_core}/main/assembly/config.py | 0 {r2r => r2r_core}/main/assembly/factory.py | 60 +- .../main/assembly/factory_extensions.py | 4 +- {r2r => r2r_core}/main/engine.py | 4 +- {r2r => r2r_core}/main/execution.py | 10 +- {r2r => r2r_core}/main/r2r.py | 0 {r2r => r2r_core}/main/services/__init__.py | 0 .../main/services/auth_service.py | 6 +- {r2r => r2r_core}/main/services/base.py | 2 +- .../main/services/ingestion_service.py | 8 +- .../main/services/management_service.py | 4 +- .../main/services/restructure_service.py | 2 +- .../main/services/retrieval_service.py | 8 +- {r2r => r2r_core}/parsers/__init__.py | 0 {r2r => r2r_core}/parsers/media/__init__.py | 0 .../parsers/media/audio_parser.py | 4 +- .../parsers/media/docx_parser.py | 4 +- {r2r => r2r_core}/parsers/media/img_parser.py | 6 +- .../parsers/media/movie_parser.py | 4 +- .../parsers/media/openai_helpers.py | 0 {r2r => r2r_core}/parsers/media/pdf_parser.py | 4 +- {r2r => r2r_core}/parsers/media/ppt_parser.py | 4 +- .../parsers/structured/__init__.py | 0 .../parsers/structured/csv_parser.py | 4 +- .../parsers/structured/json_parser.py | 4 +- .../parsers/structured/xlsx_parser.py | 4 +- {r2r => r2r_core}/parsers/text/__init__.py | 0 {r2r => r2r_core}/parsers/text/html_parser.py | 4 +- {r2r => r2r_core}/parsers/text/md_parser.py | 4 +- {r2r => r2r_core}/parsers/text/text_parser.py | 4 +- {r2r => r2r_core}/pipelines/__init__.py | 0 .../pipelines/graph_enrichment.py | 0 .../pipelines/ingestion_pipeline.py | 15 +- {r2r => r2r_core}/pipelines/rag_pipeline.py | 0 .../pipelines/search_pipeline.py | 0 {r2r => r2r_core}/pipes/__init__.py | 0 .../pipes/abstractions/__init__.py | 0 .../pipes/abstractions/generator_pipe.py | 6 +- .../pipes/abstractions/search_pipe.py | 2 +- {r2r => r2r_core}/pipes/ingestion/__init__.py | 0 .../pipes/ingestion/chunking_pipe.py | 6 +- .../pipes/ingestion/embedding_pipe.py | 4 +- .../pipes/ingestion/kg_extraction_pipe.py | 6 +- .../pipes/ingestion/parsing_pipe.py | 6 +- .../pipes/ingestion/vector_storage_pipe.py | 6 +- {r2r => r2r_core}/pipes/kg/clustering.py | 2 +- {r2r => r2r_core}/pipes/kg/extraction.py | 4 +- {r2r => r2r_core}/pipes/kg/node_extraction.py | 8 +- {r2r => r2r_core}/pipes/kg/storage.py | 6 +- .../pipes/other/web_search_pipe.py | 4 +- .../pipes/retrieval/kg_search_search_pipe.py | 2 +- .../pipes/retrieval/multi_search.py | 6 +- .../pipes/retrieval/query_transform_pipe.py | 4 +- .../pipes/retrieval/search_rag_pipe.py | 4 +- .../pipes/retrieval/streaming_rag_pipe.py | 4 +- .../pipes/retrieval/vector_search_pipe.py | 2 +- {r2r => r2r_core}/providers/__init__.py | 0 {r2r => r2r_core}/providers/auth/__init__.py | 0 {r2r => r2r_core}/providers/auth/r2r_auth.py | 4 +- .../providers/chunking/__init__.py | 0 .../providers/chunking/r2r_chunking.py | 2 +- .../chunking/unstructured_chunking.py | 2 +- .../providers/crypto/__init__.py | 0 {r2r => r2r_core}/providers/crypto/bcrypt.py | 2 +- .../providers/database/__init__.py | 0 {r2r => r2r_core}/providers/database/base.py | 0 .../providers/database/document.py | 2 +- {r2r => r2r_core}/providers/database/group.py | 12 +- .../providers/database/postgres.py | 2 +- .../providers/database/relational.py | 10 +- .../providers/database/tokens.py | 0 {r2r => r2r_core}/providers/database/user.py | 6 +- .../providers/database/vecs/__init__.py | 0 .../database/vecs/adapter/__init__.py | 0 .../providers/database/vecs/adapter/base.py | 0 .../database/vecs/adapter/markdown.py | 0 .../providers/database/vecs/adapter/noop.py | 0 .../providers/database/vecs/adapter/text.py | 0 .../providers/database/vecs/client.py | 12 +- .../providers/database/vecs/collection.py | 2 +- .../providers/database/vecs/exc.py | 0 .../providers/database/vector.py | 2 +- .../providers/embeddings/__init__.py | 0 .../providers/embeddings/litellm.py | 2 +- .../providers/embeddings/ollama.py | 2 +- .../providers/embeddings/openai.py | 2 +- {r2r => r2r_core}/providers/kg/__init__.py | 0 .../providers/kg/neo4j/__init__.py | 0 .../providers/kg/neo4j/graph_queries.py | 0 .../providers/kg/neo4j/provider.py | 6 +- {r2r => r2r_core}/providers/llm/__init__.py | 0 {r2r => r2r_core}/providers/llm/litellm.py | 4 +- {r2r => r2r_core}/providers/llm/openai.py | 4 +- .../providers/parsing/__init__.py | 0 .../providers/parsing/r2r_parsing.py | 4 +- .../providers/parsing/unstructured_parsing.py | 2 +- .../providers/prompts/__init__.py | 0 .../providers/prompts/defaults.yaml | 0 .../prompts/defaults/default_rag.yaml | 0 .../defaults/few_shot_ner_kg_extraction.yaml | 0 .../few_shot_ner_kg_extraction_with_spec.yaml | 0 .../defaults/graphrag_community_reports.yaml | 0 .../defaults/graphrag_map_system_prompt.yaml | 0 .../graphrag_reduce_system_prompt.yaml | 0 .../graphrag_triplet_extraction_few_shot.yaml | 0 ...graphrag_triplet_extraction_zero_shot.yaml | 0 .../providers/prompts/defaults/hyde.yaml | 0 .../providers/prompts/defaults/kg_search.yaml | 0 .../prompts/defaults/kg_search_with_spec.yaml | 0 .../providers/prompts/defaults/rag_agent.yaml | 0 .../prompts/defaults/rag_context.yaml | 0 .../prompts/defaults/rag_fusion.yaml | 0 .../providers/prompts/defaults/system.yaml | 0 .../defaults/zero_shot_ner_kg_extraction.yaml | 0 ...zero_shot_ner_kg_extraction_with_spec.yaml | 0 .../providers/prompts/r2r_prompts.py | 2 +- {r2r => r2r_core}/telemetry/__init__.py | 0 {r2r => r2r_core}/telemetry/events.py | 0 {r2r => r2r_core}/telemetry/posthog.py | 2 +- .../telemetry/telemetry_decorator.py | 4 +- r2r_go_sdk/go.mod | 3 + .../tests/integration/management_test.go | 55 + r2r_go_sdk/pkg/sdk/auth.go | 392 ++ r2r_go_sdk/pkg/sdk/client.go | 110 + r2r_go_sdk/pkg/sdk/ingestion.go | 189 + r2r_go_sdk/pkg/sdk/management.go | 904 ++++ r2r_go_sdk/pkg/sdk/restructure.go | 22 + r2r_go_sdk/pkg/sdk/retrieval.go | 352 ++ r2r_js_sdk/README.md | 148 + r2r_js_sdk/__tests__/r2rClient.test.ts | 43 + .../r2rClientIntegrationSuperUser.test.ts | 178 + .../r2rClientIntegrationUser.test.ts | 119 + r2r_js_sdk/examples/data/folder/karamozov.txt | 4 + r2r_js_sdk/examples/data/folder/myshkin.txt | 4 + r2r_js_sdk/examples/data/raskolnikov.txt | 8 + r2r_js_sdk/examples/hello_r2r.js | 49 + r2r_js_sdk/jest.config.js | 8 + r2r_js_sdk/package-lock.json | 4074 +++++++++++++++++ r2r_js_sdk/package.json | 43 + r2r_js_sdk/pnpm-lock.yaml | 3878 ++++++++++++++++ r2r_js_sdk/src/feature.ts | 145 + r2r_js_sdk/src/index.ts | 3 + r2r_js_sdk/src/models.tsx | 61 + r2r_js_sdk/src/r2rClient.ts | 1286 ++++++ r2r_js_sdk/tsconfig.json | 20 + r2r_python_sdk/README.md | 0 r2r_python_sdk/poetry.lock | 1098 +++++ r2r_python_sdk/pyproject.toml | 54 + r2r_python_sdk/r2r/__init__.py | 0 .../api/client => r2r_python_sdk/r2r}/auth.py | 3 +- .../client => r2r_python_sdk/r2r}/client.py | 3 +- .../r2r}/ingestion.py | 2 +- .../r2r}/management.py | 0 r2r_python_sdk/r2r/models.py | 386 ++ .../r2r}/restructure.py | 0 .../r2r}/retrieval.py | 14 +- tests/regression/runner.py | 3 +- tests/regression/test_cases/base.py | 3 +- .../test_cases/test_document_management.py | 2 +- tests/test_abstractions.py | 6 +- tests/test_auth.py | 4 +- tests/test_cli.py | 34 +- tests/test_client.py | 6 +- tests/test_config.py | 2 +- tests/test_database.py | 4 +- tests/test_embedding.py | 8 +- tests/test_end_to_end.py | 2 +- tests/test_groups.py | 10 +- tests/test_groups_client.py | 11 +- tests/test_ingestion_service.py | 8 +- tests/test_kg.py | 8 +- tests/test_llms.py | 9 +- tests/test_logging.py | 2 +- tests/test_parser.py | 18 +- tests/test_pipeline.py | 2 +- tests/test_vector_db.py | 4 +- 311 files changed, 14582 insertions(+), 471 deletions(-) create mode 100644 .github/workflows/r2r-js-sdk-ci.yml create mode 100644 .github/workflows/r2r-js-sdk-integration-tests.yml delete mode 100644 r2r/main/api/client/__init__.py create mode 100644 r2r_cli/go.mod create mode 100644 r2r_cli/go.sum create mode 100644 r2r_cli/main.go create mode 100644 r2r_cli/rag_operations.go create mode 100644 r2r_cli/server_operations.go create mode 100644 r2r_cli/utils.go rename {r2r => r2r_core}/__init__.py (99%) rename {r2r => r2r_core}/agent/__init__.py (100%) rename {r2r => r2r_core}/agent/base.py (98%) rename {r2r => r2r_core}/agent/rag.py (91%) rename {r2r => r2r_core}/base/__init__.py (100%) rename {r2r => r2r_core}/base/abstractions/__init__.py (100%) rename {r2r => r2r_core}/base/abstractions/base.py (100%) rename {r2r => r2r_core}/base/abstractions/completion.py (100%) rename {r2r => r2r_core}/base/abstractions/document.py (100%) rename {r2r => r2r_core}/base/abstractions/embedding.py (100%) rename {r2r => r2r_core}/base/abstractions/exception.py (100%) rename {r2r => r2r_core}/base/abstractions/graph.py (100%) rename {r2r => r2r_core}/base/abstractions/llm.py (100%) rename {r2r => r2r_core}/base/abstractions/prompt.py (100%) rename {r2r => r2r_core}/base/abstractions/search.py (94%) rename {r2r => r2r_core}/base/abstractions/user.py (100%) rename {r2r => r2r_core}/base/abstractions/vector.py (100%) rename {r2r => r2r_core}/base/agent/__init__.py (100%) rename {r2r => r2r_core}/base/agent/agent.py (98%) rename {r2r => r2r_core}/base/agent/base.py (79%) rename {r2r => r2r_core}/base/api/models/__init__.py (100%) rename {r2r => r2r_core}/base/api/models/auth/__init__.py (100%) rename {r2r => r2r_core}/base/api/models/auth/responses.py (90%) rename {r2r => r2r_core}/base/api/models/base.py (100%) rename {r2r => r2r_core}/base/api/models/ingestion/__init__.py (100%) rename {r2r => r2r_core}/base/api/models/ingestion/responses.py (97%) rename {r2r => r2r_core}/base/api/models/management/__init__.py (100%) rename {r2r => r2r_core}/base/api/models/management/responses.py (97%) rename {r2r => r2r_core}/base/api/models/retrieval/__init__.py (100%) rename {r2r => r2r_core}/base/api/models/retrieval/responses.py (97%) rename {r2r => r2r_core}/base/logging/__init__.py (100%) rename {r2r => r2r_core}/base/logging/base.py (100%) rename {r2r => r2r_core}/base/logging/log_processor.py (100%) rename {r2r => r2r_core}/base/logging/run_logger.py (100%) rename {r2r => r2r_core}/base/logging/run_manager.py (92%) rename {r2r => r2r_core}/base/parsers/__init__.py (100%) rename {r2r => r2r_core}/base/parsers/base_parser.py (100%) rename {r2r => r2r_core}/base/pipeline/__init__.py (100%) rename {r2r => r2r_core}/base/pipeline/base_pipeline.py (100%) rename {r2r => r2r_core}/base/pipes/__init__.py (100%) rename {r2r => r2r_core}/base/pipes/base_pipe.py (97%) rename {r2r => r2r_core}/base/providers/__init__.py (100%) rename {r2r => r2r_core}/base/providers/auth.py (100%) rename {r2r => r2r_core}/base/providers/base.py (91%) rename {r2r => r2r_core}/base/providers/chunking.py (100%) rename {r2r => r2r_core}/base/providers/crypto.py (100%) rename {r2r => r2r_core}/base/providers/database.py (100%) rename {r2r => r2r_core}/base/providers/embedding.py (100%) rename {r2r => r2r_core}/base/providers/kg.py (100%) rename {r2r => r2r_core}/base/providers/llm.py (99%) rename {r2r => r2r_core}/base/providers/parsing.py (100%) rename {r2r => r2r_core}/base/providers/prompt.py (100%) rename {r2r => r2r_core}/base/utils/__init__.py (100%) rename {r2r => r2r_core}/base/utils/base_utils.py (100%) rename {r2r => r2r_core}/base/utils/splitter/__init__.py (100%) rename {r2r => r2r_core}/base/utils/splitter/text.py (100%) rename {r2r => r2r_core}/cli/__init__.py (100%) rename {r2r => r2r_core}/cli/cli.py (94%) rename {r2r => r2r_core}/cli/command_group.py (95%) rename {r2r => r2r_core}/cli/commands/__init__.py (100%) rename {r2r => r2r_core}/cli/commands/auth_operations.py (87%) rename {r2r => r2r_core}/cli/commands/document_operations.py (97%) rename {r2r => r2r_core}/cli/commands/kg_operations.py (76%) rename {r2r => r2r_core}/cli/commands/oberservability_operations.py (93%) rename {r2r => r2r_core}/cli/commands/rag_operations.py (97%) rename {r2r => r2r_core}/cli/commands/server_operations.py (98%) rename {r2r => r2r_core}/cli/utils/__init__.py (100%) rename {r2r => r2r_core}/cli/utils/docker_utils.py (99%) rename {r2r => r2r_core}/cli/utils/param_types.py (100%) rename {r2r => r2r_core}/cli/utils/timer.py (100%) rename {r2r => r2r_core}/configs/auth.toml (100%) rename {r2r => r2r_core}/configs/local_llm.toml (100%) rename {r2r => r2r_core}/configs/local_llm_neo4j_kg.toml (100%) rename {r2r => r2r_core}/configs/neo4j_kg.toml (100%) rename {r2r => r2r_core}/configs/neo4j_kg_no_vector_postgres.toml (100%) rename {r2r => r2r_core}/configs/postgres_logging.toml (100%) rename {r2r => r2r_core}/examples/__init__.py (100%) rename {r2r => r2r_core}/examples/data/aristotle.txt (100%) rename {r2r => r2r_core}/examples/data/aristotle_v2.txt (100%) rename {r2r => r2r_core}/examples/data/got.txt (100%) rename {r2r => r2r_core}/examples/data/lyft_2021.pdf (100%) rename {r2r => r2r_core}/examples/data/pg_essay_1.html (100%) rename {r2r => r2r_core}/examples/data/pg_essay_2.html (100%) rename {r2r => r2r_core}/examples/data/pg_essay_3.html (100%) rename {r2r => r2r_core}/examples/data/pg_essay_4.html (100%) rename {r2r => r2r_core}/examples/data/pg_essay_5.html (100%) rename {r2r => r2r_core}/examples/data/sample.mp3 (100%) rename {r2r => r2r_core}/examples/data/sample2.mp3 (100%) rename {r2r => r2r_core}/examples/data/screen_shot.png (100%) rename {r2r => r2r_core}/examples/data/test.txt (100%) rename {r2r => r2r_core}/examples/data/uber_2021.pdf (100%) rename {r2r => r2r_core}/examples/data/yc_companies.txt (100%) rename {r2r => r2r_core}/examples/hello_r2r.py (96%) rename {r2r => r2r_core}/examples/scripts/advanced_kg_cookbook.py (99%) rename {r2r => r2r_core}/examples/scripts/run_auth_workflow.py (94%) rename {r2r => r2r_core}/examples/scripts/run_hyde.py (80%) rename {r2r => r2r_core}/examples/scripts/run_web_multi_rag.py (90%) rename {r2r => r2r_core}/examples/scripts/run_web_rag.py (92%) rename {r2r => r2r_core}/examples/scripts/sample_data_ingestor.py (97%) rename {r2r => r2r_core}/integrations/__init__.py (100%) rename {r2r => r2r_core}/integrations/serper.py (100%) rename {r2r => r2r_core}/main/__init__.py (97%) rename {r2r => r2r_core}/main/abstractions.py (91%) rename {r2r => r2r_core}/main/api/__init__.py (86%) rename {r2r => r2r_core}/main/api/routes/__init__.py (100%) rename {r2r => r2r_core}/main/api/routes/auth/__init__.py (100%) rename {r2r => r2r_core}/main/api/routes/auth/base.py (98%) rename {r2r => r2r_core}/main/api/routes/base_router.py (96%) rename {r2r => r2r_core}/main/api/routes/ingestion/__init__.py (100%) rename {r2r => r2r_core}/main/api/routes/ingestion/base.py (98%) rename {r2r => r2r_core}/main/api/routes/ingestion/ingestion_router_openapi.yml (100%) rename {r2r => r2r_core}/main/api/routes/management/__init__.py (100%) rename {r2r => r2r_core}/main/api/routes/management/base.py (99%) rename {r2r => r2r_core}/main/api/routes/restructure/__init__.py (100%) rename {r2r => r2r_core}/main/api/routes/restructure/base.py (88%) rename {r2r => r2r_core}/main/api/routes/retrieval/__init__.py (100%) rename {r2r => r2r_core}/main/api/routes/retrieval/base.py (99%) rename {r2r => r2r_core}/main/api/routes/retrieval/retrieval_router_openapi.yml (100%) rename {r2r => r2r_core}/main/app.py (100%) rename {r2r => r2r_core}/main/app_entry.py (100%) rename {r2r => r2r_core}/main/assembly/__init__.py (100%) rename {r2r => r2r_core}/main/assembly/builder.py (99%) rename {r2r => r2r_core}/main/assembly/config.py (100%) rename {r2r => r2r_core}/main/assembly/factory.py (92%) rename {r2r => r2r_core}/main/assembly/factory_extensions.py (95%) rename {r2r => r2r_core}/main/engine.py (98%) rename {r2r => r2r_core}/main/execution.py (98%) rename {r2r => r2r_core}/main/r2r.py (100%) rename {r2r => r2r_core}/main/services/__init__.py (100%) rename {r2r => r2r_core}/main/services/auth_service.py (96%) rename {r2r => r2r_core}/main/services/base.py (91%) rename {r2r => r2r_core}/main/services/ingestion_service.py (98%) rename {r2r => r2r_core}/main/services/management_service.py (99%) rename {r2r => r2r_core}/main/services/restructure_service.py (94%) rename {r2r => r2r_core}/main/services/retrieval_service.py (98%) rename {r2r => r2r_core}/parsers/__init__.py (100%) rename {r2r => r2r_core}/parsers/media/__init__.py (100%) rename {r2r => r2r_core}/parsers/media/audio_parser.py (88%) rename {r2r => r2r_core}/parsers/media/docx_parser.py (87%) rename {r2r => r2r_core}/parsers/media/img_parser.py (85%) rename {r2r => r2r_core}/parsers/media/movie_parser.py (97%) rename {r2r => r2r_core}/parsers/media/openai_helpers.py (100%) rename {r2r => r2r_core}/parsers/media/pdf_parser.py (98%) rename {r2r => r2r_core}/parsers/media/ppt_parser.py (88%) rename {r2r => r2r_core}/parsers/structured/__init__.py (100%) rename {r2r => r2r_core}/parsers/structured/csv_parser.py (95%) rename {r2r => r2r_core}/parsers/structured/json_parser.py (93%) rename {r2r => r2r_core}/parsers/structured/xlsx_parser.py (96%) rename {r2r => r2r_core}/parsers/text/__init__.py (100%) rename {r2r => r2r_core}/parsers/text/html_parser.py (74%) rename {r2r => r2r_core}/parsers/text/md_parser.py (82%) rename {r2r => r2r_core}/parsers/text/text_parser.py (71%) rename {r2r => r2r_core}/pipelines/__init__.py (100%) rename {r2r => r2r_core}/pipelines/graph_enrichment.py (100%) rename {r2r => r2r_core}/pipelines/ingestion_pipeline.py (92%) rename {r2r => r2r_core}/pipelines/rag_pipeline.py (100%) rename {r2r => r2r_core}/pipelines/search_pipeline.py (100%) rename {r2r => r2r_core}/pipes/__init__.py (100%) rename {r2r => r2r_core}/pipes/abstractions/__init__.py (100%) rename {r2r => r2r_core}/pipes/abstractions/generator_pipe.py (89%) rename {r2r => r2r_core}/pipes/abstractions/search_pipe.py (98%) rename {r2r => r2r_core}/pipes/ingestion/__init__.py (100%) rename {r2r => r2r_core}/pipes/ingestion/chunking_pipe.py (94%) rename {r2r => r2r_core}/pipes/ingestion/embedding_pipe.py (98%) rename {r2r => r2r_core}/pipes/ingestion/kg_extraction_pipe.py (97%) rename {r2r => r2r_core}/pipes/ingestion/parsing_pipe.py (93%) rename {r2r => r2r_core}/pipes/ingestion/vector_storage_pipe.py (95%) rename {r2r => r2r_core}/pipes/kg/clustering.py (99%) rename {r2r => r2r_core}/pipes/kg/extraction.py (98%) rename {r2r => r2r_core}/pipes/kg/node_extraction.py (97%) rename {r2r => r2r_core}/pipes/kg/storage.py (95%) rename {r2r => r2r_core}/pipes/other/web_search_pipe.py (97%) rename {r2r => r2r_core}/pipes/retrieval/kg_search_search_pipe.py (99%) rename {r2r => r2r_core}/pipes/retrieval/multi_search.py (93%) rename {r2r => r2r_core}/pipes/retrieval/query_transform_pipe.py (96%) rename {r2r => r2r_core}/pipes/retrieval/search_rag_pipe.py (97%) rename {r2r => r2r_core}/pipes/retrieval/streaming_rag_pipe.py (97%) rename {r2r => r2r_core}/pipes/retrieval/vector_search_pipe.py (99%) rename {r2r => r2r_core}/providers/__init__.py (100%) rename {r2r => r2r_core}/providers/auth/__init__.py (100%) rename {r2r => r2r_core}/providers/auth/r2r_auth.py (99%) rename {r2r => r2r_core}/providers/chunking/__init__.py (100%) rename {r2r => r2r_core}/providers/chunking/r2r_chunking.py (99%) rename {r2r => r2r_core}/providers/chunking/unstructured_chunking.py (97%) rename {r2r => r2r_core}/providers/crypto/__init__.py (100%) rename {r2r => r2r_core}/providers/crypto/bcrypt.py (96%) rename {r2r => r2r_core}/providers/database/__init__.py (100%) rename {r2r => r2r_core}/providers/database/base.py (100%) rename {r2r => r2r_core}/providers/database/document.py (98%) rename {r2r => r2r_core}/providers/database/group.py (98%) rename {r2r => r2r_core}/providers/database/postgres.py (99%) rename {r2r => r2r_core}/providers/database/relational.py (80%) rename {r2r => r2r_core}/providers/database/tokens.py (100%) rename {r2r => r2r_core}/providers/database/user.py (98%) rename {r2r => r2r_core}/providers/database/vecs/__init__.py (100%) rename {r2r => r2r_core}/providers/database/vecs/adapter/__init__.py (100%) rename {r2r => r2r_core}/providers/database/vecs/adapter/base.py (100%) rename {r2r => r2r_core}/providers/database/vecs/adapter/markdown.py (100%) rename {r2r => r2r_core}/providers/database/vecs/adapter/noop.py (100%) rename {r2r => r2r_core}/providers/database/vecs/adapter/text.py (100%) rename {r2r => r2r_core}/providers/database/vecs/client.py (95%) rename {r2r => r2r_core}/providers/database/vecs/collection.py (99%) rename {r2r => r2r_core}/providers/database/vecs/exc.py (100%) rename {r2r => r2r_core}/providers/database/vector.py (99%) rename {r2r => r2r_core}/providers/embeddings/__init__.py (100%) rename {r2r => r2r_core}/providers/embeddings/litellm.py (99%) rename {r2r => r2r_core}/providers/embeddings/ollama.py (99%) rename {r2r => r2r_core}/providers/embeddings/openai.py (99%) rename {r2r => r2r_core}/providers/kg/__init__.py (100%) rename {r2r => r2r_core}/providers/kg/neo4j/__init__.py (100%) rename {r2r => r2r_core}/providers/kg/neo4j/graph_queries.py (100%) rename {r2r => r2r_core}/providers/kg/neo4j/provider.py (98%) rename {r2r => r2r_core}/providers/llm/__init__.py (100%) rename {r2r => r2r_core}/providers/llm/litellm.py (95%) rename {r2r => r2r_core}/providers/llm/openai.py (95%) rename {r2r => r2r_core}/providers/parsing/__init__.py (100%) rename {r2r => r2r_core}/providers/parsing/r2r_parsing.py (98%) rename {r2r => r2r_core}/providers/parsing/unstructured_parsing.py (98%) rename {r2r => r2r_core}/providers/prompts/__init__.py (100%) rename {r2r => r2r_core}/providers/prompts/defaults.yaml (100%) rename {r2r => r2r_core}/providers/prompts/defaults/default_rag.yaml (100%) rename {r2r => r2r_core}/providers/prompts/defaults/few_shot_ner_kg_extraction.yaml (100%) rename {r2r => r2r_core}/providers/prompts/defaults/few_shot_ner_kg_extraction_with_spec.yaml (100%) rename {r2r => r2r_core}/providers/prompts/defaults/graphrag_community_reports.yaml (100%) rename {r2r => r2r_core}/providers/prompts/defaults/graphrag_map_system_prompt.yaml (100%) rename {r2r => r2r_core}/providers/prompts/defaults/graphrag_reduce_system_prompt.yaml (100%) rename {r2r => r2r_core}/providers/prompts/defaults/graphrag_triplet_extraction_few_shot.yaml (100%) rename {r2r => r2r_core}/providers/prompts/defaults/graphrag_triplet_extraction_zero_shot.yaml (100%) rename {r2r => r2r_core}/providers/prompts/defaults/hyde.yaml (100%) rename {r2r => r2r_core}/providers/prompts/defaults/kg_search.yaml (100%) rename {r2r => r2r_core}/providers/prompts/defaults/kg_search_with_spec.yaml (100%) rename {r2r => r2r_core}/providers/prompts/defaults/rag_agent.yaml (100%) rename {r2r => r2r_core}/providers/prompts/defaults/rag_context.yaml (100%) rename {r2r => r2r_core}/providers/prompts/defaults/rag_fusion.yaml (100%) rename {r2r => r2r_core}/providers/prompts/defaults/system.yaml (100%) rename {r2r => r2r_core}/providers/prompts/defaults/zero_shot_ner_kg_extraction.yaml (100%) rename {r2r => r2r_core}/providers/prompts/defaults/zero_shot_ner_kg_extraction_with_spec.yaml (100%) rename {r2r => r2r_core}/providers/prompts/r2r_prompts.py (98%) rename {r2r => r2r_core}/telemetry/__init__.py (100%) rename {r2r => r2r_core}/telemetry/events.py (100%) rename {r2r => r2r_core}/telemetry/posthog.py (96%) rename {r2r => r2r_core}/telemetry/telemetry_decorator.py (93%) create mode 100644 r2r_go_sdk/go.mod create mode 100644 r2r_go_sdk/internal/tests/integration/management_test.go create mode 100644 r2r_go_sdk/pkg/sdk/auth.go create mode 100644 r2r_go_sdk/pkg/sdk/client.go create mode 100644 r2r_go_sdk/pkg/sdk/ingestion.go create mode 100644 r2r_go_sdk/pkg/sdk/management.go create mode 100644 r2r_go_sdk/pkg/sdk/restructure.go create mode 100644 r2r_go_sdk/pkg/sdk/retrieval.go create mode 100644 r2r_js_sdk/README.md create mode 100644 r2r_js_sdk/__tests__/r2rClient.test.ts create mode 100644 r2r_js_sdk/__tests__/r2rClientIntegrationSuperUser.test.ts create mode 100644 r2r_js_sdk/__tests__/r2rClientIntegrationUser.test.ts create mode 100644 r2r_js_sdk/examples/data/folder/karamozov.txt create mode 100644 r2r_js_sdk/examples/data/folder/myshkin.txt create mode 100644 r2r_js_sdk/examples/data/raskolnikov.txt create mode 100644 r2r_js_sdk/examples/hello_r2r.js create mode 100644 r2r_js_sdk/jest.config.js create mode 100644 r2r_js_sdk/package-lock.json create mode 100644 r2r_js_sdk/package.json create mode 100644 r2r_js_sdk/pnpm-lock.yaml create mode 100644 r2r_js_sdk/src/feature.ts create mode 100644 r2r_js_sdk/src/index.ts create mode 100644 r2r_js_sdk/src/models.tsx create mode 100644 r2r_js_sdk/src/r2rClient.ts create mode 100644 r2r_js_sdk/tsconfig.json create mode 100644 r2r_python_sdk/README.md create mode 100644 r2r_python_sdk/poetry.lock create mode 100644 r2r_python_sdk/pyproject.toml create mode 100644 r2r_python_sdk/r2r/__init__.py rename {r2r/main/api/client => r2r_python_sdk/r2r}/auth.py (98%) rename {r2r/main/api/client => r2r_python_sdk/r2r}/client.py (99%) rename {r2r/main/api/client => r2r_python_sdk/r2r}/ingestion.py (99%) rename {r2r/main/api/client => r2r_python_sdk/r2r}/management.py (100%) create mode 100644 r2r_python_sdk/r2r/models.py rename {r2r/main/api/client => r2r_python_sdk/r2r}/restructure.py (100%) rename {r2r/main/api/client => r2r_python_sdk/r2r}/retrieval.py (96%) diff --git a/.github/workflows/r2r-js-sdk-ci.yml b/.github/workflows/r2r-js-sdk-ci.yml new file mode 100644 index 000000000..474f90df6 --- /dev/null +++ b/.github/workflows/r2r-js-sdk-ci.yml @@ -0,0 +1,38 @@ +name: R2R JS SDK Integration CI + +on: + push: + branches: [main] + paths: + - 'r2r_js_sdk/**' + pull_request: + branches: [main] + paths: + - 'r2r_js_sdk/**' + +jobs: + build-and-test: + runs-on: ubuntu-latest + + defaults: + run: + working-directory: r2r_js_sdk + + steps: + - uses: actions/checkout@v2 + + - name: Use Node.js + uses: actions/setup-node@v2 + with: + node-version: "18" + + - name: Install pnpm + uses: pnpm/action-setup@v2 + with: + version: 8 + + - name: Install dependencies + run: pnpm install + + - name: Build + run: pnpm run build diff --git a/.github/workflows/r2r-js-sdk-integration-tests.yml b/.github/workflows/r2r-js-sdk-integration-tests.yml new file mode 100644 index 000000000..1ee8ade29 --- /dev/null +++ b/.github/workflows/r2r-js-sdk-integration-tests.yml @@ -0,0 +1,68 @@ +name: R2R JS SDK Integration Tests + +on: + push: + branches: [main] + paths: + - 'r2r_js_sdk/**' + pull_request: + branches: [main] + paths: + - 'r2r_js_sdk/**' + +jobs: + test: + runs-on: ubuntu-latest + + defaults: + run: + working-directory: r2r_js_sdk + + steps: + - uses: actions/checkout@v2 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: "3.x" + + - name: Install R2R + run: | + python -m pip install --upgrade pip + pip install r2r + + - name: Start R2R server + env: + POSTGRES_HOST: ${{ secrets.POSTGRES_HOST }} + POSTGRES_USER: ${{ secrets.POSTGRES_USER }} + POSTGRES_PASSWORD: ${{ secrets.POSTGRES_PASSWORD }} + POSTGRES_PORT: ${{ secrets.POSTGRES_PORT }} + POSTGRES_DBNAME: ${{ secrets.POSTGRES_DBNAME }} + POSTGRES_VECS_COLLECTION: ${{ secrets.POSTGRES_VECS_COLLECTION }} + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} + run: | + r2r serve --port=8000 > r2r_server.log 2>&1 & + sleep 15 + + - name: Use Node.js + uses: actions/setup-node@v2 + with: + node-version: "20.x" + + - name: Install dependencies + run: npm ci + + - name: Check if R2R server is running + run: | + curl http://localhost:8000/health || echo "Server not responding" + + - name: Display R2R server logs if server not responding + if: failure() + run: cat r2r_server.log + + - name: Run integration tests + run: npm run test + + - name: Display R2R server logs if tests fail + if: failure() + run: cat r2r_server.log diff --git a/.gitignore b/.gitignore index 7dae56630..08c80b273 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +**/.DS_Store .env .DS_Store *.gguf @@ -15,3 +16,15 @@ coverage.xml **/*.sqlite* **/*.sqlite3* + +node_modules/ +dist/ + +*.exe +*.exe~ +*.dll +*.so +*.dylib +*.test +go.work +go.work.sum diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1bfad76f0..f6fdbfd4e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -15,11 +15,11 @@ repos: entry: poetry run isort language: system types: [python] - args: ["--check", "--diff"] + args: ["--profile", "black", "--filter-files"] - id: black name: black entry: poetry run black language: system types: [python] - args: ["--check", "--diff"] + exclude: ^(.venv|venv|env)/ diff --git a/poetry.lock b/poetry.lock index 53e96de38..95a1ee879 100644 --- a/poetry.lock +++ b/poetry.lock @@ -13,87 +13,102 @@ files = [ [[package]] name = "aiohttp" -version = "3.10.4" +version = "3.10.5" description = "Async http client/server framework (asyncio)" optional = false python-versions = ">=3.8" files = [ - {file = "aiohttp-3.10.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:81037ddda8cc0a95c6d8c1b9029d0b19a62db8770c0e239e3bea0109d294ab66"}, - {file = "aiohttp-3.10.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:71944d4f4090afc07ce96b7029d5a574240e2f39570450df4af0d5b93a5ee64a"}, - {file = "aiohttp-3.10.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c774f08afecc0a617966f45a9c378456e713a999ee60654d9727617def3e4ee4"}, - {file = "aiohttp-3.10.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dc990e73613c78ab2930b60266135066f37fdfce6b32dd604f42c5c377ee880a"}, - {file = "aiohttp-3.10.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f6acd1a908740f708358d240f9a3243cec31a456e3ded65c2cb46f6043bc6735"}, - {file = "aiohttp-3.10.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6075e27e7e54fbcd1c129c5699b2d251c885c9892e26d59a0fb7705141c2d14b"}, - {file = "aiohttp-3.10.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc98d93d11d860ac823beb6131f292d82efb76f226b5e28a3eab1ec578dfd041"}, - {file = "aiohttp-3.10.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:201ddf1471567568be381b6d4701e266a768f7eaa2f99ef753f2c9c5e1e3fb5c"}, - {file = "aiohttp-3.10.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:7d202ec55e61f06b1a1eaf317fba7546855cbf803c13ce7625d462fb8c88e238"}, - {file = "aiohttp-3.10.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:96b2e7c110a941c8c1a692703b8ac1013e47f17ee03356c71d55c0a54de2ce38"}, - {file = "aiohttp-3.10.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:8ba0fbc56c44883bd757ece433f9caadbca67f565934afe9bc53ba3bd99cc368"}, - {file = "aiohttp-3.10.4-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:46cc9069da466652bb7b8b3fac1f8ce2e12a9dc0fb11551faa420c4cdbc60abf"}, - {file = "aiohttp-3.10.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:93a19cd1e9dc703257fda78b8e889c3a08eabaa09f6ff0d867850b03964f80d1"}, - {file = "aiohttp-3.10.4-cp310-cp310-win32.whl", hash = "sha256:8593040bcc8075fc0e817a602bc5d3d74c7bd717619ffc175a8ba0188edebadf"}, - {file = "aiohttp-3.10.4-cp310-cp310-win_amd64.whl", hash = "sha256:326fb5228aadfc395981d9b336d56a698da335897c4143105c73b583d7500839"}, - {file = "aiohttp-3.10.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:dfe48f477e02ef5ab247c6ac431a6109c69b5c24cb3ccbcd3e27c4fb39691fe4"}, - {file = "aiohttp-3.10.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f6fe78b51852e25d4e20be51ef88c2a0bf31432b9f2223bdbd61c01a0f9253a7"}, - {file = "aiohttp-3.10.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5cc75ff5efbd92301e63a157fddb18a6964a3f40e31c77d57e97dbb9bb3373b4"}, - {file = "aiohttp-3.10.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dca39391f45fbb28daa6412f98c625265bf6b512cc41382df61672d1b242f8f4"}, - {file = "aiohttp-3.10.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8616dd5ed8b3b4029021b560305041c62e080bb28f238c27c2e150abe3539587"}, - {file = "aiohttp-3.10.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9d7958ba22854b3f00a7bbb66cde1dc759760ce8a3e6dfe9ea53f06bccaa9aa2"}, - {file = "aiohttp-3.10.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a24ac7164a824ef2e8e4e9a9f6debb1f43c44ad7ad04efc6018a6610555666d"}, - {file = "aiohttp-3.10.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:660ad010b8fd0b26e8edb8ae5c036db5b16baac4278198ad238b11956d920b3d"}, - {file = "aiohttp-3.10.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:93ee83008d3e505db9846a5a1f48a002676d8dcc90ee431a9462541c9b81393c"}, - {file = "aiohttp-3.10.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:77071795efd6ba87f409001141fb05c94ee962b9fca6c8fa1f735c2718512de4"}, - {file = "aiohttp-3.10.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:ff371ae72a1816c3eeba5c9cff42cb739aaa293fec7d78f180d1c7ee342285b6"}, - {file = "aiohttp-3.10.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:c253e81f12da97f85d45441e8c6da0d9c12e07db4a7136b0a955df6fc5e4bf51"}, - {file = "aiohttp-3.10.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2ce101c447cf7ba4b6e5ab07bfa2c0da21cbab66922f78a601f0b84fd7710d72"}, - {file = "aiohttp-3.10.4-cp311-cp311-win32.whl", hash = "sha256:705c311ecf2d30fbcf3570d1a037c657be99095694223488140c47dee4ef2460"}, - {file = "aiohttp-3.10.4-cp311-cp311-win_amd64.whl", hash = "sha256:ebddbfea8a8d6b97f717658fa85a96681a28990072710d3de3a4eba5d6804a37"}, - {file = "aiohttp-3.10.4-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:fe4d63f42d9c604521b208b754abfafe01218af4a8f6332b43196ee8fe88bbd5"}, - {file = "aiohttp-3.10.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:fef7b7bd3a6911b4d148332136d34d3c2aee3d54d354373b1da6d96bc08089a5"}, - {file = "aiohttp-3.10.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fff8606149098935188fe1e135f7e7991e6a36d6fe394fd15939fc57d0aff889"}, - {file = "aiohttp-3.10.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9eb3df1aa83602be9a5e572c834d74c3c8e382208b59a873aabfe4c493c45ed0"}, - {file = "aiohttp-3.10.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5c4a71d4a5e0cbfd4bfadd13cb84fe2bc76c64d550dc4f22c22008c9354cffb3"}, - {file = "aiohttp-3.10.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bf61884a604c399458c4a42c8caea000fbcc44255ed89577ff50cb688a0fe8e2"}, - {file = "aiohttp-3.10.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2015e4b40bd5dedc8155c2b2d24a2b07963ae02b5772373d0b599a68e38a316b"}, - {file = "aiohttp-3.10.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b06e1a66bf0a1a2d0f12aef25843dfd2093df080d6c1acbc43914bb9c8f36ed3"}, - {file = "aiohttp-3.10.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:eb898c9ad5a1228a669ebe2e2ba3d76aebe1f7c10b78f09a36000254f049fc2b"}, - {file = "aiohttp-3.10.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:2d64a5a7539320c3cecb4bca093ea825fcc906f8461cf8b42a7bf3c706ce1932"}, - {file = "aiohttp-3.10.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:438c6e1492d060b21285f4b6675b941cf96dd9ef3dfdd59940561029b82e3e1f"}, - {file = "aiohttp-3.10.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e99bf118afb2584848dba169a685fe092b338a4fe52ae08c7243d7bc4cc204fe"}, - {file = "aiohttp-3.10.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9dc26781fb95225c6170619dece8b5c6ca7cfb1b0be97b7ee719915773d0c2a9"}, - {file = "aiohttp-3.10.4-cp312-cp312-win32.whl", hash = "sha256:45bb655cb8b3a61e19977183a4e0962051ae90f6d46588ed4addb8232128141c"}, - {file = "aiohttp-3.10.4-cp312-cp312-win_amd64.whl", hash = "sha256:347bbdc48411badc24fe3a13565820bc742db3aa2f9127cd5f48c256caf87e29"}, - {file = "aiohttp-3.10.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:4ad284cee0fdcdc0216346b849fd53d201b510aff3c48aa3622daec9ada4bf80"}, - {file = "aiohttp-3.10.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:58df59234be7d7e80548b9482ebfeafdda21948c25cb2873c7f23870c8053dfe"}, - {file = "aiohttp-3.10.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5f52225af7f91f27b633f73473e9ef0aa8e2112d57b69eaf3aa4479e3ea3bc0e"}, - {file = "aiohttp-3.10.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:93f1a0e12c321d923c024b56d7dcd8012e60bf30a4b3fb69a88be15dcb9ab80b"}, - {file = "aiohttp-3.10.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c9e9e9a51dd12f2f71fdbd7f7230dcb75ed8f77d8ac8e07c73b599b6d7027e5c"}, - {file = "aiohttp-3.10.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:38bb515f1affc36d3d97b02bf82099925a5785c4a96066ff4400a83ad09d3d5d"}, - {file = "aiohttp-3.10.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e685afb0e3b7b861d89cb3690d89eeda221b43095352efddaaa735c6baf87f3"}, - {file = "aiohttp-3.10.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abd5673e3391564871ba6753cf674dcf2051ef19dc508998fe0758a6c7b429a0"}, - {file = "aiohttp-3.10.4-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:4b34e5086e1ead3baa740e32adf35cc5e42338e44c4b07f7b62b41ca6d6a5bfd"}, - {file = "aiohttp-3.10.4-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:c3fd3b8f0164fb2866400cd6eb9e884ab0dc95f882cf8b25e560ace7350c552d"}, - {file = "aiohttp-3.10.4-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:b95e1694d234f27b4bbf5bdef56bb751974ac5dbe045b1e462bde1fe39421cbe"}, - {file = "aiohttp-3.10.4-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:c031de4dfabe7bb6565743745ab43d20588944ddfc7233360169cab4008eee2f"}, - {file = "aiohttp-3.10.4-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:03c5a3143d4a82c43a3d82ac77d9cdef527a72f1c04dcca7b14770879f33d196"}, - {file = "aiohttp-3.10.4-cp38-cp38-win32.whl", hash = "sha256:b71722b527445e02168e2d1cf435772731874671a647fa159ad000feea7933b6"}, - {file = "aiohttp-3.10.4-cp38-cp38-win_amd64.whl", hash = "sha256:0fd1f57aac7d01c9c768675d531976d20d5b79d9da67fac87e55d41b4ade05f9"}, - {file = "aiohttp-3.10.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:15b36a644d1f44ea3d94a0bbb71e75d5f394a3135dc388a209466e22b711ce64"}, - {file = "aiohttp-3.10.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:394ddf9d216cf0bd429b223239a0ab628f01a7a1799c93ce4685eedcdd51b9bc"}, - {file = "aiohttp-3.10.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:dd33f4d571b4143fc9318c3d9256423579c7d183635acc458a6db81919ae5204"}, - {file = "aiohttp-3.10.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e5991b80886655e6c785aadf3114d4f86e6bec2da436e2bb62892b9f048450a4"}, - {file = "aiohttp-3.10.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:92021bf0a4b9ad16851a6c1ca3c86e5b09aecca4f7a2576430c6bbf3114922b1"}, - {file = "aiohttp-3.10.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:938e37fd337343c67471098736deb33066d72cec7d8927b9c1b6b4ea807ade9e"}, - {file = "aiohttp-3.10.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d697023b16c62f9aeb3ffdfb8ec4ac3afd477388993b9164b47dadbd60e7062"}, - {file = "aiohttp-3.10.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c2f9f07fe6d0d51bd2a788cbb339f1570fd691449c53b5dec83ff838f117703e"}, - {file = "aiohttp-3.10.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:50ac670f3fc13ce95e4d6d5a299db9288cc84c663aa630142444ef504756fcf7"}, - {file = "aiohttp-3.10.4-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:9bcdd19398212785a9cb82a63a4b75a299998343f3f5732dfd37c1a4275463f9"}, - {file = "aiohttp-3.10.4-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:122c26f0976225aba46f381e3cabb5ef89a08af6503fc30493fb732e578cfa55"}, - {file = "aiohttp-3.10.4-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:d0665e2a346b6b66959f831ffffd8aa71dd07dd2300017d478f5b47573e66cfe"}, - {file = "aiohttp-3.10.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:625a4a9d4b9f80e7bbaaf2ace06341cf701b2fee54232843addf0bb7304597fb"}, - {file = "aiohttp-3.10.4-cp39-cp39-win32.whl", hash = "sha256:5115490112f39f16ae87c1b34dff3e2c95306cf456b1d2af5974c4ac7d2d1ec7"}, - {file = "aiohttp-3.10.4-cp39-cp39-win_amd64.whl", hash = "sha256:9b58b2ef7f28a2462ba86acbf3b20371bd80a1faa1cfd82f31968af4ac81ef25"}, - {file = "aiohttp-3.10.4.tar.gz", hash = "sha256:23a5f97e7dd22e181967fb6cb6c3b11653b0fdbbc4bb7739d9b6052890ccab96"}, + {file = "aiohttp-3.10.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:18a01eba2574fb9edd5f6e5fb25f66e6ce061da5dab5db75e13fe1558142e0a3"}, + {file = "aiohttp-3.10.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:94fac7c6e77ccb1ca91e9eb4cb0ac0270b9fb9b289738654120ba8cebb1189c6"}, + {file = "aiohttp-3.10.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2f1f1c75c395991ce9c94d3e4aa96e5c59c8356a15b1c9231e783865e2772699"}, + {file = "aiohttp-3.10.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4f7acae3cf1a2a2361ec4c8e787eaaa86a94171d2417aae53c0cca6ca3118ff6"}, + {file = "aiohttp-3.10.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:94c4381ffba9cc508b37d2e536b418d5ea9cfdc2848b9a7fea6aebad4ec6aac1"}, + {file = "aiohttp-3.10.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c31ad0c0c507894e3eaa843415841995bf8de4d6b2d24c6e33099f4bc9fc0d4f"}, + {file = "aiohttp-3.10.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0912b8a8fadeb32ff67a3ed44249448c20148397c1ed905d5dac185b4ca547bb"}, + {file = "aiohttp-3.10.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d93400c18596b7dc4794d48a63fb361b01a0d8eb39f28800dc900c8fbdaca91"}, + {file = "aiohttp-3.10.5-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d00f3c5e0d764a5c9aa5a62d99728c56d455310bcc288a79cab10157b3af426f"}, + {file = "aiohttp-3.10.5-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:d742c36ed44f2798c8d3f4bc511f479b9ceef2b93f348671184139e7d708042c"}, + {file = "aiohttp-3.10.5-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:814375093edae5f1cb31e3407997cf3eacefb9010f96df10d64829362ae2df69"}, + {file = "aiohttp-3.10.5-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8224f98be68a84b19f48e0bdc14224b5a71339aff3a27df69989fa47d01296f3"}, + {file = "aiohttp-3.10.5-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d9a487ef090aea982d748b1b0d74fe7c3950b109df967630a20584f9a99c0683"}, + {file = "aiohttp-3.10.5-cp310-cp310-win32.whl", hash = "sha256:d9ef084e3dc690ad50137cc05831c52b6ca428096e6deb3c43e95827f531d5ef"}, + {file = "aiohttp-3.10.5-cp310-cp310-win_amd64.whl", hash = "sha256:66bf9234e08fe561dccd62083bf67400bdbf1c67ba9efdc3dac03650e97c6088"}, + {file = "aiohttp-3.10.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8c6a4e5e40156d72a40241a25cc226051c0a8d816610097a8e8f517aeacd59a2"}, + {file = "aiohttp-3.10.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c634a3207a5445be65536d38c13791904fda0748b9eabf908d3fe86a52941cf"}, + {file = "aiohttp-3.10.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4aff049b5e629ef9b3e9e617fa6e2dfeda1bf87e01bcfecaf3949af9e210105e"}, + {file = "aiohttp-3.10.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1942244f00baaacaa8155eca94dbd9e8cc7017deb69b75ef67c78e89fdad3c77"}, + {file = "aiohttp-3.10.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e04a1f2a65ad2f93aa20f9ff9f1b672bf912413e5547f60749fa2ef8a644e061"}, + {file = "aiohttp-3.10.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7f2bfc0032a00405d4af2ba27f3c429e851d04fad1e5ceee4080a1c570476697"}, + {file = "aiohttp-3.10.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:424ae21498790e12eb759040bbb504e5e280cab64693d14775c54269fd1d2bb7"}, + {file = "aiohttp-3.10.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:975218eee0e6d24eb336d0328c768ebc5d617609affaca5dbbd6dd1984f16ed0"}, + {file = "aiohttp-3.10.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:4120d7fefa1e2d8fb6f650b11489710091788de554e2b6f8347c7a20ceb003f5"}, + {file = "aiohttp-3.10.5-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:b90078989ef3fc45cf9221d3859acd1108af7560c52397ff4ace8ad7052a132e"}, + {file = "aiohttp-3.10.5-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:ba5a8b74c2a8af7d862399cdedce1533642fa727def0b8c3e3e02fcb52dca1b1"}, + {file = "aiohttp-3.10.5-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:02594361128f780eecc2a29939d9dfc870e17b45178a867bf61a11b2a4367277"}, + {file = "aiohttp-3.10.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:8fb4fc029e135859f533025bc82047334e24b0d489e75513144f25408ecaf058"}, + {file = "aiohttp-3.10.5-cp311-cp311-win32.whl", hash = "sha256:e1ca1ef5ba129718a8fc827b0867f6aa4e893c56eb00003b7367f8a733a9b072"}, + {file = "aiohttp-3.10.5-cp311-cp311-win_amd64.whl", hash = "sha256:349ef8a73a7c5665cca65c88ab24abe75447e28aa3bc4c93ea5093474dfdf0ff"}, + {file = "aiohttp-3.10.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:305be5ff2081fa1d283a76113b8df7a14c10d75602a38d9f012935df20731487"}, + {file = "aiohttp-3.10.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3a1c32a19ee6bbde02f1cb189e13a71b321256cc1d431196a9f824050b160d5a"}, + {file = "aiohttp-3.10.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:61645818edd40cc6f455b851277a21bf420ce347baa0b86eaa41d51ef58ba23d"}, + {file = "aiohttp-3.10.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c225286f2b13bab5987425558baa5cbdb2bc925b2998038fa028245ef421e75"}, + {file = "aiohttp-3.10.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ba01ebc6175e1e6b7275c907a3a36be48a2d487549b656aa90c8a910d9f3178"}, + {file = "aiohttp-3.10.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8eaf44ccbc4e35762683078b72bf293f476561d8b68ec8a64f98cf32811c323e"}, + {file = "aiohttp-3.10.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1c43eb1ab7cbf411b8e387dc169acb31f0ca0d8c09ba63f9eac67829585b44f"}, + {file = "aiohttp-3.10.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:de7a5299827253023c55ea549444e058c0eb496931fa05d693b95140a947cb73"}, + {file = "aiohttp-3.10.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4790f0e15f00058f7599dab2b206d3049d7ac464dc2e5eae0e93fa18aee9e7bf"}, + {file = "aiohttp-3.10.5-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:44b324a6b8376a23e6ba25d368726ee3bc281e6ab306db80b5819999c737d820"}, + {file = "aiohttp-3.10.5-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:0d277cfb304118079e7044aad0b76685d30ecb86f83a0711fc5fb257ffe832ca"}, + {file = "aiohttp-3.10.5-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:54d9ddea424cd19d3ff6128601a4a4d23d54a421f9b4c0fff740505813739a91"}, + {file = "aiohttp-3.10.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4f1c9866ccf48a6df2b06823e6ae80573529f2af3a0992ec4fe75b1a510df8a6"}, + {file = "aiohttp-3.10.5-cp312-cp312-win32.whl", hash = "sha256:dc4826823121783dccc0871e3f405417ac116055bf184ac04c36f98b75aacd12"}, + {file = "aiohttp-3.10.5-cp312-cp312-win_amd64.whl", hash = "sha256:22c0a23a3b3138a6bf76fc553789cb1a703836da86b0f306b6f0dc1617398abc"}, + {file = "aiohttp-3.10.5-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:7f6b639c36734eaa80a6c152a238242bedcee9b953f23bb887e9102976343092"}, + {file = "aiohttp-3.10.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f29930bc2921cef955ba39a3ff87d2c4398a0394ae217f41cb02d5c26c8b1b77"}, + {file = "aiohttp-3.10.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f489a2c9e6455d87eabf907ac0b7d230a9786be43fbe884ad184ddf9e9c1e385"}, + {file = "aiohttp-3.10.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:123dd5b16b75b2962d0fff566effb7a065e33cd4538c1692fb31c3bda2bfb972"}, + {file = "aiohttp-3.10.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b98e698dc34966e5976e10bbca6d26d6724e6bdea853c7c10162a3235aba6e16"}, + {file = "aiohttp-3.10.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3b9162bab7e42f21243effc822652dc5bb5e8ff42a4eb62fe7782bcbcdfacf6"}, + {file = "aiohttp-3.10.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1923a5c44061bffd5eebeef58cecf68096e35003907d8201a4d0d6f6e387ccaa"}, + {file = "aiohttp-3.10.5-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d55f011da0a843c3d3df2c2cf4e537b8070a419f891c930245f05d329c4b0689"}, + {file = "aiohttp-3.10.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:afe16a84498441d05e9189a15900640a2d2b5e76cf4efe8cbb088ab4f112ee57"}, + {file = "aiohttp-3.10.5-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f8112fb501b1e0567a1251a2fd0747baae60a4ab325a871e975b7bb67e59221f"}, + {file = "aiohttp-3.10.5-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:1e72589da4c90337837fdfe2026ae1952c0f4a6e793adbbfbdd40efed7c63599"}, + {file = "aiohttp-3.10.5-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:4d46c7b4173415d8e583045fbc4daa48b40e31b19ce595b8d92cf639396c15d5"}, + {file = "aiohttp-3.10.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:33e6bc4bab477c772a541f76cd91e11ccb6d2efa2b8d7d7883591dfb523e5987"}, + {file = "aiohttp-3.10.5-cp313-cp313-win32.whl", hash = "sha256:c58c6837a2c2a7cf3133983e64173aec11f9c2cd8e87ec2fdc16ce727bcf1a04"}, + {file = "aiohttp-3.10.5-cp313-cp313-win_amd64.whl", hash = "sha256:38172a70005252b6893088c0f5e8a47d173df7cc2b2bd88650957eb84fcf5022"}, + {file = "aiohttp-3.10.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:f6f18898ace4bcd2d41a122916475344a87f1dfdec626ecde9ee802a711bc569"}, + {file = "aiohttp-3.10.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5ede29d91a40ba22ac1b922ef510aab871652f6c88ef60b9dcdf773c6d32ad7a"}, + {file = "aiohttp-3.10.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:673f988370f5954df96cc31fd99c7312a3af0a97f09e407399f61583f30da9bc"}, + {file = "aiohttp-3.10.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:58718e181c56a3c02d25b09d4115eb02aafe1a732ce5714ab70326d9776457c3"}, + {file = "aiohttp-3.10.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4b38b1570242fbab8d86a84128fb5b5234a2f70c2e32f3070143a6d94bc854cf"}, + {file = "aiohttp-3.10.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:074d1bff0163e107e97bd48cad9f928fa5a3eb4b9d33366137ffce08a63e37fe"}, + {file = "aiohttp-3.10.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd31f176429cecbc1ba499d4aba31aaccfea488f418d60376b911269d3b883c5"}, + {file = "aiohttp-3.10.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7384d0b87d4635ec38db9263e6a3f1eb609e2e06087f0aa7f63b76833737b471"}, + {file = "aiohttp-3.10.5-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8989f46f3d7ef79585e98fa991e6ded55d2f48ae56d2c9fa5e491a6e4effb589"}, + {file = "aiohttp-3.10.5-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:c83f7a107abb89a227d6c454c613e7606c12a42b9a4ca9c5d7dad25d47c776ae"}, + {file = "aiohttp-3.10.5-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:cde98f323d6bf161041e7627a5fd763f9fd829bcfcd089804a5fdce7bb6e1b7d"}, + {file = "aiohttp-3.10.5-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:676f94c5480d8eefd97c0c7e3953315e4d8c2b71f3b49539beb2aa676c58272f"}, + {file = "aiohttp-3.10.5-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:2d21ac12dc943c68135ff858c3a989f2194a709e6e10b4c8977d7fcd67dfd511"}, + {file = "aiohttp-3.10.5-cp38-cp38-win32.whl", hash = "sha256:17e997105bd1a260850272bfb50e2a328e029c941c2708170d9d978d5a30ad9a"}, + {file = "aiohttp-3.10.5-cp38-cp38-win_amd64.whl", hash = "sha256:1c19de68896747a2aa6257ae4cf6ef59d73917a36a35ee9d0a6f48cff0f94db8"}, + {file = "aiohttp-3.10.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7e2fe37ac654032db1f3499fe56e77190282534810e2a8e833141a021faaab0e"}, + {file = "aiohttp-3.10.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f5bf3ead3cb66ab990ee2561373b009db5bc0e857549b6c9ba84b20bc462e172"}, + {file = "aiohttp-3.10.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1b2c16a919d936ca87a3c5f0e43af12a89a3ce7ccbce59a2d6784caba945b68b"}, + {file = "aiohttp-3.10.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad146dae5977c4dd435eb31373b3fe9b0b1bf26858c6fc452bf6af394067e10b"}, + {file = "aiohttp-3.10.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8c5c6fa16412b35999320f5c9690c0f554392dc222c04e559217e0f9ae244b92"}, + {file = "aiohttp-3.10.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:95c4dc6f61d610bc0ee1edc6f29d993f10febfe5b76bb470b486d90bbece6b22"}, + {file = "aiohttp-3.10.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da452c2c322e9ce0cfef392e469a26d63d42860f829026a63374fde6b5c5876f"}, + {file = "aiohttp-3.10.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:898715cf566ec2869d5cb4d5fb4be408964704c46c96b4be267442d265390f32"}, + {file = "aiohttp-3.10.5-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:391cc3a9c1527e424c6865e087897e766a917f15dddb360174a70467572ac6ce"}, + {file = "aiohttp-3.10.5-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:380f926b51b92d02a34119d072f178d80bbda334d1a7e10fa22d467a66e494db"}, + {file = "aiohttp-3.10.5-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ce91db90dbf37bb6fa0997f26574107e1b9d5ff939315247b7e615baa8ec313b"}, + {file = "aiohttp-3.10.5-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:9093a81e18c45227eebe4c16124ebf3e0d893830c6aca7cc310bfca8fe59d857"}, + {file = "aiohttp-3.10.5-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:ee40b40aa753d844162dcc80d0fe256b87cba48ca0054f64e68000453caead11"}, + {file = "aiohttp-3.10.5-cp39-cp39-win32.whl", hash = "sha256:03f2645adbe17f274444953bdea69f8327e9d278d961d85657cb0d06864814c1"}, + {file = "aiohttp-3.10.5-cp39-cp39-win_amd64.whl", hash = "sha256:d17920f18e6ee090bdd3d0bfffd769d9f2cb4c8ffde3eb203777a3895c128862"}, + {file = "aiohttp-3.10.5.tar.gz", hash = "sha256:f071854b47d39591ce9a17981c46790acb30518e2f83dfca8db2dfa091178691"}, ] [package.dependencies] @@ -140,25 +155,6 @@ typing_extensions = ">=4.0" dev = ["attribution (==1.7.0)", "black (==24.2.0)", "coverage[toml] (==7.4.1)", "flake8 (==7.0.0)", "flake8-bugbear (==24.2.6)", "flit (==3.9.0)", "mypy (==1.8.0)", "ufmt (==2.3.0)", "usort (==1.0.8.post1)"] docs = ["sphinx (==7.2.6)", "sphinx-mdinclude (==0.5.3)"] -[[package]] -name = "alembic" -version = "1.13.2" -description = "A database migration tool for SQLAlchemy." -optional = false -python-versions = ">=3.8" -files = [ - {file = "alembic-1.13.2-py3-none-any.whl", hash = "sha256:6b8733129a6224a9a711e17c99b08462dbf7cc9670ba8f2e2ae9af860ceb1953"}, - {file = "alembic-1.13.2.tar.gz", hash = "sha256:1ff0ae32975f4fd96028c39ed9bb3c867fe3af956bd7bb37343b54c9fe7445ef"}, -] - -[package.dependencies] -Mako = "*" -SQLAlchemy = ">=1.3.0" -typing-extensions = ">=4" - -[package.extras] -tz = ["backports.zoneinfo"] - [[package]] name = "annotated-types" version = "0.7.0" @@ -1544,13 +1540,13 @@ setuptools = "*" [[package]] name = "importlib-metadata" -version = "8.2.0" +version = "8.3.0" description = "Read metadata from Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "importlib_metadata-8.2.0-py3-none-any.whl", hash = "sha256:11901fa0c2f97919b288679932bb64febaeacf289d18ac84dd68cb2e74213369"}, - {file = "importlib_metadata-8.2.0.tar.gz", hash = "sha256:72e8d4399996132204f9a16dcc751af254a48f8d1b20b9ff0f98d4a8f901e73d"}, + {file = "importlib_metadata-8.3.0-py3-none-any.whl", hash = "sha256:42817a4a0be5845d22c6e212db66a94ad261e2318d80b3e0d363894a79df2b67"}, + {file = "importlib_metadata-8.3.0.tar.gz", hash = "sha256:9c8fa6e8ea0f9516ad5c8db9246a731c948193c7754d3babb0114a05b27dd364"}, ] [package.dependencies] @@ -2065,25 +2061,6 @@ html5 = ["html5lib"] htmlsoup = ["BeautifulSoup4"] source = ["Cython (>=3.0.11)"] -[[package]] -name = "mako" -version = "1.3.5" -description = "A super-fast templating language that borrows the best ideas from the existing templating languages." -optional = false -python-versions = ">=3.8" -files = [ - {file = "Mako-1.3.5-py3-none-any.whl", hash = "sha256:260f1dbc3a519453a9c856dedfe4beb4e50bd5a26d96386cb6c80856556bb91a"}, - {file = "Mako-1.3.5.tar.gz", hash = "sha256:48dbc20568c1d276a2698b36d968fa76161bf127194907ea6fc594fa81f943bc"}, -] - -[package.dependencies] -MarkupSafe = ">=0.9.2" - -[package.extras] -babel = ["Babel"] -lingua = ["lingua"] -testing = ["pytest"] - [[package]] name = "markdown" version = "3.7" @@ -2633,11 +2610,11 @@ files = [ [package.dependencies] numpy = [ {version = ">=1.21.0", markers = "python_version == \"3.9\" and platform_system == \"Darwin\" and platform_machine == \"arm64\""}, + {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, + {version = ">=1.23.5", markers = "python_version >= \"3.11\" and python_version < \"3.12\""}, {version = ">=1.21.4", markers = "python_version >= \"3.10\" and platform_system == \"Darwin\" and python_version < \"3.11\""}, {version = ">=1.21.2", markers = "platform_system != \"Darwin\" and python_version >= \"3.10\" and python_version < \"3.11\""}, {version = ">=1.19.3", markers = "platform_system == \"Linux\" and platform_machine == \"aarch64\" and python_version >= \"3.8\" and python_version < \"3.10\" or python_version > \"3.9\" and python_version < \"3.10\" or python_version >= \"3.9\" and platform_system != \"Darwin\" and python_version < \"3.10\" or python_version >= \"3.9\" and platform_machine != \"arm64\" and python_version < \"3.10\""}, - {version = ">=1.23.5", markers = "python_version >= \"3.11\" and python_version < \"3.12\""}, - {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, ] [[package]] @@ -2720,8 +2697,8 @@ files = [ [package.dependencies] numpy = [ {version = ">=1.22.4", markers = "python_version < \"3.11\""}, - {version = ">=1.23.2", markers = "python_version == \"3.11\""}, {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, + {version = ">=1.23.2", markers = "python_version == \"3.11\""}, ] python-dateutil = ">=2.8.2" pytz = ">=2020.1" @@ -3997,19 +3974,19 @@ stats = ["scipy (>=1.7)", "statsmodels (>=0.12)"] [[package]] name = "setuptools" -version = "72.2.0" +version = "73.0.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-72.2.0-py3-none-any.whl", hash = "sha256:f11dd94b7bae3a156a95ec151f24e4637fb4fa19c878e4d191bfb8b2d82728c4"}, - {file = "setuptools-72.2.0.tar.gz", hash = "sha256:80aacbf633704e9c8bfa1d99fa5dd4dc59573efcf9e4042c13d3bcef91ac2ef9"}, + {file = "setuptools-73.0.0-py3-none-any.whl", hash = "sha256:f2bfcce7ae1784d90b04c57c2802e8649e1976530bb25dc72c2b078d3ecf4864"}, + {file = "setuptools-73.0.0.tar.gz", hash = "sha256:3c08705fadfc8c7c445cf4d98078f0fafb9225775b2b4e8447e40348f82597c0"}, ] [package.extras] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.text (>=3.7)", "more-itertools (>=8.8)", "ordered-set (>=3.1.1)", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.text (>=3.7)", "more-itertools (>=8.8)", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.11.*)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (<0.4)", "pytest-ruff (>=0.2.1)", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.11.*)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (<0.4)", "pytest-ruff (>=0.2.1)", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] [[package]] name = "six" @@ -4808,4 +4785,4 @@ ingest-movies = ["moviepy", "opencv-python"] [metadata] lock-version = "2.0" python-versions = ">=3.9,<3.13" -content-hash = "df92f12a9cb37e0c8ae9ff29eb41b7fe4028acc04364639374bd4ef738b3718a" +content-hash = "0b89a6e36e677978419390c55a8c6331c80d867cc0b72af6c60b68ac1b89760f" diff --git a/pyproject.toml b/pyproject.toml index 248772265..41a348bbe 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,13 +3,13 @@ requires = ["poetry-core", "setuptools", "wheel"] build-backend = "poetry.core.masonry.api" [tool.poetry] -name = "r2r" -version = "0.2.85" +name = "r2r_core" +version = "0.1.0" description = "SciPhi R2R" authors = ["Owen Colegrove "] license = "MIT" readme = "README.md" -include = ["r2r.toml", "compose.yaml", "compose.neo4j.yaml", "compose.ollama.yaml", "compose.postgres.yaml", "pyproject.toml", "alembic.ini"] +include = ["r2r.toml", "compose.yaml", "compose.neo4j.yaml", "compose.ollama.yaml", "compose.postgres.yaml", "pyproject.toml"] [tool.poetry.dependencies] # Python Versions @@ -65,7 +65,6 @@ pyjwt = "^2.8.0" toml = "^0.10.2" pyyaml = "^6.0.1" poppler-utils = "^0.1.0" -alembic = "^1.13.2" # unstructured = {version = "^0.15.0"} psutil = "^6.0.0" deepdiff = "^7.0.1" @@ -91,10 +90,25 @@ pytest-cov = "^5.0.0" colorama = "^0.4.6" [tool.poetry.scripts] -r2r = "r2r.cli.cli:main" +r2r = "r2r_core.cli.cli:main" [tool.black] line-length = 79 +target-version = ['py39'] +include = '\.pyi?$' +extend-exclude = ''' +/( + # directories + \.eggs + | \.git + | \.hg + | \.mypy_cache + | \.tox + | \.venv + | build + | dist +)/ +''' [tool.mypy] ignore_missing_imports = true diff --git a/r2r/main/api/client/__init__.py b/r2r/main/api/client/__init__.py deleted file mode 100644 index 0d6c2e934..000000000 --- a/r2r/main/api/client/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -from .client import R2RClient - -__all__ = ["R2RClient"] diff --git a/r2r_cli/go.mod b/r2r_cli/go.mod new file mode 100644 index 000000000..b06fde584 --- /dev/null +++ b/r2r_cli/go.mod @@ -0,0 +1,15 @@ +module r2r-cli + +go 1.23.0 + +replace github.com/yourusername/r2r-go-sdk => ../r2r-go-sdk + +require ( + github.com/spf13/cobra v1.8.1 + github.com/yourusername/r2r-go-sdk v0.0.0-00010101000000-000000000000 +) + +require ( + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect +) diff --git a/r2r_cli/go.sum b/r2r_cli/go.sum new file mode 100644 index 000000000..912390a78 --- /dev/null +++ b/r2r_cli/go.sum @@ -0,0 +1,10 @@ +github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= +github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/r2r_cli/main.go b/r2r_cli/main.go new file mode 100644 index 000000000..9251fff9c --- /dev/null +++ b/r2r_cli/main.go @@ -0,0 +1,21 @@ +package main + +import ( + "fmt" + "os" + + "github.com/spf13/cobra" +) + +var rootCmd = &cobra.Command{ + Use: "r2r", + Short: "R2R CLI for all core operations", + Long: `R2R CLI for all core operations using the Go SDK.`, +} + +func main() { + if err := rootCmd.Execute(); err != nil { + fmt.Println(err) + os.Exit(1) + } +} diff --git a/r2r_cli/rag_operations.go b/r2r_cli/rag_operations.go new file mode 100644 index 000000000..0c10eae27 --- /dev/null +++ b/r2r_cli/rag_operations.go @@ -0,0 +1,181 @@ +package main + +import ( + "encoding/json" + "fmt" + + "github.com/spf13/cobra" + "github.com/yourusername/r2r-go-sdk/pkg/sdk" +) + +func init() { + rootCmd.AddCommand(ragCmd) +} + +func init() { + // rootCmd.AddCommand(inspectKnowledgeGraphCmd) + rootCmd.AddCommand(ragCmd) + rootCmd.AddCommand(searchCmd) +} + +var inspectKnowledgeGraphCmd = &cobra.Command{ + Use: "inspect-knowledge-graph", + Short: "Print relationships from the knowledge graph", + Run: withTimer(func(cmd *cobra.Command, args []string) { + client := sdk.NewClient("http://localhost:8000/v1", sdk.LogConfig{Verbose: true}) + limit, _ := cmd.Flags().GetInt("limit") + // printDescriptions, _ := cmd.Flags().GetBool("print-descriptions") + + response, err := client.InspectKnowledgeGraph() + if err != nil { + fmt.Printf("Error inspecting knowledge graph: %v\n", err) + return + } + fmt.Println(response) + }), +} + +var ragCmd = &cobra.Command{ + Use: "rag", + Short: "Perform a RAG query", + Run: withTimer(func(cmd *cobra.Command, args []string) { + client := sdk.NewClient("http://localhost:8000/v1", sdk.LogConfig{Verbose: true}) + query, _ := cmd.Flags().GetString("query") + useVectorSearch, _ := cmd.Flags().GetBool("use-vector-search") + filtersStr, _ := cmd.Flags().GetString("filters") + var filters map[string]interface{} + if filtersStr != "" { + json.Unmarshal([]byte(filtersStr), &filters) + } + searchLimit, _ := cmd.Flags().GetInt("search-limit") + doHybridSearch, _ := cmd.Flags().GetBool("do-hybrid-search") + useKgSearch, _ := cmd.Flags().GetBool("use-kg-search") + kgSearchModel, _ := cmd.Flags().GetString("kg-search-model") + stream, _ := cmd.Flags().GetBool("stream") + ragModel, _ := cmd.Flags().GetString("rag-model") + kgSearchType, _ := cmd.Flags().GetString("kg-search-type") + kgSearchLevel, _ := cmd.Flags().GetString("kg-search-level") + + generationConfig := sdk.GenerationConfig{ + Stream: stream, + } + if ragModel != "" { + generationConfig.Model = ragModel + } + + vectorSearchSettings := &sdk.VectorSearchSettings{ + UseVectorSearch: useVectorSearch, + Filters: filters, + SearchLimit: searchLimit, + DoHybridSearch: doHybridSearch, + } + + kgSearchSettings := &sdk.KGSearchSettings{ + UseKGSearch: useKgSearch, + Model: kgSearchModel, + SearchType: kgSearchType, + SearchLevel: kgSearchLevel, + } + + response, err := client.RAG(query, generationConfig, vectorSearchSettings, kgSearchSettings) + if err != nil { + fmt.Printf("Error performing RAG query: %v\n", err) + return + } + + if stream { + for chunk := range response.StreamingChannel { + fmt.Print(chunk) + } + fmt.Println() + } else { + fmt.Printf("Search Results:\n%s\n", response.SearchResults) + fmt.Printf("Completion:\n%s\n", response.Completion) + } + }), +} + +var searchCmd = &cobra.Command{ + Use: "search", + Short: "Perform a search query", + Run: withTimer(func(cmd *cobra.Command, args []string) { + client := sdk.NewClient("http://localhost:8000/v1", sdk.LogConfig{Verbose: true}) + query, _ := cmd.Flags().GetString("query") + useVectorSearch, _ := cmd.Flags().GetBool("use-vector-search") + filtersStr, _ := cmd.Flags().GetString("filters") + var filters map[string]interface{} + if filtersStr != "" { + json.Unmarshal([]byte(filtersStr), &filters) + } + searchLimit, _ := cmd.Flags().GetInt("search-limit") + doHybridSearch, _ := cmd.Flags().GetBool("do-hybrid-search") + useKgSearch, _ := cmd.Flags().GetBool("use-kg-search") + kgSearchModel, _ := cmd.Flags().GetString("kg-search-model") + kgSearchType, _ := cmd.Flags().GetString("kg-search-type") + kgSearchLevel, _ := cmd.Flags().GetString("kg-search-level") + + vectorSearchSettings := &sdk.VectorSearchSettings{ + UseVectorSearch: useVectorSearch, + Filters: filters, + SearchLimit: searchLimit, + DoHybridSearch: doHybridSearch, + } + + kgSearchSettings := &sdk.KGSearchSettings{ + UseKGSearch: useKgSearch, + Model: kgSearchModel, + SearchType: kgSearchType, + SearchLevel: kgSearchLevel, + } + + results, err := client.Search(query, vectorSearchSettings, kgSearchSettings) + if err != nil { + fmt.Printf("Error performing search: %v\n", err) + return + } + + fmt.Printf("KG_Search Enabled: %v\n", useKgSearch) + fmt.Printf("KG_Search Type: %s\n", kgSearchType) + + if len(results.VectorSearchResults) > 0 { + fmt.Println("Vector search results:") + for _, result := range results.VectorSearchResults { + fmt.Println(result) + } + } + + if len(results.KGSearchResults) > 0 { + fmt.Println("KG search results:") + for _, result := range results.KGSearchResults { + fmt.Println(result) + } + } + }), +} + +func init() { + inspectKnowledgeGraphCmd.Flags().Int("limit", 100, "Limit the number of relationships returned") + inspectKnowledgeGraphCmd.Flags().Bool("print-descriptions", false, "Print descriptions of entities and relationships") + + ragCmd.Flags().String("query", "", "The query for RAG") + ragCmd.Flags().Bool("use-vector-search", true, "Use vector search") + ragCmd.Flags().String("filters", "", "Search filters as JSON") + ragCmd.Flags().Int("search-limit", 10, "Number of search results to return") + ragCmd.Flags().Bool("do-hybrid-search", false, "Perform hybrid search") + ragCmd.Flags().Bool("use-kg-search", false, "Use knowledge graph search") + ragCmd.Flags().String("kg-search-model", "", "Model for KG agent") + ragCmd.Flags().Bool("stream", false, "Stream the RAG response") + ragCmd.Flags().String("rag-model", "", "Model for RAG") + ragCmd.Flags().String("kg-search-type", "global", "Local or Global") + ragCmd.Flags().String("kg-search-level", "", "Level of cluster to use for Global KG search") + + searchCmd.Flags().String("query", "", "The search query") + searchCmd.Flags().Bool("use-vector-search", true, "Use vector search") + searchCmd.Flags().String("filters", "", "Search filters as JSON") + searchCmd.Flags().Int("search-limit", 10, "Number of search results to return") + searchCmd.Flags().Bool("do-hybrid-search", false, "Perform hybrid search") + searchCmd.Flags().Bool("use-kg-search", false, "Use knowledge graph search") + searchCmd.Flags().String("kg-search-model", "", "Model for KG agent") + searchCmd.Flags().String("kg-search-type", "global", "Local or Global") + searchCmd.Flags().String("kg-search-level", "", "Level of KG search") +} diff --git a/r2r_cli/server_operations.go b/r2r_cli/server_operations.go new file mode 100644 index 000000000..34d1cec91 --- /dev/null +++ b/r2r_cli/server_operations.go @@ -0,0 +1,91 @@ +package main + +import ( + "encoding/json" + "fmt" + "os/exec" + "runtime" + + "github.com/spf13/cobra" + "github.com/yourusername/r2r-go-sdk/pkg/sdk" +) + +func init() { + rootCmd.AddCommand(dockerDownCmd) + rootCmd.AddCommand(healthCmd) + rootCmd.AddCommand(generateReportCmd) + + dockerDownCmd.Flags().Bool("volumes", false, "Remove named volumes") + dockerDownCmd.Flags().Bool("remove-orphans", false, "Remove containers for services not defined in the Compose file") + dockerDownCmd.Flags().String("project-name", "r2r", "Project name for Docker") +} + +// TODO: Implement the actual Docker Compose down logic +var dockerDownCmd = &cobra.Command{ + Use: "docker-down", + Short: "Bring down the Docker Compose setup", + Run: func(cmd *cobra.Command, args []string) { + volumes, _ := cmd.Flags().GetBool("volumes") + removeOrphans, _ := cmd.Flags().GetBool("remove-orphans") + projectName, _ := cmd.Flags().GetString("project-name") + + fmt.Printf("Bringing down Docker Compose setup (Project: %s, Volumes: %v, Remove Orphans: %v)\n", projectName, volumes, removeOrphans) + }, +} + +// TODO: Implement the actual system report generation logic +var generateReportCmd = &cobra.Command{ + Use: "generate-report", + Short: "Generate a system report", + Run: func(cmd *cobra.Command, args []string) { + report := make(map[string]interface{}) + + // Get R2R version + // TODO: Implement the actual version retrieval logic + report["r2r_version"] = "1.0.0" + + // Get Docker info + dockerVerison, _ := exec.Command("docker", "--version").Output() + report["docker_version"] = string(dockerVerison) + + dockerPs, _ := exec.Command("docker", "ps", "--format", "{{.ID}}\t{{.Names}}\t{{.Status}}").Output() + report["docker_info"] = string(dockerPs) + + dockerNetworks, _ := exec.Command("docker", "network", "ls", "--format", "{{.ID}}\t{{.Name}}\t{{.Driver}}").Output() + report["docker_networks"] = string(dockerNetworks) + + dockerSubnets, _ := exec.Command("docker", "network", "inspect", "bridge", "--format", "{{.IPAM.Config}}").Output() + report["docker_subnets"] = string(dockerSubnets) + + // Get OS information + report["os_info"] = map[string]string{ + "system": runtime.GOOS, + "version": runtime.Version(), + "machine": runtime.GOARCH, + "processor": runtime.GOARCH, + } + + jsonReport, _ := json.MarshalIndent(report, "", " ") + fmt.Println(string(jsonReport)) + }, +} + +var healthCmd = &cobra.Command{ + Use: "health", + Short: "Check the health of the server", + Run: withTimer(func(cmd *cobra.Command, args []string) { + client := sdk.NewClient("http://localhost:8000/v1", sdk.LogConfig{Verbose: true}) + response, err := client.Health() + if err != nil { + fmt.Printf("Error checking health: %v\n", err) + return + } + fmt.Println(response) + }), +} + +// TODO: r2r serve command + +// TODO: update + +// TODO: version diff --git a/r2r_cli/utils.go b/r2r_cli/utils.go new file mode 100644 index 000000000..d0da773e5 --- /dev/null +++ b/r2r_cli/utils.go @@ -0,0 +1,17 @@ +package main + +import ( + "fmt" + "time" + + "github.com/spf13/cobra" +) + +func withTimer(f func(*cobra.Command, []string)) func(*cobra.Command, []string) { + return func(cmd *cobra.Command, args []string) { + start := time.Now() + f(cmd, args) + duration := time.Since(start) + fmt.Printf("Time taken: %.2f seconds\n", duration.Seconds()) + } +} diff --git a/r2r/__init__.py b/r2r_core/__init__.py similarity index 99% rename from r2r/__init__.py rename to r2r_core/__init__.py index b668bda9e..0201c23f1 100644 --- a/r2r/__init__.py +++ b/r2r_core/__init__.py @@ -182,8 +182,6 @@ "R2RPipelines", "R2RAgents", ## R2R API - # Client - "R2RClient", # Routes "AuthRouter", "IngestionRouter", diff --git a/r2r/agent/__init__.py b/r2r_core/agent/__init__.py similarity index 100% rename from r2r/agent/__init__.py rename to r2r_core/agent/__init__.py diff --git a/r2r/agent/base.py b/r2r_core/agent/base.py similarity index 98% rename from r2r/agent/base.py rename to r2r_core/agent/base.py index 5fea403a7..b55daece8 100644 --- a/r2r/agent/base.py +++ b/r2r_core/agent/base.py @@ -2,13 +2,13 @@ from abc import ABCMeta from typing import AsyncGenerator, Generator, Optional -from r2r.base.abstractions import ( +from r2r_core.base.abstractions import ( AsyncSyncMeta, LLMChatCompletion, LLMChatCompletionChunk, syncable, ) -from r2r.base.agent import Agent, Message +from r2r_core.base.agent import Agent, Message class CombinedMeta(AsyncSyncMeta, ABCMeta): diff --git a/r2r/agent/rag.py b/r2r_core/agent/rag.py similarity index 91% rename from r2r/agent/rag.py rename to r2r_core/agent/rag.py index 910ba76b7..d2c94051b 100644 --- a/r2r/agent/rag.py +++ b/r2r_core/agent/rag.py @@ -1,15 +1,15 @@ import json -from r2r.agent import R2RAgent, R2RStreamingAgent -from r2r.base.abstractions import ( +from r2r_core.agent import R2RAgent, R2RStreamingAgent +from r2r_core.base.abstractions import ( KGSearchSettings, VectorSearchResult, VectorSearchSettings, ) -from r2r.base.agent import AgentConfig, Tool -from r2r.base.providers import CompletionProvider, PromptProvider -from r2r.base.utils import to_async_generator -from r2r.pipelines import SearchPipeline +from r2r_core.base.agent import AgentConfig, Tool +from r2r_core.base.providers import CompletionProvider, PromptProvider +from r2r_core.base.utils import to_async_generator +from r2r_core.pipelines import SearchPipeline class RAGAgentMixin: diff --git a/r2r/base/__init__.py b/r2r_core/base/__init__.py similarity index 100% rename from r2r/base/__init__.py rename to r2r_core/base/__init__.py diff --git a/r2r/base/abstractions/__init__.py b/r2r_core/base/abstractions/__init__.py similarity index 100% rename from r2r/base/abstractions/__init__.py rename to r2r_core/base/abstractions/__init__.py diff --git a/r2r/base/abstractions/base.py b/r2r_core/base/abstractions/base.py similarity index 100% rename from r2r/base/abstractions/base.py rename to r2r_core/base/abstractions/base.py diff --git a/r2r/base/abstractions/completion.py b/r2r_core/base/abstractions/completion.py similarity index 100% rename from r2r/base/abstractions/completion.py rename to r2r_core/base/abstractions/completion.py diff --git a/r2r/base/abstractions/document.py b/r2r_core/base/abstractions/document.py similarity index 100% rename from r2r/base/abstractions/document.py rename to r2r_core/base/abstractions/document.py diff --git a/r2r/base/abstractions/embedding.py b/r2r_core/base/abstractions/embedding.py similarity index 100% rename from r2r/base/abstractions/embedding.py rename to r2r_core/base/abstractions/embedding.py diff --git a/r2r/base/abstractions/exception.py b/r2r_core/base/abstractions/exception.py similarity index 100% rename from r2r/base/abstractions/exception.py rename to r2r_core/base/abstractions/exception.py diff --git a/r2r/base/abstractions/graph.py b/r2r_core/base/abstractions/graph.py similarity index 100% rename from r2r/base/abstractions/graph.py rename to r2r_core/base/abstractions/graph.py diff --git a/r2r/base/abstractions/llm.py b/r2r_core/base/abstractions/llm.py similarity index 100% rename from r2r/base/abstractions/llm.py rename to r2r_core/base/abstractions/llm.py diff --git a/r2r/base/abstractions/prompt.py b/r2r_core/base/abstractions/prompt.py similarity index 100% rename from r2r/base/abstractions/prompt.py rename to r2r_core/base/abstractions/prompt.py diff --git a/r2r/base/abstractions/search.py b/r2r_core/base/abstractions/search.py similarity index 94% rename from r2r/base/abstractions/search.py rename to r2r_core/base/abstractions/search.py index 269a4b47d..22050c4b2 100644 --- a/r2r/base/abstractions/search.py +++ b/r2r_core/base/abstractions/search.py @@ -1,6 +1,6 @@ """Abstractions for search functionality.""" -from typing import Any, Dict, List, Optional, Tuple +from typing import Any, Dict, Optional, Tuple from uuid import UUID from pydantic import BaseModel, Field @@ -15,7 +15,7 @@ class VectorSearchResult(BaseModel): extraction_id: UUID document_id: UUID user_id: UUID - group_ids: List[UUID] + group_ids: list[UUID] score: float text: str metadata: dict[str, Any] @@ -54,13 +54,13 @@ class Config: } -KGSearchResult = List[Tuple[str, List[Dict[str, Any]]]] +KGSearchResult = list[Tuple[str, list[Dict[str, Any]]]] class AggregateSearchResult(BaseModel): """Result of an aggregate search operation.""" - vector_search_results: Optional[List[VectorSearchResult]] + vector_search_results: Optional[list[VectorSearchResult]] kg_search_results: Optional[KGSearchResult] = None def __str__(self) -> str: @@ -98,7 +98,7 @@ class VectorSearchSettings(BaseModel): default=False, description="Whether to perform a hybrid search (combining vector and keyword search)", ) - selected_group_ids: List[UUID] = Field( + selected_group_ids: list[UUID] = Field( default_factory=list, description="Group IDs to search for", ) diff --git a/r2r/base/abstractions/user.py b/r2r_core/base/abstractions/user.py similarity index 100% rename from r2r/base/abstractions/user.py rename to r2r_core/base/abstractions/user.py diff --git a/r2r/base/abstractions/vector.py b/r2r_core/base/abstractions/vector.py similarity index 100% rename from r2r/base/abstractions/vector.py rename to r2r_core/base/abstractions/vector.py diff --git a/r2r/base/agent/__init__.py b/r2r_core/base/agent/__init__.py similarity index 100% rename from r2r/base/agent/__init__.py rename to r2r_core/base/agent/__init__.py diff --git a/r2r/base/agent/agent.py b/r2r_core/base/agent/agent.py similarity index 98% rename from r2r/base/agent/agent.py rename to r2r_core/base/agent/agent.py index 6bde2aa83..659473ab7 100644 --- a/r2r/base/agent/agent.py +++ b/r2r_core/base/agent/agent.py @@ -4,12 +4,12 @@ from pydantic import BaseModel -from r2r.base.abstractions import ( +from r2r_core.base.abstractions import ( GenerationConfig, LLMChatCompletion, MessageType, ) -from r2r.base.providers import CompletionProvider, PromptProvider +from r2r_core.base.providers import CompletionProvider, PromptProvider from .base import Message, Tool, ToolResult diff --git a/r2r/base/agent/base.py b/r2r_core/base/agent/base.py similarity index 79% rename from r2r/base/agent/base.py rename to r2r_core/base/agent/base.py index e5d57c46c..3d23a968b 100644 --- a/r2r/base/agent/base.py +++ b/r2r_core/base/agent/base.py @@ -1,8 +1,8 @@ -from typing import Any, Callable, Dict, List, Optional, Union +from typing import Any, Callable, Dict, Optional, Union from pydantic import BaseModel -from r2r.base.abstractions import MessageType +from r2r_core.base.abstractions import MessageType class Tool(BaseModel): @@ -28,4 +28,4 @@ class Message(BaseModel): content: Optional[str] = None name: Optional[str] = None function_call: Optional[Dict[str, Any]] = None - tool_calls: Optional[List[Dict[str, Any]]] = None + tool_calls: Optional[list[Dict[str, Any]]] = None diff --git a/r2r/base/api/models/__init__.py b/r2r_core/base/api/models/__init__.py similarity index 100% rename from r2r/base/api/models/__init__.py rename to r2r_core/base/api/models/__init__.py diff --git a/r2r/base/api/models/auth/__init__.py b/r2r_core/base/api/models/auth/__init__.py similarity index 100% rename from r2r/base/api/models/auth/__init__.py rename to r2r_core/base/api/models/auth/__init__.py diff --git a/r2r/base/api/models/auth/responses.py b/r2r_core/base/api/models/auth/responses.py similarity index 90% rename from r2r/base/api/models/auth/responses.py rename to r2r_core/base/api/models/auth/responses.py index cc366a1b1..9d4a546b3 100644 --- a/r2r/base/api/models/auth/responses.py +++ b/r2r_core/base/api/models/auth/responses.py @@ -4,8 +4,8 @@ from pydantic import BaseModel -from r2r.base.abstractions import Token -from r2r.base.api.models.base import ResultsWrapper +from r2r_core.base.abstractions import Token +from r2r_core.base.api.models.base import ResultsWrapper class TokenResponse(BaseModel): diff --git a/r2r/base/api/models/base.py b/r2r_core/base/api/models/base.py similarity index 100% rename from r2r/base/api/models/base.py rename to r2r_core/base/api/models/base.py diff --git a/r2r/base/api/models/ingestion/__init__.py b/r2r_core/base/api/models/ingestion/__init__.py similarity index 100% rename from r2r/base/api/models/ingestion/__init__.py rename to r2r_core/base/api/models/ingestion/__init__.py diff --git a/r2r/base/api/models/ingestion/responses.py b/r2r_core/base/api/models/ingestion/responses.py similarity index 97% rename from r2r/base/api/models/ingestion/responses.py rename to r2r_core/base/api/models/ingestion/responses.py index b93d32583..dee32d466 100644 --- a/r2r/base/api/models/ingestion/responses.py +++ b/r2r_core/base/api/models/ingestion/responses.py @@ -3,7 +3,7 @@ from pydantic import BaseModel, Field -from r2r.base.api.models.base import ResultsWrapper +from r2r_core.base.api.models.base import ResultsWrapper T = TypeVar("T") diff --git a/r2r/base/api/models/management/__init__.py b/r2r_core/base/api/models/management/__init__.py similarity index 100% rename from r2r/base/api/models/management/__init__.py rename to r2r_core/base/api/models/management/__init__.py diff --git a/r2r/base/api/models/management/responses.py b/r2r_core/base/api/models/management/responses.py similarity index 97% rename from r2r/base/api/models/management/responses.py rename to r2r_core/base/api/models/management/responses.py index 9a04b25a1..3f1a27279 100644 --- a/r2r/base/api/models/management/responses.py +++ b/r2r_core/base/api/models/management/responses.py @@ -4,7 +4,7 @@ from pydantic import BaseModel -from r2r.base.api.models.base import ResultsWrapper +from r2r_core.base.api.models.base import ResultsWrapper class PromptResponse(BaseModel): diff --git a/r2r/base/api/models/retrieval/__init__.py b/r2r_core/base/api/models/retrieval/__init__.py similarity index 100% rename from r2r/base/api/models/retrieval/__init__.py rename to r2r_core/base/api/models/retrieval/__init__.py diff --git a/r2r/base/api/models/retrieval/responses.py b/r2r_core/base/api/models/retrieval/responses.py similarity index 97% rename from r2r/base/api/models/retrieval/responses.py rename to r2r_core/base/api/models/retrieval/responses.py index 36b9543e7..bc6571d2c 100644 --- a/r2r/base/api/models/retrieval/responses.py +++ b/r2r_core/base/api/models/retrieval/responses.py @@ -2,8 +2,11 @@ from pydantic import BaseModel, Field -from r2r.base.abstractions.search import KGSearchResult, VectorSearchResult -from r2r.base.api.models.base import ResultsWrapper +from r2r_core.base.abstractions.search import ( + KGSearchResult, + VectorSearchResult, +) +from r2r_core.base.api.models.base import ResultsWrapper class SearchResponse(BaseModel): diff --git a/r2r/base/logging/__init__.py b/r2r_core/base/logging/__init__.py similarity index 100% rename from r2r/base/logging/__init__.py rename to r2r_core/base/logging/__init__.py diff --git a/r2r/base/logging/base.py b/r2r_core/base/logging/base.py similarity index 100% rename from r2r/base/logging/base.py rename to r2r_core/base/logging/base.py diff --git a/r2r/base/logging/log_processor.py b/r2r_core/base/logging/log_processor.py similarity index 100% rename from r2r/base/logging/log_processor.py rename to r2r_core/base/logging/log_processor.py diff --git a/r2r/base/logging/run_logger.py b/r2r_core/base/logging/run_logger.py similarity index 100% rename from r2r/base/logging/run_logger.py rename to r2r_core/base/logging/run_logger.py diff --git a/r2r/base/logging/run_manager.py b/r2r_core/base/logging/run_manager.py similarity index 92% rename from r2r/base/logging/run_manager.py rename to r2r_core/base/logging/run_manager.py index 9d1e55e69..84e252ef0 100644 --- a/r2r/base/logging/run_manager.py +++ b/r2r_core/base/logging/run_manager.py @@ -3,9 +3,9 @@ from typing import Optional from uuid import UUID -from r2r.base.api.models.auth.responses import UserResponse -from r2r.base.logging.base import RunType -from r2r.base.utils import generate_run_id +from r2r_core.base.api.models.auth.responses import UserResponse +from r2r_core.base.logging.base import RunType +from r2r_core.base.utils import generate_run_id from .run_logger import RunLoggingSingleton diff --git a/r2r/base/parsers/__init__.py b/r2r_core/base/parsers/__init__.py similarity index 100% rename from r2r/base/parsers/__init__.py rename to r2r_core/base/parsers/__init__.py diff --git a/r2r/base/parsers/base_parser.py b/r2r_core/base/parsers/base_parser.py similarity index 100% rename from r2r/base/parsers/base_parser.py rename to r2r_core/base/parsers/base_parser.py diff --git a/r2r/base/pipeline/__init__.py b/r2r_core/base/pipeline/__init__.py similarity index 100% rename from r2r/base/pipeline/__init__.py rename to r2r_core/base/pipeline/__init__.py diff --git a/r2r/base/pipeline/base_pipeline.py b/r2r_core/base/pipeline/base_pipeline.py similarity index 100% rename from r2r/base/pipeline/base_pipeline.py rename to r2r_core/base/pipeline/base_pipeline.py diff --git a/r2r/base/pipes/__init__.py b/r2r_core/base/pipes/__init__.py similarity index 100% rename from r2r/base/pipes/__init__.py rename to r2r_core/base/pipes/__init__.py diff --git a/r2r/base/pipes/base_pipe.py b/r2r_core/base/pipes/base_pipe.py similarity index 97% rename from r2r/base/pipes/base_pipe.py rename to r2r_core/base/pipes/base_pipe.py index 18ced8581..ec6aa6c01 100644 --- a/r2r/base/pipes/base_pipe.py +++ b/r2r_core/base/pipes/base_pipe.py @@ -7,8 +7,8 @@ from pydantic import BaseModel -from r2r.base.logging.run_logger import RunLoggingSingleton -from r2r.base.logging.run_manager import RunManager, manage_run +from r2r_core.base.logging.run_logger import RunLoggingSingleton +from r2r_core.base.logging.run_manager import RunManager, manage_run logger = logging.getLogger(__name__) diff --git a/r2r/base/providers/__init__.py b/r2r_core/base/providers/__init__.py similarity index 100% rename from r2r/base/providers/__init__.py rename to r2r_core/base/providers/__init__.py diff --git a/r2r/base/providers/auth.py b/r2r_core/base/providers/auth.py similarity index 100% rename from r2r/base/providers/auth.py rename to r2r_core/base/providers/auth.py diff --git a/r2r/base/providers/base.py b/r2r_core/base/providers/base.py similarity index 91% rename from r2r/base/providers/base.py rename to r2r_core/base/providers/base.py index c151867c9..d907b01e2 100644 --- a/r2r/base/providers/base.py +++ b/r2r_core/base/providers/base.py @@ -1,4 +1,4 @@ -from abc import ABC, abstractmethod, abstractproperty +from abc import ABC, abstractmethod from typing import Any, Optional, Type from pydantic import BaseModel @@ -20,7 +20,7 @@ def validate(self) -> None: @classmethod def create(cls: Type["ProviderConfig"], **kwargs: Any) -> "ProviderConfig": - base_args = cls.__fields__.keys() + base_args = cls.model_fields.keys() filtered_kwargs = { k: v if v != "None" else None for k, v in kwargs.items() @@ -32,8 +32,8 @@ def create(cls: Type["ProviderConfig"], **kwargs: Any) -> "ProviderConfig": instance.extra_fields[k] = v return instance - @abstractproperty @property + @abstractmethod def supported_providers(self) -> list[str]: """Define a list of supported providers.""" pass diff --git a/r2r/base/providers/chunking.py b/r2r_core/base/providers/chunking.py similarity index 100% rename from r2r/base/providers/chunking.py rename to r2r_core/base/providers/chunking.py diff --git a/r2r/base/providers/crypto.py b/r2r_core/base/providers/crypto.py similarity index 100% rename from r2r/base/providers/crypto.py rename to r2r_core/base/providers/crypto.py diff --git a/r2r/base/providers/database.py b/r2r_core/base/providers/database.py similarity index 100% rename from r2r/base/providers/database.py rename to r2r_core/base/providers/database.py diff --git a/r2r/base/providers/embedding.py b/r2r_core/base/providers/embedding.py similarity index 100% rename from r2r/base/providers/embedding.py rename to r2r_core/base/providers/embedding.py diff --git a/r2r/base/providers/kg.py b/r2r_core/base/providers/kg.py similarity index 100% rename from r2r/base/providers/kg.py rename to r2r_core/base/providers/kg.py diff --git a/r2r/base/providers/llm.py b/r2r_core/base/providers/llm.py similarity index 99% rename from r2r/base/providers/llm.py rename to r2r_core/base/providers/llm.py index 35612359a..978e0e76d 100644 --- a/r2r/base/providers/llm.py +++ b/r2r_core/base/providers/llm.py @@ -5,7 +5,7 @@ from concurrent.futures import ThreadPoolExecutor from typing import Any, AsyncGenerator, Generator, Optional -from r2r.base.abstractions.llm import ( +from r2r_core.base.abstractions.llm import ( GenerationConfig, LLMChatCompletion, LLMChatCompletionChunk, diff --git a/r2r/base/providers/parsing.py b/r2r_core/base/providers/parsing.py similarity index 100% rename from r2r/base/providers/parsing.py rename to r2r_core/base/providers/parsing.py diff --git a/r2r/base/providers/prompt.py b/r2r_core/base/providers/prompt.py similarity index 100% rename from r2r/base/providers/prompt.py rename to r2r_core/base/providers/prompt.py diff --git a/r2r/base/utils/__init__.py b/r2r_core/base/utils/__init__.py similarity index 100% rename from r2r/base/utils/__init__.py rename to r2r_core/base/utils/__init__.py diff --git a/r2r/base/utils/base_utils.py b/r2r_core/base/utils/base_utils.py similarity index 100% rename from r2r/base/utils/base_utils.py rename to r2r_core/base/utils/base_utils.py diff --git a/r2r/base/utils/splitter/__init__.py b/r2r_core/base/utils/splitter/__init__.py similarity index 100% rename from r2r/base/utils/splitter/__init__.py rename to r2r_core/base/utils/splitter/__init__.py diff --git a/r2r/base/utils/splitter/text.py b/r2r_core/base/utils/splitter/text.py similarity index 100% rename from r2r/base/utils/splitter/text.py rename to r2r_core/base/utils/splitter/text.py diff --git a/r2r/cli/__init__.py b/r2r_core/cli/__init__.py similarity index 100% rename from r2r/cli/__init__.py rename to r2r_core/cli/__init__.py diff --git a/r2r/cli/cli.py b/r2r_core/cli/cli.py similarity index 94% rename from r2r/cli/cli.py rename to r2r_core/cli/cli.py index c2cda4a29..9fbb181e0 100644 --- a/r2r/cli/cli.py +++ b/r2r_core/cli/cli.py @@ -1,5 +1,5 @@ -from r2r.cli.command_group import cli -from r2r.cli.commands import ( +from r2r_core.cli.command_group import cli +from r2r_core.cli.commands import ( auth_operations, document_operations, kg_operations, diff --git a/r2r/cli/command_group.py b/r2r_core/cli/command_group.py similarity index 95% rename from r2r/cli/command_group.py rename to r2r_core/cli/command_group.py index fbd1c5aba..e5f94bc99 100644 --- a/r2r/cli/command_group.py +++ b/r2r_core/cli/command_group.py @@ -2,7 +2,7 @@ import click -from r2r.main.execution import R2RExecutionWrapper +from r2r_core.main.execution import R2RExecutionWrapper # TODO: refactor this to remove config path and config name diff --git a/r2r/cli/commands/__init__.py b/r2r_core/cli/commands/__init__.py similarity index 100% rename from r2r/cli/commands/__init__.py rename to r2r_core/cli/commands/__init__.py diff --git a/r2r/cli/commands/auth_operations.py b/r2r_core/cli/commands/auth_operations.py similarity index 87% rename from r2r/cli/commands/auth_operations.py rename to r2r_core/cli/commands/auth_operations.py index 5a3b64b25..4cd6cd299 100644 --- a/r2r/cli/commands/auth_operations.py +++ b/r2r_core/cli/commands/auth_operations.py @@ -2,7 +2,7 @@ import click -from r2r.cli.command_group import cli +from r2r_core.cli.command_group import cli @cli.command() diff --git a/r2r/cli/commands/document_operations.py b/r2r_core/cli/commands/document_operations.py similarity index 97% rename from r2r/cli/commands/document_operations.py rename to r2r_core/cli/commands/document_operations.py index 237918d85..770131bf9 100644 --- a/r2r/cli/commands/document_operations.py +++ b/r2r_core/cli/commands/document_operations.py @@ -1,7 +1,7 @@ import click -from r2r.cli.command_group import cli -from r2r.cli.utils.timer import timer +from r2r_core.cli.command_group import cli +from r2r_core.cli.utils.timer import timer @cli.command() diff --git a/r2r/cli/commands/kg_operations.py b/r2r_core/cli/commands/kg_operations.py similarity index 76% rename from r2r/cli/commands/kg_operations.py rename to r2r_core/cli/commands/kg_operations.py index a596e153d..ad0af782c 100644 --- a/r2r/cli/commands/kg_operations.py +++ b/r2r_core/cli/commands/kg_operations.py @@ -1,7 +1,7 @@ import click -from r2r.cli.command_group import cli -from r2r.cli.utils.timer import timer +from r2r_core.cli.command_group import cli +from r2r_core.cli.utils.timer import timer @cli.command() diff --git a/r2r/cli/commands/oberservability_operations.py b/r2r_core/cli/commands/oberservability_operations.py similarity index 93% rename from r2r/cli/commands/oberservability_operations.py rename to r2r_core/cli/commands/oberservability_operations.py index 76d80b4a6..a2108e73d 100644 --- a/r2r/cli/commands/oberservability_operations.py +++ b/r2r_core/cli/commands/oberservability_operations.py @@ -3,9 +3,9 @@ import click -from r2r.cli.command_group import cli -from r2r.cli.utils.param_types import JSON -from r2r.cli.utils.timer import timer +from r2r_core.cli.command_group import cli +from r2r_core.cli.utils.param_types import JSON +from r2r_core.cli.utils.timer import timer @cli.command() diff --git a/r2r/cli/commands/rag_operations.py b/r2r_core/cli/commands/rag_operations.py similarity index 97% rename from r2r/cli/commands/rag_operations.py rename to r2r_core/cli/commands/rag_operations.py index ffed98c38..26c458974 100644 --- a/r2r/cli/commands/rag_operations.py +++ b/r2r_core/cli/commands/rag_operations.py @@ -1,8 +1,8 @@ import click -from r2r.cli.command_group import cli -from r2r.cli.utils.param_types import JSON -from r2r.cli.utils.timer import timer +from r2r_core.cli.command_group import cli +from r2r_core.cli.utils.param_types import JSON +from r2r_core.cli.utils.timer import timer @cli.command() diff --git a/r2r/cli/commands/server_operations.py b/r2r_core/cli/commands/server_operations.py similarity index 98% rename from r2r/cli/commands/server_operations.py rename to r2r_core/cli/commands/server_operations.py index 1e0ae8933..c3df1cb64 100644 --- a/r2r/cli/commands/server_operations.py +++ b/r2r_core/cli/commands/server_operations.py @@ -7,14 +7,14 @@ import click from dotenv import load_dotenv -from r2r.cli.command_group import cli -from r2r.cli.utils.docker_utils import ( +from r2r_core.cli.command_group import cli +from r2r_core.cli.utils.docker_utils import ( bring_down_docker_compose, remove_r2r_network, run_docker_serve, run_local_serve, ) -from r2r.cli.utils.timer import timer +from r2r_core.cli.utils.timer import timer @cli.command() diff --git a/r2r/cli/utils/__init__.py b/r2r_core/cli/utils/__init__.py similarity index 100% rename from r2r/cli/utils/__init__.py rename to r2r_core/cli/utils/__init__.py diff --git a/r2r/cli/utils/docker_utils.py b/r2r_core/cli/utils/docker_utils.py similarity index 99% rename from r2r/cli/utils/docker_utils.py rename to r2r_core/cli/utils/docker_utils.py index a68c93e0f..e4bcf4487 100644 --- a/r2r/cli/utils/docker_utils.py +++ b/r2r_core/cli/utils/docker_utils.py @@ -10,8 +10,8 @@ import requests from requests.exceptions import RequestException -from r2r.main import R2RBuilder, R2RConfig -from r2r.main.execution import R2RExecutionWrapper +from r2r_core.main import R2RBuilder, R2RConfig +from r2r_core.main.execution import R2RExecutionWrapper def bring_down_docker_compose(project_name, volumes, remove_orphans): diff --git a/r2r/cli/utils/param_types.py b/r2r_core/cli/utils/param_types.py similarity index 100% rename from r2r/cli/utils/param_types.py rename to r2r_core/cli/utils/param_types.py diff --git a/r2r/cli/utils/timer.py b/r2r_core/cli/utils/timer.py similarity index 100% rename from r2r/cli/utils/timer.py rename to r2r_core/cli/utils/timer.py diff --git a/r2r/configs/auth.toml b/r2r_core/configs/auth.toml similarity index 100% rename from r2r/configs/auth.toml rename to r2r_core/configs/auth.toml diff --git a/r2r/configs/local_llm.toml b/r2r_core/configs/local_llm.toml similarity index 100% rename from r2r/configs/local_llm.toml rename to r2r_core/configs/local_llm.toml diff --git a/r2r/configs/local_llm_neo4j_kg.toml b/r2r_core/configs/local_llm_neo4j_kg.toml similarity index 100% rename from r2r/configs/local_llm_neo4j_kg.toml rename to r2r_core/configs/local_llm_neo4j_kg.toml diff --git a/r2r/configs/neo4j_kg.toml b/r2r_core/configs/neo4j_kg.toml similarity index 100% rename from r2r/configs/neo4j_kg.toml rename to r2r_core/configs/neo4j_kg.toml diff --git a/r2r/configs/neo4j_kg_no_vector_postgres.toml b/r2r_core/configs/neo4j_kg_no_vector_postgres.toml similarity index 100% rename from r2r/configs/neo4j_kg_no_vector_postgres.toml rename to r2r_core/configs/neo4j_kg_no_vector_postgres.toml diff --git a/r2r/configs/postgres_logging.toml b/r2r_core/configs/postgres_logging.toml similarity index 100% rename from r2r/configs/postgres_logging.toml rename to r2r_core/configs/postgres_logging.toml diff --git a/r2r/examples/__init__.py b/r2r_core/examples/__init__.py similarity index 100% rename from r2r/examples/__init__.py rename to r2r_core/examples/__init__.py diff --git a/r2r/examples/data/aristotle.txt b/r2r_core/examples/data/aristotle.txt similarity index 100% rename from r2r/examples/data/aristotle.txt rename to r2r_core/examples/data/aristotle.txt diff --git a/r2r/examples/data/aristotle_v2.txt b/r2r_core/examples/data/aristotle_v2.txt similarity index 100% rename from r2r/examples/data/aristotle_v2.txt rename to r2r_core/examples/data/aristotle_v2.txt diff --git a/r2r/examples/data/got.txt b/r2r_core/examples/data/got.txt similarity index 100% rename from r2r/examples/data/got.txt rename to r2r_core/examples/data/got.txt diff --git a/r2r/examples/data/lyft_2021.pdf b/r2r_core/examples/data/lyft_2021.pdf similarity index 100% rename from r2r/examples/data/lyft_2021.pdf rename to r2r_core/examples/data/lyft_2021.pdf diff --git a/r2r/examples/data/pg_essay_1.html b/r2r_core/examples/data/pg_essay_1.html similarity index 100% rename from r2r/examples/data/pg_essay_1.html rename to r2r_core/examples/data/pg_essay_1.html diff --git a/r2r/examples/data/pg_essay_2.html b/r2r_core/examples/data/pg_essay_2.html similarity index 100% rename from r2r/examples/data/pg_essay_2.html rename to r2r_core/examples/data/pg_essay_2.html diff --git a/r2r/examples/data/pg_essay_3.html b/r2r_core/examples/data/pg_essay_3.html similarity index 100% rename from r2r/examples/data/pg_essay_3.html rename to r2r_core/examples/data/pg_essay_3.html diff --git a/r2r/examples/data/pg_essay_4.html b/r2r_core/examples/data/pg_essay_4.html similarity index 100% rename from r2r/examples/data/pg_essay_4.html rename to r2r_core/examples/data/pg_essay_4.html diff --git a/r2r/examples/data/pg_essay_5.html b/r2r_core/examples/data/pg_essay_5.html similarity index 100% rename from r2r/examples/data/pg_essay_5.html rename to r2r_core/examples/data/pg_essay_5.html diff --git a/r2r/examples/data/sample.mp3 b/r2r_core/examples/data/sample.mp3 similarity index 100% rename from r2r/examples/data/sample.mp3 rename to r2r_core/examples/data/sample.mp3 diff --git a/r2r/examples/data/sample2.mp3 b/r2r_core/examples/data/sample2.mp3 similarity index 100% rename from r2r/examples/data/sample2.mp3 rename to r2r_core/examples/data/sample2.mp3 diff --git a/r2r/examples/data/screen_shot.png b/r2r_core/examples/data/screen_shot.png similarity index 100% rename from r2r/examples/data/screen_shot.png rename to r2r_core/examples/data/screen_shot.png diff --git a/r2r/examples/data/test.txt b/r2r_core/examples/data/test.txt similarity index 100% rename from r2r/examples/data/test.txt rename to r2r_core/examples/data/test.txt diff --git a/r2r/examples/data/uber_2021.pdf b/r2r_core/examples/data/uber_2021.pdf similarity index 100% rename from r2r/examples/data/uber_2021.pdf rename to r2r_core/examples/data/uber_2021.pdf diff --git a/r2r/examples/data/yc_companies.txt b/r2r_core/examples/data/yc_companies.txt similarity index 100% rename from r2r/examples/data/yc_companies.txt rename to r2r_core/examples/data/yc_companies.txt diff --git a/r2r/examples/hello_r2r.py b/r2r_core/examples/hello_r2r.py similarity index 96% rename from r2r/examples/hello_r2r.py rename to r2r_core/examples/hello_r2r.py index e1230d86f..fccd73b2e 100644 --- a/r2r/examples/hello_r2r.py +++ b/r2r_core/examples/hello_r2r.py @@ -1,4 +1,4 @@ -from r2r import R2R, Document, GenerationConfig +from r2r_core import R2R, Document, GenerationConfig app = R2R() # You may pass a custom configuration to `R2R` with config=... diff --git a/r2r/examples/scripts/advanced_kg_cookbook.py b/r2r_core/examples/scripts/advanced_kg_cookbook.py similarity index 99% rename from r2r/examples/scripts/advanced_kg_cookbook.py rename to r2r_core/examples/scripts/advanced_kg_cookbook.py index be52ed529..eedbd1bfa 100644 --- a/r2r/examples/scripts/advanced_kg_cookbook.py +++ b/r2r_core/examples/scripts/advanced_kg_cookbook.py @@ -3,7 +3,6 @@ import fire import requests from bs4 import BeautifulSoup, Comment - from r2r import EntityType, R2RClient, R2RPromptProvider, RelationshipType diff --git a/r2r/examples/scripts/run_auth_workflow.py b/r2r_core/examples/scripts/run_auth_workflow.py similarity index 94% rename from r2r/examples/scripts/run_auth_workflow.py rename to r2r_core/examples/scripts/run_auth_workflow.py index 5b915f678..819ac121d 100644 --- a/r2r/examples/scripts/run_auth_workflow.py +++ b/r2r_core/examples/scripts/run_auth_workflow.py @@ -1,4 +1,5 @@ -from r2r import R2RClient +# TODO: need to import this from the package, not from the local directory +from r2r_python_sdk.r2r.client import R2RClient if __name__ == "__main__": client = R2RClient( diff --git a/r2r/examples/scripts/run_hyde.py b/r2r_core/examples/scripts/run_hyde.py similarity index 80% rename from r2r/examples/scripts/run_hyde.py rename to r2r_core/examples/scripts/run_hyde.py index f5842c62b..5fb79f73e 100644 --- a/r2r/examples/scripts/run_hyde.py +++ b/r2r_core/examples/scripts/run_hyde.py @@ -1,8 +1,10 @@ import fire -from r2r import R2RBuilder, R2RConfig -from r2r.base.abstractions.llm import GenerationConfig -from r2r.main.assembly.factory_extensions import R2RPipeFactoryWithMultiSearch +from r2r_core import R2RBuilder, R2RConfig +from r2r_core.base.abstractions.llm import GenerationConfig +from r2r_core.main.assembly.factory_extensions import ( + R2RPipeFactoryWithMultiSearch, +) def main(task_prompt_name="hyde", query="Who was aristotle?"): diff --git a/r2r/examples/scripts/run_web_multi_rag.py b/r2r_core/examples/scripts/run_web_multi_rag.py similarity index 90% rename from r2r/examples/scripts/run_web_multi_rag.py rename to r2r_core/examples/scripts/run_web_multi_rag.py index 3ba70b747..f8f77cb0f 100644 --- a/r2r/examples/scripts/run_web_multi_rag.py +++ b/r2r_core/examples/scripts/run_web_multi_rag.py @@ -1,8 +1,10 @@ import fire -from r2r import R2RBuilder, SerperClient, WebSearchPipe -from r2r.base.abstractions.llm import GenerationConfig -from r2r.main.assembly.factory_extensions import R2RPipeFactoryWithMultiSearch +from r2r_core import R2RBuilder, SerperClient, WebSearchPipe +from r2r_core.base.abstractions.llm import GenerationConfig +from r2r_core.main.assembly.factory_extensions import ( + R2RPipeFactoryWithMultiSearch, +) def run_rag_pipeline(query="Who was Aristotle?"): diff --git a/r2r/examples/scripts/run_web_rag.py b/r2r_core/examples/scripts/run_web_rag.py similarity index 92% rename from r2r/examples/scripts/run_web_rag.py rename to r2r_core/examples/scripts/run_web_rag.py index 7535ae271..6738dc933 100644 --- a/r2r/examples/scripts/run_web_rag.py +++ b/r2r_core/examples/scripts/run_web_rag.py @@ -1,7 +1,7 @@ import fire - from r2r import R2RBuilder, SerperClient, WebSearchPipe -from r2r.base.abstractions.llm import GenerationConfig + +from r2r_core.base.abstractions.llm import GenerationConfig def run_rag_pipeline(query="Who was Aristotle?"): diff --git a/r2r/examples/scripts/sample_data_ingestor.py b/r2r_core/examples/scripts/sample_data_ingestor.py similarity index 97% rename from r2r/examples/scripts/sample_data_ingestor.py rename to r2r_core/examples/scripts/sample_data_ingestor.py index 4fe9590cf..2fdc653b2 100644 --- a/r2r/examples/scripts/sample_data_ingestor.py +++ b/r2r_core/examples/scripts/sample_data_ingestor.py @@ -4,7 +4,7 @@ import fire if TYPE_CHECKING: - from r2r.main.execution import R2RExecutionWrapper + from r2r_core.main.execution import R2RExecutionWrapper class SampleDataIngestor: diff --git a/r2r/integrations/__init__.py b/r2r_core/integrations/__init__.py similarity index 100% rename from r2r/integrations/__init__.py rename to r2r_core/integrations/__init__.py diff --git a/r2r/integrations/serper.py b/r2r_core/integrations/serper.py similarity index 100% rename from r2r/integrations/serper.py rename to r2r_core/integrations/serper.py diff --git a/r2r/main/__init__.py b/r2r_core/main/__init__.py similarity index 97% rename from r2r/main/__init__.py rename to r2r_core/main/__init__.py index 0501c9d48..4843948d7 100644 --- a/r2r/main/__init__.py +++ b/r2r_core/main/__init__.py @@ -21,8 +21,6 @@ "R2RPipelines", "R2RAgents", ## R2R API - # Client - "R2RClient", # Routes "AuthRouter", "IngestionRouter", diff --git a/r2r/main/abstractions.py b/r2r_core/main/abstractions.py similarity index 91% rename from r2r/main/abstractions.py rename to r2r_core/main/abstractions.py index c02c99f98..e2df9f88b 100644 --- a/r2r/main/abstractions.py +++ b/r2r_core/main/abstractions.py @@ -2,9 +2,9 @@ from pydantic import BaseModel -from r2r.agent import R2RRAGAgent, R2RStreamingRAGAgent -from r2r.base.pipes import AsyncPipe -from r2r.base.providers import ( +from r2r_core.agent import R2RRAGAgent, R2RStreamingRAGAgent +from r2r_core.base.pipes import AsyncPipe +from r2r_core.base.providers import ( AuthProvider, ChunkingProvider, CompletionProvider, @@ -14,7 +14,7 @@ ParsingProvider, PromptProvider, ) -from r2r.pipelines import ( +from r2r_core.pipelines import ( IngestionPipeline, KGEnrichmentPipeline, RAGPipeline, diff --git a/r2r/main/api/__init__.py b/r2r_core/main/api/__init__.py similarity index 86% rename from r2r/main/api/__init__.py rename to r2r_core/main/api/__init__.py index a0d60b0c4..7eb5cea8a 100644 --- a/r2r/main/api/__init__.py +++ b/r2r_core/main/api/__init__.py @@ -1,4 +1,3 @@ -from .client import R2RClient from .routes.auth.base import AuthRouter from .routes.base_router import BaseRouter from .routes.ingestion.base import IngestionRouter @@ -6,8 +5,6 @@ from .routes.retrieval.base import RetrievalRouter __all__ = [ - # Client - "R2RClient", # Routes "AuthRouter", "IngestionRouter", diff --git a/r2r/main/api/routes/__init__.py b/r2r_core/main/api/routes/__init__.py similarity index 100% rename from r2r/main/api/routes/__init__.py rename to r2r_core/main/api/routes/__init__.py diff --git a/r2r/main/api/routes/auth/__init__.py b/r2r_core/main/api/routes/auth/__init__.py similarity index 100% rename from r2r/main/api/routes/auth/__init__.py rename to r2r_core/main/api/routes/auth/__init__.py diff --git a/r2r/main/api/routes/auth/base.py b/r2r_core/main/api/routes/auth/base.py similarity index 98% rename from r2r/main/api/routes/auth/base.py rename to r2r_core/main/api/routes/auth/base.py index 587effdaf..499b012f0 100644 --- a/r2r/main/api/routes/auth/base.py +++ b/r2r_core/main/api/routes/auth/base.py @@ -1,11 +1,11 @@ +import uuid from typing import TYPE_CHECKING -from uuid import UUID -from fastapi import Body, Depends, Path +from fastapi import Body, Depends from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm from pydantic import EmailStr -from r2r.base.api.models.auth.responses import ( +from r2r_core.base.api.models.auth.responses import ( GenericMessageResponse, WrappedGenericMessageResponse, WrappedTokenResponse, diff --git a/r2r/main/api/routes/base_router.py b/r2r_core/main/api/routes/base_router.py similarity index 96% rename from r2r/main/api/routes/base_router.py rename to r2r_core/main/api/routes/base_router.py index 56dd9560f..c5e089b27 100644 --- a/r2r/main/api/routes/base_router.py +++ b/r2r_core/main/api/routes/base_router.py @@ -5,8 +5,8 @@ from fastapi import APIRouter, HTTPException from fastapi.responses import StreamingResponse -from r2r.base import R2RException, manage_run -from r2r.base.logging.base import RunType +from r2r_core.base import R2RException, manage_run +from r2r_core.base.logging.base import RunType logger = logging.getLogger(__name__) diff --git a/r2r/main/api/routes/ingestion/__init__.py b/r2r_core/main/api/routes/ingestion/__init__.py similarity index 100% rename from r2r/main/api/routes/ingestion/__init__.py rename to r2r_core/main/api/routes/ingestion/__init__.py diff --git a/r2r/main/api/routes/ingestion/base.py b/r2r_core/main/api/routes/ingestion/base.py similarity index 98% rename from r2r/main/api/routes/ingestion/base.py rename to r2r_core/main/api/routes/ingestion/base.py index ca7c8e649..f1feb6ca2 100644 --- a/r2r/main/api/routes/ingestion/base.py +++ b/r2r_core/main/api/routes/ingestion/base.py @@ -7,9 +7,11 @@ import yaml from fastapi import Depends, File, Form, UploadFile -from r2r.base import ChunkingConfig, R2RException -from r2r.base.api.models.ingestion.responses import WrappedIngestionResponse -from r2r.base.utils import generate_user_document_id +from r2r_core.base import ChunkingConfig, R2RException +from r2r_core.base.api.models.ingestion.responses import ( + WrappedIngestionResponse, +) +from r2r_core.base.utils import generate_user_document_id from ....assembly.factory import R2RProviderFactory from ....engine import R2REngine diff --git a/r2r/main/api/routes/ingestion/ingestion_router_openapi.yml b/r2r_core/main/api/routes/ingestion/ingestion_router_openapi.yml similarity index 100% rename from r2r/main/api/routes/ingestion/ingestion_router_openapi.yml rename to r2r_core/main/api/routes/ingestion/ingestion_router_openapi.yml diff --git a/r2r/main/api/routes/management/__init__.py b/r2r_core/main/api/routes/management/__init__.py similarity index 100% rename from r2r/main/api/routes/management/__init__.py rename to r2r_core/main/api/routes/management/__init__.py diff --git a/r2r/main/api/routes/management/base.py b/r2r_core/main/api/routes/management/base.py similarity index 99% rename from r2r/main/api/routes/management/base.py rename to r2r_core/main/api/routes/management/base.py index c21150dcd..5aa90e973 100644 --- a/r2r/main/api/routes/management/base.py +++ b/r2r_core/main/api/routes/management/base.py @@ -7,8 +7,8 @@ import psutil from fastapi import Body, Depends, Path, Query -from r2r.base import R2RException -from r2r.base.api.models.management.responses import ( +from r2r_core.base import R2RException +from r2r_core.base.api.models.management.responses import ( WrappedAddUserResponse, WrappedAnalyticsResponse, WrappedAppSettingsResponse, diff --git a/r2r/main/api/routes/restructure/__init__.py b/r2r_core/main/api/routes/restructure/__init__.py similarity index 100% rename from r2r/main/api/routes/restructure/__init__.py rename to r2r_core/main/api/routes/restructure/__init__.py diff --git a/r2r/main/api/routes/restructure/base.py b/r2r_core/main/api/routes/restructure/base.py similarity index 88% rename from r2r/main/api/routes/restructure/base.py rename to r2r_core/main/api/routes/restructure/base.py index 470d92a32..ebe726448 100644 --- a/r2r/main/api/routes/restructure/base.py +++ b/r2r_core/main/api/routes/restructure/base.py @@ -1,7 +1,7 @@ from fastapi import Depends -from r2r.main.api.routes.base_router import BaseRouter -from r2r.main.engine import R2REngine +from r2r_core.main.api.routes.base_router import BaseRouter +from r2r_core.main.engine import R2REngine # TODO: Botched by Claude diff --git a/r2r/main/api/routes/retrieval/__init__.py b/r2r_core/main/api/routes/retrieval/__init__.py similarity index 100% rename from r2r/main/api/routes/retrieval/__init__.py rename to r2r_core/main/api/routes/retrieval/__init__.py diff --git a/r2r/main/api/routes/retrieval/base.py b/r2r_core/main/api/routes/retrieval/base.py similarity index 99% rename from r2r/main/api/routes/retrieval/base.py rename to r2r_core/main/api/routes/retrieval/base.py index b5c4f6e2e..e86276dbd 100644 --- a/r2r/main/api/routes/retrieval/base.py +++ b/r2r_core/main/api/routes/retrieval/base.py @@ -5,14 +5,14 @@ from fastapi import Body, Depends from fastapi.responses import StreamingResponse -from r2r.base import ( +from r2r_core.base import ( GenerationConfig, KGSearchSettings, Message, RunType, VectorSearchSettings, ) -from r2r.base.api.models import ( +from r2r_core.base.api.models import ( WrappedRAGAgentResponse, WrappedRAGResponse, WrappedSearchResponse, diff --git a/r2r/main/api/routes/retrieval/retrieval_router_openapi.yml b/r2r_core/main/api/routes/retrieval/retrieval_router_openapi.yml similarity index 100% rename from r2r/main/api/routes/retrieval/retrieval_router_openapi.yml rename to r2r_core/main/api/routes/retrieval/retrieval_router_openapi.yml diff --git a/r2r/main/app.py b/r2r_core/main/app.py similarity index 100% rename from r2r/main/app.py rename to r2r_core/main/app.py diff --git a/r2r/main/app_entry.py b/r2r_core/main/app_entry.py similarity index 100% rename from r2r/main/app_entry.py rename to r2r_core/main/app_entry.py diff --git a/r2r/main/assembly/__init__.py b/r2r_core/main/assembly/__init__.py similarity index 100% rename from r2r/main/assembly/__init__.py rename to r2r_core/main/assembly/__init__.py diff --git a/r2r/main/assembly/builder.py b/r2r_core/main/assembly/builder.py similarity index 99% rename from r2r/main/assembly/builder.py rename to r2r_core/main/assembly/builder.py index 67aad39ef..22ec703a2 100644 --- a/r2r/main/assembly/builder.py +++ b/r2r_core/main/assembly/builder.py @@ -1,8 +1,8 @@ import os from typing import Optional, Type -from r2r.agent import R2RRAGAgent -from r2r.base import ( +from r2r_core.agent import R2RRAGAgent +from r2r_core.base import ( AsyncPipe, AuthProvider, CompletionProvider, @@ -12,7 +12,7 @@ KGProvider, PromptProvider, ) -from r2r.pipelines import ( +from r2r_core.pipelines import ( IngestionPipeline, KGEnrichmentPipeline, RAGPipeline, diff --git a/r2r/main/assembly/config.py b/r2r_core/main/assembly/config.py similarity index 100% rename from r2r/main/assembly/config.py rename to r2r_core/main/assembly/config.py diff --git a/r2r/main/assembly/factory.py b/r2r_core/main/assembly/factory.py similarity index 92% rename from r2r/main/assembly/factory.py rename to r2r_core/main/assembly/factory.py index 3f6971110..78966121f 100644 --- a/r2r/main/assembly/factory.py +++ b/r2r_core/main/assembly/factory.py @@ -2,8 +2,8 @@ import os from typing import Any, Optional -from r2r.agent import R2RRAGAgent, R2RStreamingRAGAgent -from r2r.base import ( +from r2r_core.agent import R2RRAGAgent, R2RStreamingRAGAgent +from r2r_core.base import ( AsyncPipe, AuthConfig, AuthProvider, @@ -24,7 +24,7 @@ PromptProvider, RunLoggingSingleton, ) -from r2r.pipelines import ( +from r2r_core.pipelines import ( IngestionPipeline, KGEnrichmentPipeline, RAGPipeline, @@ -51,7 +51,7 @@ def create_auth_provider( ) -> AuthProvider: auth_provider: Optional[AuthProvider] = None if auth_config.provider == "r2r": - from r2r.providers import R2RAuthProvider + from r2r_core.providers import R2RAuthProvider auth_provider = R2RAuthProvider( auth_config, crypto_provider, db_provider @@ -70,7 +70,7 @@ def create_crypto_provider( ) -> CryptoProvider: crypto_provider: Optional[CryptoProvider] = None if crypto_config.provider == "bcrypt": - from r2r.providers.crypto import BCryptConfig, BCryptProvider + from r2r_core.providers.crypto import BCryptConfig, BCryptProvider crypto_provider = BCryptProvider( BCryptConfig(**crypto_config.dict()) @@ -88,11 +88,11 @@ def create_parsing_provider( parsing_config: ParsingConfig, *args, **kwargs ) -> ParsingProvider: if parsing_config.provider == "r2r": - from r2r.providers import R2RParsingProvider + from r2r_core.providers import R2RParsingProvider return R2RParsingProvider(parsing_config) elif parsing_config.provider == "unstructured": - from r2r.providers import UnstructuredParsingProvider + from r2r_core.providers import UnstructuredParsingProvider return UnstructuredParsingProvider(parsing_config) else: @@ -106,11 +106,11 @@ def create_chunking_provider( ) -> ChunkingProvider: chunking_config.validate() if chunking_config.provider == "r2r": - from r2r.providers import R2RChunkingProvider + from r2r_core.providers import R2RChunkingProvider return R2RChunkingProvider(chunking_config) elif chunking_config.provider == "unstructured": - from r2r.providers import UnstructuredChunkingProvider + from r2r_core.providers import UnstructuredChunkingProvider return UnstructuredChunkingProvider(chunking_config) else: @@ -133,7 +133,7 @@ def create_database_provider( vector_db_dimension = self.config.embedding.base_dimension if db_config.provider == "postgres": - from r2r.providers import PostgresDBProvider + from r2r_core.providers import PostgresDBProvider database_provider = PostgresDBProvider( db_config, vector_db_dimension, crypto_provider=crypto_provider @@ -158,17 +158,17 @@ def create_embedding_provider( raise ValueError( "Must set OPENAI_API_KEY in order to initialize OpenAIEmbeddingProvider." ) - from r2r.providers import OpenAIEmbeddingProvider + from r2r_core.providers import OpenAIEmbeddingProvider embedding_provider = OpenAIEmbeddingProvider(embedding) elif embedding.provider == "litellm": - from r2r.providers import LiteLLMEmbeddingProvider + from r2r_core.providers import LiteLLMEmbeddingProvider embedding_provider = LiteLLMEmbeddingProvider(embedding) elif embedding.provider == "ollama": - from r2r.providers import OllamaEmbeddingProvider + from r2r_core.providers import OllamaEmbeddingProvider embedding_provider = OllamaEmbeddingProvider(embedding) @@ -188,11 +188,11 @@ def create_llm_provider( ) -> CompletionProvider: llm_provider: Optional[CompletionProvider] = None if llm_config.provider == "openai": - from r2r.providers import OpenAICompletionProvider + from r2r_core.providers import OpenAICompletionProvider llm_provider = OpenAICompletionProvider(llm_config) elif llm_config.provider == "litellm": - from r2r.providers import LiteCompletionProvider + from r2r_core.providers import LiteCompletionProvider llm_provider = LiteCompletionProvider(llm_config) else: @@ -209,7 +209,7 @@ def create_prompt_provider( ) -> PromptProvider: prompt_provider = None if prompt_config.provider == "r2r": - from r2r.providers import R2RPromptProvider + from r2r_core.providers import R2RPromptProvider prompt_provider = R2RPromptProvider(prompt_config) else: @@ -221,7 +221,7 @@ def create_prompt_provider( @staticmethod def create_kg_provider(kg_config, *args, **kwargs): if kg_config.provider == "neo4j": - from r2r.providers import Neo4jKGProvider + from r2r_core.providers import Neo4jKGProvider return Neo4jKGProvider(kg_config) elif kg_config.provider is None: @@ -362,12 +362,12 @@ def create_pipes( ) def create_parsing_pipe(self, *args, **kwargs) -> Any: - from r2r.pipes import ParsingPipe + from r2r_core.pipes import ParsingPipe return ParsingPipe(parsing_provider=self.providers.parsing) def create_chunking_pipe(self, *args, **kwargs) -> Any: - from r2r.pipes import ChunkingPipe + from r2r_core.pipes import ChunkingPipe return ChunkingPipe(chunking_provider=self.providers.chunking) @@ -375,7 +375,7 @@ def create_embedding_pipe(self, *args, **kwargs) -> Any: if self.config.embedding.provider is None: return None - from r2r.pipes import EmbeddingPipe + from r2r_core.pipes import EmbeddingPipe return EmbeddingPipe( embedding_provider=self.providers.embedding, @@ -387,7 +387,7 @@ def create_vector_storage_pipe(self, *args, **kwargs) -> Any: if self.config.embedding.provider is None: return None - from r2r.pipes import VectorStoragePipe + from r2r_core.pipes import VectorStoragePipe return VectorStoragePipe(database_provider=self.providers.database) @@ -395,7 +395,7 @@ def create_vector_search_pipe(self, *args, **kwargs) -> Any: if self.config.embedding.provider is None: return None - from r2r.pipes import VectorSearchPipe + from r2r_core.pipes import VectorSearchPipe return VectorSearchPipe( database_provider=self.providers.database, @@ -406,7 +406,7 @@ def create_kg_pipe(self, *args, **kwargs) -> Any: if self.config.kg.provider is None: return None - from r2r.pipes import KGTriplesExtractionPipe + from r2r_core.pipes import KGTriplesExtractionPipe return KGTriplesExtractionPipe( kg_provider=self.providers.kg, @@ -420,7 +420,7 @@ def create_kg_storage_pipe(self, *args, **kwargs) -> Any: if self.config.kg.provider is None: return None - from r2r.pipes import KGStoragePipe + from r2r_core.pipes import KGStoragePipe return KGStoragePipe( kg_provider=self.providers.kg, @@ -431,7 +431,7 @@ def create_kg_search_pipe(self, *args, **kwargs) -> Any: if self.config.kg.provider is None: return None - from r2r.pipes import KGSearchSearchPipe + from r2r_core.pipes import KGSearchSearchPipe return KGSearchSearchPipe( kg_provider=self.providers.kg, @@ -442,14 +442,14 @@ def create_kg_search_pipe(self, *args, **kwargs) -> Any: def create_rag_pipe(self, stream: bool = False, *args, **kwargs) -> Any: if stream: - from r2r.pipes import StreamingSearchRAGPipe + from r2r_core.pipes import StreamingSearchRAGPipe return StreamingSearchRAGPipe( llm_provider=self.providers.llm, prompt_provider=self.providers.prompt, ) else: - from r2r.pipes import SearchRAGPipe + from r2r_core.pipes import SearchRAGPipe return SearchRAGPipe( llm_provider=self.providers.llm, @@ -457,7 +457,7 @@ def create_rag_pipe(self, stream: bool = False, *args, **kwargs) -> Any: ) def create_kg_node_extraction_pipe(self, *args, **kwargs) -> Any: - from r2r.pipes import KGNodeExtractionPipe + from r2r_core.pipes import KGNodeExtractionPipe return KGNodeExtractionPipe( kg_provider=self.providers.kg, @@ -466,7 +466,7 @@ def create_kg_node_extraction_pipe(self, *args, **kwargs) -> Any: ) def create_kg_node_description_pipe(self, *args, **kwargs) -> Any: - from r2r.pipes import KGNodeDescriptionPipe + from r2r_core.pipes import KGNodeDescriptionPipe return KGNodeDescriptionPipe( kg_provider=self.providers.kg, @@ -476,7 +476,7 @@ def create_kg_node_description_pipe(self, *args, **kwargs) -> Any: ) def create_kg_clustering_pipe(self, *args, **kwargs) -> Any: - from r2r.pipes import KGClusteringPipe + from r2r_core.pipes import KGClusteringPipe return KGClusteringPipe( kg_provider=self.providers.kg, diff --git a/r2r/main/assembly/factory_extensions.py b/r2r_core/main/assembly/factory_extensions.py similarity index 95% rename from r2r/main/assembly/factory_extensions.py rename to r2r_core/main/assembly/factory_extensions.py index 34aaa1b4f..755a1897c 100644 --- a/r2r/main/assembly/factory_extensions.py +++ b/r2r_core/main/assembly/factory_extensions.py @@ -1,5 +1,5 @@ -from r2r.pipes.retrieval.multi_search import MultiSearchPipe -from r2r.pipes.retrieval.query_transform_pipe import QueryTransformPipe +from r2r_core.pipes.retrieval.multi_search import MultiSearchPipe +from r2r_core.pipes.retrieval.query_transform_pipe import QueryTransformPipe from .factory import R2RPipeFactory diff --git a/r2r/main/engine.py b/r2r_core/main/engine.py similarity index 98% rename from r2r/main/engine.py rename to r2r_core/main/engine.py index e29daa77e..008bb622e 100644 --- a/r2r/main/engine.py +++ b/r2r_core/main/engine.py @@ -1,7 +1,7 @@ from typing import TYPE_CHECKING, Optional -from r2r.base import RunLoggingSingleton, RunManager -from r2r.base.abstractions.base import AsyncSyncMeta, syncable +from r2r_core.base import RunLoggingSingleton, RunManager +from r2r_core.base.abstractions.base import AsyncSyncMeta, syncable from .abstractions import R2RAgents, R2RPipelines, R2RProviders from .services.auth_service import AuthService diff --git a/r2r/main/execution.py b/r2r_core/main/execution.py similarity index 98% rename from r2r/main/execution.py rename to r2r_core/main/execution.py index 91c97bc4e..6be195e1f 100644 --- a/r2r/main/execution.py +++ b/r2r_core/main/execution.py @@ -10,7 +10,7 @@ import click from fastapi import UploadFile -from r2r.base import ( +from r2r_core.base import ( AnalysisTypes, GenerationConfig, KGSearchSettings, @@ -18,7 +18,9 @@ VectorSearchSettings, ) -from .api.client import R2RClient +# TODO: need to import this from the package, not from the local directory +from r2r_python_sdk.r2r.client import R2RClient + from .assembly.builder import R2RBuilder from .assembly.config import R2RConfig from .r2r import R2R @@ -430,7 +432,7 @@ def analytics( ) def ingest_sample_file(self, no_media: bool = True, option: int = 0): - from r2r.examples.scripts.sample_data_ingestor import ( + from r2r_core.examples.scripts.sample_data_ingestor import ( SampleDataIngestor, ) @@ -441,7 +443,7 @@ def ingest_sample_file(self, no_media: bool = True, option: int = 0): ) def ingest_sample_files(self, no_media: bool = True): - from r2r.examples.scripts.sample_data_ingestor import ( + from r2r_core.examples.scripts.sample_data_ingestor import ( SampleDataIngestor, ) diff --git a/r2r/main/r2r.py b/r2r_core/main/r2r.py similarity index 100% rename from r2r/main/r2r.py rename to r2r_core/main/r2r.py diff --git a/r2r/main/services/__init__.py b/r2r_core/main/services/__init__.py similarity index 100% rename from r2r/main/services/__init__.py rename to r2r_core/main/services/__init__.py diff --git a/r2r/main/services/auth_service.py b/r2r_core/main/services/auth_service.py similarity index 96% rename from r2r/main/services/auth_service.py rename to r2r_core/main/services/auth_service.py index 1677ce8f8..484c37608 100644 --- a/r2r/main/services/auth_service.py +++ b/r2r_core/main/services/auth_service.py @@ -2,9 +2,9 @@ from typing import Optional from uuid import UUID -from r2r.base import R2RException, RunLoggingSingleton, RunManager, Token -from r2r.base.api.models.auth.responses import UserResponse -from r2r.telemetry.telemetry_decorator import telemetry_event +from r2r_core.base import R2RException, RunLoggingSingleton, RunManager, Token +from r2r_core.base.api.models.auth.responses import UserResponse +from r2r_core.telemetry.telemetry_decorator import telemetry_event from ..abstractions import R2RAgents, R2RPipelines, R2RProviders from ..assembly.config import R2RConfig diff --git a/r2r/main/services/base.py b/r2r_core/main/services/base.py similarity index 91% rename from r2r/main/services/base.py rename to r2r_core/main/services/base.py index 7089f76b9..3392cd2e0 100644 --- a/r2r/main/services/base.py +++ b/r2r_core/main/services/base.py @@ -1,6 +1,6 @@ from abc import ABC -from r2r.base import RunLoggingSingleton, RunManager +from r2r_core.base import RunLoggingSingleton, RunManager from ..abstractions import R2RAgents, R2RPipelines, R2RProviders from ..assembly.config import R2RConfig diff --git a/r2r/main/services/ingestion_service.py b/r2r_core/main/services/ingestion_service.py similarity index 98% rename from r2r/main/services/ingestion_service.py rename to r2r_core/main/services/ingestion_service.py index 71e5c0f28..c488761dd 100644 --- a/r2r/main/services/ingestion_service.py +++ b/r2r_core/main/services/ingestion_service.py @@ -6,7 +6,7 @@ from fastapi import UploadFile -from r2r.base import ( +from r2r_core.base import ( Document, DocumentInfo, DocumentType, @@ -18,9 +18,9 @@ increment_version, to_async_generator, ) -from r2r.base.api.models import IngestionResponse -from r2r.base.providers import ChunkingProvider -from r2r.telemetry.telemetry_decorator import telemetry_event +from r2r_core.base.api.models import IngestionResponse +from r2r_core.base.providers import ChunkingProvider +from r2r_core.telemetry.telemetry_decorator import telemetry_event from ...base.api.models.auth.responses import UserResponse from ..abstractions import R2RAgents, R2RPipelines, R2RProviders diff --git a/r2r/main/services/management_service.py b/r2r_core/main/services/management_service.py similarity index 99% rename from r2r/main/services/management_service.py rename to r2r_core/main/services/management_service.py index 9e8337b45..c8476ae43 100644 --- a/r2r/main/services/management_service.py +++ b/r2r_core/main/services/management_service.py @@ -7,7 +7,7 @@ import toml -from r2r.base import ( +from r2r_core.base import ( AnalysisTypes, LogFilterCriteria, LogProcessor, @@ -15,7 +15,7 @@ RunLoggingSingleton, RunManager, ) -from r2r.telemetry.telemetry_decorator import telemetry_event +from r2r_core.telemetry.telemetry_decorator import telemetry_event from ..abstractions import R2RAgents, R2RPipelines, R2RProviders from ..assembly.config import R2RConfig diff --git a/r2r/main/services/restructure_service.py b/r2r_core/main/services/restructure_service.py similarity index 94% rename from r2r/main/services/restructure_service.py rename to r2r_core/main/services/restructure_service.py index a68151310..6667092dd 100644 --- a/r2r/main/services/restructure_service.py +++ b/r2r_core/main/services/restructure_service.py @@ -1,7 +1,7 @@ import logging from typing import Any, Dict, List -from r2r.base import R2RException, RunLoggingSingleton, RunManager +from r2r_core.base import R2RException, RunLoggingSingleton, RunManager from ..abstractions import R2RAgents, R2RPipelines, R2RProviders from ..assembly.config import R2RConfig diff --git a/r2r/main/services/retrieval_service.py b/r2r_core/main/services/retrieval_service.py similarity index 98% rename from r2r/main/services/retrieval_service.py rename to r2r_core/main/services/retrieval_service.py index 5b50de002..d2ec8c69f 100644 --- a/r2r/main/services/retrieval_service.py +++ b/r2r_core/main/services/retrieval_service.py @@ -4,7 +4,7 @@ from typing import Optional from uuid import UUID -from r2r.base import ( +from r2r_core.base import ( CompletionRecord, GenerationConfig, KGSearchSettings, @@ -18,9 +18,9 @@ manage_run, to_async_generator, ) -from r2r.base.api.models import RAGResponse, SearchResponse -from r2r.base.api.models.auth.responses import UserResponse -from r2r.telemetry.telemetry_decorator import telemetry_event +from r2r_core.base.api.models import RAGResponse, SearchResponse +from r2r_core.base.api.models.auth.responses import UserResponse +from r2r_core.telemetry.telemetry_decorator import telemetry_event from ..abstractions import R2RAgents, R2RPipelines, R2RProviders from ..assembly.config import R2RConfig diff --git a/r2r/parsers/__init__.py b/r2r_core/parsers/__init__.py similarity index 100% rename from r2r/parsers/__init__.py rename to r2r_core/parsers/__init__.py diff --git a/r2r/parsers/media/__init__.py b/r2r_core/parsers/media/__init__.py similarity index 100% rename from r2r/parsers/media/__init__.py rename to r2r_core/parsers/media/__init__.py diff --git a/r2r/parsers/media/audio_parser.py b/r2r_core/parsers/media/audio_parser.py similarity index 88% rename from r2r/parsers/media/audio_parser.py rename to r2r_core/parsers/media/audio_parser.py index 8a7735e4c..adc4ccb63 100644 --- a/r2r/parsers/media/audio_parser.py +++ b/r2r_core/parsers/media/audio_parser.py @@ -1,8 +1,8 @@ import os from typing import AsyncGenerator -from r2r.base.parsers.base_parser import AsyncParser -from r2r.parsers.media.openai_helpers import process_audio_with_openai +from r2r_core.base.parsers.base_parser import AsyncParser +from r2r_core.parsers.media.openai_helpers import process_audio_with_openai class AudioParser(AsyncParser[bytes]): diff --git a/r2r/parsers/media/docx_parser.py b/r2r_core/parsers/media/docx_parser.py similarity index 87% rename from r2r/parsers/media/docx_parser.py rename to r2r_core/parsers/media/docx_parser.py index 9edced810..0f555fbcd 100644 --- a/r2r/parsers/media/docx_parser.py +++ b/r2r_core/parsers/media/docx_parser.py @@ -1,8 +1,8 @@ from io import BytesIO from typing import AsyncGenerator -from r2r.base.abstractions.document import DataType -from r2r.base.parsers.base_parser import AsyncParser +from r2r_core.base.abstractions.document import DataType +from r2r_core.base.parsers.base_parser import AsyncParser class DOCXParser(AsyncParser[DataType]): diff --git a/r2r/parsers/media/img_parser.py b/r2r_core/parsers/media/img_parser.py similarity index 85% rename from r2r/parsers/media/img_parser.py rename to r2r_core/parsers/media/img_parser.py index 126907ec4..fb6519501 100644 --- a/r2r/parsers/media/img_parser.py +++ b/r2r_core/parsers/media/img_parser.py @@ -1,9 +1,9 @@ import os from typing import AsyncGenerator -from r2r.base.abstractions.document import DataType -from r2r.base.parsers.base_parser import AsyncParser -from r2r.parsers.media.openai_helpers import process_frame_with_openai +from r2r_core.base.abstractions.document import DataType +from r2r_core.base.parsers.base_parser import AsyncParser +from r2r_core.parsers.media.openai_helpers import process_frame_with_openai class ImageParser(AsyncParser[DataType]): diff --git a/r2r/parsers/media/movie_parser.py b/r2r_core/parsers/media/movie_parser.py similarity index 97% rename from r2r/parsers/media/movie_parser.py rename to r2r_core/parsers/media/movie_parser.py index c00b80d92..1ff73d5ba 100644 --- a/r2r/parsers/media/movie_parser.py +++ b/r2r_core/parsers/media/movie_parser.py @@ -2,8 +2,8 @@ import os from typing import AsyncGenerator -from r2r.base.parsers.base_parser import AsyncParser -from r2r.parsers.media.openai_helpers import ( +from r2r_core.base.parsers.base_parser import AsyncParser +from r2r_core.parsers.media.openai_helpers import ( process_audio_with_openai, process_frame_with_openai, ) diff --git a/r2r/parsers/media/openai_helpers.py b/r2r_core/parsers/media/openai_helpers.py similarity index 100% rename from r2r/parsers/media/openai_helpers.py rename to r2r_core/parsers/media/openai_helpers.py diff --git a/r2r/parsers/media/pdf_parser.py b/r2r_core/parsers/media/pdf_parser.py similarity index 98% rename from r2r/parsers/media/pdf_parser.py rename to r2r_core/parsers/media/pdf_parser.py index f50ac94fc..5f9e4c0a8 100644 --- a/r2r/parsers/media/pdf_parser.py +++ b/r2r_core/parsers/media/pdf_parser.py @@ -5,8 +5,8 @@ from io import BytesIO from typing import AsyncGenerator -from r2r.base.abstractions.document import DataType -from r2r.base.parsers.base_parser import AsyncParser +from r2r_core.base.abstractions.document import DataType +from r2r_core.base.parsers.base_parser import AsyncParser logger = logging.getLogger(__name__) diff --git a/r2r/parsers/media/ppt_parser.py b/r2r_core/parsers/media/ppt_parser.py similarity index 88% rename from r2r/parsers/media/ppt_parser.py rename to r2r_core/parsers/media/ppt_parser.py index 8f1928400..3ad4d28a6 100644 --- a/r2r/parsers/media/ppt_parser.py +++ b/r2r_core/parsers/media/ppt_parser.py @@ -1,8 +1,8 @@ from io import BytesIO from typing import AsyncGenerator -from r2r.base.abstractions.document import DataType -from r2r.base.parsers.base_parser import AsyncParser +from r2r_core.base.abstractions.document import DataType +from r2r_core.base.parsers.base_parser import AsyncParser class PPTParser(AsyncParser[DataType]): diff --git a/r2r/parsers/structured/__init__.py b/r2r_core/parsers/structured/__init__.py similarity index 100% rename from r2r/parsers/structured/__init__.py rename to r2r_core/parsers/structured/__init__.py diff --git a/r2r/parsers/structured/csv_parser.py b/r2r_core/parsers/structured/csv_parser.py similarity index 95% rename from r2r/parsers/structured/csv_parser.py rename to r2r_core/parsers/structured/csv_parser.py index cd8d563bd..1f26fc2c1 100644 --- a/r2r/parsers/structured/csv_parser.py +++ b/r2r_core/parsers/structured/csv_parser.py @@ -1,7 +1,7 @@ from typing import IO, AsyncGenerator, Union -from r2r.base.abstractions.document import DataType -from r2r.base.parsers.base_parser import AsyncParser +from r2r_core.base.abstractions.document import DataType +from r2r_core.base.parsers.base_parser import AsyncParser class CSVParser(AsyncParser[DataType]): diff --git a/r2r/parsers/structured/json_parser.py b/r2r_core/parsers/structured/json_parser.py similarity index 93% rename from r2r/parsers/structured/json_parser.py rename to r2r_core/parsers/structured/json_parser.py index 23d630656..3dcaf96df 100644 --- a/r2r/parsers/structured/json_parser.py +++ b/r2r_core/parsers/structured/json_parser.py @@ -1,8 +1,8 @@ import json from typing import AsyncGenerator -from r2r.base.abstractions.document import DataType -from r2r.base.parsers.base_parser import AsyncParser +from r2r_core.base.abstractions.document import DataType +from r2r_core.base.parsers.base_parser import AsyncParser class JSONParser(AsyncParser[DataType]): diff --git a/r2r/parsers/structured/xlsx_parser.py b/r2r_core/parsers/structured/xlsx_parser.py similarity index 96% rename from r2r/parsers/structured/xlsx_parser.py rename to r2r_core/parsers/structured/xlsx_parser.py index abd917541..b7050518b 100644 --- a/r2r/parsers/structured/xlsx_parser.py +++ b/r2r_core/parsers/structured/xlsx_parser.py @@ -1,8 +1,8 @@ from io import BytesIO from typing import AsyncGenerator -from r2r.base.abstractions.document import DataType -from r2r.base.parsers.base_parser import AsyncParser +from r2r_core.base.abstractions.document import DataType +from r2r_core.base.parsers.base_parser import AsyncParser class XLSXParser(AsyncParser[DataType]): diff --git a/r2r/parsers/text/__init__.py b/r2r_core/parsers/text/__init__.py similarity index 100% rename from r2r/parsers/text/__init__.py rename to r2r_core/parsers/text/__init__.py diff --git a/r2r/parsers/text/html_parser.py b/r2r_core/parsers/text/html_parser.py similarity index 74% rename from r2r/parsers/text/html_parser.py rename to r2r_core/parsers/text/html_parser.py index 9c663fbed..6fbeab7cd 100644 --- a/r2r/parsers/text/html_parser.py +++ b/r2r_core/parsers/text/html_parser.py @@ -2,8 +2,8 @@ from bs4 import BeautifulSoup -from r2r.base.abstractions.document import DataType -from r2r.base.parsers.base_parser import AsyncParser +from r2r_core.base.abstractions.document import DataType +from r2r_core.base.parsers.base_parser import AsyncParser class HTMLParser(AsyncParser[DataType]): diff --git a/r2r/parsers/text/md_parser.py b/r2r_core/parsers/text/md_parser.py similarity index 82% rename from r2r/parsers/text/md_parser.py rename to r2r_core/parsers/text/md_parser.py index ada9ae57e..f74fff2e1 100644 --- a/r2r/parsers/text/md_parser.py +++ b/r2r_core/parsers/text/md_parser.py @@ -2,8 +2,8 @@ from bs4 import BeautifulSoup -from r2r.base.abstractions.document import DataType -from r2r.base.parsers.base_parser import AsyncParser +from r2r_core.base.abstractions.document import DataType +from r2r_core.base.parsers.base_parser import AsyncParser class MDParser(AsyncParser[DataType]): diff --git a/r2r/parsers/text/text_parser.py b/r2r_core/parsers/text/text_parser.py similarity index 71% rename from r2r/parsers/text/text_parser.py rename to r2r_core/parsers/text/text_parser.py index 0c8ab7caf..269320946 100644 --- a/r2r/parsers/text/text_parser.py +++ b/r2r_core/parsers/text/text_parser.py @@ -1,7 +1,7 @@ from typing import AsyncGenerator -from r2r.base.abstractions.document import DataType -from r2r.base.parsers.base_parser import AsyncParser +from r2r_core.base.abstractions.document import DataType +from r2r_core.base.parsers.base_parser import AsyncParser class TextParser(AsyncParser[DataType]): diff --git a/r2r/pipelines/__init__.py b/r2r_core/pipelines/__init__.py similarity index 100% rename from r2r/pipelines/__init__.py rename to r2r_core/pipelines/__init__.py diff --git a/r2r/pipelines/graph_enrichment.py b/r2r_core/pipelines/graph_enrichment.py similarity index 100% rename from r2r/pipelines/graph_enrichment.py rename to r2r_core/pipelines/graph_enrichment.py diff --git a/r2r/pipelines/ingestion_pipeline.py b/r2r_core/pipelines/ingestion_pipeline.py similarity index 92% rename from r2r/pipelines/ingestion_pipeline.py rename to r2r_core/pipelines/ingestion_pipeline.py index 5a1fe42e7..6949a40bb 100644 --- a/r2r/pipelines/ingestion_pipeline.py +++ b/r2r_core/pipelines/ingestion_pipeline.py @@ -3,12 +3,15 @@ from asyncio import Queue from typing import Any, Optional -from r2r.base.api.models.auth.responses import UserResponse -from r2r.base.logging.run_logger import RunLoggingSingleton -from r2r.base.logging.run_manager import RunManager, manage_run -from r2r.base.pipeline.base_pipeline import AsyncPipeline, dequeue_requests -from r2r.base.pipes.base_pipe import AsyncPipe, AsyncState -from r2r.base.providers.chunking import ChunkingProvider +from r2r_core.base.api.models.auth.responses import UserResponse +from r2r_core.base.logging.run_logger import RunLoggingSingleton +from r2r_core.base.logging.run_manager import RunManager, manage_run +from r2r_core.base.pipeline.base_pipeline import ( + AsyncPipeline, + dequeue_requests, +) +from r2r_core.base.pipes.base_pipe import AsyncPipe, AsyncState +from r2r_core.base.providers.chunking import ChunkingProvider logger = logging.getLogger(__name__) diff --git a/r2r/pipelines/rag_pipeline.py b/r2r_core/pipelines/rag_pipeline.py similarity index 100% rename from r2r/pipelines/rag_pipeline.py rename to r2r_core/pipelines/rag_pipeline.py diff --git a/r2r/pipelines/search_pipeline.py b/r2r_core/pipelines/search_pipeline.py similarity index 100% rename from r2r/pipelines/search_pipeline.py rename to r2r_core/pipelines/search_pipeline.py diff --git a/r2r/pipes/__init__.py b/r2r_core/pipes/__init__.py similarity index 100% rename from r2r/pipes/__init__.py rename to r2r_core/pipes/__init__.py diff --git a/r2r/pipes/abstractions/__init__.py b/r2r_core/pipes/abstractions/__init__.py similarity index 100% rename from r2r/pipes/abstractions/__init__.py rename to r2r_core/pipes/abstractions/__init__.py diff --git a/r2r/pipes/abstractions/generator_pipe.py b/r2r_core/pipes/abstractions/generator_pipe.py similarity index 89% rename from r2r/pipes/abstractions/generator_pipe.py rename to r2r_core/pipes/abstractions/generator_pipe.py index 38d2aafa8..d72777c2e 100644 --- a/r2r/pipes/abstractions/generator_pipe.py +++ b/r2r_core/pipes/abstractions/generator_pipe.py @@ -2,15 +2,15 @@ from typing import Any, AsyncGenerator, Optional from uuid import UUID -from r2r.base import ( +from r2r_core.base import ( AsyncState, CompletionProvider, PipeType, PromptProvider, RunLoggingSingleton, ) -from r2r.base.abstractions.llm import GenerationConfig -from r2r.base.pipes.base_pipe import AsyncPipe +from r2r_core.base.abstractions.llm import GenerationConfig +from r2r_core.base.pipes.base_pipe import AsyncPipe class GeneratorPipe(AsyncPipe): diff --git a/r2r/pipes/abstractions/search_pipe.py b/r2r_core/pipes/abstractions/search_pipe.py similarity index 98% rename from r2r/pipes/abstractions/search_pipe.py rename to r2r_core/pipes/abstractions/search_pipe.py index 76f0b23bb..e533cb92d 100644 --- a/r2r/pipes/abstractions/search_pipe.py +++ b/r2r_core/pipes/abstractions/search_pipe.py @@ -3,7 +3,7 @@ from typing import Any, AsyncGenerator, Optional, Union from uuid import UUID -from r2r.base import ( +from r2r_core.base import ( AsyncPipe, AsyncState, PipeType, diff --git a/r2r/pipes/ingestion/__init__.py b/r2r_core/pipes/ingestion/__init__.py similarity index 100% rename from r2r/pipes/ingestion/__init__.py rename to r2r_core/pipes/ingestion/__init__.py diff --git a/r2r/pipes/ingestion/chunking_pipe.py b/r2r_core/pipes/ingestion/chunking_pipe.py similarity index 94% rename from r2r/pipes/ingestion/chunking_pipe.py rename to r2r_core/pipes/ingestion/chunking_pipe.py index 291a6ad0e..ff5653486 100644 --- a/r2r/pipes/ingestion/chunking_pipe.py +++ b/r2r_core/pipes/ingestion/chunking_pipe.py @@ -1,6 +1,6 @@ from typing import Any, AsyncGenerator, Optional, Union -from r2r.base import ( +from r2r_core.base import ( AsyncState, ChunkingConfig, ChunkingProvider, @@ -11,8 +11,8 @@ RunLoggingSingleton, generate_id_from_label, ) -from r2r.base.pipes.base_pipe import AsyncPipe -from r2r.providers import R2RChunkingProvider +from r2r_core.base.pipes.base_pipe import AsyncPipe +from r2r_core.providers import R2RChunkingProvider class ChunkingPipe(AsyncPipe): diff --git a/r2r/pipes/ingestion/embedding_pipe.py b/r2r_core/pipes/ingestion/embedding_pipe.py similarity index 98% rename from r2r/pipes/ingestion/embedding_pipe.py rename to r2r_core/pipes/ingestion/embedding_pipe.py index 013c3a5fa..e702b933f 100644 --- a/r2r/pipes/ingestion/embedding_pipe.py +++ b/r2r_core/pipes/ingestion/embedding_pipe.py @@ -2,7 +2,7 @@ import logging from typing import Any, AsyncGenerator, Optional, Union -from r2r.base import ( +from r2r_core.base import ( AsyncState, DocumentFragment, EmbeddingProvider, @@ -12,7 +12,7 @@ Vector, VectorEntry, ) -from r2r.base.pipes.base_pipe import AsyncPipe +from r2r_core.base.pipes.base_pipe import AsyncPipe logger = logging.getLogger(__name__) diff --git a/r2r/pipes/ingestion/kg_extraction_pipe.py b/r2r_core/pipes/ingestion/kg_extraction_pipe.py similarity index 97% rename from r2r/pipes/ingestion/kg_extraction_pipe.py rename to r2r_core/pipes/ingestion/kg_extraction_pipe.py index d36f6694a..504c0d03d 100644 --- a/r2r/pipes/ingestion/kg_extraction_pipe.py +++ b/r2r_core/pipes/ingestion/kg_extraction_pipe.py @@ -3,7 +3,7 @@ import logging from typing import Any, AsyncGenerator, Optional, Union -from r2r.base import ( +from r2r_core.base import ( AsyncState, ChunkingProvider, CompletionProvider, @@ -14,12 +14,12 @@ R2RDocumentProcessingError, RunLoggingSingleton, ) -from r2r.base.abstractions.graph import ( +from r2r_core.base.abstractions.graph import ( KGExtraction, extract_entities, extract_triples, ) -from r2r.base.pipes.base_pipe import AsyncPipe +from r2r_core.base.pipes.base_pipe import AsyncPipe logger = logging.getLogger(__name__) diff --git a/r2r/pipes/ingestion/parsing_pipe.py b/r2r_core/pipes/ingestion/parsing_pipe.py similarity index 93% rename from r2r/pipes/ingestion/parsing_pipe.py rename to r2r_core/pipes/ingestion/parsing_pipe.py index 03ceab6aa..514ac3c55 100644 --- a/r2r/pipes/ingestion/parsing_pipe.py +++ b/r2r_core/pipes/ingestion/parsing_pipe.py @@ -6,7 +6,7 @@ from typing import AsyncGenerator, Optional, Union from uuid import UUID -from r2r.base import ( +from r2r_core.base import ( AsyncState, Document, DocumentExtraction, @@ -15,8 +15,8 @@ RunLoggingSingleton, generate_id_from_label, ) -from r2r.base.abstractions.exception import R2RDocumentProcessingError -from r2r.base.pipes.base_pipe import AsyncPipe +from r2r_core.base.abstractions.exception import R2RDocumentProcessingError +from r2r_core.base.pipes.base_pipe import AsyncPipe logger = logging.getLogger(__name__) diff --git a/r2r/pipes/ingestion/vector_storage_pipe.py b/r2r_core/pipes/ingestion/vector_storage_pipe.py similarity index 95% rename from r2r/pipes/ingestion/vector_storage_pipe.py rename to r2r_core/pipes/ingestion/vector_storage_pipe.py index af516350b..ab55117dc 100644 --- a/r2r/pipes/ingestion/vector_storage_pipe.py +++ b/r2r_core/pipes/ingestion/vector_storage_pipe.py @@ -3,15 +3,15 @@ from typing import Any, AsyncGenerator, Optional, Tuple, Union from uuid import UUID -from r2r.base import ( +from r2r_core.base import ( AsyncState, DatabaseProvider, PipeType, RunLoggingSingleton, VectorEntry, ) -from r2r.base.abstractions.exception import R2RDocumentProcessingError -from r2r.base.pipes.base_pipe import AsyncPipe +from r2r_core.base.abstractions.exception import R2RDocumentProcessingError +from r2r_core.base.pipes.base_pipe import AsyncPipe logger = logging.getLogger(__name__) diff --git a/r2r/pipes/kg/clustering.py b/r2r_core/pipes/kg/clustering.py similarity index 99% rename from r2r/pipes/kg/clustering.py rename to r2r_core/pipes/kg/clustering.py index a0d6c0248..e6c7c0c9b 100644 --- a/r2r/pipes/kg/clustering.py +++ b/r2r_core/pipes/kg/clustering.py @@ -12,7 +12,7 @@ import networkx as nx from graspologic.partition import hierarchical_leiden -from r2r.base import ( +from r2r_core.base import ( AsyncPipe, AsyncState, Community, diff --git a/r2r/pipes/kg/extraction.py b/r2r_core/pipes/kg/extraction.py similarity index 98% rename from r2r/pipes/kg/extraction.py rename to r2r_core/pipes/kg/extraction.py index 4d2043c32..4d9d0f3ab 100644 --- a/r2r/pipes/kg/extraction.py +++ b/r2r_core/pipes/kg/extraction.py @@ -5,7 +5,7 @@ import uuid from typing import Any, AsyncGenerator, Optional, Union -from r2r.base import ( +from r2r_core.base import ( AsyncState, ChunkingProvider, CompletionProvider, @@ -20,7 +20,7 @@ RunLoggingSingleton, Triple, ) -from r2r.base.pipes.base_pipe import AsyncPipe +from r2r_core.base.pipes.base_pipe import AsyncPipe logger = logging.getLogger(__name__) diff --git a/r2r/pipes/kg/node_extraction.py b/r2r_core/pipes/kg/node_extraction.py similarity index 97% rename from r2r/pipes/kg/node_extraction.py rename to r2r_core/pipes/kg/node_extraction.py index 9f85fa3b8..0078a68b8 100644 --- a/r2r/pipes/kg/node_extraction.py +++ b/r2r_core/pipes/kg/node_extraction.py @@ -5,7 +5,7 @@ from typing import Any, AsyncGenerator, Optional from uuid import UUID -from r2r.base import ( +from r2r_core.base import ( AsyncState, CompletionProvider, EmbeddingProvider, @@ -14,9 +14,9 @@ PromptProvider, RunLoggingSingleton, ) -from r2r.base.abstractions.graph import Entity, Triple -from r2r.base.pipes.base_pipe import AsyncPipe -from r2r.base.providers.llm import GenerationConfig +from r2r_core.base.abstractions.graph import Entity, Triple +from r2r_core.base.pipes.base_pipe import AsyncPipe +from r2r_core.base.providers.llm import GenerationConfig logger = logging.getLogger(__name__) diff --git a/r2r/pipes/kg/storage.py b/r2r_core/pipes/kg/storage.py similarity index 95% rename from r2r/pipes/kg/storage.py rename to r2r_core/pipes/kg/storage.py index 1663856b5..635a47d73 100644 --- a/r2r/pipes/kg/storage.py +++ b/r2r_core/pipes/kg/storage.py @@ -3,15 +3,15 @@ from typing import Any, AsyncGenerator, Optional from uuid import UUID -from r2r.base import ( +from r2r_core.base import ( AsyncState, EmbeddingProvider, KGExtraction, PipeType, RunLoggingSingleton, ) -from r2r.base.pipes.base_pipe import AsyncPipe -from r2r.base.providers import KGProvider +from r2r_core.base.pipes.base_pipe import AsyncPipe +from r2r_core.base.providers import KGProvider logger = logging.getLogger(__name__) diff --git a/r2r/pipes/other/web_search_pipe.py b/r2r_core/pipes/other/web_search_pipe.py similarity index 97% rename from r2r/pipes/other/web_search_pipe.py rename to r2r_core/pipes/other/web_search_pipe.py index 1e0c5a768..f51eafa5e 100644 --- a/r2r/pipes/other/web_search_pipe.py +++ b/r2r_core/pipes/other/web_search_pipe.py @@ -3,14 +3,14 @@ from typing import Any, AsyncGenerator, Optional from uuid import UUID -from r2r.base import ( +from r2r_core.base import ( AsyncPipe, AsyncState, PipeType, VectorSearchResult, generate_id_from_label, ) -from r2r.integrations import SerperClient +from r2r_core.integrations import SerperClient from ..abstractions.search_pipe import SearchPipe diff --git a/r2r/pipes/retrieval/kg_search_search_pipe.py b/r2r_core/pipes/retrieval/kg_search_search_pipe.py similarity index 99% rename from r2r/pipes/retrieval/kg_search_search_pipe.py rename to r2r_core/pipes/retrieval/kg_search_search_pipe.py index 24eb16d4d..9435651dc 100644 --- a/r2r/pipes/retrieval/kg_search_search_pipe.py +++ b/r2r_core/pipes/retrieval/kg_search_search_pipe.py @@ -4,7 +4,7 @@ from typing import Any, Optional from uuid import UUID -from r2r.base import ( +from r2r_core.base import ( AsyncState, CompletionProvider, EmbeddingProvider, diff --git a/r2r/pipes/retrieval/multi_search.py b/r2r_core/pipes/retrieval/multi_search.py similarity index 93% rename from r2r/pipes/retrieval/multi_search.py rename to r2r_core/pipes/retrieval/multi_search.py index 74cf9f40a..ff29e3461 100644 --- a/r2r/pipes/retrieval/multi_search.py +++ b/r2r_core/pipes/retrieval/multi_search.py @@ -2,9 +2,9 @@ from typing import Any, AsyncGenerator, Optional from uuid import UUID -from r2r.base.abstractions.llm import GenerationConfig -from r2r.base.abstractions.search import VectorSearchResult -from r2r.base.pipes.base_pipe import AsyncPipe +from r2r_core.base.abstractions.llm import GenerationConfig +from r2r_core.base.abstractions.search import VectorSearchResult +from r2r_core.base.pipes.base_pipe import AsyncPipe from ..abstractions.search_pipe import SearchPipe from .query_transform_pipe import QueryTransformPipe diff --git a/r2r/pipes/retrieval/query_transform_pipe.py b/r2r_core/pipes/retrieval/query_transform_pipe.py similarity index 96% rename from r2r/pipes/retrieval/query_transform_pipe.py rename to r2r_core/pipes/retrieval/query_transform_pipe.py index 98f1bfd2f..2d2a4a2f5 100644 --- a/r2r/pipes/retrieval/query_transform_pipe.py +++ b/r2r_core/pipes/retrieval/query_transform_pipe.py @@ -2,14 +2,14 @@ from typing import Any, AsyncGenerator, Optional from uuid import UUID -from r2r.base import ( +from r2r_core.base import ( AsyncPipe, AsyncState, CompletionProvider, PipeType, PromptProvider, ) -from r2r.base.abstractions.llm import GenerationConfig +from r2r_core.base.abstractions.llm import GenerationConfig from ..abstractions.generator_pipe import GeneratorPipe diff --git a/r2r/pipes/retrieval/search_rag_pipe.py b/r2r_core/pipes/retrieval/search_rag_pipe.py similarity index 97% rename from r2r/pipes/retrieval/search_rag_pipe.py rename to r2r_core/pipes/retrieval/search_rag_pipe.py index 20ec6aee5..031f49ba0 100644 --- a/r2r/pipes/retrieval/search_rag_pipe.py +++ b/r2r_core/pipes/retrieval/search_rag_pipe.py @@ -1,6 +1,6 @@ from typing import Any, AsyncGenerator, Optional, Tuple -from r2r.base import ( +from r2r_core.base import ( AggregateSearchResult, AsyncPipe, AsyncState, @@ -9,7 +9,7 @@ PipeType, PromptProvider, ) -from r2r.base.abstractions.llm import GenerationConfig, RAGCompletion +from r2r_core.base.abstractions.llm import GenerationConfig, RAGCompletion from ..abstractions.generator_pipe import GeneratorPipe diff --git a/r2r/pipes/retrieval/streaming_rag_pipe.py b/r2r_core/pipes/retrieval/streaming_rag_pipe.py similarity index 97% rename from r2r/pipes/retrieval/streaming_rag_pipe.py rename to r2r_core/pipes/retrieval/streaming_rag_pipe.py index 68ef1f01c..a33b2e838 100644 --- a/r2r/pipes/retrieval/streaming_rag_pipe.py +++ b/r2r_core/pipes/retrieval/streaming_rag_pipe.py @@ -4,7 +4,7 @@ from typing import Any, AsyncGenerator, Generator, Optional from uuid import UUID -from r2r.base import ( +from r2r_core.base import ( AsyncState, CompletionProvider, CompletionRecord, @@ -12,7 +12,7 @@ PipeType, PromptProvider, ) -from r2r.base.abstractions.llm import GenerationConfig +from r2r_core.base.abstractions.llm import GenerationConfig from ..abstractions.generator_pipe import GeneratorPipe from .search_rag_pipe import SearchRAGPipe diff --git a/r2r/pipes/retrieval/vector_search_pipe.py b/r2r_core/pipes/retrieval/vector_search_pipe.py similarity index 99% rename from r2r/pipes/retrieval/vector_search_pipe.py rename to r2r_core/pipes/retrieval/vector_search_pipe.py index 1029ccafc..3e914820d 100644 --- a/r2r/pipes/retrieval/vector_search_pipe.py +++ b/r2r_core/pipes/retrieval/vector_search_pipe.py @@ -3,7 +3,7 @@ from typing import Any, AsyncGenerator, Optional from uuid import UUID -from r2r.base import ( +from r2r_core.base import ( AsyncPipe, AsyncState, DatabaseProvider, diff --git a/r2r/providers/__init__.py b/r2r_core/providers/__init__.py similarity index 100% rename from r2r/providers/__init__.py rename to r2r_core/providers/__init__.py diff --git a/r2r/providers/auth/__init__.py b/r2r_core/providers/auth/__init__.py similarity index 100% rename from r2r/providers/auth/__init__.py rename to r2r_core/providers/auth/__init__.py diff --git a/r2r/providers/auth/r2r_auth.py b/r2r_core/providers/auth/r2r_auth.py similarity index 99% rename from r2r/providers/auth/r2r_auth.py rename to r2r_core/providers/auth/r2r_auth.py index e52e6aab7..c68fba95d 100644 --- a/r2r/providers/auth/r2r_auth.py +++ b/r2r_core/providers/auth/r2r_auth.py @@ -7,7 +7,7 @@ from fastapi import Depends from fastapi.security import OAuth2PasswordBearer -from r2r.base import ( +from r2r_core.base import ( AuthConfig, AuthProvider, CryptoProvider, @@ -16,7 +16,7 @@ Token, TokenData, ) -from r2r.base.api.models.auth.responses import UserResponse +from r2r_core.base.api.models.auth.responses import UserResponse logger = logging.getLogger(__name__) oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") diff --git a/r2r/providers/chunking/__init__.py b/r2r_core/providers/chunking/__init__.py similarity index 100% rename from r2r/providers/chunking/__init__.py rename to r2r_core/providers/chunking/__init__.py diff --git a/r2r/providers/chunking/r2r_chunking.py b/r2r_core/providers/chunking/r2r_chunking.py similarity index 99% rename from r2r/providers/chunking/r2r_chunking.py rename to r2r_core/providers/chunking/r2r_chunking.py index 1fc48b932..de8dcbb7c 100644 --- a/r2r/providers/chunking/r2r_chunking.py +++ b/r2r_core/providers/chunking/r2r_chunking.py @@ -1,6 +1,6 @@ from typing import Any, AsyncGenerator -from r2r.base import ( +from r2r_core.base import ( ChunkingConfig, ChunkingProvider, Method, diff --git a/r2r/providers/chunking/unstructured_chunking.py b/r2r_core/providers/chunking/unstructured_chunking.py similarity index 97% rename from r2r/providers/chunking/unstructured_chunking.py rename to r2r_core/providers/chunking/unstructured_chunking.py index 908bfe066..a54f81676 100644 --- a/r2r/providers/chunking/unstructured_chunking.py +++ b/r2r_core/providers/chunking/unstructured_chunking.py @@ -1,6 +1,6 @@ from typing import AsyncGenerator -from r2r.base import ChunkingProvider +from r2r_core.base import ChunkingProvider class UnstructuredChunkingProvider(ChunkingProvider): diff --git a/r2r/providers/crypto/__init__.py b/r2r_core/providers/crypto/__init__.py similarity index 100% rename from r2r/providers/crypto/__init__.py rename to r2r_core/providers/crypto/__init__.py diff --git a/r2r/providers/crypto/bcrypt.py b/r2r_core/providers/crypto/bcrypt.py similarity index 96% rename from r2r/providers/crypto/bcrypt.py rename to r2r_core/providers/crypto/bcrypt.py index 1710f2298..7b769b09a 100644 --- a/r2r/providers/crypto/bcrypt.py +++ b/r2r_core/providers/crypto/bcrypt.py @@ -1,7 +1,7 @@ import secrets import string -from r2r.base import CryptoConfig, CryptoProvider +from r2r_core.base import CryptoConfig, CryptoProvider class BCryptConfig(CryptoConfig): diff --git a/r2r/providers/database/__init__.py b/r2r_core/providers/database/__init__.py similarity index 100% rename from r2r/providers/database/__init__.py rename to r2r_core/providers/database/__init__.py diff --git a/r2r/providers/database/base.py b/r2r_core/providers/database/base.py similarity index 100% rename from r2r/providers/database/base.py rename to r2r_core/providers/database/base.py diff --git a/r2r/providers/database/document.py b/r2r_core/providers/database/document.py similarity index 98% rename from r2r/providers/database/document.py rename to r2r_core/providers/database/document.py index 38dae9536..e7ba96ebe 100644 --- a/r2r/providers/database/document.py +++ b/r2r_core/providers/database/document.py @@ -1,7 +1,7 @@ from typing import Optional from uuid import UUID -from r2r.base import DocumentInfo, DocumentStatus, DocumentType +from r2r_core.base import DocumentInfo, DocumentStatus, DocumentType from .base import DatabaseMixin diff --git a/r2r/providers/database/group.py b/r2r_core/providers/database/group.py similarity index 98% rename from r2r/providers/database/group.py rename to r2r_core/providers/database/group.py index cd2a73f36..5a9247fa1 100644 --- a/r2r/providers/database/group.py +++ b/r2r_core/providers/database/group.py @@ -2,10 +2,14 @@ from typing import Optional from uuid import UUID -from r2r.base import R2RException -from r2r.base.abstractions import DocumentInfo, DocumentStatus, DocumentType -from r2r.base.api.models.auth.responses import UserResponse -from r2r.base.api.models.management.responses import ( +from r2r_core.base import R2RException +from r2r_core.base.abstractions import ( + DocumentInfo, + DocumentStatus, + DocumentType, +) +from r2r_core.base.api.models.auth.responses import UserResponse +from r2r_core.base.api.models.management.responses import ( GroupOverviewResponse, GroupResponse, ) diff --git a/r2r/providers/database/postgres.py b/r2r_core/providers/database/postgres.py similarity index 99% rename from r2r/providers/database/postgres.py rename to r2r_core/providers/database/postgres.py index 290abaeca..96539512e 100644 --- a/r2r/providers/database/postgres.py +++ b/r2r_core/providers/database/postgres.py @@ -2,7 +2,7 @@ import os from typing import Optional -from r2r.base import ( +from r2r_core.base import ( CryptoProvider, DatabaseConfig, DatabaseProvider, diff --git a/r2r/providers/database/relational.py b/r2r_core/providers/database/relational.py similarity index 80% rename from r2r/providers/database/relational.py rename to r2r_core/providers/database/relational.py index b2b23a829..a8ab40e33 100644 --- a/r2r/providers/database/relational.py +++ b/r2r_core/providers/database/relational.py @@ -2,11 +2,11 @@ from sqlalchemy import exc, text -from r2r.providers.database.base import DatabaseMixin, execute_query -from r2r.providers.database.document import DocumentMixin -from r2r.providers.database.group import GroupMixin -from r2r.providers.database.tokens import BlacklistedTokensMixin -from r2r.providers.database.user import UserMixin +from r2r_core.providers.database.base import DatabaseMixin, execute_query +from r2r_core.providers.database.document import DocumentMixin +from r2r_core.providers.database.group import GroupMixin +from r2r_core.providers.database.tokens import BlacklistedTokensMixin +from r2r_core.providers.database.user import UserMixin logger = logging.getLogger(__name__) diff --git a/r2r/providers/database/tokens.py b/r2r_core/providers/database/tokens.py similarity index 100% rename from r2r/providers/database/tokens.py rename to r2r_core/providers/database/tokens.py diff --git a/r2r/providers/database/user.py b/r2r_core/providers/database/user.py similarity index 98% rename from r2r/providers/database/user.py rename to r2r_core/providers/database/user.py index 0bc0e246c..45df73d01 100644 --- a/r2r/providers/database/user.py +++ b/r2r_core/providers/database/user.py @@ -4,9 +4,9 @@ from sqlalchemy import text -from r2r.base.abstractions import R2RException, UserStats -from r2r.base.api.models.auth.responses import UserResponse -from r2r.base.utils import generate_id_from_label +from r2r_core.base.abstractions import R2RException, UserStats +from r2r_core.base.api.models.auth.responses import UserResponse +from r2r_core.base.utils import generate_id_from_label from .base import DatabaseMixin, QueryBuilder diff --git a/r2r/providers/database/vecs/__init__.py b/r2r_core/providers/database/vecs/__init__.py similarity index 100% rename from r2r/providers/database/vecs/__init__.py rename to r2r_core/providers/database/vecs/__init__.py diff --git a/r2r/providers/database/vecs/adapter/__init__.py b/r2r_core/providers/database/vecs/adapter/__init__.py similarity index 100% rename from r2r/providers/database/vecs/adapter/__init__.py rename to r2r_core/providers/database/vecs/adapter/__init__.py diff --git a/r2r/providers/database/vecs/adapter/base.py b/r2r_core/providers/database/vecs/adapter/base.py similarity index 100% rename from r2r/providers/database/vecs/adapter/base.py rename to r2r_core/providers/database/vecs/adapter/base.py diff --git a/r2r/providers/database/vecs/adapter/markdown.py b/r2r_core/providers/database/vecs/adapter/markdown.py similarity index 100% rename from r2r/providers/database/vecs/adapter/markdown.py rename to r2r_core/providers/database/vecs/adapter/markdown.py diff --git a/r2r/providers/database/vecs/adapter/noop.py b/r2r_core/providers/database/vecs/adapter/noop.py similarity index 100% rename from r2r/providers/database/vecs/adapter/noop.py rename to r2r_core/providers/database/vecs/adapter/noop.py diff --git a/r2r/providers/database/vecs/adapter/text.py b/r2r_core/providers/database/vecs/adapter/text.py similarity index 100% rename from r2r/providers/database/vecs/adapter/text.py rename to r2r_core/providers/database/vecs/adapter/text.py diff --git a/r2r/providers/database/vecs/client.py b/r2r_core/providers/database/vecs/client.py similarity index 95% rename from r2r/providers/database/vecs/client.py rename to r2r_core/providers/database/vecs/client.py index 9c9df4a53..b67a1e83b 100644 --- a/r2r/providers/database/vecs/client.py +++ b/r2r_core/providers/database/vecs/client.py @@ -21,7 +21,7 @@ from .exc import CollectionNotFound if TYPE_CHECKING: - from r2r.providers.database.vecs.collection import Collection + from r2r_core.providers.database.vecs.collection import Collection logger = logging.getLogger(__name__) @@ -168,7 +168,7 @@ def get_or_create_collection( Raises: CollectionAlreadyExists: If a collection with the same name already exists """ - from r2r.providers.database.vecs.collection import Collection + from r2r_core.providers.database.vecs.collection import Collection adapter_dimension = adapter.exported_dimension if adapter else None @@ -196,7 +196,7 @@ def create_collection(self, name: str, dimension: int) -> Collection: Raises: CollectionAlreadyExists: If a collection with the same name already exists """ - from r2r.providers.database.vecs.collection import Collection + from r2r_core.providers.database.vecs.collection import Collection return Collection(name, dimension, self)._create() @@ -214,7 +214,7 @@ def get_collection(self, name: str) -> Collection: Raises: CollectionNotFound: If no collection with the given name exists. """ - from r2r.providers.database.vecs.collection import Collection + from r2r_core.providers.database.vecs.collection import Collection query = text( """ @@ -255,7 +255,7 @@ def list_collections(self) -> List["Collection"]: Returns: list[Collection]: A list of all collections. """ - from r2r.providers.database.vecs.collection import Collection + from r2r_core.providers.database.vecs.collection import Collection return Collection._list_collections(self) @@ -271,7 +271,7 @@ def delete_collection(self, name: str) -> None: Returns: None """ - from r2r.providers.database.vecs.collection import Collection + from r2r_core.providers.database.vecs.collection import Collection Collection(name, -1, self)._drop() return diff --git a/r2r/providers/database/vecs/collection.py b/r2r_core/providers/database/vecs/collection.py similarity index 99% rename from r2r/providers/database/vecs/collection.py rename to r2r_core/providers/database/vecs/collection.py index 96c499ff0..dc3c487ba 100644 --- a/r2r/providers/database/vecs/collection.py +++ b/r2r_core/providers/database/vecs/collection.py @@ -228,7 +228,7 @@ def __init__( dimension (int): The dimension of the vectors in the collection. client (Client): The client to use for interacting with the database. """ - from r2r.providers.database.vecs.adapter import Adapter + from r2r_core.providers.database.vecs.adapter import Adapter self.client = client self.name = name diff --git a/r2r/providers/database/vecs/exc.py b/r2r_core/providers/database/vecs/exc.py similarity index 100% rename from r2r/providers/database/vecs/exc.py rename to r2r_core/providers/database/vecs/exc.py diff --git a/r2r/providers/database/vector.py b/r2r_core/providers/database/vector.py similarity index 99% rename from r2r/providers/database/vector.py rename to r2r_core/providers/database/vector.py index c8523a159..bd9d20585 100644 --- a/r2r/providers/database/vector.py +++ b/r2r_core/providers/database/vector.py @@ -7,7 +7,7 @@ from sqlalchemy import exc, text from sqlalchemy.engine.url import make_url -from r2r.base import ( +from r2r_core.base import ( DatabaseConfig, VectorDBProvider, VectorEntry, diff --git a/r2r/providers/embeddings/__init__.py b/r2r_core/providers/embeddings/__init__.py similarity index 100% rename from r2r/providers/embeddings/__init__.py rename to r2r_core/providers/embeddings/__init__.py diff --git a/r2r/providers/embeddings/litellm.py b/r2r_core/providers/embeddings/litellm.py similarity index 99% rename from r2r/providers/embeddings/litellm.py rename to r2r_core/providers/embeddings/litellm.py index a2eaa54ce..c70ac16f3 100644 --- a/r2r/providers/embeddings/litellm.py +++ b/r2r_core/providers/embeddings/litellm.py @@ -4,7 +4,7 @@ from litellm import aembedding, embedding -from r2r.base import ( +from r2r_core.base import ( EmbeddingConfig, EmbeddingProvider, EmbeddingPurpose, diff --git a/r2r/providers/embeddings/ollama.py b/r2r_core/providers/embeddings/ollama.py similarity index 99% rename from r2r/providers/embeddings/ollama.py rename to r2r_core/providers/embeddings/ollama.py index e4cde4bc2..20ddbc7db 100644 --- a/r2r/providers/embeddings/ollama.py +++ b/r2r_core/providers/embeddings/ollama.py @@ -4,7 +4,7 @@ from ollama import AsyncClient, Client -from r2r.base import ( +from r2r_core.base import ( EmbeddingConfig, EmbeddingProvider, EmbeddingPurpose, diff --git a/r2r/providers/embeddings/openai.py b/r2r_core/providers/embeddings/openai.py similarity index 99% rename from r2r/providers/embeddings/openai.py rename to r2r_core/providers/embeddings/openai.py index 68ebb7e84..01ed840dd 100644 --- a/r2r/providers/embeddings/openai.py +++ b/r2r_core/providers/embeddings/openai.py @@ -6,7 +6,7 @@ from openai import AsyncOpenAI, AuthenticationError, OpenAI from openai._types import NOT_GIVEN -from r2r.base import ( +from r2r_core.base import ( EmbeddingConfig, EmbeddingProvider, EmbeddingPurpose, diff --git a/r2r/providers/kg/__init__.py b/r2r_core/providers/kg/__init__.py similarity index 100% rename from r2r/providers/kg/__init__.py rename to r2r_core/providers/kg/__init__.py diff --git a/r2r/providers/kg/neo4j/__init__.py b/r2r_core/providers/kg/neo4j/__init__.py similarity index 100% rename from r2r/providers/kg/neo4j/__init__.py rename to r2r_core/providers/kg/neo4j/__init__.py diff --git a/r2r/providers/kg/neo4j/graph_queries.py b/r2r_core/providers/kg/neo4j/graph_queries.py similarity index 100% rename from r2r/providers/kg/neo4j/graph_queries.py rename to r2r_core/providers/kg/neo4j/graph_queries.py diff --git a/r2r/providers/kg/neo4j/provider.py b/r2r_core/providers/kg/neo4j/provider.py similarity index 98% rename from r2r/providers/kg/neo4j/provider.py rename to r2r_core/providers/kg/neo4j/provider.py index a4f2b48a8..e06f2a468 100644 --- a/r2r/providers/kg/neo4j/provider.py +++ b/r2r_core/providers/kg/neo4j/provider.py @@ -6,14 +6,14 @@ from typing import Any, Dict, List, Optional from uuid import UUID -from r2r.base import ( +from r2r_core.base import ( KGConfig, KGProvider, format_entity_types, format_relations, ) -from r2r.base.abstractions.document import DocumentFragment -from r2r.base.abstractions.graph import ( +from r2r_core.base.abstractions.document import DocumentFragment +from r2r_core.base.abstractions.graph import ( Community, Entity, KGExtraction, diff --git a/r2r/providers/llm/__init__.py b/r2r_core/providers/llm/__init__.py similarity index 100% rename from r2r/providers/llm/__init__.py rename to r2r_core/providers/llm/__init__.py diff --git a/r2r/providers/llm/litellm.py b/r2r_core/providers/llm/litellm.py similarity index 95% rename from r2r/providers/llm/litellm.py rename to r2r_core/providers/llm/litellm.py index e73c064f4..7c60c7ad4 100644 --- a/r2r/providers/llm/litellm.py +++ b/r2r_core/providers/llm/litellm.py @@ -1,8 +1,8 @@ import logging from typing import Any -from r2r.base.abstractions.llm import GenerationConfig -from r2r.base.providers.llm import CompletionConfig, CompletionProvider +from r2r_core.base.abstractions.llm import GenerationConfig +from r2r_core.base.providers.llm import CompletionConfig, CompletionProvider logger = logging.getLogger(__name__) diff --git a/r2r/providers/llm/openai.py b/r2r_core/providers/llm/openai.py similarity index 95% rename from r2r/providers/llm/openai.py rename to r2r_core/providers/llm/openai.py index 58e3e06ab..57d9cd33e 100644 --- a/r2r/providers/llm/openai.py +++ b/r2r_core/providers/llm/openai.py @@ -4,8 +4,8 @@ from openai import AsyncOpenAI, OpenAI -from r2r.base.abstractions.llm import GenerationConfig -from r2r.base.providers.llm import CompletionConfig, CompletionProvider +from r2r_core.base.abstractions.llm import GenerationConfig +from r2r_core.base.providers.llm import CompletionConfig, CompletionProvider logger = logging.getLogger(__name__) diff --git a/r2r/providers/parsing/__init__.py b/r2r_core/providers/parsing/__init__.py similarity index 100% rename from r2r/providers/parsing/__init__.py rename to r2r_core/providers/parsing/__init__.py diff --git a/r2r/providers/parsing/r2r_parsing.py b/r2r_core/providers/parsing/r2r_parsing.py similarity index 98% rename from r2r/providers/parsing/r2r_parsing.py rename to r2r_core/providers/parsing/r2r_parsing.py index 273e6606d..8420c7ed7 100644 --- a/r2r/providers/parsing/r2r_parsing.py +++ b/r2r_core/providers/parsing/r2r_parsing.py @@ -2,8 +2,8 @@ import time from typing import Any, AsyncGenerator -from r2r import parsers -from r2r.base import ( +from r2r_core import parsers +from r2r_core.base import ( Document, DocumentExtraction, DocumentType, diff --git a/r2r/providers/parsing/unstructured_parsing.py b/r2r_core/providers/parsing/unstructured_parsing.py similarity index 98% rename from r2r/providers/parsing/unstructured_parsing.py rename to r2r_core/providers/parsing/unstructured_parsing.py index a6f911559..ef2d1d307 100644 --- a/r2r/providers/parsing/unstructured_parsing.py +++ b/r2r_core/providers/parsing/unstructured_parsing.py @@ -3,7 +3,7 @@ from io import BytesIO from typing import AsyncGenerator -from r2r.base import ( +from r2r_core.base import ( Document, DocumentExtraction, DocumentType, diff --git a/r2r/providers/prompts/__init__.py b/r2r_core/providers/prompts/__init__.py similarity index 100% rename from r2r/providers/prompts/__init__.py rename to r2r_core/providers/prompts/__init__.py diff --git a/r2r/providers/prompts/defaults.yaml b/r2r_core/providers/prompts/defaults.yaml similarity index 100% rename from r2r/providers/prompts/defaults.yaml rename to r2r_core/providers/prompts/defaults.yaml diff --git a/r2r/providers/prompts/defaults/default_rag.yaml b/r2r_core/providers/prompts/defaults/default_rag.yaml similarity index 100% rename from r2r/providers/prompts/defaults/default_rag.yaml rename to r2r_core/providers/prompts/defaults/default_rag.yaml diff --git a/r2r/providers/prompts/defaults/few_shot_ner_kg_extraction.yaml b/r2r_core/providers/prompts/defaults/few_shot_ner_kg_extraction.yaml similarity index 100% rename from r2r/providers/prompts/defaults/few_shot_ner_kg_extraction.yaml rename to r2r_core/providers/prompts/defaults/few_shot_ner_kg_extraction.yaml diff --git a/r2r/providers/prompts/defaults/few_shot_ner_kg_extraction_with_spec.yaml b/r2r_core/providers/prompts/defaults/few_shot_ner_kg_extraction_with_spec.yaml similarity index 100% rename from r2r/providers/prompts/defaults/few_shot_ner_kg_extraction_with_spec.yaml rename to r2r_core/providers/prompts/defaults/few_shot_ner_kg_extraction_with_spec.yaml diff --git a/r2r/providers/prompts/defaults/graphrag_community_reports.yaml b/r2r_core/providers/prompts/defaults/graphrag_community_reports.yaml similarity index 100% rename from r2r/providers/prompts/defaults/graphrag_community_reports.yaml rename to r2r_core/providers/prompts/defaults/graphrag_community_reports.yaml diff --git a/r2r/providers/prompts/defaults/graphrag_map_system_prompt.yaml b/r2r_core/providers/prompts/defaults/graphrag_map_system_prompt.yaml similarity index 100% rename from r2r/providers/prompts/defaults/graphrag_map_system_prompt.yaml rename to r2r_core/providers/prompts/defaults/graphrag_map_system_prompt.yaml diff --git a/r2r/providers/prompts/defaults/graphrag_reduce_system_prompt.yaml b/r2r_core/providers/prompts/defaults/graphrag_reduce_system_prompt.yaml similarity index 100% rename from r2r/providers/prompts/defaults/graphrag_reduce_system_prompt.yaml rename to r2r_core/providers/prompts/defaults/graphrag_reduce_system_prompt.yaml diff --git a/r2r/providers/prompts/defaults/graphrag_triplet_extraction_few_shot.yaml b/r2r_core/providers/prompts/defaults/graphrag_triplet_extraction_few_shot.yaml similarity index 100% rename from r2r/providers/prompts/defaults/graphrag_triplet_extraction_few_shot.yaml rename to r2r_core/providers/prompts/defaults/graphrag_triplet_extraction_few_shot.yaml diff --git a/r2r/providers/prompts/defaults/graphrag_triplet_extraction_zero_shot.yaml b/r2r_core/providers/prompts/defaults/graphrag_triplet_extraction_zero_shot.yaml similarity index 100% rename from r2r/providers/prompts/defaults/graphrag_triplet_extraction_zero_shot.yaml rename to r2r_core/providers/prompts/defaults/graphrag_triplet_extraction_zero_shot.yaml diff --git a/r2r/providers/prompts/defaults/hyde.yaml b/r2r_core/providers/prompts/defaults/hyde.yaml similarity index 100% rename from r2r/providers/prompts/defaults/hyde.yaml rename to r2r_core/providers/prompts/defaults/hyde.yaml diff --git a/r2r/providers/prompts/defaults/kg_search.yaml b/r2r_core/providers/prompts/defaults/kg_search.yaml similarity index 100% rename from r2r/providers/prompts/defaults/kg_search.yaml rename to r2r_core/providers/prompts/defaults/kg_search.yaml diff --git a/r2r/providers/prompts/defaults/kg_search_with_spec.yaml b/r2r_core/providers/prompts/defaults/kg_search_with_spec.yaml similarity index 100% rename from r2r/providers/prompts/defaults/kg_search_with_spec.yaml rename to r2r_core/providers/prompts/defaults/kg_search_with_spec.yaml diff --git a/r2r/providers/prompts/defaults/rag_agent.yaml b/r2r_core/providers/prompts/defaults/rag_agent.yaml similarity index 100% rename from r2r/providers/prompts/defaults/rag_agent.yaml rename to r2r_core/providers/prompts/defaults/rag_agent.yaml diff --git a/r2r/providers/prompts/defaults/rag_context.yaml b/r2r_core/providers/prompts/defaults/rag_context.yaml similarity index 100% rename from r2r/providers/prompts/defaults/rag_context.yaml rename to r2r_core/providers/prompts/defaults/rag_context.yaml diff --git a/r2r/providers/prompts/defaults/rag_fusion.yaml b/r2r_core/providers/prompts/defaults/rag_fusion.yaml similarity index 100% rename from r2r/providers/prompts/defaults/rag_fusion.yaml rename to r2r_core/providers/prompts/defaults/rag_fusion.yaml diff --git a/r2r/providers/prompts/defaults/system.yaml b/r2r_core/providers/prompts/defaults/system.yaml similarity index 100% rename from r2r/providers/prompts/defaults/system.yaml rename to r2r_core/providers/prompts/defaults/system.yaml diff --git a/r2r/providers/prompts/defaults/zero_shot_ner_kg_extraction.yaml b/r2r_core/providers/prompts/defaults/zero_shot_ner_kg_extraction.yaml similarity index 100% rename from r2r/providers/prompts/defaults/zero_shot_ner_kg_extraction.yaml rename to r2r_core/providers/prompts/defaults/zero_shot_ner_kg_extraction.yaml diff --git a/r2r/providers/prompts/defaults/zero_shot_ner_kg_extraction_with_spec.yaml b/r2r_core/providers/prompts/defaults/zero_shot_ner_kg_extraction_with_spec.yaml similarity index 100% rename from r2r/providers/prompts/defaults/zero_shot_ner_kg_extraction_with_spec.yaml rename to r2r_core/providers/prompts/defaults/zero_shot_ner_kg_extraction_with_spec.yaml diff --git a/r2r/providers/prompts/r2r_prompts.py b/r2r_core/providers/prompts/r2r_prompts.py similarity index 98% rename from r2r/providers/prompts/r2r_prompts.py rename to r2r_core/providers/prompts/r2r_prompts.py index 896eb0c00..a1be76937 100644 --- a/r2r/providers/prompts/r2r_prompts.py +++ b/r2r_core/providers/prompts/r2r_prompts.py @@ -6,7 +6,7 @@ import toml import yaml -from r2r.base import Prompt, PromptConfig, PromptProvider +from r2r_core.base import Prompt, PromptConfig, PromptProvider logger = logging.getLogger(__name__) diff --git a/r2r/telemetry/__init__.py b/r2r_core/telemetry/__init__.py similarity index 100% rename from r2r/telemetry/__init__.py rename to r2r_core/telemetry/__init__.py diff --git a/r2r/telemetry/events.py b/r2r_core/telemetry/events.py similarity index 100% rename from r2r/telemetry/events.py rename to r2r_core/telemetry/events.py diff --git a/r2r/telemetry/posthog.py b/r2r_core/telemetry/posthog.py similarity index 96% rename from r2r/telemetry/posthog.py rename to r2r_core/telemetry/posthog.py index 64e638958..90fde942b 100644 --- a/r2r/telemetry/posthog.py +++ b/r2r_core/telemetry/posthog.py @@ -3,7 +3,7 @@ import posthog -from r2r.telemetry.events import BaseTelemetryEvent +from r2r_core.telemetry.events import BaseTelemetryEvent logger = logging.getLogger(__name__) diff --git a/r2r/telemetry/telemetry_decorator.py b/r2r_core/telemetry/telemetry_decorator.py similarity index 93% rename from r2r/telemetry/telemetry_decorator.py rename to r2r_core/telemetry/telemetry_decorator.py index 2938a83eb..aba557d39 100644 --- a/r2r/telemetry/telemetry_decorator.py +++ b/r2r_core/telemetry/telemetry_decorator.py @@ -2,8 +2,8 @@ import logging from functools import wraps -from r2r.telemetry.events import ErrorEvent, FeatureUsageEvent -from r2r.telemetry.posthog import telemetry_client +from r2r_core.telemetry.events import ErrorEvent, FeatureUsageEvent +from r2r_core.telemetry.posthog import telemetry_client logger = logging.getLogger(__name__) diff --git a/r2r_go_sdk/go.mod b/r2r_go_sdk/go.mod new file mode 100644 index 000000000..4a052a9aa --- /dev/null +++ b/r2r_go_sdk/go.mod @@ -0,0 +1,3 @@ +module github.com/yourusername/r2r-go-sdk + +go 1.23.0 diff --git a/r2r_go_sdk/internal/tests/integration/management_test.go b/r2r_go_sdk/internal/tests/integration/management_test.go new file mode 100644 index 000000000..a9aa7e18e --- /dev/null +++ b/r2r_go_sdk/internal/tests/integration/management_test.go @@ -0,0 +1,55 @@ +package integration + +import ( + "os" + "testing" + + "github.com/yourusername/r2r-go-sdk/pkg/sdk" +) + +func TestServerStatsIntegration(t *testing.T) { + logConfig := sdk.LogConfig{ + Verbose: true, + LogWriter: os.Stderr, // or any io.Writer + } + + client := sdk.NewClient("http://localhost:8000/v1", logConfig) + + // Call Health + health, err := client.Health() + if err != nil { + t.Fatalf("Health returned an error: %v", err) + } + + // Check if we received a response + if health == nil { + t.Fatalf("Health returned nil") + } + + // Call ServerStats + stats, err := client.ServerStats() + if err != nil { + t.Fatalf("ServerStats returned an error: %v", err) + } + + // Check if we received a response + if stats == nil { + t.Fatalf("ServerStats returned nil") + } + + // Print the received stats for debugging + t.Logf("Received server stats: %+v", stats) + + // Check app settings + settings, err := client.AppSettings() + + if err != nil { + t.Fatalf("AppSettings returned an error: %v", err) + } + + // Check if we received a response + if settings == nil { + t.Fatalf("AppSettings returned nil") + } + +} diff --git a/r2r_go_sdk/pkg/sdk/auth.go b/r2r_go_sdk/pkg/sdk/auth.go new file mode 100644 index 000000000..31beaf221 --- /dev/null +++ b/r2r_go_sdk/pkg/sdk/auth.go @@ -0,0 +1,392 @@ +package sdk + +import ( + "bytes" + "encoding/json" + "fmt" +) + +type Auth struct { + client *Client +} + +// Register registers a new user with the given email and password. +// +// Parameters: +// +// email: The email of the user to register. +// password: The passworrd of the user to register. +// +// Returns: +// +// A map containing the response from the server. +// An error if the request fails, nil otherwise. +func (a *Auth) Register(email string, password string) (map[string]interface{}, error) { + data := map[string]interface{}{ + "email": email, + "password": password, + } + + jsonData, err := json.Marshal(data) + if err != nil { + return nil, fmt.Errorf("error marshaling register data: %w", err) + } + + result, err := a.client.makeRequest("POST", "register", bytes.NewBuffer(jsonData), "application/json") + if err != nil { + return nil, err + } + + stats, ok := result.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("unexpected response type: expected map[string]interface{}, got %T", result) + } + + return stats, nil +} + +// VerifyEmail verifies the email of a user with the given verification code. +// +// Parameters: +// +// verificationCode: The verification code to verify the email with. +// +// Returns: +// +// A map containing the response from the server. +// An error if the request fails, nil otherwise. +func (a *Auth) VerifyEmail(verificationCode string) (map[string]interface{}, error) { + data := map[string]string{ + "verification_code": verificationCode, + } + + jsonData, err := json.Marshal(data) + if err != nil { + return nil, fmt.Errorf("error marshaling verify email data: %w", err) + } + + result, err := a.client.makeRequest("POST", "verify_email", bytes.NewBuffer(jsonData), "application/json") + if err != nil { + return nil, err + } + + stats, ok := result.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("unexpected response type: expected map[string]interface{}, got %T", result) + } + + return stats, nil +} + +// Login attempts to log in a user with the given email and password. +// +// Parameters: +// +// email: The email of the user to log in. +// password: The password of the user to log in. +// +// Returns: +// +// A map containing the access and refresh tokens from the server. +// An error if the request fails, nil otherwise. +func (a *Auth) Login(email string, password string) (map[string]interface{}, error) { + data := map[string]string{ + "username": email, + "password": password, + } + + jsonData, err := json.Marshal(data) + if err != nil { + return nil, fmt.Errorf("error marshaling login data: %w", err) + } + + result, err := a.client.makeRequest("POST", "login", bytes.NewBuffer(jsonData), "application/json") + if err != nil { + return nil, err + } + + response, ok := result.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("unexpected response type: expected map[string]interface{}, got %T", result) + } + + if results, ok := response["results"].(map[string]interface{}); ok { + if accessToken, ok := results["access_token"].(map[string]interface{}); ok { + a.client.AccessToken = accessToken["token"].(string) + } + if refreshToken, ok := results["refresh_token"].(map[string]interface{}); ok { + a.client.RefreshToken = refreshToken["token"].(string) + } + } + + return response, nil +} + +// Logout logs out the currently authenticated user. +// +// Returns: +// +// A map containing the response from the server. +// An error if the request fails, nil otherwise. +func (a *Auth) Logout() (map[string]interface{}, error) { + result, err := a.client.makeRequest("POST", "logout", nil, "application/json") + if err != nil { + return nil, err + } + + response, ok := result.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("unexpected response type: expected map[string]interface{}, got %T", result) + } + + a.client.AccessToken = "" + a.client.RefreshToken = "" + + return response, nil +} + +// User retreives the information of the currently authenticated user. +// +// Returns: +// +// A map containing the user information. +func (a *Auth) User() (map[string]interface{}, error) { + result, err := a.client.makeRequest("GET", "user", nil, "application/json") + if err != nil { + return nil, err + } + + stats, ok := result.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("unexpected response type: expected map[string]interface{}, got %T", result) + } + + return stats, nil +} + +// UpdateUser updates the profile information for the currently authenticated user. +// +// Parameters: +// +// email: The updated email for the user (optional). +// name: The updated name for the user (optional). +// bio: The updated bio for the user (optional). +// profilePicture: The updated profile picture URL for the user (optional). +// +// Returns: +// +// A map containing the updated user information. +// An error if the request fails, nil otherwise. +func (a *Auth) UpdateUser(email, name, bio, profilePicture *string) (map[string]interface{}, error) { + data := make(map[string]interface{}) + if email != nil { + data["email"] = *email + } + if name != nil { + data["name"] = *name + } + if bio != nil { + data["bio"] = *bio + } + if profilePicture != nil { + data["profile_picture"] = *profilePicture + } + + jsonData, err := json.Marshal(data) + if err != nil { + return nil, fmt.Errorf("error marshaling update user data: %w", err) + } + + result, err := a.client.makeRequest("PUT", "user", bytes.NewBuffer(jsonData), "application/json") + if err != nil { + return nil, err + } + + response, ok := result.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("unexpected response type: expected map[string]interface{}, got %T", result) + } + + return response, nil +} + +// RefreshAccessToken refreshes the access token for the currently authenticated user. +// +// Returns: +// +// A map containing the new access and refresh tokens. +// An error if the request fails, nil otherwise. +func (a *Auth) RefreshAccessToken() (map[string]interface{}, error) { + data := map[string]string{ + "refresh_token": a.client.RefreshToken, + } + + jsonData, err := json.Marshal(data) + if err != nil { + return nil, fmt.Errorf("error marshaling refresh token data: %w", err) + } + + result, err := a.client.makeRequest("POST", "refresh_access_token", bytes.NewBuffer(jsonData), "application/json") + if err != nil { + return nil, err + } + + response, ok := result.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("unexpected response type: expected map[string]interface{}, got %T", result) + } + + if results, ok := response["results"].(map[string]interface{}); ok { + if accessToken, ok := results["access_token"].(map[string]interface{}); ok { + a.client.AccessToken = accessToken["token"].(string) + } + if refreshToken, ok := results["refresh_token"].(map[string]interface{}); ok { + a.client.RefreshToken = refreshToken["token"].(string) + } + } + + return response, nil +} + +// ChangePassword changes the password of the currently authenticated user. +// +// Parameters: +// +// currentPassword: The current password of the user. +// newPassword: The new password to set for the user. +// +// Returns: +// +// A map containing the response from the server. +// An error if the request fails, nil otherwise. +func (a *Auth) ChangePassword(currentPassword string, newPassword string) (map[string]interface{}, error) { + data := map[string]string{ + "current_password": currentPassword, + "new_password": newPassword, + } + + jsonData, err := json.Marshal(data) + if err != nil { + return nil, fmt.Errorf("error marshaling change password data: %w", err) + } + + result, err := a.client.makeRequest("POST", "change_password", bytes.NewBuffer(jsonData), "application/json") + if err != nil { + return nil, err + } + + stats, ok := result.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("unexpected response type: expected map[string]interface{}, got %T", result) + } + + return stats, nil +} + +// RequestPasswordReset requests a password reset for the user with the given email. +// +// Parameters: +// +// email: The email of the user to request a password reset for. +// +// Returns: +// +// A map containing the response from the server. +// An error if the request fails, nil otherwise. +func (a *Auth) RequestPasswordReset(email string) (map[string]interface{}, error) { + data := map[string]string{ + "email": email, + } + + jsonData, err := json.Marshal(data) + if err != nil { + return nil, fmt.Errorf("error marshaling request password reset data: %w", err) + } + + result, err := a.client.makeRequest("POST", "request_password_reset", bytes.NewBuffer(jsonData), "application/json") + if err != nil { + return nil, err + } + + stats, ok := result.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("unexpected response type: expected map[string]interface{}, got %T", result) + } + + return stats, nil +} + +// ConfirmPasswordReset confirms a password reset for the user with the given reset token. +// +// Parameters: +// +// resetToken: The reset token to confirm the password reset with. +// newPassword: The new password to set for the user. +// +// Returns: +// +// A map containing the response from the server. +// An error if the request fails, nil otherwise. +func (a *Auth) ConfirmPasswordReset(resetToken, newPassword string) (map[string]interface{}, error) { + data := map[string]string{ + "reset_token": resetToken, + "new_password": newPassword, + } + + jsonData, err := json.Marshal(data) + if err != nil { + return nil, fmt.Errorf("error marshaling confirm password reset data: %w", err) + } + + result, err := a.client.makeRequest("POST", "reset_password", bytes.NewBuffer(jsonData), "application/json") + if err != nil { + return nil, err + } + + response, ok := result.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("unexpected response type: expected map[string]interface{}, got %T", result) + } + + return response, nil +} + +// DeleteUser deletes the user with the given user ID. +// +// Parameters: +// +// userID: The ID of the user to delete. +// password: The password of the user to delete (optional). +// +// Returns: +// +// A map containing the response from the server. +// An error if the request fails, nil otherwise. +func (a *Auth) DeleteUser(userID string, password *string) (map[string]interface{}, error) { + data := map[string]interface{}{ + "user_id": userID, + } + if password != nil { + data["password"] = *password + } + + jsonData, err := json.Marshal(data) + if err != nil { + return nil, fmt.Errorf("error marshaling delete user data: %w", err) + } + + result, err := a.client.makeRequest("DELETE", "user", bytes.NewBuffer(jsonData), "application/json") + if err != nil { + return nil, err + } + + response, ok := result.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("unexpected response type: expected map[string]interface{}, got %T", result) + } + + a.client.AccessToken = "" + a.client.RefreshToken = "" + + return response, nil +} diff --git a/r2r_go_sdk/pkg/sdk/client.go b/r2r_go_sdk/pkg/sdk/client.go new file mode 100644 index 000000000..477b861b3 --- /dev/null +++ b/r2r_go_sdk/pkg/sdk/client.go @@ -0,0 +1,110 @@ +package sdk + +import ( + "encoding/json" + "fmt" + "io" + "log" + "net/http" + "os" + "strings" +) + +type LogConfig struct { + Verbose bool + LogWriter io.Writer +} + +type Client struct { + BaseURL string + HTTPClient *http.Client + LogConfig LogConfig + logger *log.Logger + AccessToken string + RefreshToken string + *Auth + *Ingestion + *Management + *Restructure + *Retrieval +} + +func (c *Client) log(level string, format string, v ...interface{}) { + if !c.LogConfig.Verbose { + return + } + + message := fmt.Sprintf(format, v...) + c.logger.Printf("[%s] %s", level, message) +} + +func NewClient(baseURL string, logConfig LogConfig) *Client { + if logConfig.LogWriter == nil { + logConfig.LogWriter = os.Stdout + } + + c := &Client{ + BaseURL: baseURL, + HTTPClient: &http.Client{}, + LogConfig: logConfig, + logger: log.New(logConfig.LogWriter, "", log.Ldate|log.Ltime), + } + c.Auth = &Auth{client: c} + c.Ingestion = &Ingestion{client: c} + c.Management = &Management{client: c} + c.Restructure = &Restructure{client: c} + c.Retrieval = &Retrieval{client: c} + return c +} + +func (c *Client) makeRequest(method, endpoint string, body io.Reader, contentType string) (interface{}, error) { + c.log("INFO", "Making request: %s %s", method, endpoint) + url := fmt.Sprintf("%s/%s", c.BaseURL, endpoint) + + req, err := http.NewRequest(method, url, body) + if err != nil { + return nil, err + } + + req.Header.Set("Content-Type", contentType) + + if c.AccessToken != "" { + req.Header.Set("Authorization", "Bearer "+c.AccessToken) + } + + resp, err := c.HTTPClient.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + c.log("ERROR", "API request failed with status code: %d", resp.StatusCode) + return nil, fmt.Errorf("API request failed with status code: %d", resp.StatusCode) + } + + if strings.HasPrefix(resp.Header.Get("Content-Type"), "application/json") { + var result interface{} + err = json.NewDecoder(resp.Body).Decode(&result) + if err != nil { + return nil, err + } + return result, nil + } else { + // For streaming responses or non-JSON content + return resp.Body, nil + } +} + +func (c *Client) SetAccessToken(token string) { + c.AccessToken = token +} + +func (c *Client) SetRefreshToken(token string) { + c.RefreshToken = token +} + +func (c *Client) ClearTokens() { + c.AccessToken = "" + c.RefreshToken = "" +} diff --git a/r2r_go_sdk/pkg/sdk/ingestion.go b/r2r_go_sdk/pkg/sdk/ingestion.go new file mode 100644 index 000000000..d6a77ad38 --- /dev/null +++ b/r2r_go_sdk/pkg/sdk/ingestion.go @@ -0,0 +1,189 @@ +package sdk + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "mime/multipart" + "os" + "path/filepath" +) + +type Ingestion struct { + client *Client +} + +// IngestFiles ingests files into your R2R deployment. +// +// Parameters: +// +// filePaths: List of file paths to ingest. +// metadatas: List of metadata dictionaries for each file. +// documentIDs: List of document IDs. +// versions: List of version strings for each file. +// chunkingConfigOverride: Custom chunking configuration. +// +// Returns: +// +// A map containing the response from the server. +// An error if the request fails, nil otherwise. +func (i *Ingestion) IngestFiles( + filePaths []string, + metadatas []map[string]interface{}, + documentIDs []string, + versions []string, + chunkingConfigOverride map[string]interface{}, +) (map[string]interface{}, error) { + body := &bytes.Buffer{} + writer := multipart.NewWriter(body) + + for _, path := range filePaths { + file, err := os.Open(path) + if err != nil { + return nil, fmt.Errorf("error opening file %s: %w", path, err) + } + defer file.Close() + + part, err := writer.CreateFormFile("files", filepath.Base(path)) + if err != nil { + return nil, fmt.Errorf("error creating form file: %w", err) + } + _, err = io.Copy(part, file) + if err != nil { + return nil, fmt.Errorf("error copying file content: %w", err) + } + } + + if metadatas != nil { + metadatasJSON, err := json.Marshal(metadatas) + if err != nil { + return nil, fmt.Errorf("error marshaling metadatas: %w", err) + } + writer.WriteField("metadatas", string(metadatasJSON)) + } + + if documentIDs != nil { + documentIDsJSON, err := json.Marshal(documentIDs) + if err != nil { + return nil, fmt.Errorf("error marshaling document IDs: %w", err) + } + writer.WriteField("document_ids", string(documentIDsJSON)) + } + + if versions != nil { + versionsJSON, err := json.Marshal(versions) + if err != nil { + return nil, fmt.Errorf("error marshaling versions: %w", err) + } + writer.WriteField("versions", string(versionsJSON)) + } + + if chunkingConfigOverride != nil { + chunkingConfigJSON, err := json.Marshal(chunkingConfigOverride) + if err != nil { + return nil, fmt.Errorf("error marshaling chunking config: %w", err) + } + writer.WriteField("chunking_config_override", string(chunkingConfigJSON)) + } + + err := writer.Close() + if err != nil { + return nil, fmt.Errorf("error closing multipart writer: %w", err) + } + + result, err := i.client.makeRequest("POST", "ingest_files", body, writer.FormDataContentType()) + if err != nil { + return nil, err + } + + stats, ok := result.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("unexpected response type: expected map[string]interface{}, got %T", result) + } + + return stats, nil +} + +// UpdateFiles updates existing files in your R2R deployment. +// +// Parameters: +// +// filePaths: List of file paths to update. +// documentIDs: List of document IDs. +// metadatas: List of metadata dictionaries for each file. +// chunkingConfigOverride: Custom chunking configuration. +// +// Returns: +// +// A map containing the response from the server. +// An error if the request fails, nil otherwise. +func (i *Ingestion) UpdateFiles( + filePaths []string, + documentIDs []string, + metadatas []map[string]interface{}, + chunkingConfigOverride map[string]interface{}, +) (map[string]interface{}, error) { + if len(filePaths) != len(documentIDs) { + return nil, fmt.Errorf("number of file paths must match number of document IDs") + } + + body := &bytes.Buffer{} + writer := multipart.NewWriter(body) + + for _, path := range filePaths { + file, err := os.Open(path) + if err != nil { + return nil, fmt.Errorf("error opening file %s: %w", path, err) + } + defer file.Close() + + part, err := writer.CreateFormFile("files", filepath.Base(path)) + if err != nil { + return nil, fmt.Errorf("error creating form file: %w", err) + } + _, err = io.Copy(part, file) + if err != nil { + return nil, fmt.Errorf("error copying file content: %w", err) + } + } + + documentIDsJSON, err := json.Marshal(documentIDs) + if err != nil { + return nil, fmt.Errorf("error marshaling document IDs: %w", err) + } + writer.WriteField("document_ids", string(documentIDsJSON)) + + if metadatas != nil { + metadatasJSON, err := json.Marshal(metadatas) + if err != nil { + return nil, fmt.Errorf("error marshaling metadatas: %w", err) + } + writer.WriteField("metadatas", string(metadatasJSON)) + } + + if chunkingConfigOverride != nil { + chunkingConfigJSON, err := json.Marshal(chunkingConfigOverride) + if err != nil { + return nil, fmt.Errorf("error marshaling chunking config: %w", err) + } + writer.WriteField("chunking_config_override", string(chunkingConfigJSON)) + } + + err = writer.Close() + if err != nil { + return nil, fmt.Errorf("error closing multipart writer: %w", err) + } + + result, err := i.client.makeRequest("POST", "update_files", body, writer.FormDataContentType()) + if err != nil { + return nil, err + } + + stats, ok := result.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("unexpected response type: expected map[string]interface{}, got %T", result) + } + + return stats, nil +} diff --git a/r2r_go_sdk/pkg/sdk/management.go b/r2r_go_sdk/pkg/sdk/management.go new file mode 100644 index 000000000..19c9c15ca --- /dev/null +++ b/r2r_go_sdk/pkg/sdk/management.go @@ -0,0 +1,904 @@ +package sdk + +import ( + "bytes" + "encoding/json" + "fmt" + "net/url" + "strconv" +) + +type Management struct { + client *Client +} + +// ServerStats gets statistics about the server, including the start time, uptime, CPU usage, and memory usage. +// +// Returns: +// +// A map containing the response from the server. +// An error if the request fails, nil otherwise. +func (m *Management) ServerStats() (map[string]interface{}, error) { + result, err := m.client.makeRequest("GET", "server_stats", nil, "application/json") + if err != nil { + return nil, err + } + + stats, ok := result.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("unexpected response type: expected map[string]interface{}, got %T", result) + } + + return stats, nil +} + +// UpdatePrompt updates a prompt in the database. +// +// Parameters: +// +// name: The name of the prompt to update. +// template: The new template for the prompt. +// inputTypes: The new input types for the prompt. +// +// Returns: +// +// A map containing the response from the server. +// An error if the request fails, nil otherwise. +func (m *Management) UpdatePrompt(name string, template *string, inputTypes map[string]string) (map[string]interface{}, error) { + data := map[string]interface{}{ + "name": name, + } + + if template != nil { + data["template"] = *template + } + if inputTypes != nil { + data["input_types"] = inputTypes + } + + jsonData, err := json.Marshal(data) + if err != nil { + return nil, err + } + + result, err := m.client.makeRequest("POST", "update_prompt", bytes.NewBuffer(jsonData), "application/json") + if err != nil { + return nil, err + } + + stats, ok := result.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("unexpected response type: expected map[string]interface{}, got %T", result) + } + + return stats, nil +} + +// Analytics gets analytics data from the server. +// +// Parameters: +// +// filterCriteria: The filter criteria to use. +// analysisTypes: The types of analysis to perform. +// +// Returns: +// +// A map containing the analytics data from the server. +// An error if the request fails, nil otherwise. +func (m *Management) Analytics(filterCriteria, analysisTypes interface{}) (map[string]interface{}, error) { + params := url.Values{} + + if filterCriteria != nil { + switch fc := filterCriteria.(type) { + case map[string]interface{}: + jsonFC, err := json.Marshal(fc) + if err != nil { + return nil, fmt.Errorf("error marshaling filter criteria: %w", err) + } + params.Set("filter_criteria", string(jsonFC)) + case string: + params.Set("filter_criteria", fc) + default: + return nil, fmt.Errorf("unsupported type for filter criteria: %T", filterCriteria) + } + } + + if analysisTypes != nil { + switch at := analysisTypes.(type) { + case map[string]interface{}: + jsonAT, err := json.Marshal(at) + if err != nil { + return nil, fmt.Errorf("error marshaling analysis types: %w", err) + } + params.Set("analysis_types", string(jsonAT)) + case string: + params.Set("analysis_types", at) + default: + return nil, fmt.Errorf("unsupported type for analysis types: %T", analysisTypes) + } + } + + endpoint := "analytics" + if len(params) > 0 { + endpoint += "?" + params.Encode() + } + + result, err := m.client.makeRequest("GET", endpoint, nil, "application/json") + if err != nil { + return nil, err + } + + analytics, ok := result.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("unexpected response type: expected map[string]interface{}, got %T", result) + } + + return analytics, nil +} + +// Logs gets logs from the server. +// +// Parameters: +// +// runTypeFilter: The run type to filter by. +// maxRuns: Specifies the maximum number of runs to return. Values outside the range of 1 to 1000 will be adjusted to the nearest valid value with a default of 100. +// +// Returns: +// +// A map containing the response from the server. +// An error if the request fails, nil otherwise. +func (m *Management) Logs(runTypeFilter *string, maxRuns *int) (map[string]interface{}, error) { + params := make(map[string]interface{}) + + if runTypeFilter != nil { + params["run_type_filter"] = *runTypeFilter + } + + if maxRuns != nil { + params["max_runs"] = *maxRuns + } + + values := url.Values{} + for key, value := range params { + values.Add(key, fmt.Sprintf("%v", value)) + } + + endpoint := fmt.Sprintf("logs?%s", values.Encode()) + + result, err := m.client.makeRequest("GET", endpoint, nil, "application/json") + if err != nil { + return nil, err + } + + stats, ok := result.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("unexpected response type: expected map[string]interface{}, got %T", result) + } + + return stats, nil +} + +// AppSettings gets the configuration settings for the app. +// +// Returns: +// +// A map containing the response from the server. +// An error if the request fails, nil otherwise. +func (m *Management) AppSettings() (map[string]interface{}, error) { + result, err := m.client.makeRequest("GET", "app_settings", nil, "application/json") + if err != nil { + return nil, err + } + + stats, ok := result.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("unexpected response type: expected map[string]interface{}, got %T", result) + } + + return stats, nil +} + +// ScoreCompletion assigns a score to a message from an LLM completion. The score should be a float between -1.0 and 1.0. +// +// Parameters: +// +// messageID: The ID of the message to score. +// score: The score to assign to the message. +// +// Returns: +// +// A map containing the response from the server. +// An error if the request fails, nil otherwise. +func (m *Management) ScoreCompletion(messageID string, score *float32) (map[string]interface{}, error) { + data := map[string]interface{}{ + "message_id": messageID, + } + + if score != nil { + data["score"] = *score + } + + jsonData, err := json.Marshal(data) + if err != nil { + return nil, err + } + + result, err := m.client.makeRequest("POST", "score_completion", bytes.NewBuffer(jsonData), "application/json") + if err != nil { + return nil, err + } + + stats, ok := result.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("unexpected response type: expected map[string]interface{}, got %T", result) + } + + return stats, nil +} + +// UsersOverview get an overview of the users in the R2R deployment. +// +// Parameters: +// +// userIds: A list of user IDs to get an overview for. +// +// Returns: +// +// A map containing the response from the server. +// An error if the request fails, nil otherwise. +func (m *Management) UsersOverview(userIds []string) (map[string]interface{}, error) { + values := url.Values{} + + if len(userIds) > 0 { + for _, id := range userIds { + values.Add("user_ids", id) + } + } + + endpoint := "users_overview" + if len(values) > 0 { + endpoint += "?" + values.Encode() + } + + result, err := m.client.makeRequest("GET", endpoint, nil, "application/json") + if err != nil { + return nil, err + } + + stats, ok := result.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("unexpected response type: expected map[string]interface{}, got %T", result) + } + + return stats, nil +} + +// Delete deletes data from the database given a set of filters. +// +// Parameters: +// +// filters: A map of filters to delete by. +func (m *Management) Delete(filters map[string]string) (map[string]interface{}, error) { + filtersJSON, err := json.Marshal(filters) + if err != nil { + return nil, fmt.Errorf("error marshaling filters: %w", err) + } + + values := url.Values{} + values.Add("filters", string(filtersJSON)) + + endpoint := "delete?" + values.Encode() + + result, err := m.client.makeRequest("DELETE", endpoint, nil, "application/json") + if err != nil { + return nil, err + } + + stats, ok := result.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("unexpected response type: expected map[string]interface{}, got %T", result) + } + + return stats, nil +} + +// DocumentsOverview gets an overview of documents in the R2R deployment. +// +// Parameters: +// +// documentIDs: A list of document IDs to get an overview for. +// +// Returns: +// +// A map containing the response from the server. +// An error if the request fails, nil otherwise. +func (m *Management) DocumentsOverview(userIDs []string) (map[string]interface{}, error) { + values := url.Values{} + + addIDsToValues := func(key string, ids []string) { + for _, id := range ids { + values.Add(key, id) + } + } + + if len(userIDs) > 0 { + addIDsToValues("user_ids", userIDs) + } + + endpoint := "documents_overview" + if len(values) > 0 { + endpoint += "?" + values.Encode() + } + + result, err := m.client.makeRequest("GET", endpoint, nil, "application/json") + if err != nil { + return nil, err + } + + stats, ok := result.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("unexpected response type: expected map[string]interface{}, got %T", result) + } + + return stats, nil + +} + +// DocumentChunks gets the chunks for a document. +// +// Parameters: +// +// documentID: The ID of the document to get chunks for. +// +// Returns: +// +// A map containing the response from the server. +// An error if the request fails, nil otherwise. +func (m *Management) DocumentChunks(documentID string) (map[string]interface{}, error) { + endpoint := fmt.Sprintf("document_chunks?document_id=%s", documentID) + + result, err := m.client.makeRequest("GET", endpoint, nil, "application/json") + if err != nil { + return nil, err + } + + stats, ok := result.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("unexpected response type: expected map[string]interface{}, got %T", result) + } + + return stats, nil +} + +// InspectKnowledgeGraph inspects the knowledge graph associated with your R2R deployment. +// +// Parameters: +// +// limit: The maximum number of nodes to return. Defaults to 100. +// +// Returns: +// +// A map containing the response from the server. +func (m *Management) InspectKnowledgeGraph(limit *int) (map[string]interface{}, error) { + values := url.Values{} + + if limit != nil { + values.Set("limit", strconv.Itoa(*limit)) + } + + endpoint := "inspect_knowledge_graph" + if len(values) > 0 { + endpoint += "?" + values.Encode() + } + + result, err := m.client.makeRequest("GET", endpoint, nil, "application/json") + if err != nil { + return nil, err + } + + stats, ok := result.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("unexpected response type: expected map[string]interface{}, got %T", result) + } + + return stats, nil +} + +// GroupsOverview gets an overview of existing groups. +// +// Parameters: +// +// groupIDs: A list of group IDs to get an overview for. +// limit: The maximum number of groups to return. +// offset: The offset to start at. +// +// Returns: +// +// A map containing the response from the server. +// An error if the request fails, nil otherwise. +func (m *Management) GroupsOverview(groupIDs []string, limit, offset *int) (map[string]interface{}, error) { + params := url.Values{} + + if len(groupIDs) > 0 { + for _, id := range groupIDs { + params.Add("group_ids", id) + } + } + if limit != nil { + params.Set("limit", strconv.Itoa(*limit)) + } + if offset != nil { + params.Set("offset", strconv.Itoa(*offset)) + } + + endpoint := "groups_overview" + if len(params) > 0 { + endpoint += "?" + params.Encode() + } + + result, err := m.client.makeRequest("GET", endpoint, nil, "application/json") + if err != nil { + return nil, err + } + + stats, ok := result.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("unexpected response type: expected map[string]interface{}, got %T", result) + } + + return stats, nil +} + +// CreateGroup creates a new group. +// +// Parameters: +// +// name: The name of the group to create. +// description: The description of the group to create. +// +// Returns: +// +// A map containing the response from the server. +// An error if the request fails, nil otherwise. +func (m *Management) CreateGroup(name string, description *string) (map[string]interface{}, error) { + data := map[string]interface{}{ + "name": name, + } + if description != nil { + data["description"] = *description + } + + jsonData, err := json.Marshal(data) + if err != nil { + return nil, fmt.Errorf("error marshaling request data: %w", err) + } + + result, err := m.client.makeRequest("POST", "create_group", bytes.NewBuffer(jsonData), "application/json") + if err != nil { + return nil, err + } + + stats, ok := result.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("unexpected response type: expected map[string]interface{}, got %T", result) + } + + return stats, nil +} + +// GetGroup gets a group by its ID. +// +// Parameters: +// +// groupID: The ID of the group to get. +// +// Returns: +// +// A map containing the response from the server. +// An error if the request fails, nil otherwise. +func (m *Management) GetGroup(groupID string) (map[string]interface{}, error) { + endpoint := fmt.Sprintf("get_group/%s", url.PathEscape(groupID)) + + result, err := m.client.makeRequest("GET", endpoint, nil, "application/json") + if err != nil { + return nil, err + } + + stats, ok := result.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("unexpected response type: expected map[string]interface{}, got %T", result) + } + + return stats, nil +} + +// UpdateGroup updates the name and description of a group. +// +// Parameters: +// +// groupID: The ID of the group to update. +// name: The new name for the group. +// description: The new description for the group. +// +// Returns: +// +// A map containing the response from the server. +// An error if the request fails, nil otherwise. +func (m *Management) UpdateGroup(groupID string, name, description *string) (map[string]interface{}, error) { + data := map[string]interface{}{ + "group_id": groupID, + } + if name != nil { + data["name"] = *name + } + if description != nil { + data["description"] = *description + } + + jsonData, err := json.Marshal(data) + if err != nil { + return nil, fmt.Errorf("error marshaling request data: %w", err) + } + + result, err := m.client.makeRequest("PUT", "update_group", bytes.NewBuffer(jsonData), "application/json") + if err != nil { + return nil, err + } + + stats, ok := result.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("unexpected response type: expected map[string]interface{}, got %T", result) + } + + return stats, nil +} + +// DeleteGroup deletes a group by its ID. +// +// Parameters: +// +// groupID: The ID of the group to delete. +// +// Returns: +// +// A map containing the response from the server. +// An error if the request fails, nil otherwise. +func (m *Management) DeleteGroup(groupID string) (map[string]interface{}, error) { + endpoint := fmt.Sprintf("delete_group/%s", url.PathEscape(groupID)) + + result, err := m.client.makeRequest("DELETE", endpoint, nil, "application/json") + if err != nil { + return nil, err + } + + stats, ok := result.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("unexpected response type: expected map[string]interface{}, got %T", result) + } + + return stats, nil +} + +// ListGroups lists all groups in the R2R deployment. +// +// Parameters: +// +// offset: The offset to start at. +// limit: The maximum number of groups to return. +// +// Returns: +// +// A map containing the response from the server. +// An error if the request fails, nil otherwise. +func (m *Management) ListGroups(offset, limit *int) (map[string]interface{}, error) { + params := url.Values{} + if offset != nil { + params.Set("offset", strconv.Itoa(*offset)) + } + if limit != nil { + params.Set("limit", strconv.Itoa(*limit)) + } + + endpoint := "list_groups" + if len(params) > 0 { + endpoint += "?" + params.Encode() + } + + result, err := m.client.makeRequest("GET", endpoint, nil, "application/json") + if err != nil { + return nil, err + } + + stats, ok := result.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("unexpected response type: expected map[string]interface{}, got %T", result) + } + + return stats, nil +} + +// AddUserToGroup adds a user to a group. +// +// Parameters: +// +// userID: The ID of the user to add. +// groupID: The ID of the group to add the user to. +// +// Returns: +// +// A map containing the response from the server. +// An error if the request fails, nil otherwise. +func (m *Management) AddUserToGroup(userID, groupID string) (map[string]interface{}, error) { + data := map[string]string{ + "user_id": userID, + "group_id": groupID, + } + + jsonData, err := json.Marshal(data) + if err != nil { + return nil, fmt.Errorf("error marshaling request data: %w", err) + } + + result, err := m.client.makeRequest("POST", "add_user_to_group", bytes.NewBuffer(jsonData), "application/json") + if err != nil { + return nil, err + } + + stats, ok := result.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("unexpected response type: expected map[string]interface{}, got %T", result) + } + + return stats, nil +} + +// RemoveUserFromGroup removes a user from a group. +// +// Parameters: +// +// userID: The ID of the user to remove. +// groupID: The ID of the group to remove the user from. +// +// Returns: +// +// A map containing the response from the server. +// An error if the request fails, nil otherwise. +func (m *Management) RemoveUserFromGroup(userID, groupID string) (map[string]interface{}, error) { + data := map[string]string{ + "user_id": userID, + "group_id": groupID, + } + + jsonData, err := json.Marshal(data) + if err != nil { + return nil, fmt.Errorf("error marshaling request data: %w", err) + } + + result, err := m.client.makeRequest("POST", "remove_user_from_group", bytes.NewBuffer(jsonData), "application/json") + if err != nil { + return nil, err + } + + stats, ok := result.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("unexpected response type: expected map[string]interface{}, got %T", result) + } + + return stats, nil +} + +// GetUsersInGroup gets all users in a group. +// +// Parameters: +// +// groupID: The ID of the group to get users for. +// offset: The offset to start at. +// limit: The maximum number of users to return. +// +// Returns: +// +// A map containing the response from the server. +// An error if the request fails, nil otherwise. +func (m *Management) GetUsersInGroup(groupID string, offset, limit *int) (map[string]interface{}, error) { + params := url.Values{} + + if offset != nil { + params.Set("offset", strconv.Itoa(*offset)) + } + if limit != nil { + params.Set("limit", strconv.Itoa(*limit)) + } + + endpoint := fmt.Sprintf("get_users_in_group/%s", url.PathEscape(groupID)) + if len(params) > 0 { + endpoint += "?" + params.Encode() + } + + result, err := m.client.makeRequest("GET", endpoint, nil, "application/json") + if err != nil { + return nil, err + } + + stats, ok := result.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("unexpected response type: expected map[string]interface{}, got %T", result) + } + + return stats, nil +} + +// GetGroupsForUser gets all groups a user is in. +// +// Parameters: +// +// userID: The ID of the user to get groups for. +// +// Returns: +// +// A map containing the response from the server. +// An error if the request fails, nil otherwise. +func (m *Management) GetGroupsForUser(userID string) (map[string]interface{}, error) { + endpoint := fmt.Sprintf("get_groups_for_user/%s", url.PathEscape(userID)) + + result, err := m.client.makeRequest("GET", endpoint, nil, "application/json") + if err != nil { + return nil, err + } + + stats, ok := result.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("unexpected response type: expected map[string]interface{}, got %T", result) + } + + return stats, nil +} + +// AssignDocumentToGroup assigns a document to a group. +// +// Parameters: +// +// documentID: The ID of the document to assign. +// groupID: The ID of the group to assign the document to. +// +// Returns: +// +// A map containing the response from the server. +// An error if the request fails, nil otherwise. +func (m *Management) AssignDocumentToGroup(documentID string, groupId string) (map[string]interface{}, error) { + data := map[string]string{ + "document_id": documentID, + "group_id": groupId, + } + + jsonData, err := json.Marshal(data) + if err != nil { + return nil, err + } + + result, err := m.client.makeRequest("POST", "assign_document_to_group", bytes.NewBuffer(jsonData), "application/json") + if err != nil { + return nil, err + } + + stats, ok := result.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("unexpected response type: expected map[string]interface{}, got %T", result) + } + + return stats, nil +} + +// RemoveDocumentFromGroup removes a document from a group. +// +// Parameters: +// +// documentID: The ID of the document to remove. +// groupID: The ID of the group to remove the document from. +// +// Returns: +// +// A map containing the response from the server. +// An error if the request fails, nil otherwise. +func (m *Management) RemoveDocumentFromGroup(documentID string, groupId string) (map[string]interface{}, error) { + data := map[string]string{ + "document_id": documentID, + "group_id": groupId, + } + + jsonData, err := json.Marshal(data) + if err != nil { + return nil, err + } + + result, err := m.client.makeRequest("POST", "remove_document_from_group", bytes.NewBuffer(jsonData), "application/json") + if err != nil { + return nil, err + } + + stats, ok := result.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("unexpected response type: expected map[string]interface{}, got %T", result) + } + + return stats, nil +} + +// GetDocumentGroups gets all groups that a document is assigned to. +// +// Parameters: +// +// documentID: The ID of the document to get groups for. +// +// Returns: +// +// A map containing the response from the server. +// An error if the request fails, nil otherwise. +func (m *Management) GetDocumentGroups(documentID string) (map[string]interface{}, error) { + endpoint := fmt.Sprintf("get_document_groups/%s", url.PathEscape(documentID)) + + result, err := m.client.makeRequest("GET", endpoint, nil, "application/json") + if err != nil { + return nil, err + } + + stats, ok := result.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("unexpected response type: expected map[string]interface{}, got %T", result) + } + + return stats, nil +} + +// GetDocumentsInGroup gets all documents in a group. +// +// Parameters: +// +// groupID: The ID of the group to get documents for. +// offset: The offset to start listing documents from. +// limit: The maximum number of documents to return. +// +// Returns: +// +// A map containing the response from the server. +// An error if the request fails, nil otherwise. +func (m *Management) GetDocumentsInGroup(groupID string, offset, limit *int) (map[string]interface{}, error) { + params := url.Values{} + + if offset != nil { + params.Set("offset", strconv.Itoa(*offset)) + } + if limit != nil { + params.Set("limit", strconv.Itoa(*limit)) + } + + endpoint := fmt.Sprintf("group/%s/documents", url.PathEscape(groupID)) + if len(params) > 0 { + endpoint += "?" + params.Encode() + } + + result, err := m.client.makeRequest("GET", endpoint, nil, "application/json") + if err != nil { + return nil, err + } + + stats, ok := result.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("unexpected response type: expected map[string]interface{}, got %T", result) + } + + return stats, nil +} + +func (m *Management) Health() (map[string]interface{}, error) { + result, err := m.client.makeRequest("GET", "health", nil, "application/json") + if err != nil { + return nil, err + } + + stats, ok := result.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("unexpected response type: expected map[string]interface{}, got %T", result) + } + + return stats, nil +} diff --git a/r2r_go_sdk/pkg/sdk/restructure.go b/r2r_go_sdk/pkg/sdk/restructure.go new file mode 100644 index 000000000..f6f398914 --- /dev/null +++ b/r2r_go_sdk/pkg/sdk/restructure.go @@ -0,0 +1,22 @@ +package sdk + +import "fmt" + +type Restructure struct { + client *Client +} + +func (rs *Restructure) EnrichGraph() (map[string]interface{}, error) { + + result, err := rs.client.makeRequest("POST", "enrich_graph", nil, "application/json") + if err != nil { + return nil, err + } + + stats, ok := result.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("unexpected response type: expected map[string]interface{}, got %T", result) + } + + return stats, nil +} diff --git a/r2r_go_sdk/pkg/sdk/retrieval.go b/r2r_go_sdk/pkg/sdk/retrieval.go new file mode 100644 index 000000000..6e90a6533 --- /dev/null +++ b/r2r_go_sdk/pkg/sdk/retrieval.go @@ -0,0 +1,352 @@ +package sdk + +import ( + "bufio" + "bytes" + "encoding/json" + "fmt" + "io" +) + +type Retrieval struct { + client *Client +} + +type VectorSearchResult struct { + FragmentID string `json:"fragment_id"` + ExtractionID string `json:"extraction_id"` + DocumentID string `json:"document_id"` + UserID string `json:"user_id"` + GroupIDs []string `json:"group_ids"` + Score float64 `json:"score"` + Text string `json:"text"` + Metadata map[string]interface{} `json:"metadata"` +} + +type KGSearchResult [][]interface{} + +type SearchResponse struct { + VectorSearchResults []VectorSearchResult `json:"vector_search_results"` + KGSearchResults *KGSearchResult `json:"kg_search_results,omitempty"` +} + +type RAGResponse struct { + Completion map[string]interface{} `json:"completion"` + SearchResults SearchResponse `json:"search_results"` +} + +type VectorSearchSettings struct { + UseVectorSearch bool `json:"use_vector_search"` + Filters map[string]interface{} `json:"filters"` + SearchLimit int `json:"search_limit"` + DoHybridSearch bool `json:"do_hybrid_search"` + SelectedGroupIDs []string `json:"selected_group_ids"` +} + +type KGSearchSettings struct { + UseKGSearch bool `json:"use_kg_search"` + KGSearchType string `json:"kg_search_type"` + KGSearchLevel *int `json:"kg_search_level,omitempty"` + KGSearchGenerationConfig *GenerationConfig `json:"kg_search_generation_config,omitempty"` + EntityTypes []string `json:"entity_types"` + Relationships []string `json:"relationships"` + MaxCommunityDescriptionLength int `json:"max_community_description_length"` + MaxLLMQueriesForGlobalSearch int `json:"max_llm_queries_for_global_search"` + LocalSearchLimits map[string]int `json:"local_search_limits"` +} + +type GenerationConfig struct { + Model string `json:"model"` + Temperature float64 `json:"temperature"` + TopP float64 `json:"top_p"` + MaxTokensToSample int `json:"max_tokens_to_sample"` + Stream bool `json:"stream"` + Functions *[]map[string]interface{} `json:"functions,omitempty"` + Tools *[]map[string]interface{} `json:"tools,omitempty"` + AddGenerationKwargs *map[string]interface{} `json:"add_generation_kwargs,omitempty"` + APIBase *string `json:"api_base,omitempty"` +} + +type Message struct { + Role string `json:"role"` + Content *string `json:"content,omitempty"` + Name *string `json:"name,omitempty"` + FunctionCall *map[string]interface{} `json:"function_call,omitempty"` + ToolCalls *[]map[string]interface{} `json:"tool_calls,omitempty"` +} + +// Search conducts a vector and/or KG search. +// +// Parameters: +// +// query: The query to search for. +// vectorSearchSettings: Vector search settings. +// kgSearchSettings: KG search settings. +// +// Returns: +// +// A map containing the response from the server. +// An error if the request fails, nil otherwise. +func (r *Retrieval) Search(query string, vectorSearchSettings *VectorSearchSettings, kgSearchSettings *KGSearchSettings) (*SearchResponse, error) { + data := map[string]interface{}{ + "query": query, + } + + if vectorSearchSettings != nil { + data["vector_search_settings"] = vectorSearchSettings + } + if kgSearchSettings != nil { + data["kg_search_settings"] = kgSearchSettings + } + + jsonData, err := json.Marshal(data) + if err != nil { + return nil, fmt.Errorf("error marshaling search data: %w", err) + } + + result, err := r.client.makeRequest("POST", "search", bytes.NewReader(jsonData), "application/json") + if err != nil { + return nil, err + } + + var searchResponse SearchResponse + resultJSON, err := json.Marshal(result) + if err != nil { + return nil, fmt.Errorf("error marshaling result to JSON: %w", err) + } + if err := json.Unmarshal(resultJSON, &searchResponse); err != nil { + return nil, fmt.Errorf("error unmarshaling search response: %w", err) + } + + return &searchResponse, nil +} + +// RAG conducts a Retrieval Augmented Generation (RAG) search with the given query. +// +// Parameters: +// +// query: The query to search for. +// ragGenerationConfig: RAG generation configuration. +// vectorSearchSettings: Vector search settings. +// kgSearchSettings: KG search settings. +// +// Returns: +// +// A map containing the response from the server. +// An error if the request fails, nil otherwise. +func (r *Retrieval) RAG(query string, ragGenerationConfig GenerationConfig, vectorSearchSettings *VectorSearchSettings, kgSearchSettings *KGSearchSettings) (*RAGResponse, error) { + data := map[string]interface{}{ + "query": query, + "rag_generation_config": ragGenerationConfig, + } + + if vectorSearchSettings != nil { + data["vector_search_settings"] = vectorSearchSettings + } + if kgSearchSettings != nil { + data["kg_search_settings"] = kgSearchSettings + } + + jsonData, err := json.Marshal(data) + if err != nil { + return nil, fmt.Errorf("error marshaling RAG data: %w", err) + } + + if ragGenerationConfig.Stream { + return nil, fmt.Errorf("use RAGStream for streaming responses") + } + + result, err := r.client.makeRequest("POST", "rag", bytes.NewReader(jsonData), "application/json") + if err != nil { + return nil, err + } + + var ragResponse RAGResponse + resultJSON, err := json.Marshal(result) + if err != nil { + return nil, fmt.Errorf("error marshaling result to JSON: %w", err) + } + if err := json.Unmarshal(resultJSON, &ragResponse); err != nil { + return nil, fmt.Errorf("error unmarshaling RAG response: %w", err) + } + + return &ragResponse, nil +} + +// RAGStream conducts a streaming Retrieval Augmented Generation (RAG) search with the given query. +func (r *Retrieval) RAGStream(query string, ragGenerationConfig GenerationConfig, vectorSearchSettings *VectorSearchSettings, kgSearchSettings *KGSearchSettings) (<-chan RAGResponse, <-chan error) { + responseChan := make(chan RAGResponse) + errChan := make(chan error, 1) + + go func() { + defer close(responseChan) + defer close(errChan) + + data := map[string]interface{}{ + "query": query, + "rag_generation_config": ragGenerationConfig, + } + + if vectorSearchSettings != nil { + data["vector_search_settings"] = vectorSearchSettings + } + if kgSearchSettings != nil { + data["kg_search_settings"] = kgSearchSettings + } + + jsonData, err := json.Marshal(data) + if err != nil { + errChan <- fmt.Errorf("error marshaling RAG data: %w", err) + return + } + + result, err := r.client.makeRequest("POST", "rag", bytes.NewReader(jsonData), "application/json") + if err != nil { + errChan <- err + return + } + + reader, ok := result.(io.Reader) + if !ok { + errChan <- fmt.Errorf("unexpected response type") + return + } + + scanner := bufio.NewScanner(reader) + for scanner.Scan() { + var ragResponse RAGResponse + if err := json.Unmarshal(scanner.Bytes(), &ragResponse); err != nil { + errChan <- fmt.Errorf("error unmarshaling RAG response: %w", err) + return + } + responseChan <- ragResponse + } + if err := scanner.Err(); err != nil { + errChan <- fmt.Errorf("error reading stream: %w", err) + } + }() + + return responseChan, errChan +} + +// Agent performs a single turn in a conversation with a RAG agent. +// +// Parameters: +// +// messages: The messages exchanged in the conversation so far. +// ragGenerationConfig: RAG generation configuration. +// vectorSearchSettings: Vector search settings. +// kgSearchSettings: KG search settings. +// taskPromptOverride: Task prompt override. +// includeTitleIfAvailable: Include title if available. +// +// Returns: +// +// A list of messages exchanged in the conversation. +// An error if the request fails, nil otherwise. +func (r *Retrieval) Agent(messages []Message, ragGenerationConfig GenerationConfig, vectorSearchSettings *VectorSearchSettings, kgSearchSettings *KGSearchSettings, taskPromptOverride *string, includeTitleIfAvailable *bool) ([]Message, error) { + data := map[string]interface{}{ + "messages": messages, + "rag_generation_config": ragGenerationConfig, + } + + if vectorSearchSettings != nil { + data["vector_search_settings"] = vectorSearchSettings + } + if kgSearchSettings != nil { + data["kg_search_settings"] = kgSearchSettings + } + if taskPromptOverride != nil { + data["task_prompt_override"] = *taskPromptOverride + } + if includeTitleIfAvailable != nil { + data["include_title_if_available"] = *includeTitleIfAvailable + } + + jsonData, err := json.Marshal(data) + if err != nil { + return nil, fmt.Errorf("error marshaling Agent data: %w", err) + } + + if ragGenerationConfig.Stream { + return nil, fmt.Errorf("use AgentStream for streaming responses") + } + + result, err := r.client.makeRequest("POST", "agent", bytes.NewReader(jsonData), "application/json") + if err != nil { + return nil, err + } + + var agentResponse []Message + resultJSON, err := json.Marshal(result) + if err != nil { + return nil, fmt.Errorf("error marshaling result to JSON: %w", err) + } + if err := json.Unmarshal(resultJSON, &agentResponse); err != nil { + return nil, fmt.Errorf("error unmarshaling Agent response: %w", err) + } + + return agentResponse, nil +} + +// AgentStream performs a streaming conversation turn with a RAG agent. +func (r *Retrieval) AgentStream(messages []Message, ragGenerationConfig GenerationConfig, vectorSearchSettings *VectorSearchSettings, kgSearchSettings *KGSearchSettings, taskPromptOverride *string, includeTitleIfAvailable *bool) (<-chan Message, <-chan error) { + responseChan := make(chan Message) + errChan := make(chan error, 1) + + go func() { + defer close(responseChan) + defer close(errChan) + + data := map[string]interface{}{ + "messages": messages, + "rag_generation_config": ragGenerationConfig, + } + + if vectorSearchSettings != nil { + data["vector_search_settings"] = vectorSearchSettings + } + if kgSearchSettings != nil { + data["kg_search_settings"] = kgSearchSettings + } + if taskPromptOverride != nil { + data["task_prompt_override"] = *taskPromptOverride + } + if includeTitleIfAvailable != nil { + data["include_title_if_available"] = *includeTitleIfAvailable + } + + jsonData, err := json.Marshal(data) + if err != nil { + errChan <- fmt.Errorf("error marshaling Agent data: %w", err) + return + } + + result, err := r.client.makeRequest("POST", "agent", bytes.NewReader(jsonData), "application/json") + if err != nil { + errChan <- err + return + } + + reader, ok := result.(io.Reader) + if !ok { + errChan <- fmt.Errorf("unexpected response type") + return + } + + scanner := bufio.NewScanner(reader) + for scanner.Scan() { + var message Message + if err := json.Unmarshal(scanner.Bytes(), &message); err != nil { + errChan <- fmt.Errorf("error unmarshaling Agent response: %w", err) + return + } + responseChan <- message + } + if err := scanner.Err(); err != nil { + errChan <- fmt.Errorf("error reading stream: %w", err) + } + }() + + return responseChan, errChan +} diff --git a/r2r_js_sdk/README.md b/r2r_js_sdk/README.md new file mode 100644 index 000000000..4cf1966fd --- /dev/null +++ b/r2r_js_sdk/README.md @@ -0,0 +1,148 @@ +

+ Docs + Discord + Github Stars + Commits-per-week + License: MIT + npm version +

+ +R2R JavaScript Client +

+The ultimate open source RAG answer engine - JavaScript Client +

+ +# About + +The official JavaScript client for R2R (Retrieval-Augmented Generation to Riches). R2R is designed to bridge the gap between local LLM experimentation and scalable, production-ready Retrieval-Augmented Generation (RAG). This JavaScript client provides a seamless interface to interact with the R2R RESTful API. + +For a more complete view of R2R, check out the [full documentation](https://r2r-docs.sciphi.ai/). + +## Key Features + +- **📁 Multimodal Support**: Ingest files ranging from `.txt`, `.pdf`, `.json` to `.png`, `.mp3`, and more. +- **🔍 Hybrid Search**: Combine semantic and keyword search with reciprocal rank fusion for enhanced relevancy. +- **🔗 Graph RAG**: Automatically extract relationships and build knowledge graphs. +- **🗂️ App Management**: Efficiently manage documents and users with rich observability and analytics. +- **🌐 Client-Server**: RESTful API support out of the box. +- **🧩 Configurable**: Provision your application using intuitive configuration files. +- **🔌 Extensible**: Develop your application further with easy builder + factory pattern. +- **🖥️ Dashboard**: Use the [R2R Dashboard](https://github.com/SciPhi-AI/R2R-Dashboard), an open-source React+Next.js app for a user-friendly interaction with R2R. + +## Table of Contents + +1. [Install](#install) +2. [R2R JavaScript Client Quickstart](#r2r-javascript-client-quickstart) +3. [Community and Support](#community-and-support) +4. [Contributing](#contributing) + +# Install + +```bash +npm install r2r-js +``` + +# R2R JavaScript Client Quickstart + +## Initialize the R2R client + +```javascript +const { r2rClient } = require("r2r-js"); + +const client = new r2rClient("http://localhost:8000"); +``` + +## Login + +```javascript +const EMAIL = "admin@example.com"; +const PASSWORD = "change_me_immediately"; +console.log("Logging in..."); +await client.login(EMAIL, PASSWORD); +``` + +## Ingest files + +```javascript +const files = [ + { path: "examples/data/raskolnikov.txt", name: "raskolnikov.txt" }, + { path: "examples/data/karamozov.txt", name: "karamozov.txt" }, +]; + +const ingestResult = await client.ingestFiles(files, { + metadatas: [{ title: "raskolnikov.txt" }, { title: "karamozov.txt" }], + user_ids: [ + "123e4567-e89b-12d3-a456-426614174000", + "123e4567-e89b-12d3-a456-426614174000", + ], + skip_document_info: false, +}); +console.log(ingestResult); +``` + +## Perform a search + +```javascript +const searchResult = await client.search("Who was Raskolnikov?"); +console.log(searchResult); +``` + +## Perform RAG + +```javascript +const ragResult = await client.rag({ + query: "Who was Raskolnikov?", + use_vector_search: true, + search_filters: {}, + search_limit: 10, + do_hybrid_search: false, + use_kg_search: false, + kg_generation_config: {}, + rag_generation_config: { + model: "gpt-4o", + temperature: 0.0, + stream: false, + }, +}); +console.log(ragResult); +``` + +## Stream a RAG Response + +```javascript +const streamingRagResult = await client.rag({ + query: "Who was Raskolnikov?", + rag_generation_config: { + stream: true, + }, +}); + +if (streamingRagResult instanceof ReadableStream) { + const reader = streamingRagResult.getReader(); + while (true) { + const { done, value } = await reader.read(); + if (done) break; + console.log(new TextDecoder().decode(value)); + } +} +``` + +# Community and Support + +- [Discord](https://discord.gg/p6KqD2kjtB): Chat live with maintainers and community members +- [Github Issues](https://github.com/SciPhi-AI/R2R-js/issues): Report bugs and request features + +**Explore our [R2R Docs](https://r2r-docs.sciphi.ai/) for tutorials and cookbooks on various R2R features and integrations.** + +# Contributing + +We welcome contributions of all sizes! Here's how you can help: + +- Open a PR for new features, improvements, or better documentation. +- Submit a [feature request](https://github.com/SciPhi-AI/R2R-js/issues/new?assignees=&labels=&projects=&template=feature_request.md&title=) or [bug report](https://github.com/SciPhi-AI/R2R-js/issues/new?assignees=&labels=&projects=&template=bug_report.md&title=) + +### Our Contributors + + + + diff --git a/r2r_js_sdk/__tests__/r2rClient.test.ts b/r2r_js_sdk/__tests__/r2rClient.test.ts new file mode 100644 index 000000000..38624504f --- /dev/null +++ b/r2r_js_sdk/__tests__/r2rClient.test.ts @@ -0,0 +1,43 @@ +import { r2rClient } from "../src/r2rClient"; +import axios from "axios"; + +jest.mock("axios"); + +describe("R2RClient", () => { + let client: r2rClient; + let mockAxiosInstance: any; + + beforeEach(() => { + mockAxiosInstance = { + post: jest.fn(), + request: jest.fn(), + defaults: { baseURL: "http://0.0.0.0:8000/v1" }, + }; + + (axios.create as jest.Mock).mockReturnValue(mockAxiosInstance); + + client = new r2rClient("http://0.0.0.0:8000"); + }); + + describe("Mocked Tests", () => { + test("should correctly set the baseURL with prefix", () => { + expect((client as any).axiosInstance.defaults.baseURL).toBe( + "http://0.0.0.0:8000/v1", + ); + }); + + test("health should return data from the /health endpoint", async () => { + const mockResponse = { response: "ok" }; + mockAxiosInstance.request.mockResolvedValue({ data: mockResponse }); + + const result = await client.health(); + expect(result).toEqual(mockResponse); + expect(mockAxiosInstance.request).toHaveBeenCalledWith({ + method: "GET", + url: "health", + headers: {}, + responseType: "json", + }); + }); + }); +}); diff --git a/r2r_js_sdk/__tests__/r2rClientIntegrationSuperUser.test.ts b/r2r_js_sdk/__tests__/r2rClientIntegrationSuperUser.test.ts new file mode 100644 index 000000000..2deed26f1 --- /dev/null +++ b/r2r_js_sdk/__tests__/r2rClientIntegrationSuperUser.test.ts @@ -0,0 +1,178 @@ +import { r2rClient } from "../src/index"; +const fs = require("fs"); + +const baseUrl = "http://localhost:8000"; + +describe("r2rClient Integration Tests", () => { + let client: r2rClient; + + beforeAll(async () => { + client = new r2rClient(baseUrl); + }); + + test("Health check", async () => { + await expect(client.health()).resolves.not.toThrow(); + }); + + test("Login", async () => { + await expect( + client.login("admin@example.com", "change_me_immediately"), + ).resolves.not.toThrow(); + }); + + test("Server stats", async () => { + await expect(client.serverStats()).resolves.not.toThrow(); + }); + + test("Ingest file", async () => { + const files = [ + { path: "examples/data/raskolnikov.txt", name: "raskolnikov.txt" }, + ]; + + await expect( + client.ingestFiles(files, { + metadatas: [{ title: "raskolnikov.txt" }, { title: "karamozov.txt" }], + skip_document_info: false, + }), + ).resolves.not.toThrow(); + }); + + test("Ingest files in folder", async () => { + const files = ["examples/data/folder"]; + + await expect(client.ingestFiles(files)).resolves.not.toThrow(); + }); + + // test("Update files", async () => { + // const updated_file = [ + // { path: "examples/data/folder/myshkin.txt", name: "super_myshkin.txt" }, + // ]; + // await expect( + // client.updateFiles(updated_file, { + // document_ids: ["2e05b285-2746-5778-9e4a-e293db92f3be"], + // metadatas: [{ title: "updated_karamozov.txt" }], + // }), + // ).resolves.not.toThrow(); + // }); + + test("Search documents", async () => { + await expect(client.search("test")).resolves.not.toThrow(); + }); + + test("Generate RAG response with additional parameters", async () => { + await expect( + client.rag( + "test", + { use_vector_search: true, search_limit: 5 }, + { use_kg_search: false }, + { temperature: 0.7 }, + ), + ).resolves.not.toThrow(); + }, 30000); + + test("Agentic RAG response", async () => { + const messages = [ + { role: "system", content: "You are a helpful assistant." }, + { role: "user", content: "Tell me about Raskolnikov." }, + ]; + + await expect(client.agent(messages)).resolves.not.toThrow(); + }, 30000); + + // TODO: Fix this test + // test("Score completion", async () => { + // const message_id = "4173d5f9-f62e-5981-8e35-5154b9883c7f"; + // const score = 0.5; + + // await expect( + // client.scoreCompletion(message_id, score), + // ).resolves.not.toThrow(); + // }); + + // TOOD: Fix in R2R, table logs has no column named run_id + // test("Agentic RAG response with streaming", async () => { + // const messages = [ + // { role: "system", content: "You are a helpful assistant." }, + // { role: "user", content: "Tell me about Raskolnikov." }, + // ]; + + // const stream = await client.agent(messages, undefined, undefined, { + // stream: true, + // }); + + // expect(stream).toBeDefined(); + + // let fullResponse = ""; + + // for await (const chunk of stream) { + // fullResponse += chunk; + // } + + // expect(fullResponse.length).toBeGreaterThan(0); + // }, 30000); + + test("Delete document", async () => { + await expect( + client.delete({ + document_id: "f9f61fc8-079c-52d0-910a-c657958e385b", + }), + ).resolves.toBe(""); + }); + + // TODO: verfiy that this works, blocked by R2R logging issues + // test("Get logs", async () => { + // await expect(client.logs()).resolves.not.toThrow(); + // }); + + // TODO: verfiy that this works, blocked by R2R logging issues + // test("App settings", async () => { + // await expect(client.appSettings()).resolves.not.toThrow(); + // }); + + // test("Get analytics", async () => { + // const filterCriteria: Record | string = { + // filters: { + // search_latencies: "search_latency", + // }, + // }; + + // const analysisTypes: Record | string = { + // analysis_types: { + // search_latencies: ["basic_statistics", "search_latency"], + // }, + // }; + + // await expect( + // client.analytics(filterCriteria, analysisTypes), + // ).resolves.not.toThrow(); + // }); + + // TODO: Fix in R2R, 'PostgresRelationalDBProvider' object has no attribute 'get_users_overview') + // test("Get users overview", async () => { + // await expect(client.usersOverview()).resolves.not.toThrow(); + // }); + + test("Get documents overview", async () => { + await expect(client.documentsOverview()).resolves.not.toThrow(); + }); + + test("Get document chunks", async () => { + await expect( + client.documentChunks("73749580-1ade-50c6-8fbe-a5e9e87783c8"), + ).resolves.not.toThrow(); + }); + + test("Clean up remaining documents", async () => { + await expect( + client.delete({ document_id: "73749580-1ade-50c6-8fbe-a5e9e87783c8" }), + ).resolves.toBe(""); + + await expect( + client.delete({ document_id: "2e05b285-2746-5778-9e4a-e293db92f3be" }), + ).resolves.toBe(""); + }); + + test("Logout", async () => { + await expect(client.logout()).resolves.not.toThrow(); + }); +}); diff --git a/r2r_js_sdk/__tests__/r2rClientIntegrationUser.test.ts b/r2r_js_sdk/__tests__/r2rClientIntegrationUser.test.ts new file mode 100644 index 000000000..013b629e2 --- /dev/null +++ b/r2r_js_sdk/__tests__/r2rClientIntegrationUser.test.ts @@ -0,0 +1,119 @@ +import { r2rClient } from "../src/index"; +const fs = require("fs"); + +const baseUrl = "http://localhost:8000"; + +describe("r2rClient Integration Tests", () => { + let client: r2rClient; + + beforeAll(async () => { + client = new r2rClient(baseUrl); + }); + + test("Health check", async () => { + await expect(client.health()).resolves.not.toThrow(); + }); + + test("Register user", async () => { + await expect( + client.register("test@gmail.com", "password"), + ).resolves.not.toThrow(); + }); + + test("Verify Email throws a 400 error", async () => { + await expect(client.verifyEmail("verification_code")).rejects.toThrow( + "Status 400: Email verification is not required", + ); + }); + + test("Login", async () => { + await expect( + client.login("test@gmail.com", "password"), + ).resolves.not.toThrow(); + }); + + test("Ingest file", async () => { + const files = [ + { path: "examples/data/raskolnikov.txt", name: "raskolnikov.txt" }, + ]; + + await expect( + client.ingestFiles(files, { + metadatas: [{ title: "myshkin.txt" }, { title: "karamozov.txt" }], + skip_document_info: false, + }), + ).resolves.not.toThrow(); + }); + + test("Ingest files in folder", async () => { + const files = ["examples/data/folder"]; + + await expect(client.ingestFiles(files)).resolves.not.toThrow(); + }); + + test("Update files", async () => { + const updated_file = [ + { path: "examples/data/folder/myshkin.txt", name: "myshkin.txt" }, + ]; + await expect( + client.updateFiles(updated_file, { + document_ids: ["06f6aab5-daa1-5b22-809c-d73a378600ed"], + metadatas: [{ title: "updated_karamozov.txt" }], + }), + ).resolves.not.toThrow(); + }); + + test("Search documents", async () => { + await expect(client.search("test")).resolves.not.toThrow(); + }); + + test("Generate RAG response", async () => { + await expect(client.rag("test")).resolves.not.toThrow(); + }, 30000); + + test("Delete document", async () => { + await expect( + client.delete({ document_id: "c621c119-e21d-5d11-a099-bab1993f76d0" }), + ).resolves.not.toThrow(); + }); + + test("Only a superuser can call app settings", async () => { + await expect(client.appSettings()).rejects.toThrow( + "Status 403: Only a superuser can call the `app_settings` endpoint.", + ); + }); + + test("Get documents overview", async () => { + await expect(client.documentsOverview()).resolves.not.toThrow(); + }); + + test("Logout", async () => { + await expect(client.logout()).resolves.not.toThrow(); + }); + + test("Login after logout", async () => { + await expect( + client.login("test@gmail.com", "password"), + ).resolves.not.toThrow(); + }); + + test("Clean up remaining documents", async () => { + await expect( + client.delete({ document_id: "f58d4ec4-0274-56fa-b1ce-16aa3ba9ce3c" }), + ).resolves.not.toThrow(); + + await expect( + client.delete({ document_id: "06f6aab5-daa1-5b22-809c-d73a378600ed" }), + ).resolves.not.toThrow; + }); + + test("Change password", async () => { + await expect( + client.changePassword("password", "new_password"), + ).resolves.not.toThrow(); + }); + + test("Delete User", async () => { + await expect(client.deleteUser("new_password")).resolves.not.toThrow(); + }); +}); diff --git a/r2r_js_sdk/examples/data/folder/karamozov.txt b/r2r_js_sdk/examples/data/folder/karamozov.txt new file mode 100644 index 000000000..5348a5706 --- /dev/null +++ b/r2r_js_sdk/examples/data/folder/karamozov.txt @@ -0,0 +1,4 @@ +Alexius Fyodorovich Karamazov erat tertius filius Fyodoris Pavlovich Karamazov +possessoris terrarum in nostro districtu bene noti sua aetate, et adhuc apud nos +memoriae mandati ob mortem tragicam et obscuram, quae tredecim annos abhinc +accidit, quamque suo loco describam. diff --git a/r2r_js_sdk/examples/data/folder/myshkin.txt b/r2r_js_sdk/examples/data/folder/myshkin.txt new file mode 100644 index 000000000..0e367dc8d --- /dev/null +++ b/r2r_js_sdk/examples/data/folder/myshkin.txt @@ -0,0 +1,4 @@ +Sub finem Novembris, tempore liquationis, hora nona mane, tramen in via +ferrea Varsaviae et Petropoli plenis velocitatibus Petropolim +appropinquabat. Dies ita humidus et nebulosus erat ut magno cum labore +viatores invicem videre possent. diff --git a/r2r_js_sdk/examples/data/raskolnikov.txt b/r2r_js_sdk/examples/data/raskolnikov.txt new file mode 100644 index 000000000..dfb25d60f --- /dev/null +++ b/r2r_js_sdk/examples/data/raskolnikov.txt @@ -0,0 +1,8 @@ +In vespera praecipue calida ineunte Iulio iuvenis e cenaculo in quo hospitabatur in +S. loco exiit et lente, quasi dubitans, versus pontem K. ambulavit. Feliciter vitavit +ne domina sua eum in scala occurreret. Cenaculum suum sub tecto domus altae, quinque +tabulatorum, erat, et magis armario quam conclavi simile erat. Domina, quae ei cenaculum, +prandia et ministerium praebebat, in tabulato infra habitabat, et quotienscumque exibat, +praeterire culinam eius, cuius ianua semper aperta erat, cogebatur. Et quoties praeteribat, +iuvenis aegrotum et pavidum sensum habebat, quod eum corrugare frontem et pudere faciebat. +Desperanter apud dominam suam aere alieno obrutus erat, et eam convenire timebat. diff --git a/r2r_js_sdk/examples/hello_r2r.js b/r2r_js_sdk/examples/hello_r2r.js new file mode 100644 index 000000000..a1bb8b572 --- /dev/null +++ b/r2r_js_sdk/examples/hello_r2r.js @@ -0,0 +1,49 @@ +const { r2rClient } = require("r2r-js"); + +// http://localhost:8000 or the address that you are running the R2R server +const client = new r2rClient("http://localhost:8000"); + +async function main() { + const EMAIL = "admin@example.com"; + const PASSWORD = "change_me_immediately"; + console.log("Logging in..."); + await client.login(EMAIL, PASSWORD); + + const files = [ + { path: "examples/data/raskolnikov.txt", name: "raskolnikov.txt" }, + ]; + + console.log("Ingesting file..."); + const ingestResult = await client.ingestFiles(files, { + metadatas: [{ title: "raskolnikov.txt" }], + skip_document_info: false, + }); + console.log("Ingest result:", JSON.stringify(ingestResult, null, 2)); + + console.log("Performing RAG..."); + const ragResponse = await client.rag({ + query: "What does the file talk about?", + rag_generation_config: { + model: "gpt-4o", + temperature: 0.0, + stream: false, + }, + }); + + console.log("Search Results:"); + ragResponse.results.search_results.vector_search_results.forEach( + (result, index) => { + console.log(`\nResult ${index + 1}:`); + console.log(`Text: ${result.metadata.text.substring(0, 100)}...`); + console.log(`Score: ${result.score}`); + }, + ); + + console.log("\nCompletion:"); + console.log(ragResponse.results.completion.choices[0].message.content); + + console.log("Logging out..."); + await client.logout(); +} + +main(); diff --git a/r2r_js_sdk/jest.config.js b/r2r_js_sdk/jest.config.js new file mode 100644 index 000000000..4499ebd11 --- /dev/null +++ b/r2r_js_sdk/jest.config.js @@ -0,0 +1,8 @@ +module.exports = { + preset: "ts-jest", + testEnvironment: "node", + testMatch: [ + "**/__tests__/**/*.ts?(x)", + "**/__tests__/**/?(*.)+(spec|test).ts?(x)", + ], +}; diff --git a/r2r_js_sdk/package-lock.json b/r2r_js_sdk/package-lock.json new file mode 100644 index 000000000..8a898fcc0 --- /dev/null +++ b/r2r_js_sdk/package-lock.json @@ -0,0 +1,4074 @@ +{ + "name": "r2r-js", + "version": "1.2.15", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "r2r-js", + "version": "1.2.9", + "license": "ISC", + "dependencies": { + "axios": "^1.7.2", + "form-data": "^4.0.0", + "posthog-js": "^1.148.0", + "posthog-node": "^4.0.1", + "uuid": "^10.0.0" + }, + "devDependencies": { + "@types/jest": "^29.5.12", + "@types/node": "^20.14.11", + "@types/uuid": "^10.0.0", + "jest": "^29.7.0", + "prettier": "^3.3.3", + "ts-jest": "^29.2.3", + "ts-node": "^10.9.2", + "typescript": "^5.5.3" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@ampproject/remapping/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz", + "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.7.tgz", + "integrity": "sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.24.7", + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helpers": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/template": "^7.24.7", + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz", + "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.7", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/generator/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz", + "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.24.7", + "@babel/helper-validator-option": "^7.24.7", + "browserslist": "^4.22.2", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", + "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", + "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", + "dev": true, + "dependencies": { + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", + "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", + "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz", + "integrity": "sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", + "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", + "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", + "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz", + "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.7.tgz", + "integrity": "sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==", + "dev": true, + "dependencies": { + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.24.7", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", + "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz", + "integrity": "sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.7.tgz", + "integrity": "sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", + "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz", + "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.24.7", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-hoist-variables": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", + "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", + "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/core": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", + "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", + "dev": true, + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/reporters": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.7.0", + "jest-config": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-resolve-dependencies": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "jest-watcher": "^29.7.0", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/environment": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", + "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", + "dev": true, + "dependencies": { + "expect": "^29.7.0", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", + "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", + "dev": true, + "dependencies": { + "jest-get-type": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", + "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/globals": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", + "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/types": "^29.6.3", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", + "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", + "dev": true, + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^6.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/reporters/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", + "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.18", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/source-map/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@jest/test-result": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", + "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", + "dev": true, + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", + "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", + "dev": true, + "dependencies": { + "@jest/test-result": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/transform/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, + "node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^3.0.0" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", + "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", + "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "29.5.12", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.12.tgz", + "integrity": "sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==", + "dev": true, + "dependencies": { + "expect": "^29.0.0", + "pretty-format": "^29.0.0" + } + }, + "node_modules/@types/node": { + "version": "20.14.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.11.tgz", + "integrity": "sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", + "dev": true + }, + "node_modules/@types/uuid": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==", + "dev": true + }, + "node_modules/@types/yargs": { + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "dev": true + }, + "node_modules/acorn": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz", + "integrity": "sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", + "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", + "dev": true, + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/async": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", + "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", + "dev": true, + "license": "MIT" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/axios": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz", + "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/babel-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", + "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", + "dev": true, + "dependencies": { + "@jest/transform": "^29.7.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.6.3", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", + "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", + "dev": true, + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "dev": true, + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-preset-jest": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", + "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", + "dev": true, + "dependencies": { + "babel-plugin-jest-hoist": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.23.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz", + "integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001629", + "electron-to-chromium": "^1.4.796", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.16" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "dependencies": { + "fast-json-stable-stringify": "2.x" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001636", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001636.tgz", + "integrity": "sha512-bMg2vmr8XBsbL6Lr0UHXy/21m84FTxDLWn2FSqMd5PrlbMxwJlQnC2YWYxVgp66PZE+BBNF2jYQUBKCo1FDeZg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.3.1.tgz", + "integrity": "sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==", + "dev": true + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", + "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", + "dev": true + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "node_modules/create-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", + "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "prompts": "^2.0.1" + }, + "bin": { + "create-jest": "bin/create-jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/dedent": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz", + "integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==", + "dev": true, + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/ejs": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.4.811", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.811.tgz", + "integrity": "sha512-CDyzcJ5XW78SHzsIOdn27z8J4ist8eaFLhdto2hSMSJQgsiwvbv2fbizcKUICryw1Wii1TI/FEkvzvJsR3awrA==", + "dev": true + }, + "node_modules/emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", + "dev": true, + "dependencies": { + "@jest/expect-utils": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dev": true, + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/fflate": { + "version": "0.4.8", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.4.8.tgz", + "integrity": "sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA==" + }, + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "node_modules/is-core-module": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.14.0.tgz", + "integrity": "sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==", + "dev": true, + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.2.tgz", + "integrity": "sha512-1WUsZ9R1lA0HtBSohTkm39WTPlNKSJ5iFk7UwqXkBLoHQT+hfqPsfsTDVuZdKGaBwn7din9bS7SsnoAr943hvw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jake": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz", + "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.4", + "minimatch": "^3.1.2" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", + "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", + "dev": true, + "dependencies": { + "@jest/core": "^29.7.0", + "@jest/types": "^29.6.3", + "import-local": "^3.0.2", + "jest-cli": "^29.7.0" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-changed-files": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", + "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", + "dev": true, + "dependencies": { + "execa": "^5.0.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", + "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^1.0.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.7.0", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0", + "pretty-format": "^29.7.0", + "pure-rand": "^6.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-cli": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", + "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", + "dev": true, + "dependencies": { + "@jest/core": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "create-jest": "^29.7.0", + "exit": "^0.1.2", + "import-local": "^3.0.2", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "yargs": "^17.3.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-config": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", + "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-jest": "^29.7.0", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@types/node": "*", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-diff": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-docblock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", + "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", + "dev": true, + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", + "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "jest-util": "^29.7.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-environment-node": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", + "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-leak-detector": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", + "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", + "dev": true, + "dependencies": { + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", + "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.6.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-mock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", + "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "dev": true, + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", + "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", + "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", + "dev": true, + "dependencies": { + "jest-regex-util": "^29.6.3", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runner": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", + "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", + "dev": true, + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/environment": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-leak-detector": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-resolve": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-util": "^29.7.0", + "jest-watcher": "^29.7.0", + "jest-worker": "^29.7.0", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runtime": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", + "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/globals": "^29.7.0", + "@jest/source-map": "^29.6.3", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", + "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "natural-compare": "^1.4.0", + "pretty-format": "^29.7.0", + "semver": "^7.5.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", + "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "leven": "^3.1.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-watcher": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", + "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", + "dev": true, + "dependencies": { + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "jest-util": "^29.7.0", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/micromatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "dev": true, + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "dev": true + }, + "node_modules/node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "dev": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-locate/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/picocolors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/posthog-js": { + "version": "1.148.0", + "resolved": "https://registry.npmjs.org/posthog-js/-/posthog-js-1.148.0.tgz", + "integrity": "sha512-nydf+aret26YViDBwH7DdN/c8dmCzQGNQ1yredeE47UlbpJ3J/iTgskNdmGJIofFcdSagcwAE/FF7s++YfTtvg==", + "license": "MIT", + "dependencies": { + "fflate": "^0.4.8", + "preact": "^10.19.3", + "web-vitals": "^4.0.1" + } + }, + "node_modules/posthog-node": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/posthog-node/-/posthog-node-4.0.1.tgz", + "integrity": "sha512-rtqm2h22QxLGBrW2bLYzbRhliIrqgZ0k+gF0LkQ1SNdeD06YE5eilV0MxZppFSxC8TfH0+B0cWCuebEnreIDgQ==", + "dependencies": { + "axios": "^1.6.2", + "rusha": "^0.8.14" + }, + "engines": { + "node": ">=15.0.0" + } + }, + "node_modules/preact": { + "version": "10.22.0", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.22.0.tgz", + "integrity": "sha512-RRurnSjJPj4rp5K6XoP45Ui33ncb7e4H7WiOHVpjbkvqvA3U+N8Z6Qbo0AE6leGYBV66n8EhEaFixvIu3SkxFw==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + } + }, + "node_modules/prettier": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, + "node_modules/pure-rand": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", + "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ] + }, + "node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve.exports": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", + "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/rusha": { + "version": "0.8.14", + "resolved": "https://registry.npmjs.org/rusha/-/rusha-0.8.14.tgz", + "integrity": "sha512-cLgakCUf6PedEu15t8kbsjnwIFFR2D4RfL+W3iWFJ4iac7z4B0ZI8fxy4R3J956kAI68HclCFGL8MPoUVC3qVA==" + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-jest": { + "version": "29.2.3", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.2.3.tgz", + "integrity": "sha512-yCcfVdiBFngVz9/keHin9EnsrQtQtEu3nRykNy9RVp+FiPFFbPJ3Sg6Qg4+TkmH0vMP5qsTKgXSsk80HRwvdgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "bs-logger": "0.x", + "ejs": "^3.1.10", + "fast-json-stable-stringify": "2.x", + "jest-util": "^29.0.0", + "json5": "^2.2.3", + "lodash.memoize": "4.x", + "make-error": "1.x", + "semver": "^7.5.3", + "yargs-parser": "^21.0.1" + }, + "bin": { + "ts-jest": "cli.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.0.0-beta.0 <8", + "@jest/transform": "^29.0.0", + "@jest/types": "^29.0.0", + "babel-jest": "^29.0.0", + "jest": "^29.0.0", + "typescript": ">=4.3 <6" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@jest/transform": { + "optional": true + }, + "@jest/types": { + "optional": true + }, + "babel-jest": { + "optional": true + }, + "esbuild": { + "optional": true + } + } + }, + "node_modules/ts-jest/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", + "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, + "node_modules/update-browserslist-db": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz", + "integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.2", + "picocolors": "^1.0.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uuid": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, + "node_modules/v8-to-istanbul": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", + "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/v8-to-istanbul/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/web-vitals": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-4.2.0.tgz", + "integrity": "sha512-ohj72kbtVWCpKYMxcbJ+xaOBV3En76hW47j52dG+tEGG36LZQgfFw5yHl9xyjmosy3XUMn8d/GBUAy4YPM839w==" + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/r2r_js_sdk/package.json b/r2r_js_sdk/package.json new file mode 100644 index 000000000..92b490721 --- /dev/null +++ b/r2r_js_sdk/package.json @@ -0,0 +1,43 @@ +{ + "name": "r2r-js", + "version": "1.2.15", + "description": "", + "main": "dist/index.js", + "browser": "dist/index.browser.js", + "types": "dist/index.d.ts", + "exports": { + ".": "./dist/index.js" + }, + "scripts": { + "build": "tsc", + "prepublishOnly": "npm run build", + "format": "prettier --write .", + "pretest:integration": "node setup.js", + "test": "jest --no-cache", + "test:watch": "jest --watch", + "test:coverage": "jest --coverage" + }, + "files": [ + "dist" + ], + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "axios": "^1.7.4", + "form-data": "^4.0.0", + "posthog-js": "^1.155.4", + "posthog-node": "^4.1.0", + "uuid": "^10.0.0" + }, + "devDependencies": { + "@types/jest": "^29.5.12", + "@types/node": "^20.14.15", + "@types/uuid": "^10.0.0", + "jest": "^29.7.0", + "prettier": "^3.3.3", + "ts-jest": "^29.2.4", + "ts-node": "^10.9.2", + "typescript": "^5.5.4" + } +} diff --git a/r2r_js_sdk/pnpm-lock.yaml b/r2r_js_sdk/pnpm-lock.yaml new file mode 100644 index 000000000..9c23c72b6 --- /dev/null +++ b/r2r_js_sdk/pnpm-lock.yaml @@ -0,0 +1,3878 @@ +lockfileVersion: "9.0" + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + .: + dependencies: + axios: + specifier: ^1.7.4 + version: 1.7.4 + form-data: + specifier: ^4.0.0 + version: 4.0.0 + posthog-js: + specifier: ^1.155.4 + version: 1.155.4 + posthog-node: + specifier: ^4.1.0 + version: 4.1.0 + uuid: + specifier: ^10.0.0 + version: 10.0.0 + devDependencies: + "@types/jest": + specifier: ^29.5.12 + version: 29.5.12 + "@types/node": + specifier: ^20.14.15 + version: 20.14.15 + "@types/uuid": + specifier: ^10.0.0 + version: 10.0.0 + jest: + specifier: ^29.7.0 + version: 29.7.0(@types/node@20.14.15)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)) + prettier: + specifier: ^3.3.3 + version: 3.3.3 + ts-jest: + specifier: ^29.2.4 + version: 29.2.4(@babel/core@7.25.2)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.25.2))(jest@29.7.0(@types/node@20.14.15)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)))(typescript@5.5.4) + ts-node: + specifier: ^10.9.2 + version: 10.9.2(@types/node@20.14.15)(typescript@5.5.4) + typescript: + specifier: ^5.5.4 + version: 5.5.4 + +packages: + "@ampproject/remapping@2.3.0": + resolution: + { + integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==, + } + engines: { node: ">=6.0.0" } + + "@babel/code-frame@7.24.7": + resolution: + { + integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==, + } + engines: { node: ">=6.9.0" } + + "@babel/compat-data@7.25.2": + resolution: + { + integrity: sha512-bYcppcpKBvX4znYaPEeFau03bp89ShqNMLs+rmdptMw+heSZh9+z84d2YG+K7cYLbWwzdjtDoW/uqZmPjulClQ==, + } + engines: { node: ">=6.9.0" } + + "@babel/core@7.25.2": + resolution: + { + integrity: sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==, + } + engines: { node: ">=6.9.0" } + + "@babel/generator@7.25.0": + resolution: + { + integrity: sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw==, + } + engines: { node: ">=6.9.0" } + + "@babel/helper-compilation-targets@7.25.2": + resolution: + { + integrity: sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==, + } + engines: { node: ">=6.9.0" } + + "@babel/helper-module-imports@7.24.7": + resolution: + { + integrity: sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==, + } + engines: { node: ">=6.9.0" } + + "@babel/helper-module-transforms@7.25.2": + resolution: + { + integrity: sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==, + } + engines: { node: ">=6.9.0" } + peerDependencies: + "@babel/core": ^7.0.0 + + "@babel/helper-plugin-utils@7.24.8": + resolution: + { + integrity: sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==, + } + engines: { node: ">=6.9.0" } + + "@babel/helper-simple-access@7.24.7": + resolution: + { + integrity: sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==, + } + engines: { node: ">=6.9.0" } + + "@babel/helper-string-parser@7.24.8": + resolution: + { + integrity: sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==, + } + engines: { node: ">=6.9.0" } + + "@babel/helper-validator-identifier@7.24.7": + resolution: + { + integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==, + } + engines: { node: ">=6.9.0" } + + "@babel/helper-validator-option@7.24.8": + resolution: + { + integrity: sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==, + } + engines: { node: ">=6.9.0" } + + "@babel/helpers@7.25.0": + resolution: + { + integrity: sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw==, + } + engines: { node: ">=6.9.0" } + + "@babel/highlight@7.24.7": + resolution: + { + integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==, + } + engines: { node: ">=6.9.0" } + + "@babel/parser@7.25.3": + resolution: + { + integrity: sha512-iLTJKDbJ4hMvFPgQwwsVoxtHyWpKKPBrxkANrSYewDPaPpT5py5yeVkgPIJ7XYXhndxJpaA3PyALSXQ7u8e/Dw==, + } + engines: { node: ">=6.0.0" } + hasBin: true + + "@babel/plugin-syntax-async-generators@7.8.4": + resolution: + { + integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==, + } + peerDependencies: + "@babel/core": ^7.0.0-0 + + "@babel/plugin-syntax-bigint@7.8.3": + resolution: + { + integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==, + } + peerDependencies: + "@babel/core": ^7.0.0-0 + + "@babel/plugin-syntax-class-properties@7.12.13": + resolution: + { + integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==, + } + peerDependencies: + "@babel/core": ^7.0.0-0 + + "@babel/plugin-syntax-class-static-block@7.14.5": + resolution: + { + integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==, + } + engines: { node: ">=6.9.0" } + peerDependencies: + "@babel/core": ^7.0.0-0 + + "@babel/plugin-syntax-import-attributes@7.24.7": + resolution: + { + integrity: sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==, + } + engines: { node: ">=6.9.0" } + peerDependencies: + "@babel/core": ^7.0.0-0 + + "@babel/plugin-syntax-import-meta@7.10.4": + resolution: + { + integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==, + } + peerDependencies: + "@babel/core": ^7.0.0-0 + + "@babel/plugin-syntax-json-strings@7.8.3": + resolution: + { + integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==, + } + peerDependencies: + "@babel/core": ^7.0.0-0 + + "@babel/plugin-syntax-jsx@7.24.7": + resolution: + { + integrity: sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==, + } + engines: { node: ">=6.9.0" } + peerDependencies: + "@babel/core": ^7.0.0-0 + + "@babel/plugin-syntax-logical-assignment-operators@7.10.4": + resolution: + { + integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==, + } + peerDependencies: + "@babel/core": ^7.0.0-0 + + "@babel/plugin-syntax-nullish-coalescing-operator@7.8.3": + resolution: + { + integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==, + } + peerDependencies: + "@babel/core": ^7.0.0-0 + + "@babel/plugin-syntax-numeric-separator@7.10.4": + resolution: + { + integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==, + } + peerDependencies: + "@babel/core": ^7.0.0-0 + + "@babel/plugin-syntax-object-rest-spread@7.8.3": + resolution: + { + integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==, + } + peerDependencies: + "@babel/core": ^7.0.0-0 + + "@babel/plugin-syntax-optional-catch-binding@7.8.3": + resolution: + { + integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==, + } + peerDependencies: + "@babel/core": ^7.0.0-0 + + "@babel/plugin-syntax-optional-chaining@7.8.3": + resolution: + { + integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==, + } + peerDependencies: + "@babel/core": ^7.0.0-0 + + "@babel/plugin-syntax-private-property-in-object@7.14.5": + resolution: + { + integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==, + } + engines: { node: ">=6.9.0" } + peerDependencies: + "@babel/core": ^7.0.0-0 + + "@babel/plugin-syntax-top-level-await@7.14.5": + resolution: + { + integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==, + } + engines: { node: ">=6.9.0" } + peerDependencies: + "@babel/core": ^7.0.0-0 + + "@babel/plugin-syntax-typescript@7.24.7": + resolution: + { + integrity: sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA==, + } + engines: { node: ">=6.9.0" } + peerDependencies: + "@babel/core": ^7.0.0-0 + + "@babel/template@7.25.0": + resolution: + { + integrity: sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==, + } + engines: { node: ">=6.9.0" } + + "@babel/traverse@7.25.3": + resolution: + { + integrity: sha512-HefgyP1x754oGCsKmV5reSmtV7IXj/kpaE1XYY+D9G5PvKKoFfSbiS4M77MdjuwlZKDIKFCffq9rPU+H/s3ZdQ==, + } + engines: { node: ">=6.9.0" } + + "@babel/types@7.25.2": + resolution: + { + integrity: sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q==, + } + engines: { node: ">=6.9.0" } + + "@bcoe/v8-coverage@0.2.3": + resolution: + { + integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==, + } + + "@cspotcode/source-map-support@0.8.1": + resolution: + { + integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==, + } + engines: { node: ">=12" } + + "@istanbuljs/load-nyc-config@1.1.0": + resolution: + { + integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==, + } + engines: { node: ">=8" } + + "@istanbuljs/schema@0.1.3": + resolution: + { + integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==, + } + engines: { node: ">=8" } + + "@jest/console@29.7.0": + resolution: + { + integrity: sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + "@jest/core@29.7.0": + resolution: + { + integrity: sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + "@jest/environment@29.7.0": + resolution: + { + integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + "@jest/expect-utils@29.7.0": + resolution: + { + integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + "@jest/expect@29.7.0": + resolution: + { + integrity: sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + "@jest/fake-timers@29.7.0": + resolution: + { + integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + "@jest/globals@29.7.0": + resolution: + { + integrity: sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + "@jest/reporters@29.7.0": + resolution: + { + integrity: sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + "@jest/schemas@29.6.3": + resolution: + { + integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + "@jest/source-map@29.6.3": + resolution: + { + integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + "@jest/test-result@29.7.0": + resolution: + { + integrity: sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + "@jest/test-sequencer@29.7.0": + resolution: + { + integrity: sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + "@jest/transform@29.7.0": + resolution: + { + integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + "@jest/types@29.6.3": + resolution: + { + integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + "@jridgewell/gen-mapping@0.3.5": + resolution: + { + integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==, + } + engines: { node: ">=6.0.0" } + + "@jridgewell/resolve-uri@3.1.2": + resolution: + { + integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==, + } + engines: { node: ">=6.0.0" } + + "@jridgewell/set-array@1.2.1": + resolution: + { + integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==, + } + engines: { node: ">=6.0.0" } + + "@jridgewell/sourcemap-codec@1.5.0": + resolution: + { + integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==, + } + + "@jridgewell/trace-mapping@0.3.25": + resolution: + { + integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==, + } + + "@jridgewell/trace-mapping@0.3.9": + resolution: + { + integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==, + } + + "@sinclair/typebox@0.27.8": + resolution: + { + integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==, + } + + "@sinonjs/commons@3.0.1": + resolution: + { + integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==, + } + + "@sinonjs/fake-timers@10.3.0": + resolution: + { + integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==, + } + + "@tsconfig/node10@1.0.11": + resolution: + { + integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==, + } + + "@tsconfig/node12@1.0.11": + resolution: + { + integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==, + } + + "@tsconfig/node14@1.0.3": + resolution: + { + integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==, + } + + "@tsconfig/node16@1.0.4": + resolution: + { + integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==, + } + + "@types/babel__core@7.20.5": + resolution: + { + integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==, + } + + "@types/babel__generator@7.6.8": + resolution: + { + integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==, + } + + "@types/babel__template@7.4.4": + resolution: + { + integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==, + } + + "@types/babel__traverse@7.20.6": + resolution: + { + integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==, + } + + "@types/graceful-fs@4.1.9": + resolution: + { + integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==, + } + + "@types/istanbul-lib-coverage@2.0.6": + resolution: + { + integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==, + } + + "@types/istanbul-lib-report@3.0.3": + resolution: + { + integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==, + } + + "@types/istanbul-reports@3.0.4": + resolution: + { + integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==, + } + + "@types/jest@29.5.12": + resolution: + { + integrity: sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==, + } + + "@types/node@20.14.15": + resolution: + { + integrity: sha512-Fz1xDMCF/B00/tYSVMlmK7hVeLh7jE5f3B7X1/hmV0MJBwE27KlS7EvD/Yp+z1lm8mVhwV5w+n8jOZG8AfTlKw==, + } + + "@types/stack-utils@2.0.3": + resolution: + { + integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==, + } + + "@types/uuid@10.0.0": + resolution: + { + integrity: sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==, + } + + "@types/yargs-parser@21.0.3": + resolution: + { + integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==, + } + + "@types/yargs@17.0.33": + resolution: + { + integrity: sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==, + } + + acorn-walk@8.3.3: + resolution: + { + integrity: sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==, + } + engines: { node: ">=0.4.0" } + + acorn@8.12.1: + resolution: + { + integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==, + } + engines: { node: ">=0.4.0" } + hasBin: true + + ansi-escapes@4.3.2: + resolution: + { + integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==, + } + engines: { node: ">=8" } + + ansi-regex@5.0.1: + resolution: + { + integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==, + } + engines: { node: ">=8" } + + ansi-styles@3.2.1: + resolution: + { + integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==, + } + engines: { node: ">=4" } + + ansi-styles@4.3.0: + resolution: + { + integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==, + } + engines: { node: ">=8" } + + ansi-styles@5.2.0: + resolution: + { + integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==, + } + engines: { node: ">=10" } + + anymatch@3.1.3: + resolution: + { + integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==, + } + engines: { node: ">= 8" } + + arg@4.1.3: + resolution: + { + integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==, + } + + argparse@1.0.10: + resolution: + { + integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==, + } + + async@3.2.5: + resolution: + { + integrity: sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==, + } + + asynckit@0.4.0: + resolution: + { + integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==, + } + + axios@1.7.4: + resolution: + { + integrity: sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==, + } + + babel-jest@29.7.0: + resolution: + { + integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + peerDependencies: + "@babel/core": ^7.8.0 + + babel-plugin-istanbul@6.1.1: + resolution: + { + integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==, + } + engines: { node: ">=8" } + + babel-plugin-jest-hoist@29.6.3: + resolution: + { + integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + babel-preset-current-node-syntax@1.1.0: + resolution: + { + integrity: sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==, + } + peerDependencies: + "@babel/core": ^7.0.0 + + babel-preset-jest@29.6.3: + resolution: + { + integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + peerDependencies: + "@babel/core": ^7.0.0 + + balanced-match@1.0.2: + resolution: + { + integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==, + } + + brace-expansion@1.1.11: + resolution: + { + integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==, + } + + brace-expansion@2.0.1: + resolution: + { + integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==, + } + + braces@3.0.3: + resolution: + { + integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==, + } + engines: { node: ">=8" } + + browserslist@4.23.3: + resolution: + { + integrity: sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==, + } + engines: { node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7 } + hasBin: true + + bs-logger@0.2.6: + resolution: + { + integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==, + } + engines: { node: ">= 6" } + + bser@2.1.1: + resolution: + { + integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==, + } + + buffer-from@1.1.2: + resolution: + { + integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==, + } + + callsites@3.1.0: + resolution: + { + integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==, + } + engines: { node: ">=6" } + + camelcase@5.3.1: + resolution: + { + integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==, + } + engines: { node: ">=6" } + + camelcase@6.3.0: + resolution: + { + integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==, + } + engines: { node: ">=10" } + + caniuse-lite@1.0.30001651: + resolution: + { + integrity: sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==, + } + + chalk@2.4.2: + resolution: + { + integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==, + } + engines: { node: ">=4" } + + chalk@4.1.2: + resolution: + { + integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==, + } + engines: { node: ">=10" } + + char-regex@1.0.2: + resolution: + { + integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==, + } + engines: { node: ">=10" } + + ci-info@3.9.0: + resolution: + { + integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==, + } + engines: { node: ">=8" } + + cjs-module-lexer@1.3.1: + resolution: + { + integrity: sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==, + } + + cliui@8.0.1: + resolution: + { + integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==, + } + engines: { node: ">=12" } + + co@4.6.0: + resolution: + { + integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==, + } + engines: { iojs: ">= 1.0.0", node: ">= 0.12.0" } + + collect-v8-coverage@1.0.2: + resolution: + { + integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==, + } + + color-convert@1.9.3: + resolution: + { + integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==, + } + + color-convert@2.0.1: + resolution: + { + integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==, + } + engines: { node: ">=7.0.0" } + + color-name@1.1.3: + resolution: + { + integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==, + } + + color-name@1.1.4: + resolution: + { + integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==, + } + + combined-stream@1.0.8: + resolution: + { + integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==, + } + engines: { node: ">= 0.8" } + + concat-map@0.0.1: + resolution: + { + integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==, + } + + convert-source-map@2.0.0: + resolution: + { + integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==, + } + + create-jest@29.7.0: + resolution: + { + integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + hasBin: true + + create-require@1.1.1: + resolution: + { + integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==, + } + + cross-spawn@7.0.3: + resolution: + { + integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==, + } + engines: { node: ">= 8" } + + debug@4.3.6: + resolution: + { + integrity: sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==, + } + engines: { node: ">=6.0" } + peerDependencies: + supports-color: "*" + peerDependenciesMeta: + supports-color: + optional: true + + dedent@1.5.3: + resolution: + { + integrity: sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==, + } + peerDependencies: + babel-plugin-macros: ^3.1.0 + peerDependenciesMeta: + babel-plugin-macros: + optional: true + + deepmerge@4.3.1: + resolution: + { + integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==, + } + engines: { node: ">=0.10.0" } + + delayed-stream@1.0.0: + resolution: + { + integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==, + } + engines: { node: ">=0.4.0" } + + detect-newline@3.1.0: + resolution: + { + integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==, + } + engines: { node: ">=8" } + + diff-sequences@29.6.3: + resolution: + { + integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + diff@4.0.2: + resolution: + { + integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==, + } + engines: { node: ">=0.3.1" } + + ejs@3.1.10: + resolution: + { + integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==, + } + engines: { node: ">=0.10.0" } + hasBin: true + + electron-to-chromium@1.5.9: + resolution: + { + integrity: sha512-HfkT8ndXR0SEkU8gBQQM3rz035bpE/hxkZ1YIt4KJPEFES68HfIU6LzKukH0H794Lm83WJtkSAMfEToxCs15VA==, + } + + emittery@0.13.1: + resolution: + { + integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==, + } + engines: { node: ">=12" } + + emoji-regex@8.0.0: + resolution: + { + integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==, + } + + error-ex@1.3.2: + resolution: + { + integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==, + } + + escalade@3.1.2: + resolution: + { + integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==, + } + engines: { node: ">=6" } + + escape-string-regexp@1.0.5: + resolution: + { + integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==, + } + engines: { node: ">=0.8.0" } + + escape-string-regexp@2.0.0: + resolution: + { + integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==, + } + engines: { node: ">=8" } + + esprima@4.0.1: + resolution: + { + integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==, + } + engines: { node: ">=4" } + hasBin: true + + execa@5.1.1: + resolution: + { + integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==, + } + engines: { node: ">=10" } + + exit@0.1.2: + resolution: + { + integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==, + } + engines: { node: ">= 0.8.0" } + + expect@29.7.0: + resolution: + { + integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + fast-json-stable-stringify@2.1.0: + resolution: + { + integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==, + } + + fb-watchman@2.0.2: + resolution: + { + integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==, + } + + fflate@0.4.8: + resolution: + { + integrity: sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA==, + } + + filelist@1.0.4: + resolution: + { + integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==, + } + + fill-range@7.1.1: + resolution: + { + integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==, + } + engines: { node: ">=8" } + + find-up@4.1.0: + resolution: + { + integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==, + } + engines: { node: ">=8" } + + follow-redirects@1.15.6: + resolution: + { + integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==, + } + engines: { node: ">=4.0" } + peerDependencies: + debug: "*" + peerDependenciesMeta: + debug: + optional: true + + form-data@4.0.0: + resolution: + { + integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==, + } + engines: { node: ">= 6" } + + fs.realpath@1.0.0: + resolution: + { + integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==, + } + + fsevents@2.3.3: + resolution: + { + integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==, + } + engines: { node: ^8.16.0 || ^10.6.0 || >=11.0.0 } + os: [darwin] + + function-bind@1.1.2: + resolution: + { + integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==, + } + + gensync@1.0.0-beta.2: + resolution: + { + integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==, + } + engines: { node: ">=6.9.0" } + + get-caller-file@2.0.5: + resolution: + { + integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==, + } + engines: { node: 6.* || 8.* || >= 10.* } + + get-package-type@0.1.0: + resolution: + { + integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==, + } + engines: { node: ">=8.0.0" } + + get-stream@6.0.1: + resolution: + { + integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==, + } + engines: { node: ">=10" } + + glob@7.2.3: + resolution: + { + integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==, + } + deprecated: Glob versions prior to v9 are no longer supported + + globals@11.12.0: + resolution: + { + integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==, + } + engines: { node: ">=4" } + + graceful-fs@4.2.11: + resolution: + { + integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==, + } + + has-flag@3.0.0: + resolution: + { + integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==, + } + engines: { node: ">=4" } + + has-flag@4.0.0: + resolution: + { + integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==, + } + engines: { node: ">=8" } + + hasown@2.0.2: + resolution: + { + integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==, + } + engines: { node: ">= 0.4" } + + html-escaper@2.0.2: + resolution: + { + integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==, + } + + human-signals@2.1.0: + resolution: + { + integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==, + } + engines: { node: ">=10.17.0" } + + import-local@3.2.0: + resolution: + { + integrity: sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==, + } + engines: { node: ">=8" } + hasBin: true + + imurmurhash@0.1.4: + resolution: + { + integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==, + } + engines: { node: ">=0.8.19" } + + inflight@1.0.6: + resolution: + { + integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==, + } + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + + inherits@2.0.4: + resolution: + { + integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==, + } + + is-arrayish@0.2.1: + resolution: + { + integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==, + } + + is-core-module@2.15.0: + resolution: + { + integrity: sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==, + } + engines: { node: ">= 0.4" } + + is-fullwidth-code-point@3.0.0: + resolution: + { + integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==, + } + engines: { node: ">=8" } + + is-generator-fn@2.1.0: + resolution: + { + integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==, + } + engines: { node: ">=6" } + + is-number@7.0.0: + resolution: + { + integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==, + } + engines: { node: ">=0.12.0" } + + is-stream@2.0.1: + resolution: + { + integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==, + } + engines: { node: ">=8" } + + isexe@2.0.0: + resolution: + { + integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==, + } + + istanbul-lib-coverage@3.2.2: + resolution: + { + integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==, + } + engines: { node: ">=8" } + + istanbul-lib-instrument@5.2.1: + resolution: + { + integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==, + } + engines: { node: ">=8" } + + istanbul-lib-instrument@6.0.3: + resolution: + { + integrity: sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==, + } + engines: { node: ">=10" } + + istanbul-lib-report@3.0.1: + resolution: + { + integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==, + } + engines: { node: ">=10" } + + istanbul-lib-source-maps@4.0.1: + resolution: + { + integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==, + } + engines: { node: ">=10" } + + istanbul-reports@3.1.7: + resolution: + { + integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==, + } + engines: { node: ">=8" } + + jake@10.9.2: + resolution: + { + integrity: sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==, + } + engines: { node: ">=10" } + hasBin: true + + jest-changed-files@29.7.0: + resolution: + { + integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + jest-circus@29.7.0: + resolution: + { + integrity: sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + jest-cli@29.7.0: + resolution: + { + integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + jest-config@29.7.0: + resolution: + { + integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + peerDependencies: + "@types/node": "*" + ts-node: ">=9.0.0" + peerDependenciesMeta: + "@types/node": + optional: true + ts-node: + optional: true + + jest-diff@29.7.0: + resolution: + { + integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + jest-docblock@29.7.0: + resolution: + { + integrity: sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + jest-each@29.7.0: + resolution: + { + integrity: sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + jest-environment-node@29.7.0: + resolution: + { + integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + jest-get-type@29.6.3: + resolution: + { + integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + jest-haste-map@29.7.0: + resolution: + { + integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + jest-leak-detector@29.7.0: + resolution: + { + integrity: sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + jest-matcher-utils@29.7.0: + resolution: + { + integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + jest-message-util@29.7.0: + resolution: + { + integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + jest-mock@29.7.0: + resolution: + { + integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + jest-pnp-resolver@1.2.3: + resolution: + { + integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==, + } + engines: { node: ">=6" } + peerDependencies: + jest-resolve: "*" + peerDependenciesMeta: + jest-resolve: + optional: true + + jest-regex-util@29.6.3: + resolution: + { + integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + jest-resolve-dependencies@29.7.0: + resolution: + { + integrity: sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + jest-resolve@29.7.0: + resolution: + { + integrity: sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + jest-runner@29.7.0: + resolution: + { + integrity: sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + jest-runtime@29.7.0: + resolution: + { + integrity: sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + jest-snapshot@29.7.0: + resolution: + { + integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + jest-util@29.7.0: + resolution: + { + integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + jest-validate@29.7.0: + resolution: + { + integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + jest-watcher@29.7.0: + resolution: + { + integrity: sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + jest-worker@29.7.0: + resolution: + { + integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + jest@29.7.0: + resolution: + { + integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + js-tokens@4.0.0: + resolution: + { + integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==, + } + + js-yaml@3.14.1: + resolution: + { + integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==, + } + hasBin: true + + jsesc@2.5.2: + resolution: + { + integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==, + } + engines: { node: ">=4" } + hasBin: true + + json-parse-even-better-errors@2.3.1: + resolution: + { + integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==, + } + + json5@2.2.3: + resolution: + { + integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==, + } + engines: { node: ">=6" } + hasBin: true + + kleur@3.0.3: + resolution: + { + integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==, + } + engines: { node: ">=6" } + + leven@3.1.0: + resolution: + { + integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==, + } + engines: { node: ">=6" } + + lines-and-columns@1.2.4: + resolution: + { + integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==, + } + + locate-path@5.0.0: + resolution: + { + integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==, + } + engines: { node: ">=8" } + + lodash.memoize@4.1.2: + resolution: + { + integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==, + } + + lru-cache@5.1.1: + resolution: + { + integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==, + } + + make-dir@4.0.0: + resolution: + { + integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==, + } + engines: { node: ">=10" } + + make-error@1.3.6: + resolution: + { + integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==, + } + + makeerror@1.0.12: + resolution: + { + integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==, + } + + merge-stream@2.0.0: + resolution: + { + integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==, + } + + micromatch@4.0.7: + resolution: + { + integrity: sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==, + } + engines: { node: ">=8.6" } + + mime-db@1.52.0: + resolution: + { + integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==, + } + engines: { node: ">= 0.6" } + + mime-types@2.1.35: + resolution: + { + integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==, + } + engines: { node: ">= 0.6" } + + mimic-fn@2.1.0: + resolution: + { + integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==, + } + engines: { node: ">=6" } + + minimatch@3.1.2: + resolution: + { + integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==, + } + + minimatch@5.1.6: + resolution: + { + integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==, + } + engines: { node: ">=10" } + + ms@2.1.2: + resolution: + { + integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==, + } + + natural-compare@1.4.0: + resolution: + { + integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==, + } + + node-int64@0.4.0: + resolution: + { + integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==, + } + + node-releases@2.0.18: + resolution: + { + integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==, + } + + normalize-path@3.0.0: + resolution: + { + integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==, + } + engines: { node: ">=0.10.0" } + + npm-run-path@4.0.1: + resolution: + { + integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==, + } + engines: { node: ">=8" } + + once@1.4.0: + resolution: + { + integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==, + } + + onetime@5.1.2: + resolution: + { + integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==, + } + engines: { node: ">=6" } + + p-limit@2.3.0: + resolution: + { + integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==, + } + engines: { node: ">=6" } + + p-limit@3.1.0: + resolution: + { + integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==, + } + engines: { node: ">=10" } + + p-locate@4.1.0: + resolution: + { + integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==, + } + engines: { node: ">=8" } + + p-try@2.2.0: + resolution: + { + integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==, + } + engines: { node: ">=6" } + + parse-json@5.2.0: + resolution: + { + integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==, + } + engines: { node: ">=8" } + + path-exists@4.0.0: + resolution: + { + integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==, + } + engines: { node: ">=8" } + + path-is-absolute@1.0.1: + resolution: + { + integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==, + } + engines: { node: ">=0.10.0" } + + path-key@3.1.1: + resolution: + { + integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==, + } + engines: { node: ">=8" } + + path-parse@1.0.7: + resolution: + { + integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==, + } + + picocolors@1.0.1: + resolution: + { + integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==, + } + + picomatch@2.3.1: + resolution: + { + integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==, + } + engines: { node: ">=8.6" } + + pirates@4.0.6: + resolution: + { + integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==, + } + engines: { node: ">= 6" } + + pkg-dir@4.2.0: + resolution: + { + integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==, + } + engines: { node: ">=8" } + + posthog-js@1.155.4: + resolution: + { + integrity: sha512-suxwAsmZGqMDXJe/RaCKI3PaDEHiuMDDhKcJklgGAg7eDnywieRkr5CoPcOOvnqTDMnuOPETr98jpYBXKUwGFQ==, + } + + posthog-node@4.1.0: + resolution: + { + integrity: sha512-Fd+aMWLjUttlPrfOniDWs35v62rOEIqP5GBzUvRswsNY8rr1g1KuDobqaRFGMCNnrtDmhzUN8y7QucrcwMY/+w==, + } + engines: { node: ">=15.0.0" } + + preact@10.23.2: + resolution: + { + integrity: sha512-kKYfePf9rzKnxOAKDpsWhg/ysrHPqT+yQ7UW4JjdnqjFIeNUnNcEJvhuA8fDenxAGWzUqtd51DfVg7xp/8T9NA==, + } + + prettier@3.3.3: + resolution: + { + integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==, + } + engines: { node: ">=14" } + hasBin: true + + pretty-format@29.7.0: + resolution: + { + integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + prompts@2.4.2: + resolution: + { + integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==, + } + engines: { node: ">= 6" } + + proxy-from-env@1.1.0: + resolution: + { + integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==, + } + + pure-rand@6.1.0: + resolution: + { + integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==, + } + + react-is@18.3.1: + resolution: + { + integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==, + } + + require-directory@2.1.1: + resolution: + { + integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==, + } + engines: { node: ">=0.10.0" } + + resolve-cwd@3.0.0: + resolution: + { + integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==, + } + engines: { node: ">=8" } + + resolve-from@5.0.0: + resolution: + { + integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==, + } + engines: { node: ">=8" } + + resolve.exports@2.0.2: + resolution: + { + integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==, + } + engines: { node: ">=10" } + + resolve@1.22.8: + resolution: + { + integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==, + } + hasBin: true + + rusha@0.8.14: + resolution: + { + integrity: sha512-cLgakCUf6PedEu15t8kbsjnwIFFR2D4RfL+W3iWFJ4iac7z4B0ZI8fxy4R3J956kAI68HclCFGL8MPoUVC3qVA==, + } + + semver@6.3.1: + resolution: + { + integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==, + } + hasBin: true + + semver@7.6.3: + resolution: + { + integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==, + } + engines: { node: ">=10" } + hasBin: true + + shebang-command@2.0.0: + resolution: + { + integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==, + } + engines: { node: ">=8" } + + shebang-regex@3.0.0: + resolution: + { + integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==, + } + engines: { node: ">=8" } + + signal-exit@3.0.7: + resolution: + { + integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==, + } + + sisteransi@1.0.5: + resolution: + { + integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==, + } + + slash@3.0.0: + resolution: + { + integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==, + } + engines: { node: ">=8" } + + source-map-support@0.5.13: + resolution: + { + integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==, + } + + source-map@0.6.1: + resolution: + { + integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==, + } + engines: { node: ">=0.10.0" } + + sprintf-js@1.0.3: + resolution: + { + integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==, + } + + stack-utils@2.0.6: + resolution: + { + integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==, + } + engines: { node: ">=10" } + + string-length@4.0.2: + resolution: + { + integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==, + } + engines: { node: ">=10" } + + string-width@4.2.3: + resolution: + { + integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==, + } + engines: { node: ">=8" } + + strip-ansi@6.0.1: + resolution: + { + integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==, + } + engines: { node: ">=8" } + + strip-bom@4.0.0: + resolution: + { + integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==, + } + engines: { node: ">=8" } + + strip-final-newline@2.0.0: + resolution: + { + integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==, + } + engines: { node: ">=6" } + + strip-json-comments@3.1.1: + resolution: + { + integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==, + } + engines: { node: ">=8" } + + supports-color@5.5.0: + resolution: + { + integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==, + } + engines: { node: ">=4" } + + supports-color@7.2.0: + resolution: + { + integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==, + } + engines: { node: ">=8" } + + supports-color@8.1.1: + resolution: + { + integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==, + } + engines: { node: ">=10" } + + supports-preserve-symlinks-flag@1.0.0: + resolution: + { + integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==, + } + engines: { node: ">= 0.4" } + + test-exclude@6.0.0: + resolution: + { + integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==, + } + engines: { node: ">=8" } + + tmpl@1.0.5: + resolution: + { + integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==, + } + + to-fast-properties@2.0.0: + resolution: + { + integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==, + } + engines: { node: ">=4" } + + to-regex-range@5.0.1: + resolution: + { + integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==, + } + engines: { node: ">=8.0" } + + ts-jest@29.2.4: + resolution: + { + integrity: sha512-3d6tgDyhCI29HlpwIq87sNuI+3Q6GLTTCeYRHCs7vDz+/3GCMwEtV9jezLyl4ZtnBgx00I7hm8PCP8cTksMGrw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0 } + hasBin: true + peerDependencies: + "@babel/core": ">=7.0.0-beta.0 <8" + "@jest/transform": ^29.0.0 + "@jest/types": ^29.0.0 + babel-jest: ^29.0.0 + esbuild: "*" + jest: ^29.0.0 + typescript: ">=4.3 <6" + peerDependenciesMeta: + "@babel/core": + optional: true + "@jest/transform": + optional: true + "@jest/types": + optional: true + babel-jest: + optional: true + esbuild: + optional: true + + ts-node@10.9.2: + resolution: + { + integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==, + } + hasBin: true + peerDependencies: + "@swc/core": ">=1.2.50" + "@swc/wasm": ">=1.2.50" + "@types/node": "*" + typescript: ">=2.7" + peerDependenciesMeta: + "@swc/core": + optional: true + "@swc/wasm": + optional: true + + type-detect@4.0.8: + resolution: + { + integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==, + } + engines: { node: ">=4" } + + type-fest@0.21.3: + resolution: + { + integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==, + } + engines: { node: ">=10" } + + typescript@5.5.4: + resolution: + { + integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==, + } + engines: { node: ">=14.17" } + hasBin: true + + undici-types@5.26.5: + resolution: + { + integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==, + } + + update-browserslist-db@1.1.0: + resolution: + { + integrity: sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==, + } + hasBin: true + peerDependencies: + browserslist: ">= 4.21.0" + + uuid@10.0.0: + resolution: + { + integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==, + } + hasBin: true + + v8-compile-cache-lib@3.0.1: + resolution: + { + integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==, + } + + v8-to-istanbul@9.3.0: + resolution: + { + integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==, + } + engines: { node: ">=10.12.0" } + + walker@1.0.8: + resolution: + { + integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==, + } + + web-vitals@4.2.3: + resolution: + { + integrity: sha512-/CFAm1mNxSmOj6i0Co+iGFJ58OS4NRGVP+AWS/l509uIK5a1bSoIVaHz/ZumpHTfHSZBpgrJ+wjfpAOrTHok5Q==, + } + + which@2.0.2: + resolution: + { + integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==, + } + engines: { node: ">= 8" } + hasBin: true + + wrap-ansi@7.0.0: + resolution: + { + integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==, + } + engines: { node: ">=10" } + + wrappy@1.0.2: + resolution: + { + integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==, + } + + write-file-atomic@4.0.2: + resolution: + { + integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==, + } + engines: { node: ^12.13.0 || ^14.15.0 || >=16.0.0 } + + y18n@5.0.8: + resolution: + { + integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==, + } + engines: { node: ">=10" } + + yallist@3.1.1: + resolution: + { + integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==, + } + + yargs-parser@21.1.1: + resolution: + { + integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==, + } + engines: { node: ">=12" } + + yargs@17.7.2: + resolution: + { + integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==, + } + engines: { node: ">=12" } + + yn@3.1.1: + resolution: + { + integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==, + } + engines: { node: ">=6" } + + yocto-queue@0.1.0: + resolution: + { + integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==, + } + engines: { node: ">=10" } + +snapshots: + "@ampproject/remapping@2.3.0": + dependencies: + "@jridgewell/gen-mapping": 0.3.5 + "@jridgewell/trace-mapping": 0.3.25 + + "@babel/code-frame@7.24.7": + dependencies: + "@babel/highlight": 7.24.7 + picocolors: 1.0.1 + + "@babel/compat-data@7.25.2": {} + + "@babel/core@7.25.2": + dependencies: + "@ampproject/remapping": 2.3.0 + "@babel/code-frame": 7.24.7 + "@babel/generator": 7.25.0 + "@babel/helper-compilation-targets": 7.25.2 + "@babel/helper-module-transforms": 7.25.2(@babel/core@7.25.2) + "@babel/helpers": 7.25.0 + "@babel/parser": 7.25.3 + "@babel/template": 7.25.0 + "@babel/traverse": 7.25.3 + "@babel/types": 7.25.2 + convert-source-map: 2.0.0 + debug: 4.3.6 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + "@babel/generator@7.25.0": + dependencies: + "@babel/types": 7.25.2 + "@jridgewell/gen-mapping": 0.3.5 + "@jridgewell/trace-mapping": 0.3.25 + jsesc: 2.5.2 + + "@babel/helper-compilation-targets@7.25.2": + dependencies: + "@babel/compat-data": 7.25.2 + "@babel/helper-validator-option": 7.24.8 + browserslist: 4.23.3 + lru-cache: 5.1.1 + semver: 6.3.1 + + "@babel/helper-module-imports@7.24.7": + dependencies: + "@babel/traverse": 7.25.3 + "@babel/types": 7.25.2 + transitivePeerDependencies: + - supports-color + + "@babel/helper-module-transforms@7.25.2(@babel/core@7.25.2)": + dependencies: + "@babel/core": 7.25.2 + "@babel/helper-module-imports": 7.24.7 + "@babel/helper-simple-access": 7.24.7 + "@babel/helper-validator-identifier": 7.24.7 + "@babel/traverse": 7.25.3 + transitivePeerDependencies: + - supports-color + + "@babel/helper-plugin-utils@7.24.8": {} + + "@babel/helper-simple-access@7.24.7": + dependencies: + "@babel/traverse": 7.25.3 + "@babel/types": 7.25.2 + transitivePeerDependencies: + - supports-color + + "@babel/helper-string-parser@7.24.8": {} + + "@babel/helper-validator-identifier@7.24.7": {} + + "@babel/helper-validator-option@7.24.8": {} + + "@babel/helpers@7.25.0": + dependencies: + "@babel/template": 7.25.0 + "@babel/types": 7.25.2 + + "@babel/highlight@7.24.7": + dependencies: + "@babel/helper-validator-identifier": 7.24.7 + chalk: 2.4.2 + js-tokens: 4.0.0 + picocolors: 1.0.1 + + "@babel/parser@7.25.3": + dependencies: + "@babel/types": 7.25.2 + + "@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.25.2)": + dependencies: + "@babel/core": 7.25.2 + "@babel/helper-plugin-utils": 7.24.8 + + "@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.25.2)": + dependencies: + "@babel/core": 7.25.2 + "@babel/helper-plugin-utils": 7.24.8 + + "@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.25.2)": + dependencies: + "@babel/core": 7.25.2 + "@babel/helper-plugin-utils": 7.24.8 + + "@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.25.2)": + dependencies: + "@babel/core": 7.25.2 + "@babel/helper-plugin-utils": 7.24.8 + + "@babel/plugin-syntax-import-attributes@7.24.7(@babel/core@7.25.2)": + dependencies: + "@babel/core": 7.25.2 + "@babel/helper-plugin-utils": 7.24.8 + + "@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.25.2)": + dependencies: + "@babel/core": 7.25.2 + "@babel/helper-plugin-utils": 7.24.8 + + "@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.25.2)": + dependencies: + "@babel/core": 7.25.2 + "@babel/helper-plugin-utils": 7.24.8 + + "@babel/plugin-syntax-jsx@7.24.7(@babel/core@7.25.2)": + dependencies: + "@babel/core": 7.25.2 + "@babel/helper-plugin-utils": 7.24.8 + + "@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.25.2)": + dependencies: + "@babel/core": 7.25.2 + "@babel/helper-plugin-utils": 7.24.8 + + "@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.25.2)": + dependencies: + "@babel/core": 7.25.2 + "@babel/helper-plugin-utils": 7.24.8 + + "@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.25.2)": + dependencies: + "@babel/core": 7.25.2 + "@babel/helper-plugin-utils": 7.24.8 + + "@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.25.2)": + dependencies: + "@babel/core": 7.25.2 + "@babel/helper-plugin-utils": 7.24.8 + + "@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.25.2)": + dependencies: + "@babel/core": 7.25.2 + "@babel/helper-plugin-utils": 7.24.8 + + "@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.25.2)": + dependencies: + "@babel/core": 7.25.2 + "@babel/helper-plugin-utils": 7.24.8 + + "@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.25.2)": + dependencies: + "@babel/core": 7.25.2 + "@babel/helper-plugin-utils": 7.24.8 + + "@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.25.2)": + dependencies: + "@babel/core": 7.25.2 + "@babel/helper-plugin-utils": 7.24.8 + + "@babel/plugin-syntax-typescript@7.24.7(@babel/core@7.25.2)": + dependencies: + "@babel/core": 7.25.2 + "@babel/helper-plugin-utils": 7.24.8 + + "@babel/template@7.25.0": + dependencies: + "@babel/code-frame": 7.24.7 + "@babel/parser": 7.25.3 + "@babel/types": 7.25.2 + + "@babel/traverse@7.25.3": + dependencies: + "@babel/code-frame": 7.24.7 + "@babel/generator": 7.25.0 + "@babel/parser": 7.25.3 + "@babel/template": 7.25.0 + "@babel/types": 7.25.2 + debug: 4.3.6 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + "@babel/types@7.25.2": + dependencies: + "@babel/helper-string-parser": 7.24.8 + "@babel/helper-validator-identifier": 7.24.7 + to-fast-properties: 2.0.0 + + "@bcoe/v8-coverage@0.2.3": {} + + "@cspotcode/source-map-support@0.8.1": + dependencies: + "@jridgewell/trace-mapping": 0.3.9 + + "@istanbuljs/load-nyc-config@1.1.0": + dependencies: + camelcase: 5.3.1 + find-up: 4.1.0 + get-package-type: 0.1.0 + js-yaml: 3.14.1 + resolve-from: 5.0.0 + + "@istanbuljs/schema@0.1.3": {} + + "@jest/console@29.7.0": + dependencies: + "@jest/types": 29.6.3 + "@types/node": 20.14.15 + chalk: 4.1.2 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + slash: 3.0.0 + + "@jest/core@29.7.0(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))": + dependencies: + "@jest/console": 29.7.0 + "@jest/reporters": 29.7.0 + "@jest/test-result": 29.7.0 + "@jest/transform": 29.7.0 + "@jest/types": 29.6.3 + "@types/node": 20.14.15 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + ci-info: 3.9.0 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-changed-files: 29.7.0 + jest-config: 29.7.0(@types/node@20.14.15)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)) + jest-haste-map: 29.7.0 + jest-message-util: 29.7.0 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-resolve-dependencies: 29.7.0 + jest-runner: 29.7.0 + jest-runtime: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + jest-watcher: 29.7.0 + micromatch: 4.0.7 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-ansi: 6.0.1 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + - ts-node + + "@jest/environment@29.7.0": + dependencies: + "@jest/fake-timers": 29.7.0 + "@jest/types": 29.6.3 + "@types/node": 20.14.15 + jest-mock: 29.7.0 + + "@jest/expect-utils@29.7.0": + dependencies: + jest-get-type: 29.6.3 + + "@jest/expect@29.7.0": + dependencies: + expect: 29.7.0 + jest-snapshot: 29.7.0 + transitivePeerDependencies: + - supports-color + + "@jest/fake-timers@29.7.0": + dependencies: + "@jest/types": 29.6.3 + "@sinonjs/fake-timers": 10.3.0 + "@types/node": 20.14.15 + jest-message-util: 29.7.0 + jest-mock: 29.7.0 + jest-util: 29.7.0 + + "@jest/globals@29.7.0": + dependencies: + "@jest/environment": 29.7.0 + "@jest/expect": 29.7.0 + "@jest/types": 29.6.3 + jest-mock: 29.7.0 + transitivePeerDependencies: + - supports-color + + "@jest/reporters@29.7.0": + dependencies: + "@bcoe/v8-coverage": 0.2.3 + "@jest/console": 29.7.0 + "@jest/test-result": 29.7.0 + "@jest/transform": 29.7.0 + "@jest/types": 29.6.3 + "@jridgewell/trace-mapping": 0.3.25 + "@types/node": 20.14.15 + chalk: 4.1.2 + collect-v8-coverage: 1.0.2 + exit: 0.1.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-instrument: 6.0.3 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 4.0.1 + istanbul-reports: 3.1.7 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + jest-worker: 29.7.0 + slash: 3.0.0 + string-length: 4.0.2 + strip-ansi: 6.0.1 + v8-to-istanbul: 9.3.0 + transitivePeerDependencies: + - supports-color + + "@jest/schemas@29.6.3": + dependencies: + "@sinclair/typebox": 0.27.8 + + "@jest/source-map@29.6.3": + dependencies: + "@jridgewell/trace-mapping": 0.3.25 + callsites: 3.1.0 + graceful-fs: 4.2.11 + + "@jest/test-result@29.7.0": + dependencies: + "@jest/console": 29.7.0 + "@jest/types": 29.6.3 + "@types/istanbul-lib-coverage": 2.0.6 + collect-v8-coverage: 1.0.2 + + "@jest/test-sequencer@29.7.0": + dependencies: + "@jest/test-result": 29.7.0 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + slash: 3.0.0 + + "@jest/transform@29.7.0": + dependencies: + "@babel/core": 7.25.2 + "@jest/types": 29.6.3 + "@jridgewell/trace-mapping": 0.3.25 + babel-plugin-istanbul: 6.1.1 + chalk: 4.1.2 + convert-source-map: 2.0.0 + fast-json-stable-stringify: 2.1.0 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-regex-util: 29.6.3 + jest-util: 29.7.0 + micromatch: 4.0.7 + pirates: 4.0.6 + slash: 3.0.0 + write-file-atomic: 4.0.2 + transitivePeerDependencies: + - supports-color + + "@jest/types@29.6.3": + dependencies: + "@jest/schemas": 29.6.3 + "@types/istanbul-lib-coverage": 2.0.6 + "@types/istanbul-reports": 3.0.4 + "@types/node": 20.14.15 + "@types/yargs": 17.0.33 + chalk: 4.1.2 + + "@jridgewell/gen-mapping@0.3.5": + dependencies: + "@jridgewell/set-array": 1.2.1 + "@jridgewell/sourcemap-codec": 1.5.0 + "@jridgewell/trace-mapping": 0.3.25 + + "@jridgewell/resolve-uri@3.1.2": {} + + "@jridgewell/set-array@1.2.1": {} + + "@jridgewell/sourcemap-codec@1.5.0": {} + + "@jridgewell/trace-mapping@0.3.25": + dependencies: + "@jridgewell/resolve-uri": 3.1.2 + "@jridgewell/sourcemap-codec": 1.5.0 + + "@jridgewell/trace-mapping@0.3.9": + dependencies: + "@jridgewell/resolve-uri": 3.1.2 + "@jridgewell/sourcemap-codec": 1.5.0 + + "@sinclair/typebox@0.27.8": {} + + "@sinonjs/commons@3.0.1": + dependencies: + type-detect: 4.0.8 + + "@sinonjs/fake-timers@10.3.0": + dependencies: + "@sinonjs/commons": 3.0.1 + + "@tsconfig/node10@1.0.11": {} + + "@tsconfig/node12@1.0.11": {} + + "@tsconfig/node14@1.0.3": {} + + "@tsconfig/node16@1.0.4": {} + + "@types/babel__core@7.20.5": + dependencies: + "@babel/parser": 7.25.3 + "@babel/types": 7.25.2 + "@types/babel__generator": 7.6.8 + "@types/babel__template": 7.4.4 + "@types/babel__traverse": 7.20.6 + + "@types/babel__generator@7.6.8": + dependencies: + "@babel/types": 7.25.2 + + "@types/babel__template@7.4.4": + dependencies: + "@babel/parser": 7.25.3 + "@babel/types": 7.25.2 + + "@types/babel__traverse@7.20.6": + dependencies: + "@babel/types": 7.25.2 + + "@types/graceful-fs@4.1.9": + dependencies: + "@types/node": 20.14.15 + + "@types/istanbul-lib-coverage@2.0.6": {} + + "@types/istanbul-lib-report@3.0.3": + dependencies: + "@types/istanbul-lib-coverage": 2.0.6 + + "@types/istanbul-reports@3.0.4": + dependencies: + "@types/istanbul-lib-report": 3.0.3 + + "@types/jest@29.5.12": + dependencies: + expect: 29.7.0 + pretty-format: 29.7.0 + + "@types/node@20.14.15": + dependencies: + undici-types: 5.26.5 + + "@types/stack-utils@2.0.3": {} + + "@types/uuid@10.0.0": {} + + "@types/yargs-parser@21.0.3": {} + + "@types/yargs@17.0.33": + dependencies: + "@types/yargs-parser": 21.0.3 + + acorn-walk@8.3.3: + dependencies: + acorn: 8.12.1 + + acorn@8.12.1: {} + + ansi-escapes@4.3.2: + dependencies: + type-fest: 0.21.3 + + ansi-regex@5.0.1: {} + + ansi-styles@3.2.1: + dependencies: + color-convert: 1.9.3 + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@5.2.0: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + arg@4.1.3: {} + + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + + async@3.2.5: {} + + asynckit@0.4.0: {} + + axios@1.7.4: + dependencies: + follow-redirects: 1.15.6 + form-data: 4.0.0 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + + babel-jest@29.7.0(@babel/core@7.25.2): + dependencies: + "@babel/core": 7.25.2 + "@jest/transform": 29.7.0 + "@types/babel__core": 7.20.5 + babel-plugin-istanbul: 6.1.1 + babel-preset-jest: 29.6.3(@babel/core@7.25.2) + chalk: 4.1.2 + graceful-fs: 4.2.11 + slash: 3.0.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-istanbul@6.1.1: + dependencies: + "@babel/helper-plugin-utils": 7.24.8 + "@istanbuljs/load-nyc-config": 1.1.0 + "@istanbuljs/schema": 0.1.3 + istanbul-lib-instrument: 5.2.1 + test-exclude: 6.0.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-jest-hoist@29.6.3: + dependencies: + "@babel/template": 7.25.0 + "@babel/types": 7.25.2 + "@types/babel__core": 7.20.5 + "@types/babel__traverse": 7.20.6 + + babel-preset-current-node-syntax@1.1.0(@babel/core@7.25.2): + dependencies: + "@babel/core": 7.25.2 + "@babel/plugin-syntax-async-generators": 7.8.4(@babel/core@7.25.2) + "@babel/plugin-syntax-bigint": 7.8.3(@babel/core@7.25.2) + "@babel/plugin-syntax-class-properties": 7.12.13(@babel/core@7.25.2) + "@babel/plugin-syntax-class-static-block": 7.14.5(@babel/core@7.25.2) + "@babel/plugin-syntax-import-attributes": 7.24.7(@babel/core@7.25.2) + "@babel/plugin-syntax-import-meta": 7.10.4(@babel/core@7.25.2) + "@babel/plugin-syntax-json-strings": 7.8.3(@babel/core@7.25.2) + "@babel/plugin-syntax-logical-assignment-operators": 7.10.4(@babel/core@7.25.2) + "@babel/plugin-syntax-nullish-coalescing-operator": 7.8.3(@babel/core@7.25.2) + "@babel/plugin-syntax-numeric-separator": 7.10.4(@babel/core@7.25.2) + "@babel/plugin-syntax-object-rest-spread": 7.8.3(@babel/core@7.25.2) + "@babel/plugin-syntax-optional-catch-binding": 7.8.3(@babel/core@7.25.2) + "@babel/plugin-syntax-optional-chaining": 7.8.3(@babel/core@7.25.2) + "@babel/plugin-syntax-private-property-in-object": 7.14.5(@babel/core@7.25.2) + "@babel/plugin-syntax-top-level-await": 7.14.5(@babel/core@7.25.2) + + babel-preset-jest@29.6.3(@babel/core@7.25.2): + dependencies: + "@babel/core": 7.25.2 + babel-plugin-jest-hoist: 29.6.3 + babel-preset-current-node-syntax: 1.1.0(@babel/core@7.25.2) + + balanced-match@1.0.2: {} + + brace-expansion@1.1.11: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + browserslist@4.23.3: + dependencies: + caniuse-lite: 1.0.30001651 + electron-to-chromium: 1.5.9 + node-releases: 2.0.18 + update-browserslist-db: 1.1.0(browserslist@4.23.3) + + bs-logger@0.2.6: + dependencies: + fast-json-stable-stringify: 2.1.0 + + bser@2.1.1: + dependencies: + node-int64: 0.4.0 + + buffer-from@1.1.2: {} + + callsites@3.1.0: {} + + camelcase@5.3.1: {} + + camelcase@6.3.0: {} + + caniuse-lite@1.0.30001651: {} + + chalk@2.4.2: + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + char-regex@1.0.2: {} + + ci-info@3.9.0: {} + + cjs-module-lexer@1.3.1: {} + + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + co@4.6.0: {} + + collect-v8-coverage@1.0.2: {} + + color-convert@1.9.3: + dependencies: + color-name: 1.1.3 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.3: {} + + color-name@1.1.4: {} + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + concat-map@0.0.1: {} + + convert-source-map@2.0.0: {} + + create-jest@29.7.0(@types/node@20.14.15)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)): + dependencies: + "@jest/types": 29.6.3 + chalk: 4.1.2 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-config: 29.7.0(@types/node@20.14.15)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)) + jest-util: 29.7.0 + prompts: 2.4.2 + transitivePeerDependencies: + - "@types/node" + - babel-plugin-macros + - supports-color + - ts-node + + create-require@1.1.1: {} + + cross-spawn@7.0.3: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + debug@4.3.6: + dependencies: + ms: 2.1.2 + + dedent@1.5.3: {} + + deepmerge@4.3.1: {} + + delayed-stream@1.0.0: {} + + detect-newline@3.1.0: {} + + diff-sequences@29.6.3: {} + + diff@4.0.2: {} + + ejs@3.1.10: + dependencies: + jake: 10.9.2 + + electron-to-chromium@1.5.9: {} + + emittery@0.13.1: {} + + emoji-regex@8.0.0: {} + + error-ex@1.3.2: + dependencies: + is-arrayish: 0.2.1 + + escalade@3.1.2: {} + + escape-string-regexp@1.0.5: {} + + escape-string-regexp@2.0.0: {} + + esprima@4.0.1: {} + + execa@5.1.1: + dependencies: + cross-spawn: 7.0.3 + get-stream: 6.0.1 + human-signals: 2.1.0 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + + exit@0.1.2: {} + + expect@29.7.0: + dependencies: + "@jest/expect-utils": 29.7.0 + jest-get-type: 29.6.3 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + + fast-json-stable-stringify@2.1.0: {} + + fb-watchman@2.0.2: + dependencies: + bser: 2.1.1 + + fflate@0.4.8: {} + + filelist@1.0.4: + dependencies: + minimatch: 5.1.6 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + find-up@4.1.0: + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + + follow-redirects@1.15.6: {} + + form-data@4.0.0: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + + fs.realpath@1.0.0: {} + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + gensync@1.0.0-beta.2: {} + + get-caller-file@2.0.5: {} + + get-package-type@0.1.0: {} + + get-stream@6.0.1: {} + + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + globals@11.12.0: {} + + graceful-fs@4.2.11: {} + + has-flag@3.0.0: {} + + has-flag@4.0.0: {} + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + html-escaper@2.0.2: {} + + human-signals@2.1.0: {} + + import-local@3.2.0: + dependencies: + pkg-dir: 4.2.0 + resolve-cwd: 3.0.0 + + imurmurhash@0.1.4: {} + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + + is-arrayish@0.2.1: {} + + is-core-module@2.15.0: + dependencies: + hasown: 2.0.2 + + is-fullwidth-code-point@3.0.0: {} + + is-generator-fn@2.1.0: {} + + is-number@7.0.0: {} + + is-stream@2.0.1: {} + + isexe@2.0.0: {} + + istanbul-lib-coverage@3.2.2: {} + + istanbul-lib-instrument@5.2.1: + dependencies: + "@babel/core": 7.25.2 + "@babel/parser": 7.25.3 + "@istanbuljs/schema": 0.1.3 + istanbul-lib-coverage: 3.2.2 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + istanbul-lib-instrument@6.0.3: + dependencies: + "@babel/core": 7.25.2 + "@babel/parser": 7.25.3 + "@istanbuljs/schema": 0.1.3 + istanbul-lib-coverage: 3.2.2 + semver: 7.6.3 + transitivePeerDependencies: + - supports-color + + istanbul-lib-report@3.0.1: + dependencies: + istanbul-lib-coverage: 3.2.2 + make-dir: 4.0.0 + supports-color: 7.2.0 + + istanbul-lib-source-maps@4.0.1: + dependencies: + debug: 4.3.6 + istanbul-lib-coverage: 3.2.2 + source-map: 0.6.1 + transitivePeerDependencies: + - supports-color + + istanbul-reports@3.1.7: + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + + jake@10.9.2: + dependencies: + async: 3.2.5 + chalk: 4.1.2 + filelist: 1.0.4 + minimatch: 3.1.2 + + jest-changed-files@29.7.0: + dependencies: + execa: 5.1.1 + jest-util: 29.7.0 + p-limit: 3.1.0 + + jest-circus@29.7.0: + dependencies: + "@jest/environment": 29.7.0 + "@jest/expect": 29.7.0 + "@jest/test-result": 29.7.0 + "@jest/types": 29.6.3 + "@types/node": 20.14.15 + chalk: 4.1.2 + co: 4.6.0 + dedent: 1.5.3 + is-generator-fn: 2.1.0 + jest-each: 29.7.0 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-runtime: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + p-limit: 3.1.0 + pretty-format: 29.7.0 + pure-rand: 6.1.0 + slash: 3.0.0 + stack-utils: 2.0.6 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + + jest-cli@29.7.0(@types/node@20.14.15)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)): + dependencies: + "@jest/core": 29.7.0(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)) + "@jest/test-result": 29.7.0 + "@jest/types": 29.6.3 + chalk: 4.1.2 + create-jest: 29.7.0(@types/node@20.14.15)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)) + exit: 0.1.2 + import-local: 3.2.0 + jest-config: 29.7.0(@types/node@20.14.15)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)) + jest-util: 29.7.0 + jest-validate: 29.7.0 + yargs: 17.7.2 + transitivePeerDependencies: + - "@types/node" + - babel-plugin-macros + - supports-color + - ts-node + + jest-config@29.7.0(@types/node@20.14.15)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)): + dependencies: + "@babel/core": 7.25.2 + "@jest/test-sequencer": 29.7.0 + "@jest/types": 29.6.3 + babel-jest: 29.7.0(@babel/core@7.25.2) + chalk: 4.1.2 + ci-info: 3.9.0 + deepmerge: 4.3.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-circus: 29.7.0 + jest-environment-node: 29.7.0 + jest-get-type: 29.6.3 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-runner: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + micromatch: 4.0.7 + parse-json: 5.2.0 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-json-comments: 3.1.1 + optionalDependencies: + "@types/node": 20.14.15 + ts-node: 10.9.2(@types/node@20.14.15)(typescript@5.5.4) + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + + jest-diff@29.7.0: + dependencies: + chalk: 4.1.2 + diff-sequences: 29.6.3 + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + + jest-docblock@29.7.0: + dependencies: + detect-newline: 3.1.0 + + jest-each@29.7.0: + dependencies: + "@jest/types": 29.6.3 + chalk: 4.1.2 + jest-get-type: 29.6.3 + jest-util: 29.7.0 + pretty-format: 29.7.0 + + jest-environment-node@29.7.0: + dependencies: + "@jest/environment": 29.7.0 + "@jest/fake-timers": 29.7.0 + "@jest/types": 29.6.3 + "@types/node": 20.14.15 + jest-mock: 29.7.0 + jest-util: 29.7.0 + + jest-get-type@29.6.3: {} + + jest-haste-map@29.7.0: + dependencies: + "@jest/types": 29.6.3 + "@types/graceful-fs": 4.1.9 + "@types/node": 20.14.15 + anymatch: 3.1.3 + fb-watchman: 2.0.2 + graceful-fs: 4.2.11 + jest-regex-util: 29.6.3 + jest-util: 29.7.0 + jest-worker: 29.7.0 + micromatch: 4.0.7 + walker: 1.0.8 + optionalDependencies: + fsevents: 2.3.3 + + jest-leak-detector@29.7.0: + dependencies: + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + + jest-matcher-utils@29.7.0: + dependencies: + chalk: 4.1.2 + jest-diff: 29.7.0 + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + + jest-message-util@29.7.0: + dependencies: + "@babel/code-frame": 7.24.7 + "@jest/types": 29.6.3 + "@types/stack-utils": 2.0.3 + chalk: 4.1.2 + graceful-fs: 4.2.11 + micromatch: 4.0.7 + pretty-format: 29.7.0 + slash: 3.0.0 + stack-utils: 2.0.6 + + jest-mock@29.7.0: + dependencies: + "@jest/types": 29.6.3 + "@types/node": 20.14.15 + jest-util: 29.7.0 + + jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): + optionalDependencies: + jest-resolve: 29.7.0 + + jest-regex-util@29.6.3: {} + + jest-resolve-dependencies@29.7.0: + dependencies: + jest-regex-util: 29.6.3 + jest-snapshot: 29.7.0 + transitivePeerDependencies: + - supports-color + + jest-resolve@29.7.0: + dependencies: + chalk: 4.1.2 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-pnp-resolver: 1.2.3(jest-resolve@29.7.0) + jest-util: 29.7.0 + jest-validate: 29.7.0 + resolve: 1.22.8 + resolve.exports: 2.0.2 + slash: 3.0.0 + + jest-runner@29.7.0: + dependencies: + "@jest/console": 29.7.0 + "@jest/environment": 29.7.0 + "@jest/test-result": 29.7.0 + "@jest/transform": 29.7.0 + "@jest/types": 29.6.3 + "@types/node": 20.14.15 + chalk: 4.1.2 + emittery: 0.13.1 + graceful-fs: 4.2.11 + jest-docblock: 29.7.0 + jest-environment-node: 29.7.0 + jest-haste-map: 29.7.0 + jest-leak-detector: 29.7.0 + jest-message-util: 29.7.0 + jest-resolve: 29.7.0 + jest-runtime: 29.7.0 + jest-util: 29.7.0 + jest-watcher: 29.7.0 + jest-worker: 29.7.0 + p-limit: 3.1.0 + source-map-support: 0.5.13 + transitivePeerDependencies: + - supports-color + + jest-runtime@29.7.0: + dependencies: + "@jest/environment": 29.7.0 + "@jest/fake-timers": 29.7.0 + "@jest/globals": 29.7.0 + "@jest/source-map": 29.6.3 + "@jest/test-result": 29.7.0 + "@jest/transform": 29.7.0 + "@jest/types": 29.6.3 + "@types/node": 20.14.15 + chalk: 4.1.2 + cjs-module-lexer: 1.3.1 + collect-v8-coverage: 1.0.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-message-util: 29.7.0 + jest-mock: 29.7.0 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + slash: 3.0.0 + strip-bom: 4.0.0 + transitivePeerDependencies: + - supports-color + + jest-snapshot@29.7.0: + dependencies: + "@babel/core": 7.25.2 + "@babel/generator": 7.25.0 + "@babel/plugin-syntax-jsx": 7.24.7(@babel/core@7.25.2) + "@babel/plugin-syntax-typescript": 7.24.7(@babel/core@7.25.2) + "@babel/types": 7.25.2 + "@jest/expect-utils": 29.7.0 + "@jest/transform": 29.7.0 + "@jest/types": 29.6.3 + babel-preset-current-node-syntax: 1.1.0(@babel/core@7.25.2) + chalk: 4.1.2 + expect: 29.7.0 + graceful-fs: 4.2.11 + jest-diff: 29.7.0 + jest-get-type: 29.6.3 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + natural-compare: 1.4.0 + pretty-format: 29.7.0 + semver: 7.6.3 + transitivePeerDependencies: + - supports-color + + jest-util@29.7.0: + dependencies: + "@jest/types": 29.6.3 + "@types/node": 20.14.15 + chalk: 4.1.2 + ci-info: 3.9.0 + graceful-fs: 4.2.11 + picomatch: 2.3.1 + + jest-validate@29.7.0: + dependencies: + "@jest/types": 29.6.3 + camelcase: 6.3.0 + chalk: 4.1.2 + jest-get-type: 29.6.3 + leven: 3.1.0 + pretty-format: 29.7.0 + + jest-watcher@29.7.0: + dependencies: + "@jest/test-result": 29.7.0 + "@jest/types": 29.6.3 + "@types/node": 20.14.15 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + emittery: 0.13.1 + jest-util: 29.7.0 + string-length: 4.0.2 + + jest-worker@29.7.0: + dependencies: + "@types/node": 20.14.15 + jest-util: 29.7.0 + merge-stream: 2.0.0 + supports-color: 8.1.1 + + jest@29.7.0(@types/node@20.14.15)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)): + dependencies: + "@jest/core": 29.7.0(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)) + "@jest/types": 29.6.3 + import-local: 3.2.0 + jest-cli: 29.7.0(@types/node@20.14.15)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)) + transitivePeerDependencies: + - "@types/node" + - babel-plugin-macros + - supports-color + - ts-node + + js-tokens@4.0.0: {} + + js-yaml@3.14.1: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + + jsesc@2.5.2: {} + + json-parse-even-better-errors@2.3.1: {} + + json5@2.2.3: {} + + kleur@3.0.3: {} + + leven@3.1.0: {} + + lines-and-columns@1.2.4: {} + + locate-path@5.0.0: + dependencies: + p-locate: 4.1.0 + + lodash.memoize@4.1.2: {} + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + make-dir@4.0.0: + dependencies: + semver: 7.6.3 + + make-error@1.3.6: {} + + makeerror@1.0.12: + dependencies: + tmpl: 1.0.5 + + merge-stream@2.0.0: {} + + micromatch@4.0.7: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + mimic-fn@2.1.0: {} + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.11 + + minimatch@5.1.6: + dependencies: + brace-expansion: 2.0.1 + + ms@2.1.2: {} + + natural-compare@1.4.0: {} + + node-int64@0.4.0: {} + + node-releases@2.0.18: {} + + normalize-path@3.0.0: {} + + npm-run-path@4.0.1: + dependencies: + path-key: 3.1.1 + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + onetime@5.1.2: + dependencies: + mimic-fn: 2.1.0 + + p-limit@2.3.0: + dependencies: + p-try: 2.2.0 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@4.1.0: + dependencies: + p-limit: 2.3.0 + + p-try@2.2.0: {} + + parse-json@5.2.0: + dependencies: + "@babel/code-frame": 7.24.7 + error-ex: 1.3.2 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + + path-exists@4.0.0: {} + + path-is-absolute@1.0.1: {} + + path-key@3.1.1: {} + + path-parse@1.0.7: {} + + picocolors@1.0.1: {} + + picomatch@2.3.1: {} + + pirates@4.0.6: {} + + pkg-dir@4.2.0: + dependencies: + find-up: 4.1.0 + + posthog-js@1.155.4: + dependencies: + fflate: 0.4.8 + preact: 10.23.2 + web-vitals: 4.2.3 + + posthog-node@4.1.0: + dependencies: + axios: 1.7.4 + rusha: 0.8.14 + transitivePeerDependencies: + - debug + + preact@10.23.2: {} + + prettier@3.3.3: {} + + pretty-format@29.7.0: + dependencies: + "@jest/schemas": 29.6.3 + ansi-styles: 5.2.0 + react-is: 18.3.1 + + prompts@2.4.2: + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + + proxy-from-env@1.1.0: {} + + pure-rand@6.1.0: {} + + react-is@18.3.1: {} + + require-directory@2.1.1: {} + + resolve-cwd@3.0.0: + dependencies: + resolve-from: 5.0.0 + + resolve-from@5.0.0: {} + + resolve.exports@2.0.2: {} + + resolve@1.22.8: + dependencies: + is-core-module: 2.15.0 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + rusha@0.8.14: {} + + semver@6.3.1: {} + + semver@7.6.3: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + signal-exit@3.0.7: {} + + sisteransi@1.0.5: {} + + slash@3.0.0: {} + + source-map-support@0.5.13: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map@0.6.1: {} + + sprintf-js@1.0.3: {} + + stack-utils@2.0.6: + dependencies: + escape-string-regexp: 2.0.0 + + string-length@4.0.2: + dependencies: + char-regex: 1.0.2 + strip-ansi: 6.0.1 + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-bom@4.0.0: {} + + strip-final-newline@2.0.0: {} + + strip-json-comments@3.1.1: {} + + supports-color@5.5.0: + dependencies: + has-flag: 3.0.0 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-color@8.1.1: + dependencies: + has-flag: 4.0.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + test-exclude@6.0.0: + dependencies: + "@istanbuljs/schema": 0.1.3 + glob: 7.2.3 + minimatch: 3.1.2 + + tmpl@1.0.5: {} + + to-fast-properties@2.0.0: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + ts-jest@29.2.4(@babel/core@7.25.2)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.25.2))(jest@29.7.0(@types/node@20.14.15)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)))(typescript@5.5.4): + dependencies: + bs-logger: 0.2.6 + ejs: 3.1.10 + fast-json-stable-stringify: 2.1.0 + jest: 29.7.0(@types/node@20.14.15)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)) + jest-util: 29.7.0 + json5: 2.2.3 + lodash.memoize: 4.1.2 + make-error: 1.3.6 + semver: 7.6.3 + typescript: 5.5.4 + yargs-parser: 21.1.1 + optionalDependencies: + "@babel/core": 7.25.2 + "@jest/transform": 29.7.0 + "@jest/types": 29.6.3 + babel-jest: 29.7.0(@babel/core@7.25.2) + + ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4): + dependencies: + "@cspotcode/source-map-support": 0.8.1 + "@tsconfig/node10": 1.0.11 + "@tsconfig/node12": 1.0.11 + "@tsconfig/node14": 1.0.3 + "@tsconfig/node16": 1.0.4 + "@types/node": 20.14.15 + acorn: 8.12.1 + acorn-walk: 8.3.3 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.5.4 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + + type-detect@4.0.8: {} + + type-fest@0.21.3: {} + + typescript@5.5.4: {} + + undici-types@5.26.5: {} + + update-browserslist-db@1.1.0(browserslist@4.23.3): + dependencies: + browserslist: 4.23.3 + escalade: 3.1.2 + picocolors: 1.0.1 + + uuid@10.0.0: {} + + v8-compile-cache-lib@3.0.1: {} + + v8-to-istanbul@9.3.0: + dependencies: + "@jridgewell/trace-mapping": 0.3.25 + "@types/istanbul-lib-coverage": 2.0.6 + convert-source-map: 2.0.0 + + walker@1.0.8: + dependencies: + makeerror: 1.0.12 + + web-vitals@4.2.3: {} + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrappy@1.0.2: {} + + write-file-atomic@4.0.2: + dependencies: + imurmurhash: 0.1.4 + signal-exit: 3.0.7 + + y18n@5.0.8: {} + + yallist@3.1.1: {} + + yargs-parser@21.1.1: {} + + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.1.2 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + + yn@3.1.1: {} + + yocto-queue@0.1.0: {} diff --git a/r2r_js_sdk/src/feature.ts b/r2r_js_sdk/src/feature.ts new file mode 100644 index 000000000..0cff1ab2a --- /dev/null +++ b/r2r_js_sdk/src/feature.ts @@ -0,0 +1,145 @@ +import type * as PostHogJs from "posthog-js"; +import { PostHog as PostHogNodeClient } from "posthog-node"; +import { v4 as uuidv4 } from "uuid"; + +const posthogApiKey = "phc_OPBbibOIErCGc4NDLQsOrMuYFTKDmRwXX6qxnTr6zpU"; +const posthogHost = "https://us.i.posthog.com"; + +let posthog: PostHogJs.PostHog | PostHogNodeClient; +let isPostHogInitialized = false; +let distinctId: string = uuidv4(); + +function isBrowser( + client: PostHogJs.PostHog | PostHogNodeClient, +): client is PostHogJs.PostHog { + return typeof window !== "undefined"; +} + +export function initializeTelemetry() { + if (isPostHogInitialized) { + return; + } + + if (typeof window !== "undefined") { + // Browser environment + import("posthog-js").then((posthogJs) => { + posthog = posthogJs.default; + posthog.init(posthogApiKey, { + api_host: posthogHost, + }); + + window.addEventListener("beforeunload", () => { + (posthog as PostHogJs.PostHog).capture("PageUnload"); + }); + + isPostHogInitialized = true; + }); + } else { + // Node.js environment + posthog = new PostHogNodeClient(posthogApiKey, { host: posthogHost }); + isPostHogInitialized = true; + } + + if (process.env.R2R_JS_DISABLE_TELEMETRY === "true") { + if (isBrowser(posthog)) { + posthog.opt_out_capturing(); + } else { + posthog.disable(); + } + } +} + +type AsyncFunction = (...args: any[]) => Promise; + +function captureEvent(eventName: string, properties?: Record) { + if (isPostHogInitialized) { + const environment = typeof window !== "undefined" ? "browser" : "node"; + const eventProperties = { ...properties, environment }; + + if (isBrowser(posthog)) { + posthog.capture(eventName, eventProperties); + } else { + (posthog as PostHogNodeClient).capture({ + distinctId: distinctId, + event: eventName, + properties: eventProperties, + }); + } + } +} + +export function feature(operationName: string) { + return function ( + _target: any, + _propertyKey: string | symbol, + descriptor: TypedPropertyDescriptor, + ): TypedPropertyDescriptor { + const originalMethod = descriptor.value!; + + descriptor.value = async function ( + this: any, + ...args: any[] + ): Promise { + try { + const result = await originalMethod.apply(this, args); + captureEvent("TSClient", { operation: operationName }); + return result; + } catch (error: unknown) { + captureEvent("TSClient", { + operation: operationName, + errorMessage: + error instanceof Error ? error.message : "Unknown error", + }); + throw error; + } finally { + if (isPostHogInitialized && !isBrowser(posthog)) { + // Flush events in Node.js environment + await (posthog as PostHogNodeClient).shutdown(); + } + } + }; + + return descriptor; + }; +} + +export function featureGenerator(operationName: string) { + return function ( + _target: any, + _propertyKey: string | symbol, + descriptor: TypedPropertyDescriptor< + (...args: any[]) => AsyncGenerator + >, + ): TypedPropertyDescriptor< + (...args: any[]) => AsyncGenerator + > { + const originalMethod = descriptor.value!; + + descriptor.value = async function* ( + this: any, + ...args: any[] + ): AsyncGenerator { + try { + const generator = originalMethod.apply(this, args); + for await (const chunk of generator) { + yield chunk; + } + captureEvent("TSClient", { operation: operationName }); + } catch (error: unknown) { + captureEvent("TSClient", { + operation: operationName, + errorMessage: + error instanceof Error ? error.message : "Unknown error", + }); + throw error; + } finally { + if (isPostHogInitialized && !isBrowser(posthog)) { + // Flush events in Node.js environment + await (posthog as PostHogNodeClient).shutdown(); + } + } + }; + + return descriptor; + }; +} diff --git a/r2r_js_sdk/src/index.ts b/r2r_js_sdk/src/index.ts new file mode 100644 index 000000000..0f4285074 --- /dev/null +++ b/r2r_js_sdk/src/index.ts @@ -0,0 +1,3 @@ +export { r2rClient } from "./r2rClient"; +export * from "./models"; +export { feature, initializeTelemetry } from "./feature"; diff --git a/r2r_js_sdk/src/models.tsx b/r2r_js_sdk/src/models.tsx new file mode 100644 index 000000000..ac800d737 --- /dev/null +++ b/r2r_js_sdk/src/models.tsx @@ -0,0 +1,61 @@ +export interface TokenInfo { + token: string; +} + +export interface LoginResponse { + results: { + access_token: TokenInfo; + refresh_token: TokenInfo; + }; +} + +export interface RefreshTokenResponse { + results: { + access_token: { token: string }; + refresh_token: { token: string }; + }; +} + +export interface GenerationConfig { + temperature?: number; + top_p?: number; + top_k?: number; + max_tokens_to_sample?: number; + model?: string; + stream?: boolean; + functions?: Array>; + skip_special_tokens?: boolean; + stop_token?: string; + num_beams?: number; + do_sample?: boolean; + generate_with_chat?: boolean; + add_generation_kwargs?: Record; + api_base?: string; +} + +export interface VectorSearchSettings { + use_vector_search?: boolean; + filters?: Record; + search_limit?: number; + do_hybrid_search?: boolean; +} + +export interface KGSearchSettings { + use_kg_search?: boolean; + kg_search_type?: "global" | "local"; + kg_search_level?: number | null; + kg_search_generation_config?: GenerationConfig; + entity_types?: any[]; + relationships?: any[]; + max_community_description_length?: number; + max_llm_queries_for_global_search?: number; + local_search_limits?: Record; +} +export interface Message { + role: string; + content: string; +} + +export interface R2RDocumentChunksRequest { + document_id: string; +} diff --git a/r2r_js_sdk/src/r2rClient.ts b/r2r_js_sdk/src/r2rClient.ts new file mode 100644 index 000000000..b1703e069 --- /dev/null +++ b/r2r_js_sdk/src/r2rClient.ts @@ -0,0 +1,1286 @@ +import axios, { + AxiosInstance, + Method, + AxiosResponse, + AxiosRequestConfig, +} from "axios"; +import FormData from "form-data"; +import { URLSearchParams } from "url"; + +let fs: any; +if (typeof window === "undefined") { + import("fs").then((module) => { + fs = module; + }); +} + +import { feature, featureGenerator, initializeTelemetry } from "./feature"; +import { + LoginResponse, + TokenInfo, + Message, + RefreshTokenResponse, + VectorSearchSettings, + KGSearchSettings, + GenerationConfig, +} from "./models"; + +function handleRequestError(response: AxiosResponse): void { + if (response.status < 400) { + return; + } + + let message: string; + const errorContent = response.data; + + if ( + typeof errorContent === "object" && + errorContent !== null && + "detail" in errorContent + ) { + const { detail } = errorContent; + if (typeof detail === "object" && detail !== null) { + message = (detail as { message?: string }).message || response.statusText; + } else { + message = String(detail); + } + } else { + message = String(errorContent); + } + + throw new Error(`Status ${response.status}: ${message}`); +} + +export class r2rClient { + private axiosInstance: AxiosInstance; + private baseUrl: string; + private accessToken: string | null; + private refreshToken: string | null; + + constructor(baseURL: string, prefix: string = "/v1") { + this.baseUrl = `${baseURL}${prefix}`; + this.accessToken = null; + this.refreshToken = null; + + this.axiosInstance = axios.create({ + baseURL: this.baseUrl, + headers: { + "Content-Type": "application/json", + }, + transformRequest: [ + (data) => { + if (typeof data === "string") { + return data; + } + return JSON.stringify(data); + }, + ], + }); + + initializeTelemetry(); + } + + private async _makeRequest( + method: Method, + endpoint: string, + options: any = {}, + ): Promise { + const url = `${endpoint}`; + const config: AxiosRequestConfig = { + method, + url, + headers: { ...options.headers }, + params: options.params, + ...options, + responseType: options.responseType || "json", + }; + + config.headers = config.headers || {}; + + if (options.params) { + config.paramsSerializer = (params) => { + return Object.entries(params) + .map( + ([key, value]) => + `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`, + ) + .join("&"); + }; + } + + if (options.data) { + if (typeof FormData !== "undefined" && options.data instanceof FormData) { + config.data = options.data; + delete config.headers["Content-Type"]; + } else if ( + typeof URLSearchParams !== "undefined" && + options.data instanceof URLSearchParams + ) { + config.data = options.data.toString(); + config.headers["Content-Type"] = "application/x-www-form-urlencoded"; + } else if (typeof options.data === "object") { + config.data = JSON.stringify(options.data); + if (method !== "DELETE") { + config.headers["Content-Type"] = "application/json"; + } + } else { + config.data = options.data; + } + } + + if ( + this.accessToken && + !["register", "login", "verify_email", "health"].includes(endpoint) + ) { + config.headers.Authorization = `Bearer ${this.accessToken}`; + } + + if (options.responseType === "stream") { + const fetchHeaders: Record = {}; + Object.entries(config.headers).forEach(([key, value]) => { + if (typeof value === "string") { + fetchHeaders[key] = value; + } + }); + const response = await fetch(`${this.baseUrl}/${endpoint}`, { + method, + headers: fetchHeaders, + body: config.data, + }); + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + + return response.body as unknown as T; + } + + try { + const response = await this.axiosInstance.request(config); + return options.returnFullResponse + ? (response as any as T) + : response.data; + } catch (error) { + if (axios.isAxiosError(error) && error.response) { + handleRequestError(error.response); + } + throw error; + } + } + + private _ensureAuthenticated(): void { + // if (!this.accessToken) { + // throw new Error("Not authenticated. Please login first."); + // } + } + + async health(): Promise { + return await this._makeRequest("GET", "health"); + } + + // ----------------------------------------------------------------------------- + // + // Auth + // + // ----------------------------------------------------------------------------- + /** + * Registers a new user with the given email and password. + * @param email The email of the user to register. + * @param password The password of the user to register. + * @returns A promise that resolves to the response from the server. + */ + + @feature("register") + async register(email: string, password: string): Promise { + return await this._makeRequest("POST", "register", { + data: { email, password }, + }); + } + + /** + * Verifies the email of a user with the given verification code. + * @param verification_code The verification code to verify the email with. + * @returns A promise that resolves to the response from the server. + */ + @feature("verifyEmail") + async verifyEmail(verification_code: string): Promise> { + return await this._makeRequest("POST", "verify_email", { + json: { verification_code: verification_code }, + }); + } + + /** + * Attempts to log in a user with the given email and password. + * @param email The email of the user to log in. + * @param password The password of the user to log in. + * @returns A promise that resolves to the response from the server containing the access and refresh tokens. + */ + @feature("login") + async login( + email: string, + password: string, + ): Promise<{ access_token: TokenInfo; refresh_token: TokenInfo }> { + const formData = new URLSearchParams(); + formData.append("username", email); + formData.append("password", password); + + const response = await this._makeRequest("POST", "login", { + data: formData, + headers: { + "Content-Type": "application/x-www-form-urlencoded", + }, + }); + + if (response && response.results) { + this.accessToken = response.results.access_token.token; + this.refreshToken = response.results.refresh_token.token; + } else { + throw new Error("Invalid response structure"); + } + + return response.results; + } + + /** + * Logs out the currently authenticated user. + * @returns A promise that resolves to the response from the server. + */ + @feature("logout") + async logout(): Promise { + this._ensureAuthenticated(); + + const response = await this._makeRequest("POST", "logout"); + this.accessToken = null; + this.refreshToken = null; + return response; + } + + /** + * Retrieves the user information for the currently authenticated user. + * @returns A promise that resolves to the response from the server containing the user information. + */ + @feature("user") + async user(): Promise { + this._ensureAuthenticated(); + return await this._makeRequest("GET", "user"); + } + + /** + * Updates the profile information for the currently authenticated user. + * @param email The updated email for the user. + * @param name The updated name for the user. + * @param bio The updated bio for the user. + * @param profilePicture The updated profile picture URL for the user. + * @returns A promise that resolves to the response from the server. + */ + @feature("updateUser") + async updateUser( + email?: string, + name?: string, + bio?: string, + profilePicture?: string, + ): Promise { + this._ensureAuthenticated(); + return await this._makeRequest("PUT", "user", { + data: { + email, + name, + bio, + profile_picture: profilePicture, + }, + }); + } + + /** + * Refreshes the access token for the currently authenticated user. + * @returns A promise that resolves to the response from the server containing the new access and refresh tokens. + */ + async refreshAccessToken(): Promise { + if (!this.refreshToken) { + throw new Error("No refresh token available. Please login again."); + } + + const response = await this._makeRequest( + "POST", + "refresh_access_token", + { data: { refresh_token: this.refreshToken } }, + ); + + if (response && response.results) { + this.accessToken = response.results.access_token.token; + this.refreshToken = response.results.refresh_token.token; + } else { + throw new Error("Invalid response structure"); + } + + return response; + } + + /** + * Changes the password of the currently authenticated user. + * @param current_password The current password of the user. + * @param new_password The new password to set for the user. + * @returns A promise that resolves to the response from the server. + */ + @feature("changePassword") + async changePassword( + current_password: string, + new_password: string, + ): Promise { + this._ensureAuthenticated(); + + return this._makeRequest("POST", "change_password", { + data: { + current_password, + new_password, + }, + }); + } + + /** + * Requests a password reset for the user with the given email. + * @param email The email of the user to request a password reset for. + * @returns A promise that resolves to the response from the server. + */ + @feature("requestPasswordReset") + async requestPasswordReset(email: string): Promise { + return this._makeRequest("POST", "request_password_reset", { + data: { email }, + }); + } + + /** + * Confirms a password reset for the user with the given reset token. + * @param resetToken The reset token to confirm the password reset with. + * @param newPassword The new password to set for the user. + * @returns A promise that resolves to the response from the server. + */ + @feature("confirmPasswordReset") + async confirmPasswordReset( + resetToken: string, + newPassword: string, + ): Promise { + return this._makeRequest("POST", `reset_password/${resetToken}`, { + data: { new_password: newPassword }, + }); + } + + /** + * Deletes the user with the given user ID. + * @param user_id The ID of the user to delete. + * @param password The password of the user to delete. + * @returns A promise that resolves to the response from the server. + */ + @feature("deleteUser") + async deleteUser(user_id: string, password?: string): Promise { + this._ensureAuthenticated(); + const response = await this._makeRequest("DELETE", "user", { + data: { user_id, password }, + }); + this.accessToken = null; + this.refreshToken = null; + return response; + } + + // ----------------------------------------------------------------------------- + // + // Ingestion + // + // ----------------------------------------------------------------------------- + + // TODO: Need to update to closer match the Python SDK. + /** + * Ingest files into your R2R deployment. + * @param files + * @param options + * @returns A promise that resolves to the response from the server. + */ + @feature("ingestFiles") + async ingestFiles( + files: (string | File | { path: string; name: string })[], + options: { + metadatas?: Record[]; + document_ids?: string[]; + user_ids?: (string | null)[]; + versions?: string[]; + chunking_config_override?: Record; + skip_document_info?: boolean; + } = {}, + ): Promise { + this._ensureAuthenticated(); + + const formData = new FormData(); + const processedFiles: string[] = []; + + const processPath = async ( + path: string | File | { path: string; name: string }, + index: number, + ): Promise => { + const appendFile = ( + file: File | NodeJS.ReadableStream, + filename: string, + ) => { + formData.append(`files`, file, filename); + processedFiles.push(filename); + }; + + if (typeof path === "string") { + if (typeof window === "undefined") { + const stat = await fs.promises.stat(path); + if (stat.isDirectory()) { + const files = await fs.promises.readdir(path, { + withFileTypes: true, + }); + for (const file of files) { + await processPath(`${path}/${file.name}`, index); + } + } else { + appendFile(fs.createReadStream(path), path.split("/").pop() || ""); + } + } else { + console.warn( + "File or folder path provided in browser environment. This is not supported.", + ); + } + } else if (path instanceof File) { + appendFile(path, path.name); + } else if ("path" in path && "name" in path) { + if (typeof window === "undefined") { + appendFile(fs.createReadStream(path.path), path.name); + } else { + console.warn( + "File path provided in browser environment. This is not supported.", + ); + } + } + }; + + for (let i = 0; i < files.length; i++) { + await processPath(files[i], i); + } + + const data: Record = { + metadatas: options.metadatas + ? JSON.stringify(options.metadatas) + : undefined, + document_ids: options.document_ids + ? JSON.stringify(options.document_ids) + : undefined, + user_ids: options.user_ids ? JSON.stringify(options.user_ids) : undefined, + versions: options.versions ? JSON.stringify(options.versions) : undefined, + chunking_config_override: options.chunking_config_override + ? JSON.stringify(options.chunking_config_override) + : undefined, + skip_document_info: + options.skip_document_info !== undefined + ? JSON.stringify(options.skip_document_info) + : undefined, + }; + + Object.entries(data).forEach(([key, value]) => { + if (value !== undefined) { + formData.append(key, value); + } + }); + + formData.append("file_names", JSON.stringify(processedFiles)); + + return await this._makeRequest("POST", "ingest_files", { + data: formData, + headers: formData.getHeaders?.() ?? { + "Content-Type": "multipart/form-data", + }, + transformRequest: [ + (data: any, headers: Record) => { + delete headers["Content-Type"]; + return data; + }, + ], + }); + } + + /** + * Update existing files in your R2R deployment. + * @param files + * @param options + * @returns + */ + @feature("updateFiles") + async updateFiles( + files: (File | { path: string; name: string })[], + options: { + document_ids: string[]; + metadatas?: Record[]; + chunking_config_override?: Record; + }, + ): Promise { + this._ensureAuthenticated(); + + const formData = new FormData(); + const processedFiles: string[] = []; + + if (files.length !== options.document_ids.length) { + throw new Error("Each file must have a corresponding document ID."); + } + + const processFile = ( + file: File | { path: string; name: string }, + index: number, + ) => { + if ("path" in file) { + if (typeof window === "undefined") { + formData.append("files", fs.createReadStream(file.path), file.name); + processedFiles.push(file.name); + } else { + console.warn( + "File path provided in browser environment. This is not supported.", + ); + } + } else { + formData.append("files", file); + processedFiles.push(file.name); + } + }; + + files.forEach(processFile); + + const data: Record = { + document_ids: JSON.stringify(options.document_ids.map(String)), + metadatas: options.metadatas + ? JSON.stringify(options.metadatas) + : undefined, + chunking_config_override: options.chunking_config_override + ? JSON.stringify(options.chunking_config_override) + : undefined, + }; + + Object.entries(data).forEach(([key, value]) => { + if (value !== undefined) { + formData.append(key, value); + } + }); + + formData.append("file_names", JSON.stringify(processedFiles)); + + return await this._makeRequest("POST", "update_files", { + data: formData, + headers: formData.getHeaders?.() ?? { + "Content-Type": "multipart/form-data", + }, + transformRequest: [ + (data: any, headers: Record) => { + delete headers["Content-Type"]; + return data; + }, + ], + }); + } + + // ----------------------------------------------------------------------------- + // + // Management + // + // ----------------------------------------------------------------------------- + + /** + * Get statistics about the server, including the start time, uptime, CPU usage, and memory usage. + * @returns A promise that resolves to the response from the server. + */ + @feature("serverStats") + async serverStats(): Promise { + this._ensureAuthenticated(); + return await this._makeRequest("GET", "server_stats"); + } + + /** + * Update a prompt in the database. + * @param name The name of the prompt to update. + * @param template The new template for the prompt. + * @param input_types The new input types for the prompt. + * @returns A promise that resolves to the response from the server. + */ + @feature("updatePrompt") + async updatePrompt( + name: string = "default_system", + template?: string, + input_types?: Record, + ): Promise> { + this._ensureAuthenticated(); + + const data: Record = { name }; + if (template !== undefined) { + data.template = template; + } + if (input_types !== undefined) { + data.input_types = input_types; + } + + return await this._makeRequest("POST", "update_prompt", { + data, + headers: { + "Content-Type": "application/json", + }, + }); + } + + /** + * Get analytics data from the server. + * @param filter_criteria The filter criteria to use. + * @param analysis_types The types of analysis to perform. + * @returns A promise that resolves to the response from the server. + */ + @feature("analytics") + async analytics( + filter_criteria?: Record | string, + analysis_types?: Record | string, + ): Promise { + this._ensureAuthenticated(); + + const params: Record = {}; + + if (filter_criteria) { + params.filter_criteria = + typeof filter_criteria === "object" + ? JSON.stringify(filter_criteria) + : filter_criteria; + } + + if (analysis_types) { + params.analysis_types = + typeof analysis_types === "object" + ? JSON.stringify(analysis_types) + : analysis_types; + } + + return this._makeRequest("GET", "analytics", { params }); + } + + /** + * Get logs from the server. + * @param run_type_filter The run type to filter by. + * @param max_runs Specifies the maximum number of runs to return. Values outside the range of 1 to 1000 will be adjusted to the nearest valid value with a default of 100. + * @returns + */ + @feature("logs") + async logs(run_type_filter?: string, max_runs?: number): Promise { + this._ensureAuthenticated(); + + const params: Record = {}; + + if (run_type_filter !== undefined) { + params.run_type_filter = run_type_filter; + } + + if (max_runs !== undefined) { + params.max_runs = max_runs; + } + + return this._makeRequest("GET", "logs", { params }); + } + + /** + * Get the configuration settings for the app. + * @returns A promise that resolves to the response from the server. + */ + @feature("appSettings") + async appSettings(): Promise { + this._ensureAuthenticated(); + + return this._makeRequest("GET", "app_settings"); + } + + /** + * Assign a score to a message from an LLM completion. The score should be a float between -1.0 and 1.0. + * @param message_id The ID of the message to score. + * @param score The score to assign to the message. + * @returns A promise that resolves to the response from the server. + */ + @feature("scoreCompletion") + async scoreCompletion(message_id: string, score: number): Promise { + this._ensureAuthenticated(); + + const data = { + message_id, + score, + }; + + return this._makeRequest("POST", "score_completion", { + data, + headers: { + "Content-Type": "application/json", + }, + }); + } + + /** + * An overview of the users in the R2R deployment. + * @param user_ids + * @returns + */ + @feature("usersOverview") + async usersOverview(user_ids?: string[]): Promise> { + this._ensureAuthenticated(); + + const params: { user_ids?: string[] } = {}; + if (user_ids && user_ids.length > 0) { + params.user_ids = user_ids; + } + + return this._makeRequest("GET", "users_overview", { params }); + } + + /** + * Delete data from the database given a set of filters. + * @param filters The filters to delete by. + * @returns + */ + @feature("delete") + async delete(filters: { [key: string]: string | string[] }): Promise { + this._ensureAuthenticated(); + + const params = { + filters: JSON.stringify(filters), + }; + + return this._makeRequest("DELETE", "delete", { + params, + }); + } + + /** + * Get an overview of documents in the R2R deployment. + * @param document_ids List of document IDs to get an overview for. + * @returns A promise that resolves to the response from the server. + */ + @feature("documentsOverview") + async documentsOverview(document_ids?: string[]): Promise { + this._ensureAuthenticated(); + + return this._makeRequest("GET", "documents_overview", { + params: { + document_ids: document_ids ? JSON.stringify(document_ids) : undefined, + }, + }); + } + + /** + * Get the chunks for a document. + * @param document_id The ID of the document to get the chunks for. + * @returns A promise that resolves to the response from the server. + */ + @feature("documentChunks") + async documentChunks(document_id: string): Promise { + this._ensureAuthenticated(); + + return this._makeRequest( + "GET", + `document_chunks?document_id=${document_id}`, + { + headers: { + "Content-Type": "application/json", + }, + }, + ); + } + + /** + * Inspect the knowledge graph associated with your R2R deployment. + * @param limit The maximum number of nodes to return. Defaults to 100. + * @returns A promise that resolves to the response from the server. + */ + @feature("inspectKnowledgeGraph") + async inspectKnowledgeGraph(limit?: number): Promise> { + this._ensureAuthenticated(); + + const params: { limit?: number } = {}; + if (limit !== undefined) { + params.limit = limit; + } + + return this._makeRequest("GET", "inspect_knowledge_graph", { params }); + } + + /** + * Get an overview of existing groups. + * @param groupIds List of group IDs to get an overview for. + * @param limit The maximum number of groups to return. + * @param offset The offset to start listing groups from. + * @returns + */ + @feature("groupsOverview") + async groupsOverview( + groupIds?: string[], + limit?: number, + offset?: number, + ): Promise> { + this._ensureAuthenticated(); + + const params: Record = {}; + if (groupIds && groupIds.length > 0) { + params.group_ids = groupIds; + } + if (limit !== undefined) { + params.limit = limit; + } + if (offset !== undefined) { + params.offset = offset; + } + + return this._makeRequest("GET", "groups_overview", { params }); + } + + /** + * Create a new group. + * @param name The name of the group. + * @param description The description of the group. + * @returns + */ + @feature("createGroup") + async createGroup( + name: string, + description?: string, + ): Promise> { + this._ensureAuthenticated(); + + const data: { name: string; description?: string } = { name }; + if (description !== undefined) { + data.description = description; + } + + return this._makeRequest("POST", "create_group", { data }); + } + + /** + * Get a group by its ID. + * @param groupId The ID of the group to get. + * @returns A promise that resolves to the response from the server. + */ + @feature("getGroup") + async getGroup(groupId: string): Promise> { + this._ensureAuthenticated(); + return this._makeRequest("GET", `get_group/${encodeURIComponent(groupId)}`); + } + + /** + * Updates the name and description of a group. + * @param groupId The ID of the group to update. + * @param name The new name for the group. + * @param description The new description of the group. + * @returns A promise that resolves to the response from the server. + */ + @feature("updateGroup") + async updateGroup( + groupId: string, + name?: string, + description?: string, + ): Promise> { + this._ensureAuthenticated(); + + const data: { group_id: string; name?: string; description?: string } = { + group_id: groupId, + }; + if (name !== undefined) { + data.name = name; + } + if (description !== undefined) { + data.description = description; + } + + return this._makeRequest("PUT", "update_group", { data }); + } + + /** + * Delete a group by its ID. + * @param groupId The ID of the group to delete. + * @returns A promise that resolves to the response from the server. + */ + @feature("deleteGroup") + async deleteGroup(groupId: string): Promise> { + this._ensureAuthenticated(); + return this._makeRequest( + "DELETE", + `delete_group/${encodeURIComponent(groupId)}`, + ); + } + + /** + * List all groups in the R2R deployment. + * @param offset The offset to start listing groups from. + * @param limit The maximum numberof groups to return. + * @returns + */ + @feature("listGroups") + async listGroups( + offset?: number, + limit?: number, + ): Promise> { + this._ensureAuthenticated(); + + const params: Record = {}; + if (offset !== undefined) { + params.offset = offset; + } + if (limit !== undefined) { + params.limit = limit; + } + + return this._makeRequest("GET", "list_groups", { params }); + } + + /** + * Add a user to a group. + * @param userId The ID of the user to add. + * @param groupId The ID of the group to add the user to. + * @returns A promise that resolves to the response from the server. + */ + @feature("addUserToGroup") + async addUserToGroup( + userId: string, + groupId: string, + ): Promise> { + this._ensureAuthenticated(); + return this._makeRequest("POST", "add_user_to_group", { + data: { user_id: userId, group_id: groupId }, + }); + } + + /** + * Remove a user from a group. + * @param userId The ID of the user to remove. + * @param groupId The ID of the group to remove the user from. + * @returns + */ + @feature("removeUserFromGroup") + async removeUserFromGroup( + userId: string, + groupId: string, + ): Promise> { + this._ensureAuthenticated(); + return this._makeRequest("POST", "remove_user_from_group", { + data: { user_id: userId, group_id: groupId }, + }); + } + + /** + * Get all users in a group. + * @param groupId The ID of the group to get users for. + * @param offset The offset to start listing users from. + * @param limit The maximum number of users to return. + * @returns A promise that resolves to the response from the server. + */ + @feature("getUsersInGroup") + async getUsersInGroup( + groupId: string, + offset?: number, + limit?: number, + ): Promise> { + this._ensureAuthenticated(); + + const params: Record = {}; + if (offset !== undefined) { + params.offset = offset; + } + if (limit !== undefined) { + params.limit = limit; + } + + return this._makeRequest( + "GET", + `get_users_in_group/${encodeURIComponent(groupId)}`, + { params }, + ); + } + + /** + * Get all groups that a user is a member of. + * @param userId The ID of the user to get groups for. + * @returns A promise that resolves to the response from the server. + */ + @feature("getGroupsForUser") + async getGroupsForUser(userId: string): Promise> { + this._ensureAuthenticated(); + return this._makeRequest( + "GET", + `get_groups_for_user/${encodeURIComponent(userId)}`, + ); + } + + /** + * Assign a document to a group. + * @param document_id The ID of the document to assign. + * @param group_id The ID of the group to assign the document to. + * @returns + */ + @feature("assignDocumentToGroup") + async assignDocumentToGroup( + document_id: string, + group_id: string, + ): Promise { + this._ensureAuthenticated(); + + return this._makeRequest("POST", "assign_document_to_group", { + data: { document_id, group_id }, + }); + } + + /** + * Remove a document from a group. + * @param document_id The ID of the document to remove. + * @param group_id The ID of the group to remove the document from. + * @returns A promise that resolves to the response from the server. + */ + @feature("removeDocumentFromGroup") + async removeDocumentFromGroup( + document_id: string, + group_id: string, + ): Promise { + this._ensureAuthenticated(); + + return this._makeRequest("POST", "remove_document_from_group", { + data: { document_id, group_id }, + }); + } + + /** + * Get all groups that a document is assigned to. + * @param documentId The ID of the document to get groups for. + * @returns + */ + @feature("getDocumentGroups") + async getDocumentGroups(documentId: string): Promise> { + this._ensureAuthenticated(); + + return this._makeRequest( + "GET", + `get_document_groups/${encodeURIComponent(documentId)}`, + ); + } + + /** + * Get all documents in a group. + * @param groupId The ID of the group to get documents for. + * @param offset The offset to start listing documents from. + * @param limit The maximum number of documents to return. + * @returns A promise that resolves to the response from the server. + */ + @feature("getDocumentsInGroup") + async getDocumentsInGroup( + groupId: string, + offset?: number, + limit?: number, + ): Promise> { + this._ensureAuthenticated(); + + const params: Record = {}; + if (offset !== undefined) { + params.offset = offset; + } + if (limit !== undefined) { + params.limit = limit; + } + + return this._makeRequest( + "GET", + `group/${encodeURIComponent(groupId)}/documents`, + { params }, + ); + } + + // ----------------------------------------------------------------------------- + // + // Restructure + // + // ----------------------------------------------------------------------------- + + /** + * Perform graph enrichment over the entire graph. + * @returns A promise that resolves to the response from the server. + */ + @feature("enrichGraph") + async enrichGraph(): Promise { + this._ensureAuthenticated(); + return await this._makeRequest("POST", "enrich_graph"); + } + + // ----------------------------------------------------------------------------- + // + // Retrieval + // + // ----------------------------------------------------------------------------- + + /** + * Conduct a vector and/or KG search. + * @param query The query to search for. + * @param vector_search_settings Vector search settings. + * @param kg_search_settings KG search settings. + * @returns + */ + @feature("search") + async search( + query: string, + vector_search_settings?: VectorSearchSettings | Record, + kg_search_settings?: KGSearchSettings | Record, + ): Promise { + this._ensureAuthenticated(); + + const json_data: Record = { + query, + vector_search_settings, + kg_search_settings, + }; + + Object.keys(json_data).forEach( + (key) => json_data[key] === undefined && delete json_data[key], + ); + + return await this._makeRequest("POST", "search", { data: json_data }); + } + + /** + * Conducts a Retrieval Augmented Generation (RAG) search with the given query. + * @param query The query to search for. + * @param vector_search_settings Vector search settings. + * @param kg_search_settings KG search settings. + * @param rag_generation_config RAG generation configuration. + * @returns A promise that resolves to the response from the server. + */ + @feature("rag") + async rag( + query: string, + vector_search_settings?: VectorSearchSettings | Record, + kg_search_settings?: KGSearchSettings | Record, + rag_generation_config?: GenerationConfig | Record, + ): Promise { + this._ensureAuthenticated(); + + const json_data: Record = { + query, + vector_search_settings, + kg_search_settings, + rag_generation_config, + }; + + Object.keys(json_data).forEach( + (key) => json_data[key] === undefined && delete json_data[key], + ); + + if (rag_generation_config && rag_generation_config.stream) { + return this.streamRag(json_data); + } else { + return await this._makeRequest("POST", "rag", { data: json_data }); + } + } + + // TODO: can we remove this and pull this into rag? + @featureGenerator("streamingRag") + private async *streamRag( + rag_data: Record, + ): AsyncGenerator { + this._ensureAuthenticated(); + + const response = await this._makeRequest("POST", "rag", { + data: rag_data, + headers: { + "Content-Type": "application/json", + }, + responseType: "stream", + }); + + if (!response.body) { + throw new Error("Response body is null"); + } + + const reader = response.body.getReader(); + const decoder = new TextDecoder(); + + try { + while (true) { + const { done, value } = await reader.read(); + if (done) { + break; + } + yield decoder.decode(value); + } + } finally { + reader.releaseLock(); + } + } + + /** + * Performs a single turn in a conversation with a RAG agent. + * @param messages The messages to send to the agent. + * @param vector_search_settings Vector search settings. + * @param kg_search_settings KG search settings. + * @param rag_generation_config RAG generation configuration. + * @param task_prompt_override Task prompt override. + * @param include_title_if_available Include title if available. + * @returns A promise that resolves to the response from the server. + */ + @feature("agent") + async agent( + messages: Message[], + vector_search_settings?: VectorSearchSettings | Record, + kg_search_settings?: KGSearchSettings | Record, + rag_generation_config?: GenerationConfig | Record, + task_prompt_override?: string, + include_title_if_available?: boolean, + ): Promise { + this._ensureAuthenticated(); + + const json_data: Record = { + messages, + vector_search_settings, + kg_search_settings, + rag_generation_config, + task_prompt_override, + include_title_if_available, + }; + + Object.keys(json_data).forEach( + (key) => json_data[key] === undefined && delete json_data[key], + ); + + if (rag_generation_config && rag_generation_config.stream) { + return this.streamAgent(json_data); + } else { + return await this._makeRequest("POST", "agent", { data: json_data }); + } + } + + // TODO: can we remove this and pull this into agent? + @featureGenerator("streamingAgent") + private async *streamAgent( + agent_data: Record, + ): AsyncGenerator { + this._ensureAuthenticated(); + + const response = await this._makeRequest("POST", "agent", { + data: agent_data, + headers: { + "Content-Type": "application/json", + }, + responseType: "stream", + }); + + if (!response.body) { + throw new Error("Response body is null"); + } + + const reader = response.body.getReader(); + const decoder = new TextDecoder(); + + try { + while (true) { + const { done, value } = await reader.read(); + if (done) { + break; + } + yield decoder.decode(value); + } + } finally { + reader.releaseLock(); + } + } +} + +export default r2rClient; diff --git a/r2r_js_sdk/tsconfig.json b/r2r_js_sdk/tsconfig.json new file mode 100644 index 000000000..df060141f --- /dev/null +++ b/r2r_js_sdk/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "target": "es2017", + "module": "commonjs", + "outDir": "./dist", + "rootDir": "./src", + "declaration": true, + "moduleResolution": "node", + "strict": true, + "esModuleInterop": true, + "experimentalDecorators": true, + "emitDecoratorMetadata": true, + "forceConsistentCasingInFileNames": true, + "jsx": "react", + "lib": ["es2017", "dom"], + "sourceMap": true + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "**/__tests__/*"] +} diff --git a/r2r_python_sdk/README.md b/r2r_python_sdk/README.md new file mode 100644 index 000000000..e69de29bb diff --git a/r2r_python_sdk/poetry.lock b/r2r_python_sdk/poetry.lock new file mode 100644 index 000000000..00baa0d2b --- /dev/null +++ b/r2r_python_sdk/poetry.lock @@ -0,0 +1,1098 @@ +# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. + +[[package]] +name = "annotated-types" +version = "0.7.0" +description = "Reusable constraint types to use with typing.Annotated" +optional = false +python-versions = ">=3.8" +files = [ + {file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"}, + {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, +] + +[[package]] +name = "anyio" +version = "4.4.0" +description = "High level compatibility layer for multiple asynchronous event loop implementations" +optional = false +python-versions = ">=3.8" +files = [ + {file = "anyio-4.4.0-py3-none-any.whl", hash = "sha256:c1b2d8f46a8a812513012e1107cb0e68c17159a7a594208005a57dc776e1bdc7"}, + {file = "anyio-4.4.0.tar.gz", hash = "sha256:5aadc6a1bbb7cdb0bede386cac5e2940f5e2ff3aa20277e991cf028e0585ce94"}, +] + +[package.dependencies] +exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} +idna = ">=2.8" +sniffio = ">=1.1" +typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} + +[package.extras] +doc = ["Sphinx (>=7)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] +trio = ["trio (>=0.23)"] + +[[package]] +name = "black" +version = "24.8.0" +description = "The uncompromising code formatter." +optional = false +python-versions = ">=3.8" +files = [ + {file = "black-24.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:09cdeb74d494ec023ded657f7092ba518e8cf78fa8386155e4a03fdcc44679e6"}, + {file = "black-24.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:81c6742da39f33b08e791da38410f32e27d632260e599df7245cccee2064afeb"}, + {file = "black-24.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:707a1ca89221bc8a1a64fb5e15ef39cd755633daa672a9db7498d1c19de66a42"}, + {file = "black-24.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:d6417535d99c37cee4091a2f24eb2b6d5ec42b144d50f1f2e436d9fe1916fe1a"}, + {file = "black-24.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fb6e2c0b86bbd43dee042e48059c9ad7830abd5c94b0bc518c0eeec57c3eddc1"}, + {file = "black-24.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:837fd281f1908d0076844bc2b801ad2d369c78c45cf800cad7b61686051041af"}, + {file = "black-24.8.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:62e8730977f0b77998029da7971fa896ceefa2c4c4933fcd593fa599ecbf97a4"}, + {file = "black-24.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:72901b4913cbac8972ad911dc4098d5753704d1f3c56e44ae8dce99eecb0e3af"}, + {file = "black-24.8.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:7c046c1d1eeb7aea9335da62472481d3bbf3fd986e093cffd35f4385c94ae368"}, + {file = "black-24.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:649f6d84ccbae73ab767e206772cc2d7a393a001070a4c814a546afd0d423aed"}, + {file = "black-24.8.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2b59b250fdba5f9a9cd9d0ece6e6d993d91ce877d121d161e4698af3eb9c1018"}, + {file = "black-24.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:6e55d30d44bed36593c3163b9bc63bf58b3b30e4611e4d88a0c3c239930ed5b2"}, + {file = "black-24.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:505289f17ceda596658ae81b61ebbe2d9b25aa78067035184ed0a9d855d18afd"}, + {file = "black-24.8.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b19c9ad992c7883ad84c9b22aaa73562a16b819c1d8db7a1a1a49fb7ec13c7d2"}, + {file = "black-24.8.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1f13f7f386f86f8121d76599114bb8c17b69d962137fc70efe56137727c7047e"}, + {file = "black-24.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:f490dbd59680d809ca31efdae20e634f3fae27fba3ce0ba3208333b713bc3920"}, + {file = "black-24.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:eab4dd44ce80dea27dc69db40dab62d4ca96112f87996bca68cd75639aeb2e4c"}, + {file = "black-24.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3c4285573d4897a7610054af5a890bde7c65cb466040c5f0c8b732812d7f0e5e"}, + {file = "black-24.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9e84e33b37be070ba135176c123ae52a51f82306def9f7d063ee302ecab2cf47"}, + {file = "black-24.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:73bbf84ed136e45d451a260c6b73ed674652f90a2b3211d6a35e78054563a9bb"}, + {file = "black-24.8.0-py3-none-any.whl", hash = "sha256:972085c618ee94f402da1af548a4f218c754ea7e5dc70acb168bfaca4c2542ed"}, + {file = "black-24.8.0.tar.gz", hash = "sha256:2500945420b6784c38b9ee885af039f5e7471ef284ab03fa35ecdde4688cd83f"}, +] + +[package.dependencies] +click = ">=8.0.0" +mypy-extensions = ">=0.4.3" +packaging = ">=22.0" +pathspec = ">=0.9.0" +platformdirs = ">=2" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} +typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""} + +[package.extras] +colorama = ["colorama (>=0.4.3)"] +d = ["aiohttp (>=3.7.4)", "aiohttp (>=3.7.4,!=3.9.0)"] +jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] +uvloop = ["uvloop (>=0.15.2)"] + +[[package]] +name = "certifi" +version = "2024.7.4" +description = "Python package for providing Mozilla's CA Bundle." +optional = false +python-versions = ">=3.6" +files = [ + {file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"}, + {file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"}, +] + +[[package]] +name = "cfgv" +version = "3.4.0" +description = "Validate configuration and produce human readable error messages." +optional = false +python-versions = ">=3.8" +files = [ + {file = "cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9"}, + {file = "cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560"}, +] + +[[package]] +name = "charset-normalizer" +version = "3.3.2" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, + {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, +] + +[[package]] +name = "click" +version = "8.1.7" +description = "Composable command line interface toolkit" +optional = false +python-versions = ">=3.7" +files = [ + {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, + {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[[package]] +name = "codecov" +version = "2.1.13" +description = "Hosted coverage reports for GitHub, Bitbucket and Gitlab" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "codecov-2.1.13-py2.py3-none-any.whl", hash = "sha256:c2ca5e51bba9ebb43644c43d0690148a55086f7f5e6fd36170858fa4206744d5"}, + {file = "codecov-2.1.13.tar.gz", hash = "sha256:2362b685633caeaf45b9951a9b76ce359cd3581dd515b430c6c3f5dfb4d92a8c"}, +] + +[package.dependencies] +coverage = "*" +requests = ">=2.7.9" + +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + +[[package]] +name = "coverage" +version = "7.6.1" +description = "Code coverage measurement for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "coverage-7.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b06079abebbc0e89e6163b8e8f0e16270124c154dc6e4a47b413dd538859af16"}, + {file = "coverage-7.6.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cf4b19715bccd7ee27b6b120e7e9dd56037b9c0681dcc1adc9ba9db3d417fa36"}, + {file = "coverage-7.6.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61c0abb4c85b095a784ef23fdd4aede7a2628478e7baba7c5e3deba61070a02"}, + {file = "coverage-7.6.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fd21f6ae3f08b41004dfb433fa895d858f3f5979e7762d052b12aef444e29afc"}, + {file = "coverage-7.6.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f59d57baca39b32db42b83b2a7ba6f47ad9c394ec2076b084c3f029b7afca23"}, + {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a1ac0ae2b8bd743b88ed0502544847c3053d7171a3cff9228af618a068ed9c34"}, + {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e6a08c0be454c3b3beb105c0596ebdc2371fab6bb90c0c0297f4e58fd7e1012c"}, + {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f5796e664fe802da4f57a168c85359a8fbf3eab5e55cd4e4569fbacecc903959"}, + {file = "coverage-7.6.1-cp310-cp310-win32.whl", hash = "sha256:7bb65125fcbef8d989fa1dd0e8a060999497629ca5b0efbca209588a73356232"}, + {file = "coverage-7.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:3115a95daa9bdba70aea750db7b96b37259a81a709223c8448fa97727d546fe0"}, + {file = "coverage-7.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7dea0889685db8550f839fa202744652e87c60015029ce3f60e006f8c4462c93"}, + {file = "coverage-7.6.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ed37bd3c3b063412f7620464a9ac1314d33100329f39799255fb8d3027da50d3"}, + {file = "coverage-7.6.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d85f5e9a5f8b73e2350097c3756ef7e785f55bd71205defa0bfdaf96c31616ff"}, + {file = "coverage-7.6.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bc572be474cafb617672c43fe989d6e48d3c83af02ce8de73fff1c6bb3c198d"}, + {file = "coverage-7.6.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c0420b573964c760df9e9e86d1a9a622d0d27f417e1a949a8a66dd7bcee7bc6"}, + {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1f4aa8219db826ce6be7099d559f8ec311549bfc4046f7f9fe9b5cea5c581c56"}, + {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:fc5a77d0c516700ebad189b587de289a20a78324bc54baee03dd486f0855d234"}, + {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b48f312cca9621272ae49008c7f613337c53fadca647d6384cc129d2996d1133"}, + {file = "coverage-7.6.1-cp311-cp311-win32.whl", hash = "sha256:1125ca0e5fd475cbbba3bb67ae20bd2c23a98fac4e32412883f9bcbaa81c314c"}, + {file = "coverage-7.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:8ae539519c4c040c5ffd0632784e21b2f03fc1340752af711f33e5be83a9d6c6"}, + {file = "coverage-7.6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:95cae0efeb032af8458fc27d191f85d1717b1d4e49f7cb226cf526ff28179778"}, + {file = "coverage-7.6.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5621a9175cf9d0b0c84c2ef2b12e9f5f5071357c4d2ea6ca1cf01814f45d2391"}, + {file = "coverage-7.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:260933720fdcd75340e7dbe9060655aff3af1f0c5d20f46b57f262ab6c86a5e8"}, + {file = "coverage-7.6.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07e2ca0ad381b91350c0ed49d52699b625aab2b44b65e1b4e02fa9df0e92ad2d"}, + {file = "coverage-7.6.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c44fee9975f04b33331cb8eb272827111efc8930cfd582e0320613263ca849ca"}, + {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:877abb17e6339d96bf08e7a622d05095e72b71f8afd8a9fefc82cf30ed944163"}, + {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3e0cadcf6733c09154b461f1ca72d5416635e5e4ec4e536192180d34ec160f8a"}, + {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c3c02d12f837d9683e5ab2f3d9844dc57655b92c74e286c262e0fc54213c216d"}, + {file = "coverage-7.6.1-cp312-cp312-win32.whl", hash = "sha256:e05882b70b87a18d937ca6768ff33cc3f72847cbc4de4491c8e73880766718e5"}, + {file = "coverage-7.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:b5d7b556859dd85f3a541db6a4e0167b86e7273e1cdc973e5b175166bb634fdb"}, + {file = "coverage-7.6.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a4acd025ecc06185ba2b801f2de85546e0b8ac787cf9d3b06e7e2a69f925b106"}, + {file = "coverage-7.6.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a6d3adcf24b624a7b778533480e32434a39ad8fa30c315208f6d3e5542aeb6e9"}, + {file = "coverage-7.6.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0c212c49b6c10e6951362f7c6df3329f04c2b1c28499563d4035d964ab8e08c"}, + {file = "coverage-7.6.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e81d7a3e58882450ec4186ca59a3f20a5d4440f25b1cff6f0902ad890e6748a"}, + {file = "coverage-7.6.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78b260de9790fd81e69401c2dc8b17da47c8038176a79092a89cb2b7d945d060"}, + {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a78d169acd38300060b28d600344a803628c3fd585c912cacc9ea8790fe96862"}, + {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2c09f4ce52cb99dd7505cd0fc8e0e37c77b87f46bc9c1eb03fe3bc9991085388"}, + {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6878ef48d4227aace338d88c48738a4258213cd7b74fd9a3d4d7582bb1d8a155"}, + {file = "coverage-7.6.1-cp313-cp313-win32.whl", hash = "sha256:44df346d5215a8c0e360307d46ffaabe0f5d3502c8a1cefd700b34baf31d411a"}, + {file = "coverage-7.6.1-cp313-cp313-win_amd64.whl", hash = "sha256:8284cf8c0dd272a247bc154eb6c95548722dce90d098c17a883ed36e67cdb129"}, + {file = "coverage-7.6.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:d3296782ca4eab572a1a4eca686d8bfb00226300dcefdf43faa25b5242ab8a3e"}, + {file = "coverage-7.6.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:502753043567491d3ff6d08629270127e0c31d4184c4c8d98f92c26f65019962"}, + {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a89ecca80709d4076b95f89f308544ec8f7b4727e8a547913a35f16717856cb"}, + {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a318d68e92e80af8b00fa99609796fdbcdfef3629c77c6283566c6f02c6d6704"}, + {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13b0a73a0896988f053e4fbb7de6d93388e6dd292b0d87ee51d106f2c11b465b"}, + {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4421712dbfc5562150f7554f13dde997a2e932a6b5f352edcce948a815efee6f"}, + {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:166811d20dfea725e2e4baa71fffd6c968a958577848d2131f39b60043400223"}, + {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:225667980479a17db1048cb2bf8bfb39b8e5be8f164b8f6628b64f78a72cf9d3"}, + {file = "coverage-7.6.1-cp313-cp313t-win32.whl", hash = "sha256:170d444ab405852903b7d04ea9ae9b98f98ab6d7e63e1115e82620807519797f"}, + {file = "coverage-7.6.1-cp313-cp313t-win_amd64.whl", hash = "sha256:b9f222de8cded79c49bf184bdbc06630d4c58eec9459b939b4a690c82ed05657"}, + {file = "coverage-7.6.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6db04803b6c7291985a761004e9060b2bca08da6d04f26a7f2294b8623a0c1a0"}, + {file = "coverage-7.6.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f1adfc8ac319e1a348af294106bc6a8458a0f1633cc62a1446aebc30c5fa186a"}, + {file = "coverage-7.6.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a95324a9de9650a729239daea117df21f4b9868ce32e63f8b650ebe6cef5595b"}, + {file = "coverage-7.6.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b43c03669dc4618ec25270b06ecd3ee4fa94c7f9b3c14bae6571ca00ef98b0d3"}, + {file = "coverage-7.6.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8929543a7192c13d177b770008bc4e8119f2e1f881d563fc6b6305d2d0ebe9de"}, + {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a09ece4a69cf399510c8ab25e0950d9cf2b42f7b3cb0374f95d2e2ff594478a6"}, + {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:9054a0754de38d9dbd01a46621636689124d666bad1936d76c0341f7d71bf569"}, + {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0dbde0f4aa9a16fa4d754356a8f2e36296ff4d83994b2c9d8398aa32f222f989"}, + {file = "coverage-7.6.1-cp38-cp38-win32.whl", hash = "sha256:da511e6ad4f7323ee5702e6633085fb76c2f893aaf8ce4c51a0ba4fc07580ea7"}, + {file = "coverage-7.6.1-cp38-cp38-win_amd64.whl", hash = "sha256:3f1156e3e8f2872197af3840d8ad307a9dd18e615dc64d9ee41696f287c57ad8"}, + {file = "coverage-7.6.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:abd5fd0db5f4dc9289408aaf34908072f805ff7792632250dcb36dc591d24255"}, + {file = "coverage-7.6.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:547f45fa1a93154bd82050a7f3cddbc1a7a4dd2a9bf5cb7d06f4ae29fe94eaf8"}, + {file = "coverage-7.6.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:645786266c8f18a931b65bfcefdbf6952dd0dea98feee39bd188607a9d307ed2"}, + {file = "coverage-7.6.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9e0b2df163b8ed01d515807af24f63de04bebcecbd6c3bfeff88385789fdf75a"}, + {file = "coverage-7.6.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:609b06f178fe8e9f89ef676532760ec0b4deea15e9969bf754b37f7c40326dbc"}, + {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:702855feff378050ae4f741045e19a32d57d19f3e0676d589df0575008ea5004"}, + {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:2bdb062ea438f22d99cba0d7829c2ef0af1d768d1e4a4f528087224c90b132cb"}, + {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:9c56863d44bd1c4fe2abb8a4d6f5371d197f1ac0ebdee542f07f35895fc07f36"}, + {file = "coverage-7.6.1-cp39-cp39-win32.whl", hash = "sha256:6e2cd258d7d927d09493c8df1ce9174ad01b381d4729a9d8d4e38670ca24774c"}, + {file = "coverage-7.6.1-cp39-cp39-win_amd64.whl", hash = "sha256:06a737c882bd26d0d6ee7269b20b12f14a8704807a01056c80bb881a4b2ce6ca"}, + {file = "coverage-7.6.1-pp38.pp39.pp310-none-any.whl", hash = "sha256:e9a6e0eb86070e8ccaedfbd9d38fec54864f3125ab95419970575b42af7541df"}, + {file = "coverage-7.6.1.tar.gz", hash = "sha256:953510dfb7b12ab69d20135a0662397f077c59b1e6379a768e97c59d852ee51d"}, +] + +[package.dependencies] +tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""} + +[package.extras] +toml = ["tomli"] + +[[package]] +name = "distlib" +version = "0.3.8" +description = "Distribution utilities" +optional = false +python-versions = "*" +files = [ + {file = "distlib-0.3.8-py2.py3-none-any.whl", hash = "sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784"}, + {file = "distlib-0.3.8.tar.gz", hash = "sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64"}, +] + +[[package]] +name = "exceptiongroup" +version = "1.2.2" +description = "Backport of PEP 654 (exception groups)" +optional = false +python-versions = ">=3.7" +files = [ + {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, + {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, +] + +[package.extras] +test = ["pytest (>=6)"] + +[[package]] +name = "fastapi" +version = "0.109.2" +description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production" +optional = false +python-versions = ">=3.8" +files = [ + {file = "fastapi-0.109.2-py3-none-any.whl", hash = "sha256:2c9bab24667293b501cad8dd388c05240c850b58ec5876ee3283c47d6e1e3a4d"}, + {file = "fastapi-0.109.2.tar.gz", hash = "sha256:f3817eac96fe4f65a2ebb4baa000f394e55f5fccdaf7f75250804bc58f354f73"}, +] + +[package.dependencies] +pydantic = ">=1.7.4,<1.8 || >1.8,<1.8.1 || >1.8.1,<2.0.0 || >2.0.0,<2.0.1 || >2.0.1,<2.1.0 || >2.1.0,<3.0.0" +starlette = ">=0.36.3,<0.37.0" +typing-extensions = ">=4.8.0" + +[package.extras] +all = ["email-validator (>=2.0.0)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=2.11.2)", "orjson (>=3.2.1)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.7)", "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)"] + +[[package]] +name = "filelock" +version = "3.15.4" +description = "A platform independent file lock." +optional = false +python-versions = ">=3.8" +files = [ + {file = "filelock-3.15.4-py3-none-any.whl", hash = "sha256:6ca1fffae96225dab4c6eaf1c4f4f28cd2568d3ec2a44e15a08520504de468e7"}, + {file = "filelock-3.15.4.tar.gz", hash = "sha256:2207938cbc1844345cb01a5a95524dae30f0ce089eba5b00378295a17e3e90cb"}, +] + +[package.extras] +docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] +testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8.0.1)", "pytest (>=7.4.3)", "pytest-asyncio (>=0.21)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)", "virtualenv (>=20.26.2)"] +typing = ["typing-extensions (>=4.8)"] + +[[package]] +name = "flake8" +version = "6.1.0" +description = "the modular source code checker: pep8 pyflakes and co" +optional = false +python-versions = ">=3.8.1" +files = [ + {file = "flake8-6.1.0-py2.py3-none-any.whl", hash = "sha256:ffdfce58ea94c6580c77888a86506937f9a1a227dfcd15f245d694ae20a6b6e5"}, + {file = "flake8-6.1.0.tar.gz", hash = "sha256:d5b3857f07c030bdb5bf41c7f53799571d75c4491748a3adcd47de929e34cd23"}, +] + +[package.dependencies] +mccabe = ">=0.7.0,<0.8.0" +pycodestyle = ">=2.11.0,<2.12.0" +pyflakes = ">=3.1.0,<3.2.0" + +[[package]] +name = "h11" +version = "0.14.0" +description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" +optional = false +python-versions = ">=3.7" +files = [ + {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, + {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, +] + +[[package]] +name = "httpcore" +version = "1.0.5" +description = "A minimal low-level HTTP client." +optional = false +python-versions = ">=3.8" +files = [ + {file = "httpcore-1.0.5-py3-none-any.whl", hash = "sha256:421f18bac248b25d310f3cacd198d55b8e6125c107797b609ff9b7a6ba7991b5"}, + {file = "httpcore-1.0.5.tar.gz", hash = "sha256:34a38e2f9291467ee3b44e89dd52615370e152954ba21721378a87b2960f7a61"}, +] + +[package.dependencies] +certifi = "*" +h11 = ">=0.13,<0.15" + +[package.extras] +asyncio = ["anyio (>=4.0,<5.0)"] +http2 = ["h2 (>=3,<5)"] +socks = ["socksio (==1.*)"] +trio = ["trio (>=0.22.0,<0.26.0)"] + +[[package]] +name = "httpx" +version = "0.27.0" +description = "The next generation HTTP client." +optional = false +python-versions = ">=3.8" +files = [ + {file = "httpx-0.27.0-py3-none-any.whl", hash = "sha256:71d5465162c13681bff01ad59b2cc68dd838ea1f10e51574bac27103f00c91a5"}, + {file = "httpx-0.27.0.tar.gz", hash = "sha256:a0cb88a46f32dc874e04ee956e4c2764aba2aa228f650b06788ba6bda2962ab5"}, +] + +[package.dependencies] +anyio = "*" +certifi = "*" +httpcore = "==1.*" +idna = "*" +sniffio = "*" + +[package.extras] +brotli = ["brotli", "brotlicffi"] +cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] +http2 = ["h2 (>=3,<5)"] +socks = ["socksio (==1.*)"] + +[[package]] +name = "identify" +version = "2.6.0" +description = "File identification library for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "identify-2.6.0-py2.py3-none-any.whl", hash = "sha256:e79ae4406387a9d300332b5fd366d8994f1525e8414984e1a59e058b2eda2dd0"}, + {file = "identify-2.6.0.tar.gz", hash = "sha256:cb171c685bdc31bcc4c1734698736a7d5b6c8bf2e0c15117f4d469c8640ae5cf"}, +] + +[package.extras] +license = ["ukkonen"] + +[[package]] +name = "idna" +version = "3.7" +description = "Internationalized Domain Names in Applications (IDNA)" +optional = false +python-versions = ">=3.5" +files = [ + {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, + {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, +] + +[[package]] +name = "iniconfig" +version = "2.0.0" +description = "brain-dead simple config-ini parsing" +optional = false +python-versions = ">=3.7" +files = [ + {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, + {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, +] + +[[package]] +name = "isort" +version = "5.12.0" +description = "A Python utility / library to sort Python imports." +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "isort-5.12.0-py3-none-any.whl", hash = "sha256:f84c2818376e66cf843d497486ea8fed8700b340f308f076c6fb1229dff318b6"}, + {file = "isort-5.12.0.tar.gz", hash = "sha256:8bef7dde241278824a6d83f44a544709b065191b95b6e50894bdc722fcba0504"}, +] + +[package.extras] +colors = ["colorama (>=0.4.3)"] +pipfile-deprecated-finder = ["pip-shims (>=0.5.2)", "pipreqs", "requirementslib"] +plugins = ["setuptools"] +requirements-deprecated-finder = ["pip-api", "pipreqs"] + +[[package]] +name = "mccabe" +version = "0.7.0" +description = "McCabe checker, plugin for flake8" +optional = false +python-versions = ">=3.6" +files = [ + {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, + {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, +] + +[[package]] +name = "mypy" +version = "1.11.1" +description = "Optional static typing for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "mypy-1.11.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a32fc80b63de4b5b3e65f4be82b4cfa362a46702672aa6a0f443b4689af7008c"}, + {file = "mypy-1.11.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c1952f5ea8a5a959b05ed5f16452fddadbaae48b5d39235ab4c3fc444d5fd411"}, + {file = "mypy-1.11.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e1e30dc3bfa4e157e53c1d17a0dad20f89dc433393e7702b813c10e200843b03"}, + {file = "mypy-1.11.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2c63350af88f43a66d3dfeeeb8d77af34a4f07d760b9eb3a8697f0386c7590b4"}, + {file = "mypy-1.11.1-cp310-cp310-win_amd64.whl", hash = "sha256:a831671bad47186603872a3abc19634f3011d7f83b083762c942442d51c58d58"}, + {file = "mypy-1.11.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7b6343d338390bb946d449677726edf60102a1c96079b4f002dedff375953fc5"}, + {file = "mypy-1.11.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e4fe9f4e5e521b458d8feb52547f4bade7ef8c93238dfb5bbc790d9ff2d770ca"}, + {file = "mypy-1.11.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:886c9dbecc87b9516eff294541bf7f3655722bf22bb898ee06985cd7269898de"}, + {file = "mypy-1.11.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fca4a60e1dd9fd0193ae0067eaeeb962f2d79e0d9f0f66223a0682f26ffcc809"}, + {file = "mypy-1.11.1-cp311-cp311-win_amd64.whl", hash = "sha256:0bd53faf56de9643336aeea1c925012837432b5faf1701ccca7fde70166ccf72"}, + {file = "mypy-1.11.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f39918a50f74dc5969807dcfaecafa804fa7f90c9d60506835036cc1bc891dc8"}, + {file = "mypy-1.11.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0bc71d1fb27a428139dd78621953effe0d208aed9857cb08d002280b0422003a"}, + {file = "mypy-1.11.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b868d3bcff720dd7217c383474008ddabaf048fad8d78ed948bb4b624870a417"}, + {file = "mypy-1.11.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a707ec1527ffcdd1c784d0924bf5cb15cd7f22683b919668a04d2b9c34549d2e"}, + {file = "mypy-1.11.1-cp312-cp312-win_amd64.whl", hash = "sha256:64f4a90e3ea07f590c5bcf9029035cf0efeae5ba8be511a8caada1a4893f5525"}, + {file = "mypy-1.11.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:749fd3213916f1751fff995fccf20c6195cae941dc968f3aaadf9bb4e430e5a2"}, + {file = "mypy-1.11.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b639dce63a0b19085213ec5fdd8cffd1d81988f47a2dec7100e93564f3e8fb3b"}, + {file = "mypy-1.11.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4c956b49c5d865394d62941b109728c5c596a415e9c5b2be663dd26a1ff07bc0"}, + {file = "mypy-1.11.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:45df906e8b6804ef4b666af29a87ad9f5921aad091c79cc38e12198e220beabd"}, + {file = "mypy-1.11.1-cp38-cp38-win_amd64.whl", hash = "sha256:d44be7551689d9d47b7abc27c71257adfdb53f03880841a5db15ddb22dc63edb"}, + {file = "mypy-1.11.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2684d3f693073ab89d76da8e3921883019ea8a3ec20fa5d8ecca6a2db4c54bbe"}, + {file = "mypy-1.11.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:79c07eb282cb457473add5052b63925e5cc97dfab9812ee65a7c7ab5e3cb551c"}, + {file = "mypy-1.11.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11965c2f571ded6239977b14deebd3f4c3abd9a92398712d6da3a772974fad69"}, + {file = "mypy-1.11.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a2b43895a0f8154df6519706d9bca8280cda52d3d9d1514b2d9c3e26792a0b74"}, + {file = "mypy-1.11.1-cp39-cp39-win_amd64.whl", hash = "sha256:1a81cf05975fd61aec5ae16501a091cfb9f605dc3e3c878c0da32f250b74760b"}, + {file = "mypy-1.11.1-py3-none-any.whl", hash = "sha256:0624bdb940255d2dd24e829d99a13cfeb72e4e9031f9492148f410ed30bcab54"}, + {file = "mypy-1.11.1.tar.gz", hash = "sha256:f404a0b069709f18bbdb702eb3dcfe51910602995de00bd39cea3050b5772d08"}, +] + +[package.dependencies] +mypy-extensions = ">=1.0.0" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} +typing-extensions = ">=4.6.0" + +[package.extras] +dmypy = ["psutil (>=4.0)"] +install-types = ["pip"] +mypyc = ["setuptools (>=50)"] +reports = ["lxml"] + +[[package]] +name = "mypy-extensions" +version = "1.0.0" +description = "Type system extensions for programs checked with the mypy type checker." +optional = false +python-versions = ">=3.5" +files = [ + {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, + {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, +] + +[[package]] +name = "nest-asyncio" +version = "1.6.0" +description = "Patch asyncio to allow nested event loops" +optional = false +python-versions = ">=3.5" +files = [ + {file = "nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c"}, + {file = "nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe"}, +] + +[[package]] +name = "nodeenv" +version = "1.9.1" +description = "Node.js virtual environment builder" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9"}, + {file = "nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f"}, +] + +[[package]] +name = "packaging" +version = "24.1" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, + {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, +] + +[[package]] +name = "pathspec" +version = "0.12.1" +description = "Utility library for gitignore style pattern matching of file paths." +optional = false +python-versions = ">=3.8" +files = [ + {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, + {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, +] + +[[package]] +name = "platformdirs" +version = "4.2.2" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." +optional = false +python-versions = ">=3.8" +files = [ + {file = "platformdirs-4.2.2-py3-none-any.whl", hash = "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee"}, + {file = "platformdirs-4.2.2.tar.gz", hash = "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3"}, +] + +[package.extras] +docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] +type = ["mypy (>=1.8)"] + +[[package]] +name = "pluggy" +version = "1.5.0" +description = "plugin and hook calling mechanisms for python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, + {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, +] + +[package.extras] +dev = ["pre-commit", "tox"] +testing = ["pytest", "pytest-benchmark"] + +[[package]] +name = "pre-commit" +version = "2.21.0" +description = "A framework for managing and maintaining multi-language pre-commit hooks." +optional = false +python-versions = ">=3.7" +files = [ + {file = "pre_commit-2.21.0-py2.py3-none-any.whl", hash = "sha256:e2f91727039fc39a92f58a588a25b87f936de6567eed4f0e673e0507edc75bad"}, + {file = "pre_commit-2.21.0.tar.gz", hash = "sha256:31ef31af7e474a8d8995027fefdfcf509b5c913ff31f2015b4ec4beb26a6f658"}, +] + +[package.dependencies] +cfgv = ">=2.0.0" +identify = ">=1.0.0" +nodeenv = ">=0.11.1" +pyyaml = ">=5.1" +virtualenv = ">=20.10.0" + +[[package]] +name = "pycodestyle" +version = "2.11.1" +description = "Python style guide checker" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pycodestyle-2.11.1-py2.py3-none-any.whl", hash = "sha256:44fe31000b2d866f2e41841b18528a505fbd7fef9017b04eff4e2648a0fadc67"}, + {file = "pycodestyle-2.11.1.tar.gz", hash = "sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f"}, +] + +[[package]] +name = "pydantic" +version = "2.8.2" +description = "Data validation using Python type hints" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pydantic-2.8.2-py3-none-any.whl", hash = "sha256:73ee9fddd406dc318b885c7a2eab8a6472b68b8fb5ba8150949fc3db939f23c8"}, + {file = "pydantic-2.8.2.tar.gz", hash = "sha256:6f62c13d067b0755ad1c21a34bdd06c0c12625a22b0fc09c6b149816604f7c2a"}, +] + +[package.dependencies] +annotated-types = ">=0.4.0" +pydantic-core = "2.20.1" +typing-extensions = {version = ">=4.6.1", markers = "python_version < \"3.13\""} + +[package.extras] +email = ["email-validator (>=2.0.0)"] + +[[package]] +name = "pydantic-core" +version = "2.20.1" +description = "Core functionality for Pydantic validation and serialization" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pydantic_core-2.20.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3acae97ffd19bf091c72df4d726d552c473f3576409b2a7ca36b2f535ffff4a3"}, + {file = "pydantic_core-2.20.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:41f4c96227a67a013e7de5ff8f20fb496ce573893b7f4f2707d065907bffdbd6"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f239eb799a2081495ea659d8d4a43a8f42cd1fe9ff2e7e436295c38a10c286a"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:53e431da3fc53360db73eedf6f7124d1076e1b4ee4276b36fb25514544ceb4a3"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f1f62b2413c3a0e846c3b838b2ecd6c7a19ec6793b2a522745b0869e37ab5bc1"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5d41e6daee2813ecceea8eda38062d69e280b39df793f5a942fa515b8ed67953"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d482efec8b7dc6bfaedc0f166b2ce349df0011f5d2f1f25537ced4cfc34fd98"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e93e1a4b4b33daed65d781a57a522ff153dcf748dee70b40c7258c5861e1768a"}, + {file = "pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e7c4ea22b6739b162c9ecaaa41d718dfad48a244909fe7ef4b54c0b530effc5a"}, + {file = "pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4f2790949cf385d985a31984907fecb3896999329103df4e4983a4a41e13e840"}, + {file = "pydantic_core-2.20.1-cp310-none-win32.whl", hash = "sha256:5e999ba8dd90e93d57410c5e67ebb67ffcaadcea0ad973240fdfd3a135506250"}, + {file = "pydantic_core-2.20.1-cp310-none-win_amd64.whl", hash = "sha256:512ecfbefef6dac7bc5eaaf46177b2de58cdf7acac8793fe033b24ece0b9566c"}, + {file = "pydantic_core-2.20.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d2a8fa9d6d6f891f3deec72f5cc668e6f66b188ab14bb1ab52422fe8e644f312"}, + {file = "pydantic_core-2.20.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:175873691124f3d0da55aeea1d90660a6ea7a3cfea137c38afa0a5ffabe37b88"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37eee5b638f0e0dcd18d21f59b679686bbd18917b87db0193ae36f9c23c355fc"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:25e9185e2d06c16ee438ed39bf62935ec436474a6ac4f9358524220f1b236e43"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:150906b40ff188a3260cbee25380e7494ee85048584998c1e66df0c7a11c17a6"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ad4aeb3e9a97286573c03df758fc7627aecdd02f1da04516a86dc159bf70121"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3f3ed29cd9f978c604708511a1f9c2fdcb6c38b9aae36a51905b8811ee5cbf1"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b0dae11d8f5ded51699c74d9548dcc5938e0804cc8298ec0aa0da95c21fff57b"}, + {file = "pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:faa6b09ee09433b87992fb5a2859efd1c264ddc37280d2dd5db502126d0e7f27"}, + {file = "pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9dc1b507c12eb0481d071f3c1808f0529ad41dc415d0ca11f7ebfc666e66a18b"}, + {file = "pydantic_core-2.20.1-cp311-none-win32.whl", hash = "sha256:fa2fddcb7107e0d1808086ca306dcade7df60a13a6c347a7acf1ec139aa6789a"}, + {file = "pydantic_core-2.20.1-cp311-none-win_amd64.whl", hash = "sha256:40a783fb7ee353c50bd3853e626f15677ea527ae556429453685ae32280c19c2"}, + {file = "pydantic_core-2.20.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:595ba5be69b35777474fa07f80fc260ea71255656191adb22a8c53aba4479231"}, + {file = "pydantic_core-2.20.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a4f55095ad087474999ee28d3398bae183a66be4823f753cd7d67dd0153427c9"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9aa05d09ecf4c75157197f27cdc9cfaeb7c5f15021c6373932bf3e124af029f"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e97fdf088d4b31ff4ba35db26d9cc472ac7ef4a2ff2badeabf8d727b3377fc52"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bc633a9fe1eb87e250b5c57d389cf28998e4292336926b0b6cdaee353f89a237"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d573faf8eb7e6b1cbbcb4f5b247c60ca8be39fe2c674495df0eb4318303137fe"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26dc97754b57d2fd00ac2b24dfa341abffc380b823211994c4efac7f13b9e90e"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:33499e85e739a4b60c9dac710c20a08dc73cb3240c9a0e22325e671b27b70d24"}, + {file = "pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:bebb4d6715c814597f85297c332297c6ce81e29436125ca59d1159b07f423eb1"}, + {file = "pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:516d9227919612425c8ef1c9b869bbbee249bc91912c8aaffb66116c0b447ebd"}, + {file = "pydantic_core-2.20.1-cp312-none-win32.whl", hash = "sha256:469f29f9093c9d834432034d33f5fe45699e664f12a13bf38c04967ce233d688"}, + {file = "pydantic_core-2.20.1-cp312-none-win_amd64.whl", hash = "sha256:035ede2e16da7281041f0e626459bcae33ed998cca6a0a007a5ebb73414ac72d"}, + {file = "pydantic_core-2.20.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:0827505a5c87e8aa285dc31e9ec7f4a17c81a813d45f70b1d9164e03a813a686"}, + {file = "pydantic_core-2.20.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:19c0fa39fa154e7e0b7f82f88ef85faa2a4c23cc65aae2f5aea625e3c13c735a"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa223cd1e36b642092c326d694d8bf59b71ddddc94cdb752bbbb1c5c91d833b"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c336a6d235522a62fef872c6295a42ecb0c4e1d0f1a3e500fe949415761b8a19"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7eb6a0587eded33aeefea9f916899d42b1799b7b14b8f8ff2753c0ac1741edac"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:70c8daf4faca8da5a6d655f9af86faf6ec2e1768f4b8b9d0226c02f3d6209703"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9fa4c9bf273ca41f940bceb86922a7667cd5bf90e95dbb157cbb8441008482c"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:11b71d67b4725e7e2a9f6e9c0ac1239bbc0c48cce3dc59f98635efc57d6dac83"}, + {file = "pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:270755f15174fb983890c49881e93f8f1b80f0b5e3a3cc1394a255706cabd203"}, + {file = "pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c81131869240e3e568916ef4c307f8b99583efaa60a8112ef27a366eefba8ef0"}, + {file = "pydantic_core-2.20.1-cp313-none-win32.whl", hash = "sha256:b91ced227c41aa29c672814f50dbb05ec93536abf8f43cd14ec9521ea09afe4e"}, + {file = "pydantic_core-2.20.1-cp313-none-win_amd64.whl", hash = "sha256:65db0f2eefcaad1a3950f498aabb4875c8890438bc80b19362cf633b87a8ab20"}, + {file = "pydantic_core-2.20.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:4745f4ac52cc6686390c40eaa01d48b18997cb130833154801a442323cc78f91"}, + {file = "pydantic_core-2.20.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a8ad4c766d3f33ba8fd692f9aa297c9058970530a32c728a2c4bfd2616d3358b"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41e81317dd6a0127cabce83c0c9c3fbecceae981c8391e6f1dec88a77c8a569a"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:04024d270cf63f586ad41fff13fde4311c4fc13ea74676962c876d9577bcc78f"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eaad4ff2de1c3823fddf82f41121bdf453d922e9a238642b1dedb33c4e4f98ad"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:26ab812fa0c845df815e506be30337e2df27e88399b985d0bb4e3ecfe72df31c"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c5ebac750d9d5f2706654c638c041635c385596caf68f81342011ddfa1e5598"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2aafc5a503855ea5885559eae883978c9b6d8c8993d67766ee73d82e841300dd"}, + {file = "pydantic_core-2.20.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:4868f6bd7c9d98904b748a2653031fc9c2f85b6237009d475b1008bfaeb0a5aa"}, + {file = "pydantic_core-2.20.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:aa2f457b4af386254372dfa78a2eda2563680d982422641a85f271c859df1987"}, + {file = "pydantic_core-2.20.1-cp38-none-win32.whl", hash = "sha256:225b67a1f6d602de0ce7f6c1c3ae89a4aa25d3de9be857999e9124f15dab486a"}, + {file = "pydantic_core-2.20.1-cp38-none-win_amd64.whl", hash = "sha256:6b507132dcfc0dea440cce23ee2182c0ce7aba7054576efc65634f080dbe9434"}, + {file = "pydantic_core-2.20.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:b03f7941783b4c4a26051846dea594628b38f6940a2fdc0df00b221aed39314c"}, + {file = "pydantic_core-2.20.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1eedfeb6089ed3fad42e81a67755846ad4dcc14d73698c120a82e4ccf0f1f9f6"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:635fee4e041ab9c479e31edda27fcf966ea9614fff1317e280d99eb3e5ab6fe2"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:77bf3ac639c1ff567ae3b47f8d4cc3dc20f9966a2a6dd2311dcc055d3d04fb8a"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ed1b0132f24beeec5a78b67d9388656d03e6a7c837394f99257e2d55b461611"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c6514f963b023aeee506678a1cf821fe31159b925c4b76fe2afa94cc70b3222b"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10d4204d8ca33146e761c79f83cc861df20e7ae9f6487ca290a97702daf56006"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2d036c7187b9422ae5b262badb87a20a49eb6c5238b2004e96d4da1231badef1"}, + {file = "pydantic_core-2.20.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9ebfef07dbe1d93efb94b4700f2d278494e9162565a54f124c404a5656d7ff09"}, + {file = "pydantic_core-2.20.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6b9d9bb600328a1ce523ab4f454859e9d439150abb0906c5a1983c146580ebab"}, + {file = "pydantic_core-2.20.1-cp39-none-win32.whl", hash = "sha256:784c1214cb6dd1e3b15dd8b91b9a53852aed16671cc3fbe4786f4f1db07089e2"}, + {file = "pydantic_core-2.20.1-cp39-none-win_amd64.whl", hash = "sha256:d2fe69c5434391727efa54b47a1e7986bb0186e72a41b203df8f5b0a19a4f669"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a45f84b09ac9c3d35dfcf6a27fd0634d30d183205230a0ebe8373a0e8cfa0906"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d02a72df14dfdbaf228424573a07af10637bd490f0901cee872c4f434a735b94"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2b27e6af28f07e2f195552b37d7d66b150adbaa39a6d327766ffd695799780f"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:084659fac3c83fd674596612aeff6041a18402f1e1bc19ca39e417d554468482"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:242b8feb3c493ab78be289c034a1f659e8826e2233786e36f2893a950a719bb6"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:38cf1c40a921d05c5edc61a785c0ddb4bed67827069f535d794ce6bcded919fc"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e0bbdd76ce9aa5d4209d65f2b27fc6e5ef1312ae6c5333c26db3f5ade53a1e99"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:254ec27fdb5b1ee60684f91683be95e5133c994cc54e86a0b0963afa25c8f8a6"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:407653af5617f0757261ae249d3fba09504d7a71ab36ac057c938572d1bc9331"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:c693e916709c2465b02ca0ad7b387c4f8423d1db7b4649c551f27a529181c5ad"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b5ff4911aea936a47d9376fd3ab17e970cc543d1b68921886e7f64bd28308d1"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:177f55a886d74f1808763976ac4efd29b7ed15c69f4d838bbd74d9d09cf6fa86"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:964faa8a861d2664f0c7ab0c181af0bea66098b1919439815ca8803ef136fc4e"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:4dd484681c15e6b9a977c785a345d3e378d72678fd5f1f3c0509608da24f2ac0"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f6d6cff3538391e8486a431569b77921adfcdef14eb18fbf19b7c0a5294d4e6a"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a6d511cc297ff0883bc3708b465ff82d7560193169a8b93260f74ecb0a5e08a7"}, + {file = "pydantic_core-2.20.1.tar.gz", hash = "sha256:26ca695eeee5f9f1aeeb211ffc12f10bcb6f71e2989988fda61dabd65db878d4"}, +] + +[package.dependencies] +typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" + +[[package]] +name = "pyflakes" +version = "3.1.0" +description = "passive checker of Python programs" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pyflakes-3.1.0-py2.py3-none-any.whl", hash = "sha256:4132f6d49cb4dae6819e5379898f2b8cce3c5f23994194c24b77d5da2e36f774"}, + {file = "pyflakes-3.1.0.tar.gz", hash = "sha256:a0aae034c444db0071aa077972ba4768d40c830d9539fd45bf4cd3f8f6992efc"}, +] + +[[package]] +name = "pytest" +version = "8.3.2" +description = "pytest: simple powerful testing with Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pytest-8.3.2-py3-none-any.whl", hash = "sha256:4ba08f9ae7dcf84ded419494d229b48d0903ea6407b030eaec46df5e6a73bba5"}, + {file = "pytest-8.3.2.tar.gz", hash = "sha256:c132345d12ce551242c87269de812483f5bcc87cdbb4722e48487ba194f9fdce"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "sys_platform == \"win32\""} +exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} +iniconfig = "*" +packaging = "*" +pluggy = ">=1.5,<2" +tomli = {version = ">=1", markers = "python_version < \"3.11\""} + +[package.extras] +dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] + +[[package]] +name = "pytest-asyncio" +version = "0.23.8" +description = "Pytest support for asyncio" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pytest_asyncio-0.23.8-py3-none-any.whl", hash = "sha256:50265d892689a5faefb84df80819d1ecef566eb3549cf915dfb33569359d1ce2"}, + {file = "pytest_asyncio-0.23.8.tar.gz", hash = "sha256:759b10b33a6dc61cce40a8bd5205e302978bbbcc00e279a8b61d9a6a3c82e4d3"}, +] + +[package.dependencies] +pytest = ">=7.0.0,<9" + +[package.extras] +docs = ["sphinx (>=5.3)", "sphinx-rtd-theme (>=1.0)"] +testing = ["coverage (>=6.2)", "hypothesis (>=5.7.1)"] + +[[package]] +name = "pytest-cov" +version = "5.0.0" +description = "Pytest plugin for measuring coverage." +optional = false +python-versions = ">=3.8" +files = [ + {file = "pytest-cov-5.0.0.tar.gz", hash = "sha256:5837b58e9f6ebd335b0f8060eecce69b662415b16dc503883a02f45dfeb14857"}, + {file = "pytest_cov-5.0.0-py3-none-any.whl", hash = "sha256:4f0764a1219df53214206bf1feea4633c3b558a2925c8b59f144f682861ce652"}, +] + +[package.dependencies] +coverage = {version = ">=5.2.1", extras = ["toml"]} +pytest = ">=4.6" + +[package.extras] +testing = ["fields", "hunter", "process-tests", "pytest-xdist", "virtualenv"] + +[[package]] +name = "pytest-dependency" +version = "0.6.0" +description = "Manage dependencies of tests" +optional = false +python-versions = ">=3.4" +files = [ + {file = "pytest-dependency-0.6.0.tar.gz", hash = "sha256:934b0e6a39d95995062c193f7eaeed8a8ffa06ff1bcef4b62b0dc74a708bacc1"}, +] + +[package.dependencies] +pytest = ">=3.7.0" +setuptools = "*" + +[[package]] +name = "pytest-mock" +version = "3.14.0" +description = "Thin-wrapper around the mock package for easier use with pytest" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pytest-mock-3.14.0.tar.gz", hash = "sha256:2719255a1efeceadbc056d6bf3df3d1c5015530fb40cf347c0f9afac88410bd0"}, + {file = "pytest_mock-3.14.0-py3-none-any.whl", hash = "sha256:0b72c38033392a5f4621342fe11e9219ac11ec9d375f8e2a0c164539e0d70f6f"}, +] + +[package.dependencies] +pytest = ">=6.2.5" + +[package.extras] +dev = ["pre-commit", "pytest-asyncio", "tox"] + +[[package]] +name = "pyyaml" +version = "6.0.2" +description = "YAML parser and emitter for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, + {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, + {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, + {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, + {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, + {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, + {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, + {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, + {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, + {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, + {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"}, + {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"}, + {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"}, + {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, + {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, + {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, + {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, +] + +[[package]] +name = "requests" +version = "2.32.3" +description = "Python HTTP for Humans." +optional = false +python-versions = ">=3.8" +files = [ + {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, + {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, +] + +[package.dependencies] +certifi = ">=2017.4.17" +charset-normalizer = ">=2,<4" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<3" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] + +[[package]] +name = "setuptools" +version = "73.0.0" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "setuptools-73.0.0-py3-none-any.whl", hash = "sha256:f2bfcce7ae1784d90b04c57c2802e8649e1976530bb25dc72c2b078d3ecf4864"}, + {file = "setuptools-73.0.0.tar.gz", hash = "sha256:3c08705fadfc8c7c445cf4d98078f0fafb9225775b2b4e8447e40348f82597c0"}, +] + +[package.extras] +core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.text (>=3.7)", "more-itertools (>=8.8)", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.11.*)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (<0.4)", "pytest-ruff (>=0.2.1)", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] + +[[package]] +name = "sniffio" +version = "1.3.1" +description = "Sniff out which async library your code is running under" +optional = false +python-versions = ">=3.7" +files = [ + {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}, + {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, +] + +[[package]] +name = "starlette" +version = "0.36.3" +description = "The little ASGI library that shines." +optional = false +python-versions = ">=3.8" +files = [ + {file = "starlette-0.36.3-py3-none-any.whl", hash = "sha256:13d429aa93a61dc40bf503e8c801db1f1bca3dc706b10ef2434a36123568f044"}, + {file = "starlette-0.36.3.tar.gz", hash = "sha256:90a671733cfb35771d8cc605e0b679d23b992f8dcfad48cc60b38cb29aeb7080"}, +] + +[package.dependencies] +anyio = ">=3.4.0,<5" +typing-extensions = {version = ">=3.10.0", markers = "python_version < \"3.10\""} + +[package.extras] +full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart (>=0.0.7)", "pyyaml"] + +[[package]] +name = "tomli" +version = "2.0.1" +description = "A lil' TOML parser" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, + {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, +] + +[[package]] +name = "typing-extensions" +version = "4.12.2" +description = "Backported and Experimental Type Hints for Python 3.8+" +optional = false +python-versions = ">=3.8" +files = [ + {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, + {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, +] + +[[package]] +name = "urllib3" +version = "2.2.2" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=3.8" +files = [ + {file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"}, + {file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"}, +] + +[package.extras] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +h2 = ["h2 (>=4,<5)"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] + +[[package]] +name = "virtualenv" +version = "20.26.3" +description = "Virtual Python Environment builder" +optional = false +python-versions = ">=3.7" +files = [ + {file = "virtualenv-20.26.3-py3-none-any.whl", hash = "sha256:8cc4a31139e796e9a7de2cd5cf2489de1217193116a8fd42328f1bd65f434589"}, + {file = "virtualenv-20.26.3.tar.gz", hash = "sha256:4c43a2a236279d9ea36a0d76f98d84bd6ca94ac4e0f4a3b9d46d05e10fea542a"}, +] + +[package.dependencies] +distlib = ">=0.3.7,<1" +filelock = ">=3.12.2,<4" +platformdirs = ">=3.9.1,<5" + +[package.extras] +docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2,!=7.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] +test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"] + +[metadata] +lock-version = "2.0" +python-versions = ">=3.9,<3.13" +content-hash = "943e573d66e0f64a5ce610f95d5afbdbd2b5ceb65732fd4bde167da390503414" diff --git a/r2r_python_sdk/pyproject.toml b/r2r_python_sdk/pyproject.toml new file mode 100644 index 000000000..7a05bb2d5 --- /dev/null +++ b/r2r_python_sdk/pyproject.toml @@ -0,0 +1,54 @@ +[build-system] +requires = ["poetry-core", "setuptools", "wheel"] +build-backend = "poetry.core.masonry.api" + +[tool.poetry] +name = "r2r" +version = "0.3.0" +description = "Lightweight Python SDK for R2R" +authors = ["Owen Colegrove "] +license = "MIT" +readme = "README.md" + +[tool.poetry.dependencies] +# Python Versions +python = ">=3.9,<3.13" +httpx = "^0.27.0" +nest-asyncio = "^1.6.0" +fastapi = "^0.109.2" + +[tool.poetry.group.dev.dependencies] +black = "^24.3.0" +codecov = "^2.1.13" +flake8 = "6.1.0" +isort = "5.12.0" +mypy = "^1.5.1" +pre-commit = "^2.9" +pytest = "^8.2.0" +pytest-asyncio = "^0.23.6" +pytest-dependency = "^0.6.0" +pytest-mock = "^3.14.0" +pytest-cov = "^5.0.0" +colorama = "^0.4.6" + +[tool.black] +line-length = 79 +target-version = ['py39'] +include = '\.pyi?$' +extend-exclude = ''' +/( + # directories + \.eggs + | \.git + | \.hg + | \.mypy_cache + | \.tox + | \.venv + | venv + | env + | build + | dist +)/ +''' +skip-string-normalization = true +skip-magic-trailing-comma = false diff --git a/r2r_python_sdk/r2r/__init__.py b/r2r_python_sdk/r2r/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/r2r/main/api/client/auth.py b/r2r_python_sdk/r2r/auth.py similarity index 98% rename from r2r/main/api/client/auth.py rename to r2r_python_sdk/r2r/auth.py index 27b8ad71b..578bea36b 100644 --- a/r2r/main/api/client/auth.py +++ b/r2r_python_sdk/r2r/auth.py @@ -1,7 +1,6 @@ from typing import Optional -from r2r.base import Token -from r2r.base.api.models.auth.responses import UserResponse +from .models import Token, UserResponse class AuthMethods: diff --git a/r2r/main/api/client/client.py b/r2r_python_sdk/r2r/client.py similarity index 99% rename from r2r/main/api/client/client.py rename to r2r_python_sdk/r2r/client.py index 9e44267e6..a477c2a79 100644 --- a/r2r/main/api/client/client.py +++ b/r2r_python_sdk/r2r/client.py @@ -6,11 +6,10 @@ import nest_asyncio from fastapi.testclient import TestClient -from r2r.base import R2RException - from .auth import AuthMethods from .ingestion import IngestionMethods from .management import ManagementMethods +from .models import R2RException from .restructure import RestructureMethods from .retrieval import RetrievalMethods diff --git a/r2r/main/api/client/ingestion.py b/r2r_python_sdk/r2r/ingestion.py similarity index 99% rename from r2r/main/api/client/ingestion.py rename to r2r_python_sdk/r2r/ingestion.py index 796e57e8a..01c9629f1 100644 --- a/r2r/main/api/client/ingestion.py +++ b/r2r_python_sdk/r2r/ingestion.py @@ -3,7 +3,7 @@ from contextlib import ExitStack from typing import Optional, Union -from r2r.base import ChunkingConfig +from .models import ChunkingConfig class IngestionMethods: diff --git a/r2r/main/api/client/management.py b/r2r_python_sdk/r2r/management.py similarity index 100% rename from r2r/main/api/client/management.py rename to r2r_python_sdk/r2r/management.py diff --git a/r2r_python_sdk/r2r/models.py b/r2r_python_sdk/r2r/models.py new file mode 100644 index 000000000..d6fbd2598 --- /dev/null +++ b/r2r_python_sdk/r2r/models.py @@ -0,0 +1,386 @@ +from abc import ABC, abstractmethod +from datetime import datetime +from enum import Enum +from typing import Any, ClassVar, Dict, Optional, Tuple, Type, Union +from uuid import UUID + +from pydantic import BaseModel, Field + + +class GenerationConfig(BaseModel): + _defaults: ClassVar[dict] = { + "model": "openai/gpt-4o", + "temperature": 0.1, + "top_p": 1.0, + "max_tokens_to_sample": 1024, + "stream": False, + "functions": None, + "tools": None, + "add_generation_kwargs": None, + "api_base": None, + } + + model: str = Field( + default_factory=lambda: GenerationConfig._defaults["model"] + ) + temperature: float = Field( + default_factory=lambda: GenerationConfig._defaults["temperature"] + ) + top_p: float = Field( + default_factory=lambda: GenerationConfig._defaults["top_p"] + ) + max_tokens_to_sample: int = Field( + default_factory=lambda: GenerationConfig._defaults[ + "max_tokens_to_sample" + ] + ) + stream: bool = Field( + default_factory=lambda: GenerationConfig._defaults["stream"] + ) + functions: Optional[list[dict]] = Field( + default_factory=lambda: GenerationConfig._defaults["functions"] + ) + tools: Optional[list[dict]] = Field( + default_factory=lambda: GenerationConfig._defaults["tools"] + ) + add_generation_kwargs: Optional[dict] = Field( + default_factory=lambda: GenerationConfig._defaults[ + "add_generation_kwargs" + ] + ) + api_base: Optional[str] = Field( + default_factory=lambda: GenerationConfig._defaults["api_base"] + ) + + @classmethod + def set_default(cls, **kwargs): + for key, value in kwargs.items(): + if key in cls._defaults: + cls._defaults[key] = value + else: + raise AttributeError( + f"No default attribute '{key}' in GenerationConfig" + ) + + def __init__(self, **data): + model = data.pop("model", None) + if model is not None: + super().__init__(model=model, **data) + else: + super().__init__(**data) + + +class KGSearchSettings(BaseModel): + use_kg_search: bool = False + kg_search_type: str = "global" # 'global' or 'local' + kg_search_level: Optional[str] = None + kg_search_generation_config: Optional[GenerationConfig] = Field( + default_factory=GenerationConfig + ) + entity_types: list = [] + relationships: list = [] + max_community_description_length: int = 4096 * 4 + max_llm_queries_for_global_search: int = 250 + local_search_limits: dict[str, int] = { + "__Entity__": 20, + "__Relationship__": 20, + "__Community__": 20, + } + + +class ProviderConfig(BaseModel, ABC): + """A base provider configuration class""" + + extra_fields: dict[str, Any] = {} + provider: Optional[str] = None + + class Config: + arbitrary_types_allowed = True + ignore_extra = True + + @abstractmethod + def validate(self) -> None: + pass + + @classmethod + def create(cls: Type["ProviderConfig"], **kwargs: Any) -> "ProviderConfig": + base_args = cls.model_fields.keys() + filtered_kwargs = { + k: v if v != "None" else None + for k, v in kwargs.items() + if k in base_args + } + instance = cls(**filtered_kwargs) + for k, v in kwargs.items(): + if k not in base_args: + instance.extra_fields[k] = v + return instance + + @property + @abstractmethod + def supported_providers(self) -> list[str]: + """Define a list of supported providers.""" + pass + + +class MessageType(Enum): + SYSTEM = "system" + USER = "user" + ASSISTANT = "assistant" + FUNCTION = "function" + TOOL = "tool" + + def __str__(self): + return self.value + + +class Message(BaseModel): + role: Union[MessageType, str] + content: Optional[str] = None + name: Optional[str] = None + function_call: Optional[Dict[str, Any]] = None + tool_calls: Optional[list[Dict[str, Any]]] = None + + +class Method(str, Enum): + BY_TITLE = "by_title" + BASIC = "basic" + RECURSIVE = "recursive" + + +class ChunkingConfig(ProviderConfig): + provider: str = "r2r" + method: Method = Method.RECURSIVE + chunk_size: int = 512 + chunk_overlap: int = 20 + max_chunk_size: Optional[int] = None + + def validate(self) -> None: + if self.provider not in self.supported_providers: + raise ValueError(f"Provider {self.provider} is not supported.") + if self.chunk_size <= 0: + raise ValueError("chunk_size must be greater than 0") + if self.chunk_overlap < 0: + raise ValueError("chunk_overlap must be non-negative") + + @property + def supported_providers(self) -> list[str]: + return ["r2r", "unstructured", None] + + class Config: + json_schema_extra = { + "type": "object", + "properties": { + "provider": {"type": "string"}, + "method": {"type": "string"}, + "chunk_size": {"type": "integer"}, + "chunk_overlap": {"type": "integer"}, + "max_chunk_size": {"type": "integer"}, + }, + "required": ["provider", "method", "chunk_size", "chunk_overlap"], + "example": { + "provider": "r2r", + "method": "recursive", + "chunk_size": 512, + "chunk_overlap": 20, + "max_chunk_size": 1024, + }, + } + + +KGSearchResult = list[Tuple[str, list[Dict[str, Any]]]] + + +class R2RException(Exception): + def __init__( + self, message: str, status_code: int, detail: Optional[Any] = None + ): + self.message = message + self.status_code = status_code + super().__init__(self.message) + + +class Token(BaseModel): + token: str + token_type: str + + +class VectorSearchSettings(BaseModel): + use_vector_search: bool = Field( + default=True, description="Whether to use vector search" + ) + filters: dict[str, Any] = Field( + default_factory=dict, + description="Filters to apply to the vector search", + ) + search_limit: int = Field( + default=10, + description="Maximum number of results to return", + ge=1, + le=100, + ) + do_hybrid_search: bool = Field( + default=False, + description="Whether to perform a hybrid search (combining vector and keyword search)", + ) + selected_group_ids: list[UUID] = Field( + default_factory=list, + description="Group IDs to search for", + ) + + class Config: + json_encoders = {UUID: str} + + def model_dump(self, *args, **kwargs): + dump = super().model_dump(*args, **kwargs) + dump["selected_group_ids"] = [ + str(uuid) for uuid in dump["selected_group_ids"] + ] + return dump + + +class UserResponse(BaseModel): + id: UUID + email: str + is_active: bool = True + is_superuser: bool = False + created_at: datetime = datetime.now() + updated_at: datetime = datetime.now() + is_verified: bool = False + group_ids: list[UUID] = [] + + # Optional fields (to update or set at creation) + hashed_password: Optional[str] = None + verification_code_expiry: Optional[datetime] = None + name: Optional[str] = None + bio: Optional[str] = None + profile_picture: Optional[str] = None + + +class VectorSearchResult(BaseModel): + """Result of a search operation.""" + + fragment_id: UUID + extraction_id: UUID + document_id: UUID + user_id: UUID + group_ids: list[UUID] + score: float + text: str + metadata: dict[str, Any] + + def __str__(self) -> str: + return f"VectorSearchResult(fragment_id={self.fragment_id}, extraction_id={self.extraction_id}, document_id={self.document_id}, score={self.score})" + + def __repr__(self) -> str: + return self.__str__() + + def dict(self) -> dict: + return { + "fragment_id": self.fragment_id, + "extraction_id": self.extraction_id, + "document_id": self.document_id, + "user_id": self.user_id, + "group_ids": self.group_ids, + "score": self.score, + "text": self.text, + "metadata": self.metadata, + } + + class Config: + json_schema_extra = { + "fragment_id": "c68dc72e-fc23-5452-8f49-d7bd46088a96", + "extraction_id": "3f3d47f3-8baf-58eb-8bc2-0171fb1c6e09", + "document_id": "3e157b3a-8469-51db-90d9-52e7d896b49b", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "score": 0.23943702876567796, + "text": "Example text from the document", + "metadata": { + "title": "example_document.pdf", + "associatedQuery": "What is the capital of France?", + }, + } + + +class SearchResponse(BaseModel): + vector_search_results: list[VectorSearchResult] = Field( + ..., + description="List of vector search results", + ) + kg_search_results: Optional[KGSearchResult] = Field( + None, + description="Knowledge graph search results, if applicable", + ) + + class Config: + json_schema_extra = { + "example": { + "vector_search_results": [ + { + "fragment_id": "c68dc72e-fc23-5452-8f49-d7bd46088a96", + "extraction_id": "3f3d47f3-8baf-58eb-8bc2-0171fb1c6e09", + "document_id": "3e157b3a-8469-51db-90d9-52e7d896b49b", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "score": 0.23943702876567796, + "text": "Example text from the document", + "metadata": { + "title": "example_document.pdf", + "associatedQuery": "What is the capital of France?", + }, + } + ], + "kg_search_results": None, + } + } + + +class RAGResponse(BaseModel): + completion: Any = Field( + ..., + description="The generated completion from the RAG process", + ) + search_results: SearchResponse = Field( + ..., + description="The search results used for the RAG process", + ) + + class Config: + json_schema_extra = { + "example": { + "completion": { + "id": "chatcmpl-example123", + "choices": [ + { + "finish_reason": "stop", + "index": 0, + "logprobs": None, + "message": { + "content": "Paris is the capital of France.", + "role": "assistant", + }, + } + ], + }, + "search_results": { + "vector_search_results": [ + { + "fragment_id": "c68dc72e-fc23-5452-8f49-d7bd46088a96", + "extraction_id": "3f3d47f3-8baf-58eb-8bc2-0171fb1c6e09", + "document_id": "3e157b3a-8469-51db-90d9-52e7d896b49b", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "score": 0.23943702876567796, + "text": "Paris is the capital and most populous city of France.", + "metadata": { + "text": "Paris is the capital and most populous city of France.", + "title": "france_info.pdf", + "associatedQuery": "What is the capital of France?", + }, + } + ], + "kg_search_results": None, + }, + } + } diff --git a/r2r/main/api/client/restructure.py b/r2r_python_sdk/r2r/restructure.py similarity index 100% rename from r2r/main/api/client/restructure.py rename to r2r_python_sdk/r2r/restructure.py diff --git a/r2r/main/api/client/retrieval.py b/r2r_python_sdk/r2r/retrieval.py similarity index 96% rename from r2r/main/api/client/retrieval.py rename to r2r_python_sdk/r2r/retrieval.py index 8255c444b..d042c0355 100644 --- a/r2r/main/api/client/retrieval.py +++ b/r2r_python_sdk/r2r/retrieval.py @@ -1,12 +1,16 @@ from typing import AsyncGenerator, Optional, Union -from r2r.base import ( +from r2r_core.base import VectorSearchSettings +from r2r_core.base.api.models import RAGResponse, SearchResponse + +from .models import ( GenerationConfig, KGSearchSettings, Message, + RAGResponse, + SearchResponse, VectorSearchSettings, ) -from r2r.base.api.models import RAGResponse, SearchResponse class RetrievalMethods: @@ -19,7 +23,7 @@ async def search( ] = None, kg_search_settings: Optional[Union[dict, KGSearchSettings]] = None, *args, - **kwargs + **kwargs, ) -> SearchResponse: """ Conduct a vector and/or KG search. @@ -62,7 +66,7 @@ async def rag( ] = None, kg_search_settings: Optional[Union[dict, KGSearchSettings]] = None, *args, - **kwargs + **kwargs, ) -> Union[RAGResponse, AsyncGenerator[RAGResponse, None]]: """ Conducts a Retrieval Augmented Generation (RAG) search with the given query. @@ -122,7 +126,7 @@ async def agent( task_prompt_override: Optional[str] = None, include_title_if_available: Optional[bool] = False, *args, - **kwargs + **kwargs, ) -> Union[list[Message], AsyncGenerator[Message, None]]: """ Performs a single turn in a conversation with a RAG agent. diff --git a/tests/regression/runner.py b/tests/regression/runner.py index 7101177c7..46e7cb3b2 100644 --- a/tests/regression/runner.py +++ b/tests/regression/runner.py @@ -6,7 +6,8 @@ from colorama import Fore, Style, init from test_cases.base import BaseTest, RegressionTest -from r2r.main.api.client import R2RClient +# TODO: need to import this from the package, not from the local directory +from r2r_python_sdk.r2r.client import R2RClient class RegressionTestRunner: diff --git a/tests/regression/test_cases/base.py b/tests/regression/test_cases/base.py index e4b0378b5..aa2f96fb5 100644 --- a/tests/regression/test_cases/base.py +++ b/tests/regression/test_cases/base.py @@ -6,7 +6,8 @@ from colorama import Fore, Style, init from deepdiff import DeepDiff -from r2r.main.api.client import R2RClient +# TODO: need to import this from the package, not from the local directory +from r2r_python_sdk.r2r.client import R2RClient def _to_snake_case(name: str) -> str: diff --git a/tests/regression/test_cases/test_document_management.py b/tests/regression/test_cases/test_document_management.py index 4c2ee97bf..c6085af9c 100644 --- a/tests/regression/test_cases/test_document_management.py +++ b/tests/regression/test_cases/test_document_management.py @@ -1,6 +1,6 @@ import os -from r2r import R2RException +from r2r_core import R2RException from tests.regression.test_cases.base import BaseTest diff --git a/tests/test_abstractions.py b/tests/test_abstractions.py index 72dac6964..6597ba007 100644 --- a/tests/test_abstractions.py +++ b/tests/test_abstractions.py @@ -4,7 +4,7 @@ import pytest -from r2r import ( +from r2r_core import ( AsyncPipe, AsyncState, Prompt, @@ -14,8 +14,8 @@ VectorType, generate_id_from_label, ) -from r2r.base.abstractions.completion import CompletionRecord, MessageType -from r2r.base.abstractions.search import AggregateSearchResult +from r2r_core.base.abstractions.completion import CompletionRecord, MessageType +from r2r_core.base.abstractions.search import AggregateSearchResult @pytest.fixture(scope="session", autouse=True) diff --git a/tests/test_auth.py b/tests/test_auth.py index 211e9ff0c..1e4f4e693 100644 --- a/tests/test_auth.py +++ b/tests/test_auth.py @@ -4,7 +4,7 @@ import pytest -from r2r import ( +from r2r_core import ( AuthConfig, BCryptConfig, BCryptProvider, @@ -13,7 +13,7 @@ R2RAuthProvider, R2RException, ) -from r2r.main.services import AuthService +from r2r_core.main.services import AuthService # Fixture for PostgresDBProvider diff --git a/tests/test_cli.py b/tests/test_cli.py index 3466609a4..79850a008 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -4,8 +4,8 @@ import pytest from click.testing import CliRunner -from r2r.cli.cli import cli -from r2r.cli.utils.param_types import JSON +from r2r_core.cli.cli import cli +from r2r_core.cli.utils.param_types import JSON @pytest.fixture @@ -242,11 +242,14 @@ def test_json_param_type(): def test_docker_down_command(runner): - with patch( - "r2r.cli.commands.server_operations.bring_down_docker_compose" - ) as mock_bring_down, patch( - "r2r.cli.commands.server_operations.remove_r2r_network" - ) as mock_remove_network: + with ( + patch( + "r2r.cli.commands.server_operations.bring_down_docker_compose" + ) as mock_bring_down, + patch( + "r2r.cli.commands.server_operations.remove_r2r_network" + ) as mock_remove_network, + ): mock_bring_down.return_value = 0 result = runner.invoke(cli, ["docker-down"]) @@ -271,15 +274,14 @@ def test_docker_down_command(runner): def test_generate_report_command(): runner = CliRunner() - with patch("subprocess.check_output") as mock_check_output, patch( - "platform.system" - ) as mock_system, patch("platform.release") as mock_release, patch( - "platform.version" - ) as mock_version, patch( - "platform.machine" - ) as mock_machine, patch( - "platform.processor" - ) as mock_processor: + with ( + patch("subprocess.check_output") as mock_check_output, + patch("platform.system") as mock_system, + patch("platform.release") as mock_release, + patch("platform.version") as mock_version, + patch("platform.machine") as mock_machine, + patch("platform.processor") as mock_processor, + ): mock_check_output.side_effect = [ "container1\tname1\tUp 2 hours\n", diff --git a/tests/test_client.py b/tests/test_client.py index cb25247a7..135121700 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -7,17 +7,19 @@ from fastapi.security import OAuth2PasswordBearer from fastapi.testclient import TestClient -from r2r import ( +from r2r_core import ( DocumentInfo, R2RApp, R2RBuilder, - R2RClient, R2REngine, R2RException, Token, UserResponse, ) +# TODO: need to import this from the package, not from the local directory +from r2r_python_sdk.r2r.client import R2RClient + oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") diff --git a/tests/test_config.py b/tests/test_config.py index 807669318..e26209110 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -4,7 +4,7 @@ import pytest import toml -from r2r import DocumentType, R2RConfig +from r2r_core import DocumentType, R2RConfig @pytest.fixture(scope="session", autouse=True) diff --git a/tests/test_database.py b/tests/test_database.py index b9662a6fe..d6f86135a 100644 --- a/tests/test_database.py +++ b/tests/test_database.py @@ -4,14 +4,14 @@ import pytest from dotenv import load_dotenv -from r2r import ( +from r2r_core import ( DatabaseConfig, DatabaseProvider, Vector, VectorEntry, generate_id_from_label, ) -from r2r.providers import PostgresDBProvider +from r2r_core.providers import PostgresDBProvider load_dotenv() diff --git a/tests/test_embedding.py b/tests/test_embedding.py index 68bbd7136..f565ecb40 100644 --- a/tests/test_embedding.py +++ b/tests/test_embedding.py @@ -3,7 +3,7 @@ import pytest -from r2r import EmbeddingConfig +from r2r_core import EmbeddingConfig @pytest.fixture(scope="session", autouse=True) @@ -19,7 +19,7 @@ async def cleanup_tasks(): await asyncio.gather(*tasks, return_exceptions=True) -from r2r.providers import LiteLLMEmbeddingProvider +from r2r_core.providers import LiteLLMEmbeddingProvider @pytest.fixture @@ -200,7 +200,7 @@ async def test_litellm_async_get_embedding_error_handling(mocker): await provider.async_get_embedding("test") -from r2r.providers import OpenAIEmbeddingProvider +from r2r_core.providers import OpenAIEmbeddingProvider @pytest.fixture @@ -321,7 +321,7 @@ def test_openai_rerank_model_not_supported(): OpenAIEmbeddingProvider(config) -from r2r.providers import OllamaEmbeddingProvider +from r2r_core.providers import OllamaEmbeddingProvider @pytest.fixture diff --git a/tests/test_end_to_end.py b/tests/test_end_to_end.py index bacf0d95f..c9eabe7a2 100644 --- a/tests/test_end_to_end.py +++ b/tests/test_end_to_end.py @@ -5,7 +5,7 @@ import pytest from fastapi.datastructures import UploadFile -from r2r import ( +from r2r_core import ( Document, DocumentInfo, DocumentStatus, diff --git a/tests/test_groups.py b/tests/test_groups.py index 12e39fb14..541e00960 100644 --- a/tests/test_groups.py +++ b/tests/test_groups.py @@ -4,9 +4,13 @@ import pytest -from r2r import DatabaseConfig, R2RException -from r2r.base.abstractions import DocumentInfo, DocumentStatus, DocumentType -from r2r.providers import BCryptConfig, BCryptProvider, PostgresDBProvider +from r2r_core import DatabaseConfig, R2RException +from r2r_core.base.abstractions import ( + DocumentInfo, + DocumentStatus, + DocumentType, +) +from r2r_core.providers import BCryptConfig, BCryptProvider, PostgresDBProvider # Add this fixture to create test documents diff --git a/tests/test_groups_client.py b/tests/test_groups_client.py index b213aa906..2b1c756cd 100644 --- a/tests/test_groups_client.py +++ b/tests/test_groups_client.py @@ -7,8 +7,15 @@ from fastapi.security import OAuth2PasswordBearer from fastapi.testclient import TestClient -from r2r import R2RApp, R2RBuilder, R2RClient, R2REngine, Token, UserResponse -from r2r.base import GroupResponse +from r2r_core import ( + R2RApp, + R2RBuilder, + R2RClient, + R2REngine, + Token, + UserResponse, +) +from r2r_core.base import GroupResponse oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") diff --git a/tests/test_ingestion_service.py b/tests/test_ingestion_service.py index 13b79d499..4d33d42ae 100644 --- a/tests/test_ingestion_service.py +++ b/tests/test_ingestion_service.py @@ -8,8 +8,8 @@ import pytest from fastapi import UploadFile -from r2r import R2RAgents -from r2r.base import ( +from r2r_core import R2RAgents +from r2r_core.base import ( Document, DocumentInfo, R2RDocumentProcessingError, @@ -18,8 +18,8 @@ UserResponse, generate_id_from_label, ) -from r2r.main import R2RPipelines, R2RProviders -from r2r.main.services.ingestion_service import IngestionService +from r2r_core.main import R2RPipelines, R2RProviders +from r2r_core.main.services.ingestion_service import IngestionService logger = logging.getLogger(__name__) diff --git a/tests/test_kg.py b/tests/test_kg.py index cb6acf3cc..fffb8bea8 100644 --- a/tests/test_kg.py +++ b/tests/test_kg.py @@ -4,10 +4,10 @@ # import pytest -# from r2r.base.abstractions.document import DocumentFragment -# from r2r.base.abstractions.graph import Entity, Triple -# from r2r.base.providers.kg import KGConfig -# from r2r.providers.kg.neo4j.provider import Neo4jKGProvider +# from r2r_core.base.abstractions.document import DocumentFragment +# from r2r_core.base.abstractions.graph import Entity, Triple +# from r2r_core.base.providers.kg import KGConfig +# from r2r_core.providers.kg.neo4j.provider import Neo4jKGProvider # @pytest.fixture diff --git a/tests/test_llms.py b/tests/test_llms.py index 04b36e5d3..0708f9a84 100644 --- a/tests/test_llms.py +++ b/tests/test_llms.py @@ -4,9 +4,12 @@ import pytest -from r2r import CompletionConfig, GenerationConfig -from r2r.base.abstractions.llm import LLMChatCompletion, LLMChatCompletionChunk -from r2r.providers import LiteCompletionProvider, OpenAICompletionProvider +from r2r_core import CompletionConfig, GenerationConfig +from r2r_core.base.abstractions.llm import ( + LLMChatCompletion, + LLMChatCompletionChunk, +) +from r2r_core.providers import LiteCompletionProvider, OpenAICompletionProvider class MockCompletionResponse: diff --git a/tests/test_logging.py b/tests/test_logging.py index 7e4372a5e..659151c23 100644 --- a/tests/test_logging.py +++ b/tests/test_logging.py @@ -6,7 +6,7 @@ import pytest -from r2r import ( +from r2r_core import ( LocalRunLoggingProvider, LoggingConfig, PostgresLoggingConfig, diff --git a/tests/test_parser.py b/tests/test_parser.py index 7edfe15f0..c7fdec41c 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -4,15 +4,15 @@ import pytest -from r2r.parsers.media.docx_parser import DOCXParser -from r2r.parsers.media.pdf_parser import PDFParser -from r2r.parsers.media.ppt_parser import PPTParser -from r2r.parsers.structured.csv_parser import CSVParser -from r2r.parsers.structured.json_parser import JSONParser -from r2r.parsers.structured.xlsx_parser import XLSXParser -from r2r.parsers.text.html_parser import HTMLParser -from r2r.parsers.text.md_parser import MDParser -from r2r.parsers.text.text_parser import TextParser +from r2r_core.parsers.media.docx_parser import DOCXParser +from r2r_core.parsers.media.pdf_parser import PDFParser +from r2r_core.parsers.media.ppt_parser import PPTParser +from r2r_core.parsers.structured.csv_parser import CSVParser +from r2r_core.parsers.structured.json_parser import JSONParser +from r2r_core.parsers.structured.xlsx_parser import XLSXParser +from r2r_core.parsers.text.html_parser import HTMLParser +from r2r_core.parsers.text.md_parser import MDParser +from r2r_core.parsers.text.text_parser import TextParser @pytest.fixture(scope="session", autouse=True) diff --git a/tests/test_pipeline.py b/tests/test_pipeline.py index 1811de0f0..ff9773f6a 100644 --- a/tests/test_pipeline.py +++ b/tests/test_pipeline.py @@ -3,7 +3,7 @@ import pytest -from r2r import AsyncPipe, AsyncPipeline, PipeType +from r2r_core import AsyncPipe, AsyncPipeline, PipeType class MultiplierPipe(AsyncPipe): diff --git a/tests/test_vector_db.py b/tests/test_vector_db.py index fe24384cf..8396793e2 100644 --- a/tests/test_vector_db.py +++ b/tests/test_vector_db.py @@ -3,8 +3,8 @@ import pytest -from r2r.base import DatabaseConfig, Vector, VectorEntry -from r2r.providers import PostgresDBProvider +from r2r_core.base import DatabaseConfig, Vector, VectorEntry +from r2r_core.providers import PostgresDBProvider @pytest.fixture From fabea80efde6415b66710ea37ca53a24a4eea80a Mon Sep 17 00:00:00 2001 From: emrgnt-cmplxty <68796651+emrgnt-cmplxty@users.noreply.github.com> Date: Tue, 20 Aug 2024 08:36:07 -0700 Subject: [PATCH 11/74] Feature/merge w nolan (#894) * cleanup hybrid search * cleanups in --- .../integration-test-workflow-debian.yml | 4 +- .../integration-test-workflow-windows.yml | 4 +- r2r_core/agent/rag.py | 1 + r2r_core/base/abstractions/llm.py | 13 + r2r_core/base/abstractions/search.py | 105 +++++- r2r_core/cli/commands/rag_operations.py | 16 +- .../examples/scripts/advanced_kg_cookbook.py | 17 +- r2r_core/main/api/routes/retrieval/base.py | 41 +-- .../retrieval/retrieval_router_openapi.yml | 12 +- r2r_core/main/app.py | 1 - r2r_core/main/execution.py | 13 +- r2r_core/main/services/ingestion_service.py | 1 - r2r_core/main/services/management_service.py | 2 +- r2r_core/main/services/retrieval_service.py | 17 +- r2r_core/pipelines/rag_pipeline.py | 1 - r2r_core/pipelines/search_pipeline.py | 10 +- r2r_core/pipes/ingestion/chunking_pipe.py | 1 + r2r_core/pipes/ingestion/parsing_pipe.py | 2 + .../pipes/retrieval/vector_search_pipe.py | 20 +- r2r_core/providers/database/document.py | 13 + .../providers/database/vecs/collection.py | 212 ++++++------ r2r_core/providers/database/vector.py | 314 +++++++++--------- tests/regression/test_cases/test_retrieval.py | 4 +- 23 files changed, 476 insertions(+), 348 deletions(-) diff --git a/.github/workflows/integration-test-workflow-debian.yml b/.github/workflows/integration-test-workflow-debian.yml index cfc3ff109..c7a9226b5 100644 --- a/.github/workflows/integration-test-workflow-debian.yml +++ b/.github/workflows/integration-test-workflow-debian.yml @@ -90,13 +90,13 @@ jobs: r2r search --query="What was Uber'\''s profit in 2020?" echo "Hybrid Search" - r2r search --query="What is a fierce nerd?" --do-hybrid-search + r2r search --query="What is a fierce nerd?" --use-hybrid-search echo "Basic RAG" r2r rag --query="What was Uber'\''s profit in 2020?" echo "RAG with Hybrid Search" - r2r rag --query="Who is John Snow?" --do-hybrid-search + r2r rag --query="Who is John Snow?" --use-hybrid-search echo "Streaming RAG" r2r rag --query="What was Lyft'\''s profit in 2020?" --stream diff --git a/.github/workflows/integration-test-workflow-windows.yml b/.github/workflows/integration-test-workflow-windows.yml index 3af101349..f0b29f6a0 100644 --- a/.github/workflows/integration-test-workflow-windows.yml +++ b/.github/workflows/integration-test-workflow-windows.yml @@ -91,13 +91,13 @@ jobs: r2r search --query="What was Uber's profit in 2020?" echo Hybrid Search - r2r search --query="What is a fierce nerd?" --do-hybrid-search + r2r search --query="What is a fierce nerd?" --use-hybrid-search echo Basic RAG r2r rag --query="What was Uber's profit in 2020?" echo RAG with Hybrid Search - r2r rag --query="Who is John Snow?" --do-hybrid-search + r2r rag --query="Who is John Snow?" --use-hybrid-search echo Streaming RAG r2r rag --query="What was Lyft's profit in 2020?" --stream diff --git a/r2r_core/agent/rag.py b/r2r_core/agent/rag.py index d2c94051b..9dd5f1127 100644 --- a/r2r_core/agent/rag.py +++ b/r2r_core/agent/rag.py @@ -56,6 +56,7 @@ async def asearch( response = await self.search_pipeline.run( to_async_generator([query]), vector_search_settings=vector_search_settings, + kg_search_settings=kg_search_settings, ) return response.vector_search_results diff --git a/r2r_core/base/abstractions/llm.py b/r2r_core/base/abstractions/llm.py index cf8809c82..487cd046f 100644 --- a/r2r_core/base/abstractions/llm.py +++ b/r2r_core/base/abstractions/llm.py @@ -87,3 +87,16 @@ def __init__(self, **data): super().__init__(model=model, **data) else: super().__init__(**data) + + class Config: + json_schema_extra = { + "model": "openai/gpt-4o", + "temperature": 0.1, + "top_p": 1.0, + "max_tokens_to_sample": 1024, + "stream": False, + "functions": None, + "tools": None, + "add_generation_kwargs": None, + "api_base": None, + } diff --git a/r2r_core/base/abstractions/search.py b/r2r_core/base/abstractions/search.py index 22050c4b2..8411faa1a 100644 --- a/r2r_core/base/abstractions/search.py +++ b/r2r_core/base/abstractions/search.py @@ -1,5 +1,6 @@ """Abstractions for search functionality.""" +from enum import Enum from typing import Any, Dict, Optional, Tuple from uuid import UUID @@ -80,10 +81,46 @@ def dict(self) -> dict: } +# TODO - stop duplication of this enum, move collections primitives to 'abstractions' +class IndexMeasure(str, Enum): + """ + An enum representing the types of distance measures available for indexing. + + Attributes: + cosine_distance (str): The cosine distance measure for indexing. + l2_distance (str): The Euclidean (L2) distance measure for indexing. + max_inner_product (str): The maximum inner product measure for indexing. + """ + + cosine_distance = "cosine_distance" + l2_distance = "l2_distance" + max_inner_product = "max_inner_product" + + +class HybridSearchSettings(BaseModel): + full_text_weight: float = Field( + default=1.0, description="Weight to apply to full text search" + ) + semantic_weight: float = Field( + default=5.0, description="Weight to apply to semantic search" + ) + full_text_limit: int = Field( + default=200, + description="Maximum number of results to return from full text search", + ) + rrf_k: int = Field( + default=50, description="K-value for RRF (Rank Reciprocal Fusion)" + ) + + class VectorSearchSettings(BaseModel): use_vector_search: bool = Field( default=True, description="Whether to use vector search" ) + use_hybrid_search: bool = Field( + default=False, + description="Whether to perform a hybrid search (combining vector and keyword search)", + ) filters: dict[str, Any] = Field( default_factory=dict, description="Filters to apply to the vector search", @@ -92,19 +129,59 @@ class VectorSearchSettings(BaseModel): default=10, description="Maximum number of results to return", ge=1, - le=100, - ) - do_hybrid_search: bool = Field( - default=False, - description="Whether to perform a hybrid search (combining vector and keyword search)", + le=1_000, ) selected_group_ids: list[UUID] = Field( default_factory=list, description="Group IDs to search for", ) + index_measure: IndexMeasure = Field( + default=IndexMeasure.cosine_distance, + description="The distance measure to use for indexing", + ) + include_values: bool = Field( + default=True, + description="Whether to include search score values in the search results", + ) + include_metadatas: bool = Field( + default=True, + description="Whether to include element metadata in the search results", + ) + probes: Optional[int] = Field( + default=10, + description="Number of ivfflat index lists to query. Higher increases accuracy but decreases speed.", + ) + ef_search: Optional[int] = Field( + default=40, + description="Size of the dynamic candidate list for HNSW index search. Higher increases accuracy but decreases speed.", + ) + hybrid_search_settings: Optional[HybridSearchSettings] = Field( + default=HybridSearchSettings(), + description="Settings for hybrid search", + ) class Config: json_encoders = {UUID: str} + json_schema_extra = { + "use_vector_search": True, + "use_hybrid_search": True, + "filters": {"category": "technology"}, + "search_limit": 20, + "selected_group_ids": [ + "2acb499e-8428-543b-bd85-0d9098718220", + "3e157b3a-8469-51db-90d9-52e7d896b49b", + ], + "index_measure": "cosine_distance", + "include_metadata": True, + "probes": 10, + "ef_search": 40, + "hybrid_search_settings": { + "full_text_weight": 1.0, + "semantic_weight": 5.0, + "full_text_limit": 200, + "rrf_k": 50, + }, + } def model_dump(self, *args, **kwargs): dump = super().model_dump(*args, **kwargs) @@ -130,3 +207,21 @@ class KGSearchSettings(BaseModel): "__Relationship__": 20, "__Community__": 20, } + + class Config: + json_encoders = {UUID: str} + json_schema_extra = { + "use_kg_search": True, + "kg_search_type": "global", + "kg_search_level": "global", + "kg_search_generation_config": GenerationConfig.Config.json_schema_extra, + "entity_types": ["Person", "Organization"], + "relationships": ["founder", "CEO"], + "max_community_description_length": 4096 * 4, + "max_llm_queries_for_global_search": 250, + "local_search_limits": { + "__Entity__": 20, + "__Relationship__": 20, + "__Community__": 20, + }, + } diff --git a/r2r_core/cli/commands/rag_operations.py b/r2r_core/cli/commands/rag_operations.py index 26c458974..af79505be 100644 --- a/r2r_core/cli/commands/rag_operations.py +++ b/r2r_core/cli/commands/rag_operations.py @@ -32,7 +32,9 @@ def inspect_knowledge_graph(obj, limit, print_descriptions): @click.option( "--search-limit", default=10, help="Number of search results to return" ) -@click.option("--do-hybrid-search", is_flag=True, help="Perform hybrid search") +@click.option( + "--use-hybrid-search", is_flag=True, help="Perform hybrid search" +) @click.option( "--use-kg-search", is_flag=True, help="Use knowledge graph search" ) @@ -52,7 +54,7 @@ def rag( use_vector_search, filters, search_limit, - do_hybrid_search, + use_hybrid_search, use_kg_search, kg_search_model, stream, @@ -74,7 +76,7 @@ def rag( use_vector_search, filters, search_limit, - do_hybrid_search, + use_hybrid_search, use_kg_search, kg_search_generation_config, stream, @@ -105,7 +107,9 @@ def rag( @click.option( "--search-limit", default=10, help="Number of search results to return" ) -@click.option("--do-hybrid-search", is_flag=True, help="Perform hybrid search") +@click.option( + "--use-hybrid-search", is_flag=True, help="Perform hybrid search" +) @click.option( "--use-kg-search", is_flag=True, help="Use knowledge graph search" ) @@ -119,7 +123,7 @@ def search( use_vector_search, filters, search_limit, - do_hybrid_search, + use_hybrid_search, use_kg_search, kg_search_model, kg_search_type, @@ -138,7 +142,7 @@ def search( use_vector_search=use_vector_search, filters=filters, search_limit=search_limit, - do_hybrid_search=do_hybrid_search, + use_hybrid_search=use_hybrid_search, use_kg_search=use_kg_search, entity_types=entity_types, relationships=relationships, diff --git a/r2r_core/examples/scripts/advanced_kg_cookbook.py b/r2r_core/examples/scripts/advanced_kg_cookbook.py index eedbd1bfa..6818ad213 100644 --- a/r2r_core/examples/scripts/advanced_kg_cookbook.py +++ b/r2r_core/examples/scripts/advanced_kg_cookbook.py @@ -3,6 +3,7 @@ import fire import requests from bs4 import BeautifulSoup, Comment + from r2r import EntityType, R2RClient, R2RPromptProvider, RelationshipType @@ -160,22 +161,6 @@ def main( ] ) - if not local_mode: - - # support local and global - result = client.search( - query="Find up to 10 founders that worked at Google", - kg_search_settings={"ause_kg_search": True}, - )["results"] - - # print("Search Result:\n", result["kg_search_results"]) - - # result = client.rag( - # query="Find up to 10 founders that worked at Google", - # kg_search_settings={"use_kg_search": True}, - # ) - # print("RAG Result:\n", result) - if __name__ == "__main__": fire.Fire(main) diff --git a/r2r_core/main/api/routes/retrieval/base.py b/r2r_core/main/api/routes/retrieval/base.py index e86276dbd..a8e469c5c 100644 --- a/r2r_core/main/api/routes/retrieval/base.py +++ b/r2r_core/main/api/routes/retrieval/base.py @@ -53,12 +53,6 @@ async def search_app( vector_search_settings: VectorSearchSettings = Body( default_factory=VectorSearchSettings, description=search_descriptions.get("vector_search_settings"), - example={ - "use_vector_search": True, - "filters": {"category": "technology"}, - "search_limit": 20, - "do_hybrid_search": True, - }, ), kg_search_settings: KGSearchSettings = Body( default_factory=KGSearchSettings, @@ -73,7 +67,7 @@ async def search_app( Filters can be applied to various fields such as document_id, and internal metadata values. - Allowed filtered operators include `eq`, `neq`, `gt`, `gte`, `lt`, `lte`, `like`, `ilike`, `in`, and `nin`. + Allowed operators include `eq`, `neq`, `gt`, `gte`, `lt`, `lte`, `like`, `ilike`, `in`, and `nin`. """ @@ -86,18 +80,21 @@ async def search_app( f"{selected_groups - allowed_groups}" ) - vector_search_settings.filters = { + filters = { "$or": [ {"user_id": str(auth_user.id)}, {"group_ids": {"$overlap": list(allowed_groups)}}, - ], - "$and": vector_search_settings.filters, + ] } + if vector_search_settings.filters != {}: + filters = {"$and": [filters, vector_search_settings.filters]} + + vector_search_settings.filters = filters + results = await self.engine.asearch( query=query, vector_search_settings=vector_search_settings, kg_search_settings=kg_search_settings, - user=auth_user, ) return results @@ -138,13 +135,16 @@ async def rag_app( The generation process can be customized using the rag_generation_config parameter. """ allowed_groups = set(auth_user.group_ids) - vector_search_settings.filters = { + filters = { "$or": [ {"user_id": str(auth_user.id)}, {"group_ids": {"$overlap": list(allowed_groups)}}, - ], - "$and": vector_search_settings.filters, + ] } + if vector_search_settings.filters != {}: + filters = {"$and": [filters, vector_search_settings.filters]} + + vector_search_settings.filters = filters response = await self.engine.arag( query=query, @@ -152,7 +152,6 @@ async def rag_app( kg_search_settings=kg_search_settings, rag_generation_config=rag_generation_config, task_prompt_override=task_prompt_override, - user=auth_user, ) if rag_generation_config.stream: @@ -213,14 +212,19 @@ async def agent_app( The agent's behavior can be customized using the rag_generation_config and task_prompt_override parameters. """ + # TODO - Don't just copy paste the same code, refactor this allowed_groups = set(auth_user.group_ids) - vector_search_settings.filters = { + filters = { "$or": [ {"user_id": str(auth_user.id)}, {"group_ids": {"$overlap": list(allowed_groups)}}, - ], - "$and": vector_search_settings.filters, + ] } + if vector_search_settings.filters != {}: + filters = {"$and": [filters, vector_search_settings.filters]} + + vector_search_settings.filters = filters + response = await self.engine.arag_agent( messages=messages, vector_search_settings=vector_search_settings, @@ -228,7 +232,6 @@ async def agent_app( rag_generation_config=rag_generation_config, task_prompt_override=task_prompt_override, include_title_if_available=include_title_if_available, - user=auth_user, ) if rag_generation_config.stream: diff --git a/r2r_core/main/api/routes/retrieval/retrieval_router_openapi.yml b/r2r_core/main/api/routes/retrieval/retrieval_router_openapi.yml index 7faa8c0b2..a61b209a2 100644 --- a/r2r_core/main/api/routes/retrieval/retrieval_router_openapi.yml +++ b/r2r_core/main/api/routes/retrieval/retrieval_router_openapi.yml @@ -14,7 +14,7 @@ search: "use_vector_search": True, "filters": {"document_id": {"eq": "3e157b3a-8469-51db-90d9-52e7d896b49b"}}, "search_limit": 20, - "do_hybrid_search": True + "use_hybrid_search": True } ) - lang: Shell @@ -28,7 +28,7 @@ search: "use_vector_search": true, "filters": {"document_id": {"eq": "3e157b3a-8469-51db-90d9-52e7d896b49b"}}, "search_limit": 20, - "do_hybrid_search": true + "use_hybrid_search": true } }' @@ -53,7 +53,7 @@ rag: "use_vector_search": True, "filters": {"document_id": {"eq": "3e157b3a-8469-51db-90d9-52e7d896b49b"}}, "search_limit": 20, - "do_hybrid_search": True + "use_hybrid_search": True }, rag_generation_config={ "stream": False, @@ -72,7 +72,7 @@ rag: "use_vector_search": true, "filters": {"document_id": {"eq": "3e157b3a-8469-51db-90d9-52e7d896b49b"}}, "search_limit": 20, - "do_hybrid_search": true + "use_hybrid_search": true }, "rag_generation_config": { "stream": false, @@ -108,7 +108,7 @@ agent: "use_vector_search": True, "filters": {"document_id": {"eq": "5e157b3a-8469-51db-90d9-52e7d896b49b"}}, "search_limit": 20, - "do_hybrid_search": True + "use_hybrid_search": True }, rag_generation_config={ "stream": False, @@ -132,7 +132,7 @@ agent: "use_vector_search": true, "filters": {"document_id": {"eq": "5e157b3a-8469-51db-90d9-52e7d896b49b"}}, "search_limit": 20, - "do_hybrid_search": true + "use_hybrid_search": true }, "rag_generation_config": { "stream": false, diff --git a/r2r_core/main/app.py b/r2r_core/main/app.py index 2dd61787c..8276c8e7e 100644 --- a/r2r_core/main/app.py +++ b/r2r_core/main/app.py @@ -37,7 +37,6 @@ def _setup_routes(self): self.engine ) auth_router = auth_base.AuthRouter.build_router(self.engine) - restructure_router = restructure_base.RestructureRouter.build_router( self.engine ) diff --git a/r2r_core/main/execution.py b/r2r_core/main/execution.py index 6be195e1f..412adea27 100644 --- a/r2r_core/main/execution.py +++ b/r2r_core/main/execution.py @@ -172,7 +172,6 @@ def spinner(): metadatas=metadatas, versions=versions, ) - print("results = ", results) results["results"] else: results = self.app.ingest_files( @@ -228,7 +227,7 @@ def search( use_vector_search: bool = True, filters: Optional[dict[str, str]] = None, search_limit: int = 10, - do_hybrid_search: bool = False, + use_hybrid_search: bool = False, use_kg_search: bool = False, kg_search_generation_config: Optional[dict] = None, kg_search_type: str = "global", @@ -243,7 +242,7 @@ def search( use_vector_search=use_vector_search, filters=filters or {}, search_limit=search_limit, - do_hybrid_search=do_hybrid_search, + use_hybrid_search=use_hybrid_search, ), KGSearchSettings( use_kg_search=use_kg_search, @@ -263,7 +262,7 @@ def search( use_vector_search=use_vector_search, filters=filters or {}, search_limit=search_limit, - do_hybrid_search=do_hybrid_search, + use_hybrid_search=use_hybrid_search, ), KGSearchSettings( use_kg_search=use_kg_search, @@ -283,7 +282,7 @@ def rag( use_vector_search: bool = True, filters: Optional[dict[str, str]] = None, search_limit: int = 10, - do_hybrid_search: bool = False, + use_hybrid_search: bool = False, use_kg_search: bool = False, kg_search_generation_config: Optional[dict] = None, stream: bool = False, @@ -298,7 +297,7 @@ def rag( use_vector_search=use_vector_search, filters=filters or {}, search_limit=search_limit, - do_hybrid_search=do_hybrid_search, + use_hybrid_search=use_hybrid_search, ), kg_search_settings=KGSearchSettings( use_kg_search=use_kg_search, @@ -325,7 +324,7 @@ def rag( use_vector_search=use_vector_search, filters=filters or {}, search_limit=search_limit, - do_hybrid_search=do_hybrid_search, + use_hybrid_search=use_hybrid_search, ), kg_search_settings=KGSearchSettings( use_kg_search=use_kg_search, diff --git a/r2r_core/main/services/ingestion_service.py b/r2r_core/main/services/ingestion_service.py index c488761dd..30defa28f 100644 --- a/r2r_core/main/services/ingestion_service.py +++ b/r2r_core/main/services/ingestion_service.py @@ -91,7 +91,6 @@ async def ingest_files( return await self.ingest_documents( documents, versions, - user=user, chunking_provider=chunking_provider, *args, **kwargs, diff --git a/r2r_core/main/services/management_service.py b/r2r_core/main/services/management_service.py index c8476ae43..78efb01e0 100644 --- a/r2r_core/main/services/management_service.py +++ b/r2r_core/main/services/management_service.py @@ -434,7 +434,7 @@ async def aremove_document_from_group( @telemetry_event("GetDocumentGroups") async def aget_document_groups(self, document_id: str): - group_ids = self.providers.database.vector.get_document_groups( + group_ids = self.providers.database.relational.get_document_groups( document_id ) return {"group_ids": [str(group_id) for group_id in group_ids]} diff --git a/r2r_core/main/services/retrieval_service.py b/r2r_core/main/services/retrieval_service.py index d2ec8c69f..7138af38c 100644 --- a/r2r_core/main/services/retrieval_service.py +++ b/r2r_core/main/services/retrieval_service.py @@ -79,6 +79,15 @@ async def search( message="Vector search is not enabled in the configuration.", ) + if ( + vector_search_settings.use_vector_search + and vector_search_settings.use_hybrid_search + and not vector_search_settings.hybrid_search_settings + ): + raise R2RException( + status_code=400, + message="Hybrid search settings must be specified in the input configuration.", + ) # TODO - Remove these transforms once we have a better way to handle this for filter, value in vector_search_settings.filters.items(): if isinstance(value, UUID): @@ -111,7 +120,6 @@ async def rag( rag_generation_config: GenerationConfig, vector_search_settings: VectorSearchSettings = VectorSearchSettings(), kg_search_settings: KGSearchSettings = KGSearchSettings(), - user: Optional[UserResponse] = None, *args, **kwargs, ) -> RAGResponse: @@ -140,12 +148,10 @@ async def rag( if rag_generation_config.stream: return await self.stream_rag_response( query, - run_id, completion_record, rag_generation_config, vector_search_settings, kg_search_settings, - user, *args, **kwargs, ) @@ -195,7 +201,7 @@ async def rag( if "NoneType" in str(e): raise R2RException( status_code=502, - message="Ollama server not reachable or returned an invalid response", + message="Remote server not reachable or returned an invalid response", ) raise R2RException( status_code=500, message="Internal Server Error" @@ -204,12 +210,10 @@ async def rag( async def stream_rag_response( self, query, - run_id, completion_record, rag_generation_config, vector_search_settings, kg_search_settings, - user, *args, **kwargs, ): @@ -238,7 +242,6 @@ async def agent( rag_generation_config: GenerationConfig, vector_search_settings: VectorSearchSettings = VectorSearchSettings(), kg_search_settings: KGSearchSettings = KGSearchSettings(), - user: Optional[UserResponse] = None, task_prompt_override: Optional[str] = None, include_title_if_available: Optional[bool] = False, *args, diff --git a/r2r_core/pipelines/rag_pipeline.py b/r2r_core/pipelines/rag_pipeline.py index c67c7da2a..dc6604fbf 100644 --- a/r2r_core/pipelines/rag_pipeline.py +++ b/r2r_core/pipelines/rag_pipeline.py @@ -34,7 +34,6 @@ async def run( vector_search_settings: VectorSearchSettings = VectorSearchSettings(), kg_search_settings: KGSearchSettings = KGSearchSettings(), rag_generation_config: GenerationConfig = GenerationConfig(), - user: Optional[UserResponse] = None, *args: Any, **kwargs: Any, ): diff --git a/r2r_core/pipelines/search_pipeline.py b/r2r_core/pipelines/search_pipeline.py index 9bccbbc8d..e184d6090 100644 --- a/r2r_core/pipelines/search_pipeline.py +++ b/r2r_core/pipelines/search_pipeline.py @@ -8,7 +8,6 @@ KGSearchSettings, VectorSearchSettings, ) -from ..base.api.models.auth.responses import UserResponse from ..base.logging.run_logger import RunLoggingSingleton from ..base.logging.run_manager import RunManager, manage_run from ..base.pipeline.base_pipeline import AsyncPipeline, dequeue_requests @@ -38,12 +37,11 @@ async def run( run_manager: Optional[RunManager] = None, vector_search_settings: VectorSearchSettings = VectorSearchSettings(), kg_search_settings: KGSearchSettings = KGSearchSettings(), - user: Optional[UserResponse] = None, *args: Any, **kwargs: Any, ): self.state = state or AsyncState() - do_vector_search = ( + use_vector_search = ( self._vector_search_pipeline is not None and vector_search_settings.use_vector_search ) @@ -58,7 +56,7 @@ async def run( async def enqueue_requests(): async for message in input: - if do_vector_search: + if use_vector_search: await vector_search_queue.put(message) if do_kg: await kg_queue.put(message) @@ -70,7 +68,7 @@ async def enqueue_requests(): enqueue_task = asyncio.create_task(enqueue_requests()) # Start the embedding and KG pipelines in parallel - if do_vector_search: + if use_vector_search: vector_search_task = asyncio.create_task( self._vector_search_pipeline.run( dequeue_requests(vector_search_queue), @@ -99,7 +97,7 @@ async def enqueue_requests(): await enqueue_task vector_search_results = ( - await vector_search_task if do_vector_search else None + await vector_search_task if use_vector_search else None ) kg_results = await kg_task if do_kg else None diff --git a/r2r_core/pipes/ingestion/chunking_pipe.py b/r2r_core/pipes/ingestion/chunking_pipe.py index ff5653486..04ce83a05 100644 --- a/r2r_core/pipes/ingestion/chunking_pipe.py +++ b/r2r_core/pipes/ingestion/chunking_pipe.py @@ -65,6 +65,7 @@ async def _run_logic( try: iteration = 0 async for chunk in chunking_provider.chunk(item.data): + item.metadata["chunk_order"] = iteration yield DocumentFragment( id=generate_id_from_label(f"{item.id}-{iteration}"), extraction_id=item.id, diff --git a/r2r_core/pipes/ingestion/parsing_pipe.py b/r2r_core/pipes/ingestion/parsing_pipe.py index 514ac3c55..28bb997d9 100644 --- a/r2r_core/pipes/ingestion/parsing_pipe.py +++ b/r2r_core/pipes/ingestion/parsing_pipe.py @@ -58,6 +58,8 @@ async def _parse( f"{extraction.id}-{version}" ) extraction.id = extraction_id + # Add version to metadata + extraction.metadata["version"] = version yield extraction except Exception as e: yield R2RDocumentProcessingError( diff --git a/r2r_core/pipes/retrieval/vector_search_pipe.py b/r2r_core/pipes/retrieval/vector_search_pipe.py index 3e914820d..e32d622c5 100644 --- a/r2r_core/pipes/retrieval/vector_search_pipe.py +++ b/r2r_core/pipes/retrieval/vector_search_pipe.py @@ -49,8 +49,10 @@ async def search( await self.enqueue_log( run_id=run_id, key="search_query", value=message ) - filters = vector_search_settings.filters or self.config.filters - search_limit = ( + vector_search_settings.filters = ( + vector_search_settings.filters or self.config.filters + ) + vector_search_settings.search_limit = ( vector_search_settings.search_limit or self.config.search_limit ) results = [] @@ -62,18 +64,18 @@ async def search( self.database_provider.vector.hybrid_search( query_vector=query_vector, query_text=message, - filters=filters, - limit=search_limit, + search_settings=vector_search_settings, ) - if vector_search_settings.do_hybrid_search - else self.database_provider.vector.search( + if vector_search_settings.use_hybrid_search + else self.database_provider.vector.semantic_search( query_vector=query_vector, - filters=filters, - limit=search_limit, + search_settings=vector_search_settings, ) ) reranked_results = self.embedding_provider.rerank( - query=message, results=search_results, limit=search_limit + query=message, + results=search_results, + limit=vector_search_settings.search_limit, ) include_title_if_available = kwargs.get( "include_title_if_available", False diff --git a/r2r_core/providers/database/document.py b/r2r_core/providers/database/document.py index e7ba96ebe..07b214021 100644 --- a/r2r_core/providers/database/document.py +++ b/r2r_core/providers/database/document.py @@ -109,3 +109,16 @@ def get_documents_overview( ) for row in results ] + + def get_document_groups(self, document_id: str) -> list[str]: + query = f""" + SELECT group_ids + FROM {self._get_table_name('document_info')} + WHERE document_id = :document_id + """ + params = {"document_id": document_id} + result = self.execute_query(query, params).fetchone() + + if result and result[0]: + return [str(group_id) for group_id in result[0]] + return [] diff --git a/r2r_core/providers/database/vecs/collection.py b/r2r_core/providers/database/vecs/collection.py index dc3c487ba..bf8d00f42 100644 --- a/r2r_core/providers/database/vecs/collection.py +++ b/r2r_core/providers/database/vecs/collection.py @@ -21,7 +21,7 @@ Tuple, Union, ) -from uuid import UUID +from uuid import UUID, uuid4 import psycopg2 from flupy import flu @@ -43,6 +43,8 @@ from sqlalchemy.dialects import postgresql from sqlalchemy.types import Float, UserDefinedType +from r2r_core.base.abstractions import VectorSearchSettings + from .adapter import Adapter, AdapterContext, NoOp, Record from .exc import ( ArgError, @@ -350,7 +352,7 @@ def _create(self): ) self.table.create(self.client.engine) - unique_string = str(uuid.uuid4()).replace("-", "_")[0:7] + unique_string = str(uuid4()).replace("-", "_")[0:7] with self.client.Session() as sess: sess.execute( text( @@ -403,16 +405,12 @@ def _drop(self): def upsert( self, records: Iterable[Record], - skip_adapter: bool = False, ) -> None: chunk_size = 512 - if skip_adapter: - pipeline = flu(records).chunk(chunk_size) - else: - pipeline = flu( - self.adapter(records, AdapterContext("upsert")) - ).chunk(chunk_size) + pipeline = flu(self.adapter(records, AdapterContext("upsert"))).chunk( + chunk_size + ) with self.client.Session() as sess: with sess.begin(): @@ -532,7 +530,7 @@ def delete( } if filters: - meta_filter = self._build_complex_filters(filters) + meta_filter = self.build_filters(filters) delete_stmt = ( delete(self.table) .where(meta_filter) @@ -576,53 +574,37 @@ def __getitem__(self, items): def query( self, vector: list[float], - filters: Dict[str, Any] = {}, - imeasure: IndexMeasure = IndexMeasure.cosine_distance, - limit: int = 10, - include_value: bool = False, - include_metadata: bool = False, - *, - probes: Optional[int] = None, - ef_search: Optional[int] = None, + search_settings: VectorSearchSettings, ) -> Union[List[Record], List[str]]: """ - Executes a similarity search in the collection based on the new query structure. + Executes a similarity search in the collection. + + The return type is dependent on arguments *include_value* and *include_metadata* Args: - vector (list[float]): The query vector. - filters (Dict[str, Any], optional): Metadata filters to apply. Defaults to {}. - imeasure (IndexMeasure, optional): The distance measure to use. Defaults to IndexMeasure.cosine_distance. - limit (int, optional): The maximum number of results to return. Defaults to 10. - include_value (bool, optional): Whether to include the distance value in the results. Defaults to False. - include_metadata (bool, optional): Whether to include the metadata in the results. Defaults to False. - probes (Optional[int], optional): Number of ivfflat index lists to query. - ef_search (Optional[int], optional): Size of the dynamic candidate list for HNSW index search. + data (list[float]): The vector to use as the query. + search_settings (VectorSearchSettings): The search settings to use. Returns: Union[List[Record], List[str]]: The result of the similarity search. - - Raises: - ArgError: If the limit is greater than 1000 or if an invalid distance measure is provided. """ - if probes is None: - probes = 10 - - if ef_search is None: - ef_search = 40 - if limit > 1000: - raise ArgError("limit must be <= 1000") + try: + imeasure_obj = IndexMeasure(search_settings.index_measure) + except ValueError: + raise ArgError("Invalid index measure") - if not self.is_indexed_for_measure(imeasure): + if not self.is_indexed_for_measure(imeasure_obj): warnings.warn( UserWarning( - f"Query does not have a covering index for {imeasure}. See Collection.create_index" + f"Query does not have a covering index for {imeasure_obj}. See Collection.create_index" ) ) - distance_lambda = INDEX_MEASURE_TO_SQLA_ACC.get(imeasure) + distance_lambda = INDEX_MEASURE_TO_SQLA_ACC.get(imeasure_obj) if distance_lambda is None: - raise ArgError("invalid distance_measure") + # unreachable + raise ArgError("invalid distance_measure") # pragma: no cover distance_clause = distance_lambda(self.table.c.vec)(vector) @@ -634,110 +616,142 @@ def query( self.table.c.group_ids, self.table.c.text, ] - if include_value: + if search_settings.include_values: cols.append(distance_clause) - if include_metadata: + if search_settings.include_metadatas: cols.append(self.table.c.metadata) stmt = select(*cols) - stmt = stmt.filter(self._build_complex_filters(filters)) + # if filters: + stmt = stmt.filter(self.build_filters(search_settings.filters)) # type: ignore stmt = stmt.order_by(distance_clause) - stmt = stmt.limit(limit) + stmt = stmt.limit(search_settings.search_limit) with self.client.Session() as sess: with sess.begin(): + # index ignored if greater than n_lists sess.execute( text("set local ivfflat.probes = :probes").bindparams( - probes=probes + probes=search_settings.probes ) ) if self.client._supports_hnsw(): sess.execute( text( "set local hnsw.ef_search = :ef_search" - ).bindparams(ef_search=ef_search) + ).bindparams(ef_search=search_settings.ef_search) ) if len(cols) == 1: return [str(x) for x in sess.scalars(stmt).fetchall()] return sess.execute(stmt).fetchall() or [] - def _build_complex_filters(self, filters: Dict[str, Any]): + def build_filters(self, filters: Dict): """ - Builds complex filters for SQL query based on the new filter structure. + PUBLIC + + Builds filters for SQL query based on provided dictionary. Args: - filters (Dict[str, Any]): The dictionary specifying filter conditions. + table: The SQLAlchemy table object. + filters (Dict): The dictionary specifying filter conditions. + + Raises: + FilterError: If filter conditions are not correctly formatted. Returns: The filter clause for the SQL query. """ - def parse_condition(key, condition): - if key in self.COLUMN_VARS: + if not isinstance(filters, dict): + raise FilterError("filters must be a dict") + + def parse_condition(key, value): + if key in Collection.COLUMN_VARS: # Handle column-based filters column = getattr(self.table.c, key) - if isinstance(condition, dict): - op = list(condition.keys())[0] - value = condition[op] + if isinstance(value, dict): + op, clause = next(iter(value.items())) if op == "$eq": - return column == value + return column == clause elif op == "$ne": - return column != value + return column != clause elif op == "$in": - return column.in_(value) + return column.in_(clause) elif op == "$nin": - return ~column.in_(value) + return ~column.in_(clause) elif op == "$overlap": - return column.overlap(value) + return column.overlap(clause) else: raise FilterError( f"Unsupported operator for column {key}: {op}" ) else: - return column == condition + return column == value else: - if isinstance(condition, dict): - op = list(condition.keys())[0] - value = condition[op] - if op == "$eq": - return self.table.c.metadata[key].astext == str(value) - elif op == "$ne": - return self.table.c.metadata[key].astext != str(value) - elif op == "$gt": - return ( - cast(self.table.c.metadata[key].astext, Float) - > value - ) - elif op == "$gte": - return ( - cast(self.table.c.metadata[key].astext, Float) - >= value - ) - elif op == "$lt": - return ( - cast(self.table.c.metadata[key].astext, Float) - < value - ) - elif op == "$lte": - return ( - cast(self.table.c.metadata[key].astext, Float) - <= value - ) - elif op == "$in": - return self.table.c.metadata[key].astext.in_( - [str(v) for v in value] - ) - elif op == "$nin": - return ~self.table.c.metadata[key].astext.in_( - [str(v) for v in value] + # Handle JSON-based filters + json_col = self.table.c.metadata + if isinstance(value, dict): + if len(value) > 1: + raise FilterError("only one operator permitted") + operator, clause = next(iter(value.items())) + if operator not in ( + "$eq", + "$ne", + "$lt", + "$lte", + "$gt", + "$gte", + "$in", + "$contains", + ): + raise FilterError("unknown operator") + + if operator == "$eq" and not hasattr(clause, "__len__"): + contains_value = cast({key: clause}, postgresql.JSONB) + return json_col.op("@>")(contains_value) + + if operator == "$in": + if not isinstance(clause, list): + raise FilterError( + "argument to $in filter must be a list" + ) + for elem in clause: + if not isinstance(elem, (int, str, float)): + raise FilterError( + "argument to $in filter must be a list of scalars" + ) + contains_value = [ + cast(elem, postgresql.JSONB) for elem in clause + ] + return json_col.op("->")(key).in_(contains_value) + + matches_value = cast(clause, postgresql.JSONB) + + if operator == "$contains": + if not isinstance(clause, (int, str, float)): + raise FilterError( + "argument to $contains filter must be a scalar" + ) + return and_( + json_col.op("->")(key).contains(matches_value), + func.jsonb_typeof(json_col.op("->")(key)) + == "array", ) - else: - raise FilterError(f"Unsupported operator: {op}") + + return { + "$eq": json_col.op("->")(key) == matches_value, + "$ne": json_col.op("->")(key) != matches_value, + "$lt": json_col.op("->")(key) < matches_value, + "$lte": json_col.op("->")(key) <= matches_value, + "$gt": json_col.op("->")(key) > matches_value, + "$gte": json_col.op("->")(key) >= matches_value, + }[operator] else: - return self.table.c.metadata[key].astext == str(condition) + contains_value = cast({key: value}, postgresql.JSONB) + return json_col.op("@>")(contains_value) def parse_filter(filter_dict): conditions = [] @@ -951,7 +965,7 @@ def create_index( if ops is None: raise ArgError("Unknown index measure") - unique_string = str(uuid.uuid4()).replace("-", "_")[0:7] + unique_string = str(uuid4()).replace("-", "_")[0:7] with self.client.Session() as sess: with sess.begin(): diff --git a/r2r_core/providers/database/vector.py b/r2r_core/providers/database/vector.py index bd9d20585..754ce6489 100644 --- a/r2r_core/providers/database/vector.py +++ b/r2r_core/providers/database/vector.py @@ -14,6 +14,7 @@ VectorSearchResult, generate_id_from_label, ) +from r2r_core.base.abstractions import VectorSearchSettings from .vecs import Client, Collection, create_client @@ -120,7 +121,6 @@ def __init__(self, config: DatabaseConfig, *args, **kwargs): self.collection: Optional[Collection] = None self._initialize_vector_db(dimension) - self._create_hybrid_search_function() logger.info( f"Successfully initialized PGVectorDB with collection: {self.collection_name}" ) @@ -130,107 +130,6 @@ def _initialize_vector_db(self, dimension: int) -> None: name=self.collection_name, dimension=dimension ) - def _create_hybrid_search_function(self): - hybrid_search_function = f""" - CREATE OR REPLACE FUNCTION hybrid_search_{self.collection_name}( - query_text TEXT, - query_embedding VECTOR(512), - match_limit INT, - full_text_weight FLOAT = 1, - semantic_weight FLOAT = 1, - rrf_k INT = 50, - filter_condition JSONB = NULL - ) - RETURNS TABLE( - fragment_id UUID, - extraction_id UUID, - document_id UUID, - user_id UUID, - group_ids UUID[], - vec VECTOR(512), - text TEXT, - metadata JSONB, - rrf_score FLOAT, - semantic_score FLOAT, - full_text_score FLOAT, - rank_semantic INT, - rank_full_text INT - ) - LANGUAGE sql - AS $$ - WITH full_text AS ( - SELECT - fragment_id, - ts_rank_cd(to_tsvector('english', text), websearch_to_tsquery('english', query_text), 1 | 2 | 4 | 8 | 16 | 32 | 64) * 10000 AS full_text_score, - ROW_NUMBER() OVER (ORDER BY ts_rank_cd(to_tsvector('english', text), websearch_to_tsquery('english', query_text), 1 | 2 | 4 | 8 | 16 | 32 | 64) DESC) AS rank_ix - FROM vecs."{self.collection_name}" - WHERE to_tsvector('english', text) @@ websearch_to_tsquery('english', query_text) - AND (filter_condition IS NULL OR (metadata @> filter_condition)) - ORDER BY rank_ix - LIMIT LEAST(match_limit, 30) * 2 - ), - semantic AS ( - SELECT - fragment_id, - 1 - (vec <=> query_embedding) AS semantic_score, - ROW_NUMBER() OVER (ORDER BY (vec <=> query_embedding)) AS rank_ix - FROM vecs."{self.collection_name}" - WHERE filter_condition IS NULL OR (metadata @> filter_condition) - ORDER BY rank_ix - LIMIT LEAST(match_limit, 30) * 2 - ) - SELECT - vecs."{self.collection_name}".fragment_id, - vecs."{self.collection_name}".extraction_id, - vecs."{self.collection_name}".document_id, - vecs."{self.collection_name}".user_id, - vecs."{self.collection_name}".group_ids, - vecs."{self.collection_name}".vec, - vecs."{self.collection_name}".text, - vecs."{self.collection_name}".metadata, - (COALESCE(1.0 / (rrf_k + full_text.rank_ix), 0.0) * full_text_weight + - COALESCE(1.0 / (rrf_k + semantic.rank_ix), 0.0) * semantic_weight) AS rrf_score, - COALESCE(semantic.semantic_score, 0) AS semantic_score, - COALESCE(full_text.full_text_score, 0) AS full_text_score, - semantic.rank_ix AS rank_semantic, - full_text.rank_ix AS rank_full_text - FROM - full_text - FULL OUTER JOIN semantic - ON full_text.fragment_id = semantic.fragment_id - JOIN vecs."{self.collection_name}" - ON vecs."{self.collection_name}".fragment_id = COALESCE(full_text.fragment_id, semantic.fragment_id) - ORDER BY - rrf_score DESC - LIMIT - LEAST(match_limit, 30); - $$; - """ - retry_attempts = 5 - for attempt in range(retry_attempts): - try: - with self.vx.Session() as sess: - # Acquire an advisory lock - sess.execute(text("SELECT pg_advisory_lock(123456789)")) - try: - sess.execute(text(hybrid_search_function)) - sess.commit() - finally: - # Release the advisory lock - sess.execute( - text("SELECT pg_advisory_unlock(123456789)") - ) - break # Break the loop if successful - except exc.InternalError as e: - if "tuple concurrently updated" in str(e): - time.sleep(2**attempt) # Exponential backoff - else: - raise # Re-raise the exception if it's not a concurrency issue - else: - raise RuntimeError( - "Failed to create hybrid search function after multiple attempts" - ) - def upsert(self, entry: VectorEntry) -> None: if self.collection is None: raise ValueError( @@ -287,26 +186,15 @@ def get_document_groups(self, document_id: str) -> list[str]: group_ids = result.scalar() return [str(group_id) for group_id in (group_ids or [])] - def search( - self, - query_vector: list[float], - filters: dict[str, Any] = {}, - limit: int = 10, - measure: str = "cosine_distance", - *args, - **kwargs, + def semantic_search( + self, query_vector: list[float], search_settings: VectorSearchSettings ) -> list[VectorSearchResult]: if self.collection is None: raise ValueError( - "Please call `initialize_collection` before attempting to run `search`." + "Please call `initialize_collection` before attempting to run `semantic_search`." ) results = self.collection.query( - vector=query_vector, - filters=filters, - limit=limit, - imeasure=measure, - include_value=True, - include_metadata=True, + vector=query_vector, search_settings=search_settings ) return [ VectorSearchResult( @@ -322,66 +210,176 @@ def search( for result in results ] + def full_text_search( + self, query_text: str, search_settings: VectorSearchSettings + ) -> list[VectorSearchResult]: + if self.collection is None: + raise ValueError( + "Please call `initialize_collection` before attempting to run `full_text_search`." + ) + from sqlalchemy import func, select + from sqlalchemy.sql.expression import or_ + + full_text_query = ( + select( + self.collection.table.c.fragment_id, + self.collection.table.c.extraction_id, + self.collection.table.c.document_id, + self.collection.table.c.user_id, + self.collection.table.c.group_ids, + self.collection.table.c.text, + self.collection.table.c.metadata, + func.ts_rank_cd( + func.to_tsvector("english", self.collection.table.c.text), + func.websearch_to_tsquery("english", query_text), + 1 | 2 | 4 | 8 | 16 | 32 | 64, + ).label("rank"), + func.ts_headline( + "english", + self.collection.table.c.text, + func.websearch_to_tsquery("english", query_text), + "StartSel = , StopSel = , MaxWords=35, MinWords=15", + ).label("headline"), + ) + .where( + or_( + func.to_tsvector( + "english", self.collection.table.c.text + ).op("@@")( + func.websearch_to_tsquery("english", query_text) + ), + func.similarity(self.collection.table.c.text, query_text) + > 0.3, + ) + ) + .order_by( + func.ts_rank_cd( + func.to_tsvector("english", self.collection.table.c.text), + func.websearch_to_tsquery("english", query_text), + 1 | 2 | 4 | 8 | 16 | 32 | 64, + ).desc() + ) + .limit(search_settings.hybrid_search_settings.full_text_limit) + ) + + if search_settings.filters: + full_text_query = full_text_query.where( + self.collection.build_filters(search_settings.filters) + ) + + with self.vx.Session() as session: + results = session.execute(full_text_query).fetchall() + + return [ + VectorSearchResult( + fragment_id=result.fragment_id, + extraction_id=result.extraction_id, + document_id=result.document_id, + user_id=result.user_id, + group_ids=result.group_ids, + text=result.text, + score=float(result.rank), + metadata={**result.metadata, "headline": result.headline}, + ) + for result in results + ] + def hybrid_search( self, query_text: str, query_vector: list[float], - limit: int = 10, - filters: dict[str, Any] = {}, - full_text_weight: float = 1.0, - semantic_weight: float = 1.0, - rrf_k: int = 20, + search_settings: VectorSearchSettings, *args, **kwargs, ) -> list[VectorSearchResult]: - if self.collection is None: + if search_settings.hybrid_search_settings is None: raise ValueError( - "Please call `initialize_collection` before attempting to run `hybrid_search`." + "Please provide a valid `hybrid_search_settings` in the `search_settings`." ) - - # Convert filters to a JSON-compatible format - filter_condition = json.dumps(filters) if filters else None - - query = text( - f""" - SELECT * FROM hybrid_search_{self.collection_name}( - cast(:query_text as TEXT), cast(:query_embedding as VECTOR), cast(:match_limit as INT), - cast(:full_text_weight as FLOAT), cast(:semantic_weight as FLOAT), cast(:rrf_k as INT), - cast(:filter_condition as JSONB) + if ( + search_settings.hybrid_search_settings.full_text_limit + < search_settings.search_limit + ): + raise ValueError( + "The `full_text_limit` must be greater than or equal to the `search_limit`." ) - """ + semantic_results = self.semantic_search(query_vector, search_settings) + full_text_results = self.full_text_search( + query_text, + search_settings, + ) + + semantic_limit = search_settings.search_limit + full_text_limit = ( + search_settings.hybrid_search_settings.full_text_limit + ) + semantic_weight = ( + search_settings.hybrid_search_settings.semantic_weight ) + full_text_weight = ( + search_settings.hybrid_search_settings.full_text_weight + ) + rrf_k = search_settings.hybrid_search_settings.rrf_k + # Combine results using RRF + combined_results = {} + for rank, result in enumerate(semantic_results, 1): + combined_results[result.fragment_id] = { + "semantic_rank": rank, + "full_text_rank": full_text_limit, + "data": result, + } + + for rank, result in enumerate(full_text_results, 1): + if result.fragment_id in combined_results: + combined_results[result.fragment_id]["full_text_rank"] = rank + else: + combined_results[result.fragment_id] = { + "semantic_rank": semantic_limit, + "full_text_rank": rank, + "data": result, + } - params = { - "query_text": str(query_text), - "query_embedding": list(query_vector), - "match_limit": limit, - "full_text_weight": full_text_weight, - "semantic_weight": semantic_weight, - "rrf_k": rrf_k, - "filter_condition": filter_condition, + # Filter out non-overlapping results + combined_results = { + k: v + for k, v in combined_results.items() + if v["semantic_rank"] <= semantic_limit * 2 + and v["full_text_rank"] <= full_text_limit * 2 } - with self.vx.Session() as session: - results = session.execute(query, params).fetchall() + # Calculate RRF scores + for result in combined_results.values(): + semantic_score = 1 / (rrf_k + result["semantic_rank"]) + full_text_score = 1 / (rrf_k + result["full_text_rank"]) + result["rrf_score"] = ( + semantic_score * semantic_weight + + full_text_score * full_text_weight + ) / (semantic_weight + full_text_weight) + + # Sort by RRF score and convert to VectorSearchResult + limit = min(semantic_limit, full_text_limit) + sorted_results = sorted( + combined_results.values(), + key=lambda x: x["rrf_score"], + reverse=True, + )[:limit] + return [ VectorSearchResult( - fragment_id=result[0], - extraction_id=result[1], - document_id=result[2], - user_id=result[3], - group_ids=result[4], - text=result[6], + fragment_id=result["data"].fragment_id, + extraction_id=result["data"].extraction_id, + document_id=result["data"].document_id, + user_id=result["data"].user_id, + group_ids=result["data"].group_ids, + text=result["data"].text, + score=result["rrf_score"], metadata={ - **result[7], - "semantic_score": result[9], - "semantic_rank": result[11], - "full_text_score": result[10], - "full_text_rank": result[12], + **result["data"].metadata, + "semantic_rank": result["semantic_rank"], + "full_text_rank": result["full_text_rank"], }, - score=result[8], ) - for result in results + for result in sorted_results ] def create_index(self, index_type, column_name, index_options): diff --git a/tests/regression/test_cases/test_retrieval.py b/tests/regression/test_cases/test_retrieval.py index f336744d4..54be2f790 100644 --- a/tests/regression/test_cases/test_retrieval.py +++ b/tests/regression/test_cases/test_retrieval.py @@ -47,7 +47,7 @@ def search_test(self, client): def hybrid_search_test(self, client): try: return client.search( - "What is the capital of France?", {"do_hybrid_search": True} + "What is the capital of France?", {"use_hybrid_search": True} ) except Exception as e: return {"results": str(e)} @@ -60,7 +60,7 @@ def basic_rag_test(self, client): def hybrid_rag_test(self, client): try: - return client.rag("Who is John Snow?", {"do_hybrid_search": True}) + return client.rag("Who is John Snow?", {"use_hybrid_search": True}) except Exception as e: return {"results": str(e)} From 2af4c81c44fafcdcb74f2e459652e746ce760db2 Mon Sep 17 00:00:00 2001 From: NolanTrem <34580718+NolanTrem@users.noreply.github.com> Date: Tue, 20 Aug 2024 10:43:51 -0700 Subject: [PATCH 12/74] Fix structure --- {r2r_cli => go/cli}/go.mod | 4 +- {r2r_cli => go/cli}/go.sum | 0 {r2r_cli => go/cli}/main.go | 0 {r2r_cli => go/cli}/rag_operations.go | 2 +- {r2r_cli => go/cli}/server_operations.go | 24 +- {r2r_cli => go/cli}/utils.go | 0 go/sdk/go.mod | 3 + .../tests/integration/management_test.go | 2 +- {r2r_go_sdk => go/sdk}/pkg/sdk/auth.go | 0 {r2r_go_sdk => go/sdk}/pkg/sdk/client.go | 0 {r2r_go_sdk => go/sdk}/pkg/sdk/ingestion.go | 0 {r2r_go_sdk => go/sdk}/pkg/sdk/management.go | 0 {r2r_go_sdk => go/sdk}/pkg/sdk/restructure.go | 0 {r2r_go_sdk => go/sdk}/pkg/sdk/retrieval.go | 0 {r2r_js_sdk => js/sdk}/README.md | 0 .../sdk}/__tests__/r2rClient.test.ts | 0 .../r2rClientIntegrationSuperUser.test.ts | 0 .../r2rClientIntegrationUser.test.ts | 0 .../sdk}/examples/data/folder/karamozov.txt | 0 .../sdk}/examples/data/folder/myshkin.txt | 0 .../sdk}/examples/data/raskolnikov.txt | 0 {r2r_js_sdk => js/sdk}/examples/hello_r2r.js | 0 {r2r_js_sdk => js/sdk}/jest.config.js | 0 {r2r_js_sdk => js/sdk}/package-lock.json | 0 {r2r_js_sdk => js/sdk}/package.json | 0 {r2r_js_sdk => js/sdk}/pnpm-lock.yaml | 0 {r2r_js_sdk => js/sdk}/src/feature.ts | 0 {r2r_js_sdk => js/sdk}/src/index.ts | 0 {r2r_js_sdk => js/sdk}/src/models.tsx | 0 {r2r_js_sdk => js/sdk}/src/r2rClient.ts | 0 {r2r_js_sdk => js/sdk}/tsconfig.json | 0 poetry.lock | 235 ++-- {r2r_core => py/core}/__init__.py | 0 {r2r_core => py/core}/agent/__init__.py | 0 {r2r_core => py/core}/agent/base.py | 4 +- {r2r_core => py/core}/agent/rag.py | 12 +- {r2r_core => py/core}/base/__init__.py | 0 .../core}/base/abstractions/__init__.py | 0 .../core}/base/abstractions/base.py | 0 .../core}/base/abstractions/completion.py | 0 .../core}/base/abstractions/document.py | 0 .../core}/base/abstractions/embedding.py | 0 .../core}/base/abstractions/exception.py | 0 .../core}/base/abstractions/graph.py | 0 .../core}/base/abstractions/llm.py | 0 .../core}/base/abstractions/prompt.py | 0 .../core}/base/abstractions/search.py | 0 .../core}/base/abstractions/user.py | 0 .../core}/base/abstractions/vector.py | 0 {r2r_core => py/core}/base/agent/__init__.py | 0 {r2r_core => py/core}/base/agent/agent.py | 7 +- {r2r_core => py/core}/base/agent/base.py | 3 +- .../core}/base/api/models/__init__.py | 0 .../core}/base/api/models/auth/__init__.py | 0 .../core}/base/api/models/auth/responses.py | 5 +- {r2r_core => py/core}/base/api/models/base.py | 0 .../base/api/models/ingestion/__init__.py | 0 .../base/api/models/ingestion/responses.py | 3 +- .../base/api/models/management/__init__.py | 0 .../base/api/models/management/responses.py | 3 +- .../base/api/models/retrieval/__init__.py | 0 .../base/api/models/retrieval/responses.py | 8 +- .../core}/base/logging/__init__.py | 0 {r2r_core => py/core}/base/logging/base.py | 0 .../core}/base/logging/log_processor.py | 0 .../core}/base/logging/run_logger.py | 0 .../core}/base/logging/run_manager.py | 6 +- .../core}/base/parsers/__init__.py | 0 .../core}/base/parsers/base_parser.py | 0 .../core}/base/pipeline/__init__.py | 0 .../core}/base/pipeline/base_pipeline.py | 0 {r2r_core => py/core}/base/pipes/__init__.py | 0 {r2r_core => py/core}/base/pipes/base_pipe.py | 5 +- .../core}/base/providers/__init__.py | 0 {r2r_core => py/core}/base/providers/auth.py | 0 {r2r_core => py/core}/base/providers/base.py | 0 .../core}/base/providers/chunking.py | 0 .../core}/base/providers/crypto.py | 0 .../core}/base/providers/database.py | 0 .../core}/base/providers/embedding.py | 0 {r2r_core => py/core}/base/providers/kg.py | 0 {r2r_core => py/core}/base/providers/llm.py | 2 +- .../core}/base/providers/parsing.py | 0 .../core}/base/providers/prompt.py | 0 {r2r_core => py/core}/base/utils/__init__.py | 0 .../core}/base/utils/base_utils.py | 0 .../core}/base/utils/splitter/__init__.py | 0 .../core}/base/utils/splitter/text.py | 0 {r2r_core => py/core}/cli/__init__.py | 0 {r2r_core => py/core}/cli/cli.py | 4 +- {r2r_core => py/core}/cli/command_group.py | 3 +- .../core}/cli/commands/__init__.py | 0 .../core}/cli/commands/auth_operations.py | 3 +- .../core}/cli/commands/document_operations.py | 5 +- .../core}/cli/commands/kg_operations.py | 5 +- .../commands/oberservability_operations.py | 7 +- .../core}/cli/commands/rag_operations.py | 7 +- .../core}/cli/commands/server_operations.py | 9 +- {r2r_core => py/core}/cli/utils/__init__.py | 0 .../core}/cli/utils/docker_utils.py | 5 +- .../core}/cli/utils/param_types.py | 0 {r2r_core => py/core}/cli/utils/timer.py | 0 {r2r_core => py/core}/configs/auth.toml | 0 {r2r_core => py/core}/configs/local_llm.toml | 0 .../core}/configs/local_llm_neo4j_kg.toml | 0 {r2r_core => py/core}/configs/neo4j_kg.toml | 0 .../configs/neo4j_kg_no_vector_postgres.toml | 0 .../core}/configs/postgres_logging.toml | 0 {r2r_core => py/core}/examples/__init__.py | 0 .../core}/examples/data/aristotle.txt | 0 .../core}/examples/data/aristotle_v2.txt | 0 {r2r_core => py/core}/examples/data/got.txt | 0 .../core}/examples/data/lyft_2021.pdf | Bin .../core}/examples/data/pg_essay_1.html | 0 .../core}/examples/data/pg_essay_2.html | 0 .../core}/examples/data/pg_essay_3.html | 0 .../core}/examples/data/pg_essay_4.html | 0 .../core}/examples/data/pg_essay_5.html | 0 .../core}/examples/data/sample.mp3 | Bin .../core}/examples/data/sample2.mp3 | Bin .../core}/examples/data/screen_shot.png | Bin {r2r_core => py/core}/examples/data/test.txt | 0 .../core}/examples/data/uber_2021.pdf | Bin .../core}/examples/data/yc_companies.txt | 0 {r2r_core => py/core}/examples/hello_r2r.py | 2 +- .../examples/scripts/advanced_kg_cookbook.py | 1 - .../examples/scripts/run_auth_workflow.py | 2 +- .../core}/examples/scripts/run_hyde.py | 9 +- .../examples/scripts/run_web_multi_rag.py | 9 +- .../core}/examples/scripts/run_web_rag.py | 3 +- .../examples/scripts/sample_data_ingestor.py | 2 +- .../core}/integrations/__init__.py | 0 {r2r_core => py/core}/integrations/serper.py | 0 {r2r_core => py/core}/main/__init__.py | 0 {r2r_core => py/core}/main/abstractions.py | 11 +- {r2r_core => py/core}/main/api/__init__.py | 0 .../core}/main/api/routes/__init__.py | 0 .../core}/main/api/routes/auth/__init__.py | 0 .../core}/main/api/routes/auth/base.py | 9 +- .../core}/main/api/routes/base_router.py | 5 +- .../main/api/routes/ingestion/__init__.py | 0 .../core}/main/api/routes/ingestion/base.py | 9 +- .../ingestion/ingestion_router_openapi.yml | 0 .../main/api/routes/management/__init__.py | 0 .../core}/main/api/routes/management/base.py | 7 +- .../main/api/routes/restructure/__init__.py | 0 .../core}/main/api/routes/restructure/base.py | 5 +- .../main/api/routes/retrieval/__init__.py | 0 .../core}/main/api/routes/retrieval/base.py | 9 +- .../retrieval/retrieval_router_openapi.yml | 0 {r2r_core => py/core}/main/app.py | 0 {r2r_core => py/core}/main/app_entry.py | 0 .../core}/main/assembly/__init__.py | 0 .../core}/main/assembly/builder.py | 6 +- {r2r_core => py/core}/main/assembly/config.py | 8 +- .../core}/main/assembly/factory.py | 60 +- .../core}/main/assembly/factory_extensions.py | 4 +- {r2r_core => py/core}/main/engine.py | 4 +- {r2r_core => py/core}/main/execution.py | 13 +- {r2r_core => py/core}/main/r2r.py | 0 .../core}/main/services/__init__.py | 0 .../core}/main/services/auth_service.py | 6 +- {r2r_core => py/core}/main/services/base.py | 2 +- .../core}/main/services/ingestion_service.py | 11 +- .../core}/main/services/management_service.py | 5 +- .../main/services/restructure_service.py | 2 +- .../core}/main/services/retrieval_service.py | 8 +- {r2r_core => py/core}/parsers/__init__.py | 0 .../core}/parsers/media/__init__.py | 0 .../core}/parsers/media/audio_parser.py | 4 +- .../core}/parsers/media/docx_parser.py | 4 +- .../core}/parsers/media/img_parser.py | 6 +- .../core}/parsers/media/movie_parser.py | 4 +- .../core}/parsers/media/openai_helpers.py | 0 .../core}/parsers/media/pdf_parser.py | 4 +- .../core}/parsers/media/ppt_parser.py | 4 +- .../core}/parsers/structured/__init__.py | 0 .../core}/parsers/structured/csv_parser.py | 4 +- .../core}/parsers/structured/json_parser.py | 4 +- .../core}/parsers/structured/xlsx_parser.py | 4 +- .../core}/parsers/text/__init__.py | 0 .../core}/parsers/text/html_parser.py | 5 +- .../core}/parsers/text/md_parser.py | 5 +- .../core}/parsers/text/text_parser.py | 4 +- {r2r_core => py/core}/pipelines/__init__.py | 0 .../core}/pipelines/graph_enrichment.py | 0 .../core}/pipelines/ingestion_pipeline.py | 15 +- .../core}/pipelines/rag_pipeline.py | 0 .../core}/pipelines/search_pipeline.py | 0 {r2r_core => py/core}/pipes/__init__.py | 0 .../core}/pipes/abstractions/__init__.py | 0 .../pipes/abstractions/generator_pipe.py | 6 +- .../core}/pipes/abstractions/search_pipe.py | 2 +- .../core}/pipes/ingestion/__init__.py | 0 .../core}/pipes/ingestion/chunking_pipe.py | 6 +- .../core}/pipes/ingestion/embedding_pipe.py | 4 +- .../pipes/ingestion/kg_extraction_pipe.py | 6 +- .../core}/pipes/ingestion/parsing_pipe.py | 6 +- .../pipes/ingestion/vector_storage_pipe.py | 6 +- {r2r_core => py/core}/pipes/kg/clustering.py | 5 +- {r2r_core => py/core}/pipes/kg/extraction.py | 4 +- .../core}/pipes/kg/node_extraction.py | 8 +- {r2r_core => py/core}/pipes/kg/storage.py | 6 +- .../core}/pipes/other/web_search_pipe.py | 4 +- .../pipes/retrieval/kg_search_search_pipe.py | 2 +- .../core}/pipes/retrieval/multi_search.py | 6 +- .../pipes/retrieval/query_transform_pipe.py | 4 +- .../core}/pipes/retrieval/search_rag_pipe.py | 4 +- .../pipes/retrieval/streaming_rag_pipe.py | 4 +- .../pipes/retrieval/vector_search_pipe.py | 2 +- {r2r_core => py/core}/providers/__init__.py | 0 .../core}/providers/auth/__init__.py | 0 .../core}/providers/auth/r2r_auth.py | 9 +- .../core}/providers/chunking/__init__.py | 0 .../core}/providers/chunking/r2r_chunking.py | 2 +- .../chunking/unstructured_chunking.py | 2 +- .../core}/providers/crypto/__init__.py | 0 .../core}/providers/crypto/bcrypt.py | 2 +- .../core}/providers/database/__init__.py | 0 .../core}/providers/database/base.py | 0 .../core}/providers/database/document.py | 2 +- .../core}/providers/database/group.py | 12 +- .../core}/providers/database/postgres.py | 2 +- .../core}/providers/database/relational.py | 11 +- .../core}/providers/database/tokens.py | 0 .../core}/providers/database/user.py | 7 +- .../core}/providers/database/vecs/__init__.py | 0 .../database/vecs/adapter/__init__.py | 0 .../providers/database/vecs/adapter/base.py | 0 .../database/vecs/adapter/markdown.py | 0 .../providers/database/vecs/adapter/noop.py | 0 .../providers/database/vecs/adapter/text.py | 0 .../core}/providers/database/vecs/client.py | 12 +- .../providers/database/vecs/collection.py | 5 +- .../core}/providers/database/vecs/exc.py | 0 .../core}/providers/database/vector.py | 9 +- .../core}/providers/embeddings/__init__.py | 0 .../core}/providers/embeddings/litellm.py | 5 +- .../core}/providers/embeddings/ollama.py | 5 +- .../core}/providers/embeddings/openai.py | 7 +- .../core}/providers/kg/__init__.py | 0 .../core}/providers/kg/neo4j/__init__.py | 0 .../core}/providers/kg/neo4j/graph_queries.py | 0 .../core}/providers/kg/neo4j/provider.py | 6 +- .../core}/providers/llm/__init__.py | 0 .../core}/providers/llm/litellm.py | 4 +- {r2r_core => py/core}/providers/llm/openai.py | 5 +- .../core}/providers/parsing/__init__.py | 0 .../core}/providers/parsing/r2r_parsing.py | 4 +- .../providers/parsing/unstructured_parsing.py | 2 +- .../core}/providers/prompts/__init__.py | 0 .../core}/providers/prompts/defaults.yaml | 0 .../prompts/defaults/default_rag.yaml | 0 .../defaults/few_shot_ner_kg_extraction.yaml | 0 .../few_shot_ner_kg_extraction_with_spec.yaml | 0 .../defaults/graphrag_community_reports.yaml | 0 .../defaults/graphrag_map_system_prompt.yaml | 0 .../graphrag_reduce_system_prompt.yaml | 0 .../graphrag_triplet_extraction_few_shot.yaml | 0 ...graphrag_triplet_extraction_zero_shot.yaml | 0 .../providers/prompts/defaults/hyde.yaml | 0 .../providers/prompts/defaults/kg_search.yaml | 0 .../prompts/defaults/kg_search_with_spec.yaml | 0 .../providers/prompts/defaults/rag_agent.yaml | 0 .../prompts/defaults/rag_context.yaml | 0 .../prompts/defaults/rag_fusion.yaml | 0 .../providers/prompts/defaults/system.yaml | 0 .../defaults/zero_shot_ner_kg_extraction.yaml | 0 ...zero_shot_ner_kg_extraction_with_spec.yaml | 0 .../core}/providers/prompts/r2r_prompts.py | 3 +- {r2r_core => py/core}/telemetry/__init__.py | 0 {r2r_core => py/core}/telemetry/events.py | 0 {r2r_core => py/core}/telemetry/posthog.py | 3 +- .../core}/telemetry/telemetry_decorator.py | 4 +- py/sdk/__init__.py | 6 + {r2r_python_sdk/r2r => py/sdk}/auth.py | 0 {r2r_python_sdk/r2r => py/sdk}/client.py | 0 {r2r_python_sdk/r2r => py/sdk}/ingestion.py | 0 {r2r_python_sdk/r2r => py/sdk}/management.py | 0 {r2r_python_sdk/r2r => py/sdk}/models.py | 0 {r2r_python_sdk/r2r => py/sdk}/restructure.py | 0 {r2r_python_sdk/r2r => py/sdk}/retrieval.py | 4 +- pyproject.toml | 108 +- r2r_go_sdk/go.mod | 3 - r2r_python_sdk/README.md | 0 r2r_python_sdk/poetry.lock | 1098 ----------------- r2r_python_sdk/pyproject.toml | 54 - r2r_python_sdk/r2r/__init__.py | 0 tests/regression/runner.py | 4 +- tests/regression/test_cases/base.py | 2 +- .../test_cases/test_document_management.py | 3 +- tests/test_abstractions.py | 7 +- tests/test_auth.py | 5 +- tests/test_cli.py | 5 +- tests/test_client.py | 11 +- tests/test_config.py | 3 +- tests/test_database.py | 7 +- tests/test_embedding.py | 9 +- tests/test_end_to_end.py | 5 +- tests/test_groups.py | 11 +- tests/test_groups_client.py | 12 +- tests/test_ingestion_service.py | 11 +- tests/test_llms.py | 7 +- tests/test_logging.py | 3 +- tests/test_parser.py | 19 +- tests/test_pipeline.py | 3 +- tests/test_vector_db.py | 5 +- 307 files changed, 528 insertions(+), 1740 deletions(-) rename {r2r_cli => go/cli}/go.mod (60%) rename {r2r_cli => go/cli}/go.sum (100%) rename {r2r_cli => go/cli}/main.go (100%) rename {r2r_cli => go/cli}/rag_operations.go (99%) rename {r2r_cli => go/cli}/server_operations.go (83%) rename {r2r_cli => go/cli}/utils.go (100%) create mode 100644 go/sdk/go.mod rename {r2r_go_sdk => go/sdk}/internal/tests/integration/management_test.go (95%) rename {r2r_go_sdk => go/sdk}/pkg/sdk/auth.go (100%) rename {r2r_go_sdk => go/sdk}/pkg/sdk/client.go (100%) rename {r2r_go_sdk => go/sdk}/pkg/sdk/ingestion.go (100%) rename {r2r_go_sdk => go/sdk}/pkg/sdk/management.go (100%) rename {r2r_go_sdk => go/sdk}/pkg/sdk/restructure.go (100%) rename {r2r_go_sdk => go/sdk}/pkg/sdk/retrieval.go (100%) rename {r2r_js_sdk => js/sdk}/README.md (100%) rename {r2r_js_sdk => js/sdk}/__tests__/r2rClient.test.ts (100%) rename {r2r_js_sdk => js/sdk}/__tests__/r2rClientIntegrationSuperUser.test.ts (100%) rename {r2r_js_sdk => js/sdk}/__tests__/r2rClientIntegrationUser.test.ts (100%) rename {r2r_js_sdk => js/sdk}/examples/data/folder/karamozov.txt (100%) rename {r2r_js_sdk => js/sdk}/examples/data/folder/myshkin.txt (100%) rename {r2r_js_sdk => js/sdk}/examples/data/raskolnikov.txt (100%) rename {r2r_js_sdk => js/sdk}/examples/hello_r2r.js (100%) rename {r2r_js_sdk => js/sdk}/jest.config.js (100%) rename {r2r_js_sdk => js/sdk}/package-lock.json (100%) rename {r2r_js_sdk => js/sdk}/package.json (100%) rename {r2r_js_sdk => js/sdk}/pnpm-lock.yaml (100%) rename {r2r_js_sdk => js/sdk}/src/feature.ts (100%) rename {r2r_js_sdk => js/sdk}/src/index.ts (100%) rename {r2r_js_sdk => js/sdk}/src/models.tsx (100%) rename {r2r_js_sdk => js/sdk}/src/r2rClient.ts (100%) rename {r2r_js_sdk => js/sdk}/tsconfig.json (100%) rename {r2r_core => py/core}/__init__.py (100%) rename {r2r_core => py/core}/agent/__init__.py (100%) rename {r2r_core => py/core}/agent/base.py (98%) rename {r2r_core => py/core}/agent/rag.py (91%) rename {r2r_core => py/core}/base/__init__.py (100%) rename {r2r_core => py/core}/base/abstractions/__init__.py (100%) rename {r2r_core => py/core}/base/abstractions/base.py (100%) rename {r2r_core => py/core}/base/abstractions/completion.py (100%) rename {r2r_core => py/core}/base/abstractions/document.py (100%) rename {r2r_core => py/core}/base/abstractions/embedding.py (100%) rename {r2r_core => py/core}/base/abstractions/exception.py (100%) rename {r2r_core => py/core}/base/abstractions/graph.py (100%) rename {r2r_core => py/core}/base/abstractions/llm.py (100%) rename {r2r_core => py/core}/base/abstractions/prompt.py (100%) rename {r2r_core => py/core}/base/abstractions/search.py (100%) rename {r2r_core => py/core}/base/abstractions/user.py (100%) rename {r2r_core => py/core}/base/abstractions/vector.py (100%) rename {r2r_core => py/core}/base/agent/__init__.py (100%) rename {r2r_core => py/core}/base/agent/agent.py (98%) rename {r2r_core => py/core}/base/agent/base.py (93%) rename {r2r_core => py/core}/base/api/models/__init__.py (100%) rename {r2r_core => py/core}/base/api/models/auth/__init__.py (100%) rename {r2r_core => py/core}/base/api/models/auth/responses.py (90%) rename {r2r_core => py/core}/base/api/models/base.py (100%) rename {r2r_core => py/core}/base/api/models/ingestion/__init__.py (100%) rename {r2r_core => py/core}/base/api/models/ingestion/responses.py (97%) rename {r2r_core => py/core}/base/api/models/management/__init__.py (100%) rename {r2r_core => py/core}/base/api/models/management/responses.py (97%) rename {r2r_core => py/core}/base/api/models/retrieval/__init__.py (100%) rename {r2r_core => py/core}/base/api/models/retrieval/responses.py (97%) rename {r2r_core => py/core}/base/logging/__init__.py (100%) rename {r2r_core => py/core}/base/logging/base.py (100%) rename {r2r_core => py/core}/base/logging/log_processor.py (100%) rename {r2r_core => py/core}/base/logging/run_logger.py (100%) rename {r2r_core => py/core}/base/logging/run_manager.py (92%) rename {r2r_core => py/core}/base/parsers/__init__.py (100%) rename {r2r_core => py/core}/base/parsers/base_parser.py (100%) rename {r2r_core => py/core}/base/pipeline/__init__.py (100%) rename {r2r_core => py/core}/base/pipeline/base_pipeline.py (100%) rename {r2r_core => py/core}/base/pipes/__init__.py (100%) rename {r2r_core => py/core}/base/pipes/base_pipe.py (97%) rename {r2r_core => py/core}/base/providers/__init__.py (100%) rename {r2r_core => py/core}/base/providers/auth.py (100%) rename {r2r_core => py/core}/base/providers/base.py (100%) rename {r2r_core => py/core}/base/providers/chunking.py (100%) rename {r2r_core => py/core}/base/providers/crypto.py (100%) rename {r2r_core => py/core}/base/providers/database.py (100%) rename {r2r_core => py/core}/base/providers/embedding.py (100%) rename {r2r_core => py/core}/base/providers/kg.py (100%) rename {r2r_core => py/core}/base/providers/llm.py (99%) rename {r2r_core => py/core}/base/providers/parsing.py (100%) rename {r2r_core => py/core}/base/providers/prompt.py (100%) rename {r2r_core => py/core}/base/utils/__init__.py (100%) rename {r2r_core => py/core}/base/utils/base_utils.py (100%) rename {r2r_core => py/core}/base/utils/splitter/__init__.py (100%) rename {r2r_core => py/core}/base/utils/splitter/text.py (100%) rename {r2r_core => py/core}/cli/__init__.py (100%) rename {r2r_core => py/core}/cli/cli.py (94%) rename {r2r_core => py/core}/cli/command_group.py (95%) rename {r2r_core => py/core}/cli/commands/__init__.py (100%) rename {r2r_core => py/core}/cli/commands/auth_operations.py (87%) rename {r2r_core => py/core}/cli/commands/document_operations.py (97%) rename {r2r_core => py/core}/cli/commands/kg_operations.py (76%) rename {r2r_core => py/core}/cli/commands/oberservability_operations.py (93%) rename {r2r_core => py/core}/cli/commands/rag_operations.py (97%) rename {r2r_core => py/core}/cli/commands/server_operations.py (98%) rename {r2r_core => py/core}/cli/utils/__init__.py (100%) rename {r2r_core => py/core}/cli/utils/docker_utils.py (99%) rename {r2r_core => py/core}/cli/utils/param_types.py (100%) rename {r2r_core => py/core}/cli/utils/timer.py (100%) rename {r2r_core => py/core}/configs/auth.toml (100%) rename {r2r_core => py/core}/configs/local_llm.toml (100%) rename {r2r_core => py/core}/configs/local_llm_neo4j_kg.toml (100%) rename {r2r_core => py/core}/configs/neo4j_kg.toml (100%) rename {r2r_core => py/core}/configs/neo4j_kg_no_vector_postgres.toml (100%) rename {r2r_core => py/core}/configs/postgres_logging.toml (100%) rename {r2r_core => py/core}/examples/__init__.py (100%) rename {r2r_core => py/core}/examples/data/aristotle.txt (100%) rename {r2r_core => py/core}/examples/data/aristotle_v2.txt (100%) rename {r2r_core => py/core}/examples/data/got.txt (100%) rename {r2r_core => py/core}/examples/data/lyft_2021.pdf (100%) rename {r2r_core => py/core}/examples/data/pg_essay_1.html (100%) rename {r2r_core => py/core}/examples/data/pg_essay_2.html (100%) rename {r2r_core => py/core}/examples/data/pg_essay_3.html (100%) rename {r2r_core => py/core}/examples/data/pg_essay_4.html (100%) rename {r2r_core => py/core}/examples/data/pg_essay_5.html (100%) rename {r2r_core => py/core}/examples/data/sample.mp3 (100%) rename {r2r_core => py/core}/examples/data/sample2.mp3 (100%) rename {r2r_core => py/core}/examples/data/screen_shot.png (100%) rename {r2r_core => py/core}/examples/data/test.txt (100%) rename {r2r_core => py/core}/examples/data/uber_2021.pdf (100%) rename {r2r_core => py/core}/examples/data/yc_companies.txt (100%) rename {r2r_core => py/core}/examples/hello_r2r.py (96%) rename {r2r_core => py/core}/examples/scripts/advanced_kg_cookbook.py (99%) rename {r2r_core => py/core}/examples/scripts/run_auth_workflow.py (97%) rename {r2r_core => py/core}/examples/scripts/run_hyde.py (80%) rename {r2r_core => py/core}/examples/scripts/run_web_multi_rag.py (90%) rename {r2r_core => py/core}/examples/scripts/run_web_rag.py (92%) rename {r2r_core => py/core}/examples/scripts/sample_data_ingestor.py (97%) rename {r2r_core => py/core}/integrations/__init__.py (100%) rename {r2r_core => py/core}/integrations/serper.py (100%) rename {r2r_core => py/core}/main/__init__.py (100%) rename {r2r_core => py/core}/main/abstractions.py (91%) rename {r2r_core => py/core}/main/api/__init__.py (100%) rename {r2r_core => py/core}/main/api/routes/__init__.py (100%) rename {r2r_core => py/core}/main/api/routes/auth/__init__.py (100%) rename {r2r_core => py/core}/main/api/routes/auth/base.py (99%) rename {r2r_core => py/core}/main/api/routes/base_router.py (95%) rename {r2r_core => py/core}/main/api/routes/ingestion/__init__.py (100%) rename {r2r_core => py/core}/main/api/routes/ingestion/base.py (98%) rename {r2r_core => py/core}/main/api/routes/ingestion/ingestion_router_openapi.yml (100%) rename {r2r_core => py/core}/main/api/routes/management/__init__.py (100%) rename {r2r_core => py/core}/main/api/routes/management/base.py (99%) rename {r2r_core => py/core}/main/api/routes/restructure/__init__.py (100%) rename {r2r_core => py/core}/main/api/routes/restructure/base.py (88%) rename {r2r_core => py/core}/main/api/routes/retrieval/__init__.py (100%) rename {r2r_core => py/core}/main/api/routes/retrieval/base.py (99%) rename {r2r_core => py/core}/main/api/routes/retrieval/retrieval_router_openapi.yml (100%) rename {r2r_core => py/core}/main/app.py (100%) rename {r2r_core => py/core}/main/app_entry.py (100%) rename {r2r_core => py/core}/main/assembly/__init__.py (100%) rename {r2r_core => py/core}/main/assembly/builder.py (99%) rename {r2r_core => py/core}/main/assembly/config.py (95%) rename {r2r_core => py/core}/main/assembly/factory.py (92%) rename {r2r_core => py/core}/main/assembly/factory_extensions.py (95%) rename {r2r_core => py/core}/main/engine.py (98%) rename {r2r_core => py/core}/main/execution.py (98%) rename {r2r_core => py/core}/main/r2r.py (100%) rename {r2r_core => py/core}/main/services/__init__.py (100%) rename {r2r_core => py/core}/main/services/auth_service.py (96%) rename {r2r_core => py/core}/main/services/base.py (91%) rename {r2r_core => py/core}/main/services/ingestion_service.py (98%) rename {r2r_core => py/core}/main/services/management_service.py (99%) rename {r2r_core => py/core}/main/services/restructure_service.py (94%) rename {r2r_core => py/core}/main/services/retrieval_service.py (98%) rename {r2r_core => py/core}/parsers/__init__.py (100%) rename {r2r_core => py/core}/parsers/media/__init__.py (100%) rename {r2r_core => py/core}/parsers/media/audio_parser.py (88%) rename {r2r_core => py/core}/parsers/media/docx_parser.py (87%) rename {r2r_core => py/core}/parsers/media/img_parser.py (85%) rename {r2r_core => py/core}/parsers/media/movie_parser.py (97%) rename {r2r_core => py/core}/parsers/media/openai_helpers.py (100%) rename {r2r_core => py/core}/parsers/media/pdf_parser.py (98%) rename {r2r_core => py/core}/parsers/media/ppt_parser.py (88%) rename {r2r_core => py/core}/parsers/structured/__init__.py (100%) rename {r2r_core => py/core}/parsers/structured/csv_parser.py (95%) rename {r2r_core => py/core}/parsers/structured/json_parser.py (93%) rename {r2r_core => py/core}/parsers/structured/xlsx_parser.py (96%) rename {r2r_core => py/core}/parsers/text/__init__.py (100%) rename {r2r_core => py/core}/parsers/text/html_parser.py (74%) rename {r2r_core => py/core}/parsers/text/md_parser.py (82%) rename {r2r_core => py/core}/parsers/text/text_parser.py (71%) rename {r2r_core => py/core}/pipelines/__init__.py (100%) rename {r2r_core => py/core}/pipelines/graph_enrichment.py (100%) rename {r2r_core => py/core}/pipelines/ingestion_pipeline.py (92%) rename {r2r_core => py/core}/pipelines/rag_pipeline.py (100%) rename {r2r_core => py/core}/pipelines/search_pipeline.py (100%) rename {r2r_core => py/core}/pipes/__init__.py (100%) rename {r2r_core => py/core}/pipes/abstractions/__init__.py (100%) rename {r2r_core => py/core}/pipes/abstractions/generator_pipe.py (89%) rename {r2r_core => py/core}/pipes/abstractions/search_pipe.py (98%) rename {r2r_core => py/core}/pipes/ingestion/__init__.py (100%) rename {r2r_core => py/core}/pipes/ingestion/chunking_pipe.py (94%) rename {r2r_core => py/core}/pipes/ingestion/embedding_pipe.py (98%) rename {r2r_core => py/core}/pipes/ingestion/kg_extraction_pipe.py (97%) rename {r2r_core => py/core}/pipes/ingestion/parsing_pipe.py (93%) rename {r2r_core => py/core}/pipes/ingestion/vector_storage_pipe.py (95%) rename {r2r_core => py/core}/pipes/kg/clustering.py (99%) rename {r2r_core => py/core}/pipes/kg/extraction.py (98%) rename {r2r_core => py/core}/pipes/kg/node_extraction.py (97%) rename {r2r_core => py/core}/pipes/kg/storage.py (95%) rename {r2r_core => py/core}/pipes/other/web_search_pipe.py (97%) rename {r2r_core => py/core}/pipes/retrieval/kg_search_search_pipe.py (99%) rename {r2r_core => py/core}/pipes/retrieval/multi_search.py (93%) rename {r2r_core => py/core}/pipes/retrieval/query_transform_pipe.py (96%) rename {r2r_core => py/core}/pipes/retrieval/search_rag_pipe.py (97%) rename {r2r_core => py/core}/pipes/retrieval/streaming_rag_pipe.py (97%) rename {r2r_core => py/core}/pipes/retrieval/vector_search_pipe.py (99%) rename {r2r_core => py/core}/providers/__init__.py (100%) rename {r2r_core => py/core}/providers/auth/__init__.py (100%) rename {r2r_core => py/core}/providers/auth/r2r_auth.py (99%) rename {r2r_core => py/core}/providers/chunking/__init__.py (100%) rename {r2r_core => py/core}/providers/chunking/r2r_chunking.py (99%) rename {r2r_core => py/core}/providers/chunking/unstructured_chunking.py (97%) rename {r2r_core => py/core}/providers/crypto/__init__.py (100%) rename {r2r_core => py/core}/providers/crypto/bcrypt.py (96%) rename {r2r_core => py/core}/providers/database/__init__.py (100%) rename {r2r_core => py/core}/providers/database/base.py (100%) rename {r2r_core => py/core}/providers/database/document.py (98%) rename {r2r_core => py/core}/providers/database/group.py (98%) rename {r2r_core => py/core}/providers/database/postgres.py (99%) rename {r2r_core => py/core}/providers/database/relational.py (80%) rename {r2r_core => py/core}/providers/database/tokens.py (100%) rename {r2r_core => py/core}/providers/database/user.py (98%) rename {r2r_core => py/core}/providers/database/vecs/__init__.py (100%) rename {r2r_core => py/core}/providers/database/vecs/adapter/__init__.py (100%) rename {r2r_core => py/core}/providers/database/vecs/adapter/base.py (100%) rename {r2r_core => py/core}/providers/database/vecs/adapter/markdown.py (100%) rename {r2r_core => py/core}/providers/database/vecs/adapter/noop.py (100%) rename {r2r_core => py/core}/providers/database/vecs/adapter/text.py (100%) rename {r2r_core => py/core}/providers/database/vecs/client.py (95%) rename {r2r_core => py/core}/providers/database/vecs/collection.py (99%) rename {r2r_core => py/core}/providers/database/vecs/exc.py (100%) rename {r2r_core => py/core}/providers/database/vector.py (99%) rename {r2r_core => py/core}/providers/embeddings/__init__.py (100%) rename {r2r_core => py/core}/providers/embeddings/litellm.py (99%) rename {r2r_core => py/core}/providers/embeddings/ollama.py (99%) rename {r2r_core => py/core}/providers/embeddings/openai.py (99%) rename {r2r_core => py/core}/providers/kg/__init__.py (100%) rename {r2r_core => py/core}/providers/kg/neo4j/__init__.py (100%) rename {r2r_core => py/core}/providers/kg/neo4j/graph_queries.py (100%) rename {r2r_core => py/core}/providers/kg/neo4j/provider.py (98%) rename {r2r_core => py/core}/providers/llm/__init__.py (100%) rename {r2r_core => py/core}/providers/llm/litellm.py (95%) rename {r2r_core => py/core}/providers/llm/openai.py (95%) rename {r2r_core => py/core}/providers/parsing/__init__.py (100%) rename {r2r_core => py/core}/providers/parsing/r2r_parsing.py (98%) rename {r2r_core => py/core}/providers/parsing/unstructured_parsing.py (98%) rename {r2r_core => py/core}/providers/prompts/__init__.py (100%) rename {r2r_core => py/core}/providers/prompts/defaults.yaml (100%) rename {r2r_core => py/core}/providers/prompts/defaults/default_rag.yaml (100%) rename {r2r_core => py/core}/providers/prompts/defaults/few_shot_ner_kg_extraction.yaml (100%) rename {r2r_core => py/core}/providers/prompts/defaults/few_shot_ner_kg_extraction_with_spec.yaml (100%) rename {r2r_core => py/core}/providers/prompts/defaults/graphrag_community_reports.yaml (100%) rename {r2r_core => py/core}/providers/prompts/defaults/graphrag_map_system_prompt.yaml (100%) rename {r2r_core => py/core}/providers/prompts/defaults/graphrag_reduce_system_prompt.yaml (100%) rename {r2r_core => py/core}/providers/prompts/defaults/graphrag_triplet_extraction_few_shot.yaml (100%) rename {r2r_core => py/core}/providers/prompts/defaults/graphrag_triplet_extraction_zero_shot.yaml (100%) rename {r2r_core => py/core}/providers/prompts/defaults/hyde.yaml (100%) rename {r2r_core => py/core}/providers/prompts/defaults/kg_search.yaml (100%) rename {r2r_core => py/core}/providers/prompts/defaults/kg_search_with_spec.yaml (100%) rename {r2r_core => py/core}/providers/prompts/defaults/rag_agent.yaml (100%) rename {r2r_core => py/core}/providers/prompts/defaults/rag_context.yaml (100%) rename {r2r_core => py/core}/providers/prompts/defaults/rag_fusion.yaml (100%) rename {r2r_core => py/core}/providers/prompts/defaults/system.yaml (100%) rename {r2r_core => py/core}/providers/prompts/defaults/zero_shot_ner_kg_extraction.yaml (100%) rename {r2r_core => py/core}/providers/prompts/defaults/zero_shot_ner_kg_extraction_with_spec.yaml (100%) rename {r2r_core => py/core}/providers/prompts/r2r_prompts.py (98%) rename {r2r_core => py/core}/telemetry/__init__.py (100%) rename {r2r_core => py/core}/telemetry/events.py (100%) rename {r2r_core => py/core}/telemetry/posthog.py (96%) rename {r2r_core => py/core}/telemetry/telemetry_decorator.py (93%) create mode 100644 py/sdk/__init__.py rename {r2r_python_sdk/r2r => py/sdk}/auth.py (100%) rename {r2r_python_sdk/r2r => py/sdk}/client.py (100%) rename {r2r_python_sdk/r2r => py/sdk}/ingestion.py (100%) rename {r2r_python_sdk/r2r => py/sdk}/management.py (100%) rename {r2r_python_sdk/r2r => py/sdk}/models.py (100%) rename {r2r_python_sdk/r2r => py/sdk}/restructure.py (100%) rename {r2r_python_sdk/r2r => py/sdk}/retrieval.py (98%) delete mode 100644 r2r_go_sdk/go.mod delete mode 100644 r2r_python_sdk/README.md delete mode 100644 r2r_python_sdk/poetry.lock delete mode 100644 r2r_python_sdk/pyproject.toml delete mode 100644 r2r_python_sdk/r2r/__init__.py diff --git a/r2r_cli/go.mod b/go/cli/go.mod similarity index 60% rename from r2r_cli/go.mod rename to go/cli/go.mod index b06fde584..da0ecc818 100644 --- a/r2r_cli/go.mod +++ b/go/cli/go.mod @@ -2,11 +2,11 @@ module r2r-cli go 1.23.0 -replace github.com/yourusername/r2r-go-sdk => ../r2r-go-sdk +replace github.com/yourusername/r2r_go_sdk => ../r2r_go_sdk require ( github.com/spf13/cobra v1.8.1 - github.com/yourusername/r2r-go-sdk v0.0.0-00010101000000-000000000000 + github.com/yourusername/r2r_go_sdk v0.0.0-00010101000000-000000000000 ) require ( diff --git a/r2r_cli/go.sum b/go/cli/go.sum similarity index 100% rename from r2r_cli/go.sum rename to go/cli/go.sum diff --git a/r2r_cli/main.go b/go/cli/main.go similarity index 100% rename from r2r_cli/main.go rename to go/cli/main.go diff --git a/r2r_cli/rag_operations.go b/go/cli/rag_operations.go similarity index 99% rename from r2r_cli/rag_operations.go rename to go/cli/rag_operations.go index 0c10eae27..dee23cd65 100644 --- a/r2r_cli/rag_operations.go +++ b/go/cli/rag_operations.go @@ -5,7 +5,7 @@ import ( "fmt" "github.com/spf13/cobra" - "github.com/yourusername/r2r-go-sdk/pkg/sdk" + "github.com/yourusername/r2r_go_sdk/pkg/sdk" ) func init() { diff --git a/r2r_cli/server_operations.go b/go/cli/server_operations.go similarity index 83% rename from r2r_cli/server_operations.go rename to go/cli/server_operations.go index 34d1cec91..4010d3c8d 100644 --- a/r2r_cli/server_operations.go +++ b/go/cli/server_operations.go @@ -5,9 +5,10 @@ import ( "fmt" "os/exec" "runtime" + "runtime/debug" "github.com/spf13/cobra" - "github.com/yourusername/r2r-go-sdk/pkg/sdk" + "github.com/yourusername/r2r_go_sdk/pkg/sdk" ) func init() { @@ -88,4 +89,23 @@ var healthCmd = &cobra.Command{ // TODO: update -// TODO: version +var versionCmd = &cobra.Command{ + Use: "version", + Short: "Print the version of R2R", + Run: func(cmd *cobra.Command, args []string) { + info, ok := debug.ReadBuildInfo() + if !ok { + fmt.Println("No version information available") + return + } + + for _, dep := range info.Deps { + if dep.Path == "github.com/yourusername/r2r_go_sdk" { + fmt.Printf("R2R version: %s\n", dep.Version) + return + } + } + + fmt.Println("R2R version information not found") + }, +} diff --git a/r2r_cli/utils.go b/go/cli/utils.go similarity index 100% rename from r2r_cli/utils.go rename to go/cli/utils.go diff --git a/go/sdk/go.mod b/go/sdk/go.mod new file mode 100644 index 000000000..a27c7c31d --- /dev/null +++ b/go/sdk/go.mod @@ -0,0 +1,3 @@ +module github.com/yourusername/r2r_go_sdk + +go 1.23.0 diff --git a/r2r_go_sdk/internal/tests/integration/management_test.go b/go/sdk/internal/tests/integration/management_test.go similarity index 95% rename from r2r_go_sdk/internal/tests/integration/management_test.go rename to go/sdk/internal/tests/integration/management_test.go index a9aa7e18e..55dae6586 100644 --- a/r2r_go_sdk/internal/tests/integration/management_test.go +++ b/go/sdk/internal/tests/integration/management_test.go @@ -4,7 +4,7 @@ import ( "os" "testing" - "github.com/yourusername/r2r-go-sdk/pkg/sdk" + "github.com/yourusername/r2r_go_sdk/pkg/sdk" ) func TestServerStatsIntegration(t *testing.T) { diff --git a/r2r_go_sdk/pkg/sdk/auth.go b/go/sdk/pkg/sdk/auth.go similarity index 100% rename from r2r_go_sdk/pkg/sdk/auth.go rename to go/sdk/pkg/sdk/auth.go diff --git a/r2r_go_sdk/pkg/sdk/client.go b/go/sdk/pkg/sdk/client.go similarity index 100% rename from r2r_go_sdk/pkg/sdk/client.go rename to go/sdk/pkg/sdk/client.go diff --git a/r2r_go_sdk/pkg/sdk/ingestion.go b/go/sdk/pkg/sdk/ingestion.go similarity index 100% rename from r2r_go_sdk/pkg/sdk/ingestion.go rename to go/sdk/pkg/sdk/ingestion.go diff --git a/r2r_go_sdk/pkg/sdk/management.go b/go/sdk/pkg/sdk/management.go similarity index 100% rename from r2r_go_sdk/pkg/sdk/management.go rename to go/sdk/pkg/sdk/management.go diff --git a/r2r_go_sdk/pkg/sdk/restructure.go b/go/sdk/pkg/sdk/restructure.go similarity index 100% rename from r2r_go_sdk/pkg/sdk/restructure.go rename to go/sdk/pkg/sdk/restructure.go diff --git a/r2r_go_sdk/pkg/sdk/retrieval.go b/go/sdk/pkg/sdk/retrieval.go similarity index 100% rename from r2r_go_sdk/pkg/sdk/retrieval.go rename to go/sdk/pkg/sdk/retrieval.go diff --git a/r2r_js_sdk/README.md b/js/sdk/README.md similarity index 100% rename from r2r_js_sdk/README.md rename to js/sdk/README.md diff --git a/r2r_js_sdk/__tests__/r2rClient.test.ts b/js/sdk/__tests__/r2rClient.test.ts similarity index 100% rename from r2r_js_sdk/__tests__/r2rClient.test.ts rename to js/sdk/__tests__/r2rClient.test.ts diff --git a/r2r_js_sdk/__tests__/r2rClientIntegrationSuperUser.test.ts b/js/sdk/__tests__/r2rClientIntegrationSuperUser.test.ts similarity index 100% rename from r2r_js_sdk/__tests__/r2rClientIntegrationSuperUser.test.ts rename to js/sdk/__tests__/r2rClientIntegrationSuperUser.test.ts diff --git a/r2r_js_sdk/__tests__/r2rClientIntegrationUser.test.ts b/js/sdk/__tests__/r2rClientIntegrationUser.test.ts similarity index 100% rename from r2r_js_sdk/__tests__/r2rClientIntegrationUser.test.ts rename to js/sdk/__tests__/r2rClientIntegrationUser.test.ts diff --git a/r2r_js_sdk/examples/data/folder/karamozov.txt b/js/sdk/examples/data/folder/karamozov.txt similarity index 100% rename from r2r_js_sdk/examples/data/folder/karamozov.txt rename to js/sdk/examples/data/folder/karamozov.txt diff --git a/r2r_js_sdk/examples/data/folder/myshkin.txt b/js/sdk/examples/data/folder/myshkin.txt similarity index 100% rename from r2r_js_sdk/examples/data/folder/myshkin.txt rename to js/sdk/examples/data/folder/myshkin.txt diff --git a/r2r_js_sdk/examples/data/raskolnikov.txt b/js/sdk/examples/data/raskolnikov.txt similarity index 100% rename from r2r_js_sdk/examples/data/raskolnikov.txt rename to js/sdk/examples/data/raskolnikov.txt diff --git a/r2r_js_sdk/examples/hello_r2r.js b/js/sdk/examples/hello_r2r.js similarity index 100% rename from r2r_js_sdk/examples/hello_r2r.js rename to js/sdk/examples/hello_r2r.js diff --git a/r2r_js_sdk/jest.config.js b/js/sdk/jest.config.js similarity index 100% rename from r2r_js_sdk/jest.config.js rename to js/sdk/jest.config.js diff --git a/r2r_js_sdk/package-lock.json b/js/sdk/package-lock.json similarity index 100% rename from r2r_js_sdk/package-lock.json rename to js/sdk/package-lock.json diff --git a/r2r_js_sdk/package.json b/js/sdk/package.json similarity index 100% rename from r2r_js_sdk/package.json rename to js/sdk/package.json diff --git a/r2r_js_sdk/pnpm-lock.yaml b/js/sdk/pnpm-lock.yaml similarity index 100% rename from r2r_js_sdk/pnpm-lock.yaml rename to js/sdk/pnpm-lock.yaml diff --git a/r2r_js_sdk/src/feature.ts b/js/sdk/src/feature.ts similarity index 100% rename from r2r_js_sdk/src/feature.ts rename to js/sdk/src/feature.ts diff --git a/r2r_js_sdk/src/index.ts b/js/sdk/src/index.ts similarity index 100% rename from r2r_js_sdk/src/index.ts rename to js/sdk/src/index.ts diff --git a/r2r_js_sdk/src/models.tsx b/js/sdk/src/models.tsx similarity index 100% rename from r2r_js_sdk/src/models.tsx rename to js/sdk/src/models.tsx diff --git a/r2r_js_sdk/src/r2rClient.ts b/js/sdk/src/r2rClient.ts similarity index 100% rename from r2r_js_sdk/src/r2rClient.ts rename to js/sdk/src/r2rClient.ts diff --git a/r2r_js_sdk/tsconfig.json b/js/sdk/tsconfig.json similarity index 100% rename from r2r_js_sdk/tsconfig.json rename to js/sdk/tsconfig.json diff --git a/poetry.lock b/poetry.lock index 95a1ee879..54e7c651a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,10 +1,10 @@ -# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. [[package]] name = "aiohappyeyeballs" version = "2.4.0" description = "Happy Eyeballs for asyncio" -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "aiohappyeyeballs-2.4.0-py3-none-any.whl", hash = "sha256:7ce92076e249169a13c2f49320d1967425eaf1f407522d707d59cac7628d62bd"}, @@ -15,7 +15,7 @@ files = [ name = "aiohttp" version = "3.10.5" description = "Async http client/server framework (asyncio)" -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "aiohttp-3.10.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:18a01eba2574fb9edd5f6e5fb25f66e6ce061da5dab5db75e13fe1558142e0a3"}, @@ -127,7 +127,7 @@ speedups = ["Brotli", "aiodns (>=3.2.0)", "brotlicffi"] name = "aiosignal" version = "1.3.1" description = "aiosignal: a list of registered asynchronous callbacks" -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "aiosignal-1.3.1-py3-none-any.whl", hash = "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17"}, @@ -141,7 +141,7 @@ frozenlist = ">=1.1.0" name = "aiosqlite" version = "0.20.0" description = "asyncio bridge to the standard sqlite3 module" -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "aiosqlite-0.20.0-py3-none-any.whl", hash = "sha256:36a1deaca0cac40ebe32aac9977a6e2bbc7f5189f23f4a54d5908986729e5bd6"}, @@ -192,7 +192,7 @@ trio = ["trio (>=0.23)"] name = "anytree" version = "2.12.1" description = "Powerful and Lightweight Python Tree Data Structure with various plugins" -optional = false +optional = true python-versions = ">=3.7.2,<4" files = [ {file = "anytree-2.12.1-py3-none-any.whl", hash = "sha256:5ea9e61caf96db1e5b3d0a914378d2cd83c269dfce1fb8242ce96589fa3382f0"}, @@ -206,7 +206,7 @@ six = "*" name = "async-timeout" version = "4.0.3" description = "Timeout context manager for asyncio programs" -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "async-timeout-4.0.3.tar.gz", hash = "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f"}, @@ -217,7 +217,7 @@ files = [ name = "asyncpg" version = "0.29.0" description = "An asyncio PostgreSQL driver" -optional = false +optional = true python-versions = ">=3.8.0" files = [ {file = "asyncpg-0.29.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72fd0ef9f00aeed37179c62282a3d14262dbbafb74ec0ba16e1b1864d8a12169"}, @@ -274,7 +274,7 @@ test = ["flake8 (>=6.1,<7.0)", "uvloop (>=0.15.3)"] name = "attrs" version = "24.2.0" description = "Classes Without Boilerplate" -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, @@ -293,7 +293,7 @@ tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] name = "autograd" version = "1.6.2" description = "Efficiently computes derivatives of numpy code." -optional = false +optional = true python-versions = "*" files = [ {file = "autograd-1.6.2-py3-none-any.whl", hash = "sha256:208dde2a938e63b4f8f5049b1985505139e529068b0d26f8cd7771fd3eb145d5"}, @@ -308,7 +308,7 @@ numpy = ">=1.12" name = "backoff" version = "2.2.1" description = "Function decoration for backoff and retry" -optional = false +optional = true python-versions = ">=3.7,<4.0" files = [ {file = "backoff-2.2.1-py3-none-any.whl", hash = "sha256:63579f9a0628e06278f7e47b7d7d5b6ce20dc65c5e96a6f3ca99a6adca0396e8"}, @@ -319,7 +319,7 @@ files = [ name = "bcrypt" version = "4.2.0" description = "Modern password hashing for your software and your servers" -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "bcrypt-4.2.0-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:096a15d26ed6ce37a14c1ac1e48119660f21b24cba457f160a4b830f3fe6b5cb"}, @@ -359,7 +359,7 @@ typecheck = ["mypy"] name = "beartype" version = "0.18.5" description = "Unbearably fast runtime type checking in pure Python." -optional = false +optional = true python-versions = ">=3.8.0" files = [ {file = "beartype-0.18.5-py3-none-any.whl", hash = "sha256:5301a14f2a9a5540fe47ec6d34d758e9cd8331d36c4760fc7a5499ab86310089"}, @@ -377,7 +377,7 @@ test-tox-coverage = ["coverage (>=5.5)"] name = "beautifulsoup4" version = "4.12.3" description = "Screen-scraping library" -optional = false +optional = true python-versions = ">=3.6.0" files = [ {file = "beautifulsoup4-4.12.3-py3-none-any.whl", hash = "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed"}, @@ -605,7 +605,7 @@ files = [ name = "contourpy" version = "1.2.1" description = "Python library for calculating contours of 2D quadrilateral grids" -optional = false +optional = true python-versions = ">=3.9" files = [ {file = "contourpy-1.2.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bd7c23df857d488f418439686d3b10ae2fbf9bc256cd045b37a8c16575ea1040"}, @@ -755,7 +755,7 @@ toml = ["tomli"] name = "cycler" version = "0.12.1" description = "Composable style cycles" -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30"}, @@ -781,7 +781,7 @@ files = [ name = "deepdiff" version = "7.0.1" description = "Deep Difference and Search of any Python object/data. Recreate objects by adding adding deltas to each other." -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "deepdiff-7.0.1-py3-none-any.whl", hash = "sha256:447760081918216aa4fd4ca78a4b6a848b81307b2ea94c810255334b759e1dc3"}, @@ -799,7 +799,7 @@ optimize = ["orjson"] name = "deprecated" version = "1.2.14" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." -optional = false +optional = true python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, @@ -827,7 +827,7 @@ files = [ name = "distro" version = "1.9.0" description = "Distro - an OS platform information API" -optional = false +optional = true python-versions = ">=3.6" files = [ {file = "distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2"}, @@ -838,7 +838,7 @@ files = [ name = "dnspython" version = "2.6.1" description = "DNS toolkit" -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "dnspython-2.6.1-py3-none-any.whl", hash = "sha256:5ef3b9680161f6fa89daf8ad451b5f1a33b18ae8a1c6778cdf4b43f08c0a6e50"}, @@ -858,7 +858,7 @@ wmi = ["wmi (>=1.5.1)"] name = "email-validator" version = "2.2.0" description = "A robust email address syntax and deliverability validation library." -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "email_validator-2.2.0-py3-none-any.whl", hash = "sha256:561977c2d73ce3611850a06fa56b414621e0c8faa9d66f2611407d87465da631"}, @@ -873,7 +873,7 @@ idna = ">=2.0.0" name = "et-xmlfile" version = "1.1.0" description = "An implementation of lxml.xmlfile for the standard library" -optional = false +optional = true python-versions = ">=3.6" files = [ {file = "et_xmlfile-1.1.0-py3-none-any.whl", hash = "sha256:a2ba85d1d6a74ef63837eed693bcb89c3f752169b0e3e7ae5b16ca5e1b3deada"}, @@ -933,7 +933,7 @@ typing = ["typing-extensions (>=4.8)"] name = "fire" version = "0.5.0" description = "A library for automatically generating command line interfaces." -optional = false +optional = true python-versions = "*" files = [ {file = "fire-0.5.0.tar.gz", hash = "sha256:a6b0d49e98c8963910021f92bba66f65ab440da2982b78eb1bbf95a0a34aacc6"}, @@ -963,7 +963,7 @@ pyflakes = ">=3.1.0,<3.2.0" name = "flupy" version = "1.2.0" description = "Method chaining built on generators" -optional = false +optional = true python-versions = "*" files = [ {file = "flupy-1.2.0.tar.gz", hash = "sha256:12487a008e9744cd35d0f6ea3cfa06f4b2b27cb138bf57d0788f5c26e57afe69"}, @@ -979,7 +979,7 @@ dev = ["black", "mypy", "pre-commit", "pylint", "pytest", "pytest-benchmark", "p name = "fonttools" version = "4.53.1" description = "Tools to manipulate font files" -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "fonttools-4.53.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0679a30b59d74b6242909945429dbddb08496935b82f91ea9bf6ad240ec23397"}, @@ -1044,7 +1044,7 @@ woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] name = "frozenlist" version = "1.4.1" description = "A list-like structure which implements collections.abc.MutableSequence" -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "frozenlist-1.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f9aa1878d1083b276b0196f2dfbe00c9b7e752475ed3b682025ff20c1c1f51ac"}, @@ -1130,7 +1130,7 @@ files = [ name = "fsspec" version = "2024.6.1" description = "File-system specification" -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "fsspec-2024.6.1-py3-none-any.whl", hash = "sha256:3cb443f8bcd2efb31295a5b9fdb02aee81d8452c80d28f97a6d0959e6cee101e"}, @@ -1169,7 +1169,7 @@ tqdm = ["tqdm"] name = "future" version = "1.0.0" description = "Clean single-source support for Python 3 and 2" -optional = false +optional = true python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" files = [ {file = "future-1.0.0-py3-none-any.whl", hash = "sha256:929292d34f5872e70396626ef385ec22355a1fae8ad29e1a734c3e43f9fbc216"}, @@ -1180,7 +1180,7 @@ files = [ name = "gensim" version = "4.3.3" description = "Python framework for fast Vector Space Modelling" -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "gensim-4.3.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4e72840adfbea35c5804fd559bc0cb6bc9f439926220a37d852b7ce76eb325c1"}, @@ -1226,7 +1226,7 @@ test-win = ["POT", "pytest", "pytest-cov", "testfixtures"] name = "graspologic" version = "3.4.1" description = "A set of Python modules for graph statistics" -optional = false +optional = true python-versions = "<3.13,>=3.9" files = [ {file = "graspologic-3.4.1-py3-none-any.whl", hash = "sha256:c6563e087eda599bad1de831d4b7321c0daa7a82f4e85a7d7737ff67e07cdda2"}, @@ -1255,7 +1255,7 @@ umap-learn = ">=0.5.6,<0.6.0" name = "graspologic-native" version = "1.2.1" description = "Python native companion module to the graspologic library" -optional = false +optional = true python-versions = ">=3.6, <3.13" files = [ {file = "graspologic_native-1.2.1-cp36-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:eccb2fa475b604375e34b4ae1d5497a428c34ed65f27888495239f8e120acea1"}, @@ -1268,7 +1268,7 @@ files = [ name = "greenlet" version = "3.0.3" description = "Lightweight in-process concurrent programming" -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "greenlet-3.0.3-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:9da2bd29ed9e4f15955dd1595ad7bc9320308a3b766ef7f837e23ad4b4aac31a"}, @@ -1339,7 +1339,7 @@ test = ["objgraph", "psutil"] name = "gunicorn" version = "21.2.0" description = "WSGI HTTP Server for UNIX" -optional = false +optional = true python-versions = ">=3.5" files = [ {file = "gunicorn-21.2.0-py3-none-any.whl", hash = "sha256:3213aa5e8c24949e792bcacfc176fef362e7aac80b76c56f6b5122bf350722f0"}, @@ -1415,7 +1415,7 @@ socks = ["socksio (==1.*)"] name = "huggingface-hub" version = "0.24.6" description = "Client library to download and publish models, datasets and other repos on the huggingface.co hub" -optional = false +optional = true python-versions = ">=3.8.0" files = [ {file = "huggingface_hub-0.24.6-py3-none-any.whl", hash = "sha256:a990f3232aa985fe749bc9474060cbad75e8b2f115f6665a9fda5b9c97818970"}, @@ -1449,7 +1449,7 @@ typing = ["types-PyYAML", "types-requests", "types-simplejson", "types-toml", "t name = "hyppo" version = "0.4.0" description = "A comprehensive independence testing package" -optional = false +optional = true python-versions = "*" files = [ {file = "hyppo-0.4.0-py3-none-any.whl", hash = "sha256:4e75565b8deb601485cd7bc1b5c3f44e6ddf329136fc81e65d011f9b4e95132f"}, @@ -1542,7 +1542,7 @@ setuptools = "*" name = "importlib-metadata" version = "8.3.0" description = "Read metadata from Python packages" -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "importlib_metadata-8.3.0-py3-none-any.whl", hash = "sha256:42817a4a0be5845d22c6e212db66a94ad261e2318d80b3e0d363894a79df2b67"}, @@ -1561,7 +1561,7 @@ test = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "p name = "importlib-resources" version = "6.4.3" description = "Read resources from Python packages" -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "importlib_resources-6.4.3-py3-none-any.whl", hash = "sha256:2d6dfe3b9e055f72495c2085890837fc8c758984e209115c8792bddcb762cd93"}, @@ -1607,7 +1607,7 @@ requirements-deprecated-finder = ["pip-api", "pipreqs"] name = "jinja2" version = "3.1.4" description = "A very fast and expressive template engine." -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, @@ -1624,7 +1624,7 @@ i18n = ["Babel (>=2.7)"] name = "jiter" version = "0.5.0" description = "Fast iterable JSON parser." -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "jiter-0.5.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b599f4e89b3def9a94091e6ee52e1d7ad7bc33e238ebb9c4c63f211d74822c3f"}, @@ -1694,7 +1694,7 @@ files = [ name = "joblib" version = "1.4.2" description = "Lightweight pipelining with Python functions" -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "joblib-1.4.2-py3-none-any.whl", hash = "sha256:06d478d5674cbc267e7496a410ee875abd68e4340feff4490bcb7afb88060ae6"}, @@ -1705,7 +1705,7 @@ files = [ name = "jsonschema" version = "4.23.0" description = "An implementation of JSON Schema validation for Python" -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "jsonschema-4.23.0-py3-none-any.whl", hash = "sha256:fbadb6f8b144a8f8cf9f0b89ba94501d143e50411a1278633f56a7acf7fd5566"}, @@ -1726,7 +1726,7 @@ format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339- name = "jsonschema-specifications" version = "2023.12.1" description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry" -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "jsonschema_specifications-2023.12.1-py3-none-any.whl", hash = "sha256:87e4fdf3a94858b8a2ba2778d9ba57d8a9cafca7c7489c46ba0d30a8bc6a9c3c"}, @@ -1740,7 +1740,7 @@ referencing = ">=0.31.0" name = "kiwisolver" version = "1.4.5" description = "A fast implementation of the Cassowary constraint solver" -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "kiwisolver-1.4.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:05703cf211d585109fcd72207a31bb170a0f22144d68298dc5e61b3c946518af"}, @@ -1851,13 +1851,13 @@ files = [ [[package]] name = "litellm" -version = "1.43.18" +version = "1.43.19" description = "Library to easily interface with LLM API providers" -optional = false +optional = true python-versions = "!=2.7.*,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,!=3.7.*,>=3.8" files = [ - {file = "litellm-1.43.18-py3-none-any.whl", hash = "sha256:68d853b4a0198a16e2260e4406a20f8d2e59bd903e019b7f3ba5a9f35ecc3e62"}, - {file = "litellm-1.43.18.tar.gz", hash = "sha256:e22b20065b62663dd060be9da1e84ca05903931c41c49d35a98649ed09e79d29"}, + {file = "litellm-1.43.19-py3-none-any.whl", hash = "sha256:f66bfe9c8b91577af57a5d1203728abc9b59df38a545148b7e85dec903185c12"}, + {file = "litellm-1.43.19.tar.gz", hash = "sha256:b1f475f98073632f0cea6d814bb10b14b6498e5ff93b91b52dfc00445bf013ab"}, ] [package.dependencies] @@ -1881,7 +1881,7 @@ proxy = ["PyJWT (>=2.8.0,<3.0.0)", "apscheduler (>=3.10.4,<4.0.0)", "backoff", " name = "llvmlite" version = "0.43.0" description = "lightweight wrapper around basic LLVM functionality" -optional = false +optional = true python-versions = ">=3.9" files = [ {file = "llvmlite-0.43.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a289af9a1687c6cf463478f0fa8e8aa3b6fb813317b0d70bf1ed0759eab6f761"}, @@ -1911,7 +1911,7 @@ files = [ name = "lxml" version = "5.3.0" description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API." -optional = false +optional = true python-versions = ">=3.6" files = [ {file = "lxml-5.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:dd36439be765e2dde7660212b5275641edbc813e7b24668831a5c8ac91180656"}, @@ -2065,7 +2065,7 @@ source = ["Cython (>=3.0.11)"] name = "markdown" version = "3.7" description = "Python implementation of John Gruber's Markdown." -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "Markdown-3.7-py3-none-any.whl", hash = "sha256:7eb6df5690b81a1d7942992c97fad2938e956e79df20cbc6186e9c3a77b1c803"}, @@ -2083,7 +2083,7 @@ testing = ["coverage", "pyyaml"] name = "markupsafe" version = "2.1.5" description = "Safely add untrusted strings to HTML/XML markup." -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, @@ -2152,7 +2152,7 @@ files = [ name = "matplotlib" version = "3.9.2" description = "Python plotting package" -optional = false +optional = true python-versions = ">=3.9" files = [ {file = "matplotlib-3.9.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:9d78bbc0cbc891ad55b4f39a48c22182e9bdaea7fc0e5dbd364f49f729ca1bbb"}, @@ -2227,7 +2227,7 @@ files = [ name = "monotonic" version = "1.6" description = "An implementation of time.monotonic() for Python 2 & < 3.3" -optional = false +optional = true python-versions = "*" files = [ {file = "monotonic-1.6-py2.py3-none-any.whl", hash = "sha256:68687e19a14f11f26d140dd5c86f3dba4bf5df58003000ed467e0e2a69bca96c"}, @@ -2262,7 +2262,7 @@ test = ["coverage (<5.0)", "coveralls (>=1.1,<2.0)", "pytest (>=3.0.0,<4.0)", "p name = "multidict" version = "6.0.5" description = "multidict implementation" -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "multidict-6.0.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:228b644ae063c10e7f324ab1ab6b548bdf6f8b47f3ec234fef1093bc2735e5f9"}, @@ -2419,7 +2419,7 @@ files = [ name = "neo4j" version = "5.23.1" description = "Neo4j Bolt driver for Python" -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "neo4j-5.23.1-py3-none-any.whl", hash = "sha256:97996fbf39421e0677fdcb8afe50b6810cbe8027e055a9dcf81da6070a82a009"}, @@ -2449,7 +2449,7 @@ files = [ name = "networkx" version = "3.2.1" description = "Python package for creating and manipulating graphs and networks" -optional = false +optional = true python-versions = ">=3.9" files = [ {file = "networkx-3.2.1-py3-none-any.whl", hash = "sha256:f18c69adc97877c42332c170849c96cefa91881c99a7cb3e95b7c659ebdc1ec2"}, @@ -2478,7 +2478,7 @@ files = [ name = "numba" version = "0.60.0" description = "compiling Python code using LLVM" -optional = false +optional = true python-versions = ">=3.9" files = [ {file = "numba-0.60.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5d761de835cd38fb400d2c26bb103a2726f548dc30368853121d66201672e651"}, @@ -2512,7 +2512,7 @@ numpy = ">=1.22,<2.1" name = "numpy" version = "1.26.4" description = "Fundamental package for array computing in Python" -optional = false +optional = true python-versions = ">=3.9" files = [ {file = "numpy-1.26.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0"}, @@ -2557,7 +2557,7 @@ files = [ name = "ollama" version = "0.3.1" description = "The official Python client for Ollama." -optional = false +optional = true python-versions = "<4.0,>=3.8" files = [ {file = "ollama-0.3.1-py3-none-any.whl", hash = "sha256:db50034c73d6350349bdfba19c3f0d54a3cea73eb97b35f9d7419b2fc7206454"}, @@ -2569,13 +2569,13 @@ httpx = ">=0.27.0,<0.28.0" [[package]] name = "openai" -version = "1.41.0" +version = "1.41.1" description = "The official Python library for the openai API" -optional = false +optional = true python-versions = ">=3.7.1" files = [ - {file = "openai-1.41.0-py3-none-any.whl", hash = "sha256:3b6cca4571667f3e0800442ef8f2bfa6a6f3301c51776bc7626159a4d81c242c"}, - {file = "openai-1.41.0.tar.gz", hash = "sha256:26b81f39b49dce92ff5d30c373625ddb212c2f1050e1574e456d18423730cdd0"}, + {file = "openai-1.41.1-py3-none-any.whl", hash = "sha256:56fb04105263f79559aff3ceea2e1dd16f8c5385e8238cb66cf0e6888fa8bfcf"}, + {file = "openai-1.41.1.tar.gz", hash = "sha256:e38e376efd91e0d4db071e2a6517b6b4cac1c2a6fd63efdc5ec6be10c5967c1b"}, ] [package.dependencies] @@ -2610,18 +2610,18 @@ files = [ [package.dependencies] numpy = [ {version = ">=1.21.0", markers = "python_version == \"3.9\" and platform_system == \"Darwin\" and platform_machine == \"arm64\""}, - {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, - {version = ">=1.23.5", markers = "python_version >= \"3.11\" and python_version < \"3.12\""}, {version = ">=1.21.4", markers = "python_version >= \"3.10\" and platform_system == \"Darwin\" and python_version < \"3.11\""}, {version = ">=1.21.2", markers = "platform_system != \"Darwin\" and python_version >= \"3.10\" and python_version < \"3.11\""}, {version = ">=1.19.3", markers = "platform_system == \"Linux\" and platform_machine == \"aarch64\" and python_version >= \"3.8\" and python_version < \"3.10\" or python_version > \"3.9\" and python_version < \"3.10\" or python_version >= \"3.9\" and platform_system != \"Darwin\" and python_version < \"3.10\" or python_version >= \"3.9\" and platform_machine != \"arm64\" and python_version < \"3.10\""}, + {version = ">=1.23.5", markers = "python_version >= \"3.11\" and python_version < \"3.12\""}, + {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, ] [[package]] name = "openpyxl" version = "3.1.5" description = "A Python library to read/write Excel 2010 xlsx/xlsm files" -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "openpyxl-3.1.5-py2.py3-none-any.whl", hash = "sha256:5282c12b107bffeef825f4617dc029afaf41d0ea60823bbb665ef3079dc79de2"}, @@ -2635,7 +2635,7 @@ et-xmlfile = "*" name = "ordered-set" version = "4.1.0" description = "An OrderedSet is a custom MutableSet that remembers its order, so that every" -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "ordered-set-4.1.0.tar.gz", hash = "sha256:694a8e44c87657c59292ede72891eb91d34131f6531463aab3009191c77364a8"}, @@ -2660,7 +2660,7 @@ files = [ name = "pandas" version = "2.2.2" description = "Powerful data structures for data analysis, time series, and statistics" -optional = false +optional = true python-versions = ">=3.9" files = [ {file = "pandas-2.2.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:90c6fca2acf139569e74e8781709dccb6fe25940488755716d1d354d6bc58bce"}, @@ -2697,8 +2697,8 @@ files = [ [package.dependencies] numpy = [ {version = ">=1.22.4", markers = "python_version < \"3.11\""}, - {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, {version = ">=1.23.2", markers = "python_version == \"3.11\""}, + {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, ] python-dateutil = ">=2.8.2" pytz = ">=2020.1" @@ -2733,7 +2733,7 @@ xml = ["lxml (>=4.9.2)"] name = "passlib" version = "1.7.4" description = "comprehensive password hashing framework supporting over 30 schemes" -optional = false +optional = true python-versions = "*" files = [ {file = "passlib-1.7.4-py2.py3-none-any.whl", hash = "sha256:aa6bca462b8d8bda89c70b382f0c298a20b5560af6cbfa2dce410c0a2fb669f1"}, @@ -2761,7 +2761,7 @@ files = [ name = "patsy" version = "0.5.6" description = "A Python package for describing statistical models and for building design matrices." -optional = false +optional = true python-versions = "*" files = [ {file = "patsy-0.5.6-py2.py3-none-any.whl", hash = "sha256:19056886fd8fa71863fa32f0eb090267f21fb74be00f19f5c70b2e9d76c883c6"}, @@ -2779,7 +2779,7 @@ test = ["pytest", "pytest-cov", "scipy"] name = "pgvector" version = "0.1.8" description = "pgvector support for Python" -optional = false +optional = true python-versions = ">=3.6" files = [ {file = "pgvector-0.1.8-py2.py3-none-any.whl", hash = "sha256:99dce3a6580ef73863edb9b8441937671f4e1a09383826e6b0838176cd441a96"}, @@ -2792,7 +2792,7 @@ numpy = "*" name = "pillow" version = "10.4.0" description = "Python Imaging Library (Fork)" -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "pillow-10.4.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:4d9667937cfa347525b319ae34375c37b9ee6b525440f3ef48542fcf66f2731e"}, @@ -2920,7 +2920,7 @@ testing = ["pytest", "pytest-benchmark"] name = "poppler-utils" version = "0.1.0" description = "Precompiled command-line utilities (based on Poppler) for manipulating PDF files and converting them to other formats." -optional = false +optional = true python-versions = "*" files = [ {file = "poppler-utils-0.1.0.tar.gz", hash = "sha256:e97a92dcfde57b21a90c3070694e58f8eea155515ae8e624266a052d0776a349"}, @@ -2937,7 +2937,7 @@ dev = ["Click (>=7.0)", "Sphinx (>=2.2.1)"] name = "posthog" version = "3.5.0" description = "Integrate PostHog into any python application." -optional = false +optional = true python-versions = "*" files = [ {file = "posthog-3.5.0-py2.py3-none-any.whl", hash = "sha256:3c672be7ba6f95d555ea207d4486c171d06657eb34b3ce25eb043bfe7b6b5b76"}, @@ -2960,7 +2960,7 @@ test = ["coverage", "flake8", "freezegun (==0.3.15)", "mock (>=2.0.0)", "pylint" name = "pot" version = "0.9.4" description = "Python Optimal Transport Library" -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "POT-0.9.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8418ab9c24f549290fdc452caebb58ded05b986a024063fe3354cfd2e704b378"}, @@ -3056,7 +3056,7 @@ tqdm = "*" name = "psutil" version = "6.0.0" description = "Cross-platform lib for process and system monitoring in Python." -optional = false +optional = true python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" files = [ {file = "psutil-6.0.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a021da3e881cd935e64a3d0a20983bda0bb4cf80e4f74fa9bfcb1bc5785360c6"}, @@ -3085,7 +3085,7 @@ test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] name = "psycopg2-binary" version = "2.9.9" description = "psycopg2 - Python-PostgreSQL Database Adapter" -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "psycopg2-binary-2.9.9.tar.gz", hash = "sha256:7f01846810177d829c7692f1f5ada8096762d9172af1b1a28d4ab5b77c923c1c"}, @@ -3309,7 +3309,7 @@ files = [ name = "pyjwt" version = "2.9.0" description = "JSON Web Token implementation in Python" -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, @@ -3326,7 +3326,7 @@ tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] name = "pynndescent" version = "0.5.13" description = "Nearest Neighbor Descent" -optional = false +optional = true python-versions = "*" files = [ {file = "pynndescent-0.5.13-py3-none-any.whl", hash = "sha256:69aabb8f394bc631b6ac475a1c7f3994c54adf3f51cd63b2730fefba5771b949"}, @@ -3344,7 +3344,7 @@ scipy = ">=1.0" name = "pyparsing" version = "3.1.2" description = "pyparsing module - Classes and methods to define and execute parsing grammars" -optional = false +optional = true python-versions = ">=3.6.8" files = [ {file = "pyparsing-3.1.2-py3-none-any.whl", hash = "sha256:f9db75911801ed778fe61bb643079ff86601aca99fcae6345aa67292038fb742"}, @@ -3358,7 +3358,7 @@ diagrams = ["jinja2", "railroad-diagrams"] name = "pypdf" version = "4.3.1" description = "A pure-python PDF library capable of splitting, merging, cropping, and transforming PDF files" -optional = false +optional = true python-versions = ">=3.6" files = [ {file = "pypdf-4.3.1-py3-none-any.whl", hash = "sha256:64b31da97eda0771ef22edb1bfecd5deee4b72c3d1736b7df2689805076d6418"}, @@ -3468,7 +3468,7 @@ dev = ["pre-commit", "pytest-asyncio", "tox"] name = "python-dateutil" version = "2.9.0.post0" description = "Extensions to the standard Python datetime module" -optional = false +optional = true python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, @@ -3482,7 +3482,7 @@ six = ">=1.5" name = "python-docx" version = "1.1.2" description = "Create, read, and update Microsoft Word .docx files." -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "python_docx-1.1.2-py3-none-any.whl", hash = "sha256:08c20d6058916fb19853fcf080f7f42b6270d89eac9fa5f8c15f691c0017fabe"}, @@ -3497,7 +3497,7 @@ typing-extensions = ">=4.9.0" name = "python-dotenv" version = "1.0.1" description = "Read key-value pairs from a .env file and set them as environment variables" -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca"}, @@ -3511,7 +3511,7 @@ cli = ["click (>=5.0)"] name = "python-multipart" version = "0.0.9" description = "A streaming multipart parser for Python" -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "python_multipart-0.0.9-py3-none-any.whl", hash = "sha256:97ca7b8ea7b05f977dc3849c3ba99d51689822fab725c3703af7c866a0c2b215"}, @@ -3525,7 +3525,7 @@ dev = ["atomicwrites (==1.4.1)", "attrs (==23.2.0)", "coverage (==7.4.1)", "hatc name = "python-pptx" version = "0.6.23" description = "Generate and manipulate Open XML PowerPoint (.pptx) files" -optional = false +optional = true python-versions = "*" files = [ {file = "python-pptx-0.6.23.tar.gz", hash = "sha256:587497ff28e779ab18dbb074f6d4052893c85dedc95ed75df319364f331fedee"}, @@ -3541,7 +3541,7 @@ XlsxWriter = ">=0.5.7" name = "pytz" version = "2024.1" description = "World timezone definitions, modern and historical" -optional = false +optional = true python-versions = "*" files = [ {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"}, @@ -3614,7 +3614,7 @@ files = [ name = "redis" version = "5.0.8" description = "Python client for Redis database and key-value store" -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "redis-5.0.8-py3-none-any.whl", hash = "sha256:56134ee08ea909106090934adc36f65c9bcbbaecea5b21ba704ba6fb561f8eb4"}, @@ -3632,7 +3632,7 @@ ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==20.0.1)", "requests (>=2.26.0)" name = "referencing" version = "0.35.1" description = "JSON Referencing + Python" -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "referencing-0.35.1-py3-none-any.whl", hash = "sha256:eda6d3234d62814d1c64e305c1331c9a3a6132da475ab6382eaa997b21ee75de"}, @@ -3647,7 +3647,7 @@ rpds-py = ">=0.7.0" name = "regex" version = "2024.7.24" description = "Alternative regular expression module, to replace re." -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "regex-2024.7.24-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:228b0d3f567fafa0633aee87f08b9276c7062da9616931382993c03808bb68ce"}, @@ -3756,7 +3756,7 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] name = "rpds-py" version = "0.20.0" description = "Python bindings to Rust's persistent data structures (rpds)" -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "rpds_py-0.20.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3ad0fda1635f8439cde85c700f964b23ed5fc2d28016b32b9ee5fe30da5c84e2"}, @@ -3868,7 +3868,7 @@ files = [ name = "scikit-learn" version = "1.5.1" description = "A set of python modules for machine learning and data mining" -optional = false +optional = true python-versions = ">=3.9" files = [ {file = "scikit_learn-1.5.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:781586c414f8cc58e71da4f3d7af311e0505a683e112f2f62919e3019abd3745"}, @@ -3913,7 +3913,7 @@ tests = ["black (>=24.3.0)", "matplotlib (>=3.3.4)", "mypy (>=1.9)", "numpydoc ( name = "scipy" version = "1.12.0" description = "Fundamental algorithms for scientific computing in Python" -optional = false +optional = true python-versions = ">=3.9" files = [ {file = "scipy-1.12.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:78e4402e140879387187f7f25d91cc592b3501a2e51dfb320f48dfb73565f10b"}, @@ -3955,7 +3955,7 @@ test = ["asv", "gmpy2", "hypothesis", "mpmath", "pooch", "pytest", "pytest-cov", name = "seaborn" version = "0.13.2" description = "Statistical data visualization" -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "seaborn-0.13.2-py3-none-any.whl", hash = "sha256:636f8336facf092165e27924f223d3c62ca560b1f2bb5dff7ab7fad265361987"}, @@ -3992,7 +3992,7 @@ test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata name = "six" version = "1.16.0" description = "Python 2 and 3 compatibility utilities" -optional = false +optional = true python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" files = [ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, @@ -4003,7 +4003,7 @@ files = [ name = "smart-open" version = "7.0.4" description = "Utils for streaming large files (S3, HDFS, GCS, Azure Blob Storage, gzip, bz2...)" -optional = false +optional = true python-versions = "<4.0,>=3.7" files = [ {file = "smart_open-7.0.4-py3-none-any.whl", hash = "sha256:4e98489932b3372595cddc075e6033194775165702887216b65eba760dfd8d47"}, @@ -4039,7 +4039,7 @@ files = [ name = "soupsieve" version = "2.6" description = "A modern CSS selector implementation for Beautiful Soup." -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "soupsieve-2.6-py3-none-any.whl", hash = "sha256:e72c4ff06e4fb6e4b5a9f0f55fe6e81514581fca1515028625d0f299c602ccc9"}, @@ -4050,7 +4050,7 @@ files = [ name = "sqlalchemy" version = "2.0.32" description = "Database Abstraction Library" -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "SQLAlchemy-2.0.32-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0c9045ecc2e4db59bfc97b20516dfdf8e41d910ac6fb667ebd3a79ea54084619"}, @@ -4155,7 +4155,7 @@ full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart (>=0.0.7 name = "statsmodels" version = "0.14.2" description = "Statistical computations and models for Python" -optional = false +optional = true python-versions = ">=3.9" files = [ {file = "statsmodels-0.14.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df5d6f95c46f0341da6c79ee7617e025bf2b371e190a8e60af1ae9cabbdb7a97"}, @@ -4200,7 +4200,7 @@ docs = ["ipykernel", "jupyter-client", "matplotlib", "nbconvert", "nbformat", "n name = "termcolor" version = "2.4.0" description = "ANSI color formatting for output in terminal" -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "termcolor-2.4.0-py3-none-any.whl", hash = "sha256:9297c0df9c99445c2412e832e882a7884038a25617c60cea2ad69488d4040d63"}, @@ -4214,7 +4214,7 @@ tests = ["pytest", "pytest-cov"] name = "threadpoolctl" version = "3.5.0" description = "threadpoolctl" -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "threadpoolctl-3.5.0-py3-none-any.whl", hash = "sha256:56c1e26c150397e58c4926da8eeee87533b1e32bef131bd4bf6a2f45f3185467"}, @@ -4225,7 +4225,7 @@ files = [ name = "tiktoken" version = "0.7.0" description = "tiktoken is a fast BPE tokeniser for use with OpenAI's models" -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "tiktoken-0.7.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:485f3cc6aba7c6b6ce388ba634fbba656d9ee27f766216f45146beb4ac18b25f"}, @@ -4277,7 +4277,7 @@ blobfile = ["blobfile (>=2)"] name = "tokenizers" version = "0.20.0" description = "" -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "tokenizers-0.20.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:6cff5c5e37c41bc5faa519d6f3df0679e4b37da54ea1f42121719c5e2b4905c0"}, @@ -4394,7 +4394,7 @@ testing = ["black (==22.3)", "datasets", "numpy", "pytest", "requests", "ruff"] name = "toml" version = "0.10.2" description = "Python Library for Tom's Obvious, Minimal Language" -optional = false +optional = true python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" files = [ {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, @@ -4416,7 +4416,7 @@ files = [ name = "tqdm" version = "4.66.5" description = "Fast, Extensible Progress Meter" -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "tqdm-4.66.5-py3-none-any.whl", hash = "sha256:90279a3770753eafc9194a0364852159802111925aa30eb3f9d85b0e805ac7cd"}, @@ -4436,7 +4436,7 @@ telegram = ["requests"] name = "types-requests" version = "2.32.0.20240712" description = "Typing stubs for requests" -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "types-requests-2.32.0.20240712.tar.gz", hash = "sha256:90c079ff05e549f6bf50e02e910210b98b8ff1ebdd18e19c873cd237737c1358"}, @@ -4461,7 +4461,7 @@ files = [ name = "tzdata" version = "2024.1" description = "Provider of IANA time zone data" -optional = false +optional = true python-versions = ">=2" files = [ {file = "tzdata-2024.1-py2.py3-none-any.whl", hash = "sha256:9068bc196136463f5245e51efda838afa15aaeca9903f49050dfa2679db4d252"}, @@ -4472,7 +4472,7 @@ files = [ name = "umap-learn" version = "0.5.6" description = "Uniform Manifold Approximation and Projection" -optional = false +optional = true python-versions = "*" files = [ {file = "umap-learn-0.5.6.tar.gz", hash = "sha256:5b3917a862c23ba0fc83bfcd67a7b719dec85b3d9c01fdc7d894cce455df4e03"}, @@ -4513,7 +4513,7 @@ zstd = ["zstandard (>=0.18.0)"] name = "uvicorn" version = "0.27.1" description = "The lightning-fast ASGI server." -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "uvicorn-0.27.1-py3-none-any.whl", hash = "sha256:5c89da2f3895767472a35556e539fd59f7edbe9b1e9c0e1c99eebeadc61838e4"}, @@ -4532,7 +4532,7 @@ standard = ["colorama (>=0.4)", "httptools (>=0.5.0)", "python-dotenv (>=0.13)", name = "vecs" version = "0.4.4" description = "pgvector client" -optional = false +optional = true python-versions = "*" files = [ {file = "vecs-0.4.4.tar.gz", hash = "sha256:3e03491c05a47484a33b32d6ec1d9f4841116ba7307ed9994510678f098316fd"}, @@ -4574,7 +4574,7 @@ test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess name = "wrapt" version = "1.16.0" description = "Module for decorators, wrappers and monkey patching." -optional = false +optional = true python-versions = ">=3.6" files = [ {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, @@ -4653,7 +4653,7 @@ files = [ name = "xlsxwriter" version = "3.2.0" description = "A Python module for creating Excel XLSX files." -optional = false +optional = true python-versions = ">=3.6" files = [ {file = "XlsxWriter-3.2.0-py3-none-any.whl", hash = "sha256:ecfd5405b3e0e228219bcaf24c2ca0915e012ca9464a14048021d21a995d490e"}, @@ -4664,7 +4664,7 @@ files = [ name = "yarl" version = "1.9.4" description = "Yet another URL library" -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "yarl-1.9.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a8c1df72eb746f4136fe9a2e72b0c9dc1da1cbd23b5372f94b5820ff8ae30e0e"}, @@ -4767,7 +4767,7 @@ multidict = ">=4.0" name = "zipp" version = "3.20.0" description = "Backport of pathlib-compatible object wrapper for zip files" -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "zipp-3.20.0-py3-none-any.whl", hash = "sha256:58da6168be89f0be59beb194da1250516fdaa062ccebd30127ac65d30045e10d"}, @@ -4779,10 +4779,11 @@ doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linke test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy", "pytest-ruff (>=0.2.1)"] [extras] -all = ["moviepy", "opencv-python"] +all = [] +core = ["aiosqlite", "asyncpg", "bcrypt", "beautifulsoup4", "deepdiff", "fire", "fsspec", "graspologic", "gunicorn", "litellm", "markdown", "neo4j", "ollama", "openai", "openpyxl", "passlib", "poppler-utils", "posthog", "psutil", "pydantic", "pyjwt", "pypdf", "python-docx", "python-multipart", "python-pptx", "pyyaml", "redis", "requests", "sqlalchemy", "toml", "types-requests", "uvicorn", "vecs"] ingest-movies = ["moviepy", "opencv-python"] [metadata] lock-version = "2.0" python-versions = ">=3.9,<3.13" -content-hash = "0b89a6e36e677978419390c55a8c6331c80d867cc0b72af6c60b68ac1b89760f" +content-hash = "63c0d66d4c195c646341dcf5e1e863a898d30fc96abf58170eaa1e26faca8de0" diff --git a/r2r_core/__init__.py b/py/core/__init__.py similarity index 100% rename from r2r_core/__init__.py rename to py/core/__init__.py diff --git a/r2r_core/agent/__init__.py b/py/core/agent/__init__.py similarity index 100% rename from r2r_core/agent/__init__.py rename to py/core/agent/__init__.py diff --git a/r2r_core/agent/base.py b/py/core/agent/base.py similarity index 98% rename from r2r_core/agent/base.py rename to py/core/agent/base.py index b55daece8..1b9375418 100644 --- a/r2r_core/agent/base.py +++ b/py/core/agent/base.py @@ -2,13 +2,13 @@ from abc import ABCMeta from typing import AsyncGenerator, Generator, Optional -from r2r_core.base.abstractions import ( +from core.base.abstractions import ( AsyncSyncMeta, LLMChatCompletion, LLMChatCompletionChunk, syncable, ) -from r2r_core.base.agent import Agent, Message +from core.base.agent import Agent, Message class CombinedMeta(AsyncSyncMeta, ABCMeta): diff --git a/r2r_core/agent/rag.py b/py/core/agent/rag.py similarity index 91% rename from r2r_core/agent/rag.py rename to py/core/agent/rag.py index 9dd5f1127..078f4f17e 100644 --- a/r2r_core/agent/rag.py +++ b/py/core/agent/rag.py @@ -1,15 +1,15 @@ import json -from r2r_core.agent import R2RAgent, R2RStreamingAgent -from r2r_core.base.abstractions import ( +from core.agent import R2RAgent, R2RStreamingAgent +from core.base.abstractions import ( KGSearchSettings, VectorSearchResult, VectorSearchSettings, ) -from r2r_core.base.agent import AgentConfig, Tool -from r2r_core.base.providers import CompletionProvider, PromptProvider -from r2r_core.base.utils import to_async_generator -from r2r_core.pipelines import SearchPipeline +from core.base.agent import AgentConfig, Tool +from core.base.providers import CompletionProvider, PromptProvider +from core.base.utils import to_async_generator +from core.pipelines import SearchPipeline class RAGAgentMixin: diff --git a/r2r_core/base/__init__.py b/py/core/base/__init__.py similarity index 100% rename from r2r_core/base/__init__.py rename to py/core/base/__init__.py diff --git a/r2r_core/base/abstractions/__init__.py b/py/core/base/abstractions/__init__.py similarity index 100% rename from r2r_core/base/abstractions/__init__.py rename to py/core/base/abstractions/__init__.py diff --git a/r2r_core/base/abstractions/base.py b/py/core/base/abstractions/base.py similarity index 100% rename from r2r_core/base/abstractions/base.py rename to py/core/base/abstractions/base.py diff --git a/r2r_core/base/abstractions/completion.py b/py/core/base/abstractions/completion.py similarity index 100% rename from r2r_core/base/abstractions/completion.py rename to py/core/base/abstractions/completion.py diff --git a/r2r_core/base/abstractions/document.py b/py/core/base/abstractions/document.py similarity index 100% rename from r2r_core/base/abstractions/document.py rename to py/core/base/abstractions/document.py diff --git a/r2r_core/base/abstractions/embedding.py b/py/core/base/abstractions/embedding.py similarity index 100% rename from r2r_core/base/abstractions/embedding.py rename to py/core/base/abstractions/embedding.py diff --git a/r2r_core/base/abstractions/exception.py b/py/core/base/abstractions/exception.py similarity index 100% rename from r2r_core/base/abstractions/exception.py rename to py/core/base/abstractions/exception.py diff --git a/r2r_core/base/abstractions/graph.py b/py/core/base/abstractions/graph.py similarity index 100% rename from r2r_core/base/abstractions/graph.py rename to py/core/base/abstractions/graph.py diff --git a/r2r_core/base/abstractions/llm.py b/py/core/base/abstractions/llm.py similarity index 100% rename from r2r_core/base/abstractions/llm.py rename to py/core/base/abstractions/llm.py diff --git a/r2r_core/base/abstractions/prompt.py b/py/core/base/abstractions/prompt.py similarity index 100% rename from r2r_core/base/abstractions/prompt.py rename to py/core/base/abstractions/prompt.py diff --git a/r2r_core/base/abstractions/search.py b/py/core/base/abstractions/search.py similarity index 100% rename from r2r_core/base/abstractions/search.py rename to py/core/base/abstractions/search.py diff --git a/r2r_core/base/abstractions/user.py b/py/core/base/abstractions/user.py similarity index 100% rename from r2r_core/base/abstractions/user.py rename to py/core/base/abstractions/user.py diff --git a/r2r_core/base/abstractions/vector.py b/py/core/base/abstractions/vector.py similarity index 100% rename from r2r_core/base/abstractions/vector.py rename to py/core/base/abstractions/vector.py diff --git a/r2r_core/base/agent/__init__.py b/py/core/base/agent/__init__.py similarity index 100% rename from r2r_core/base/agent/__init__.py rename to py/core/base/agent/__init__.py diff --git a/r2r_core/base/agent/agent.py b/py/core/base/agent/agent.py similarity index 98% rename from r2r_core/base/agent/agent.py rename to py/core/base/agent/agent.py index 659473ab7..ce39c3d20 100644 --- a/r2r_core/base/agent/agent.py +++ b/py/core/base/agent/agent.py @@ -2,14 +2,13 @@ from abc import ABC, abstractmethod from typing import Any, AsyncGenerator, Dict, List, Optional, Type, Union -from pydantic import BaseModel - -from r2r_core.base.abstractions import ( +from core.base.abstractions import ( GenerationConfig, LLMChatCompletion, MessageType, ) -from r2r_core.base.providers import CompletionProvider, PromptProvider +from core.base.providers import CompletionProvider, PromptProvider +from pydantic import BaseModel from .base import Message, Tool, ToolResult diff --git a/r2r_core/base/agent/base.py b/py/core/base/agent/base.py similarity index 93% rename from r2r_core/base/agent/base.py rename to py/core/base/agent/base.py index 3d23a968b..386e6af7d 100644 --- a/r2r_core/base/agent/base.py +++ b/py/core/base/agent/base.py @@ -1,9 +1,8 @@ from typing import Any, Callable, Dict, Optional, Union +from core.base.abstractions import MessageType from pydantic import BaseModel -from r2r_core.base.abstractions import MessageType - class Tool(BaseModel): name: str diff --git a/r2r_core/base/api/models/__init__.py b/py/core/base/api/models/__init__.py similarity index 100% rename from r2r_core/base/api/models/__init__.py rename to py/core/base/api/models/__init__.py diff --git a/r2r_core/base/api/models/auth/__init__.py b/py/core/base/api/models/auth/__init__.py similarity index 100% rename from r2r_core/base/api/models/auth/__init__.py rename to py/core/base/api/models/auth/__init__.py diff --git a/r2r_core/base/api/models/auth/responses.py b/py/core/base/api/models/auth/responses.py similarity index 90% rename from r2r_core/base/api/models/auth/responses.py rename to py/core/base/api/models/auth/responses.py index 9d4a546b3..b5eb702ae 100644 --- a/r2r_core/base/api/models/auth/responses.py +++ b/py/core/base/api/models/auth/responses.py @@ -2,11 +2,10 @@ from typing import Optional from uuid import UUID +from core.base.abstractions import Token +from core.base.api.models.base import ResultsWrapper from pydantic import BaseModel -from r2r_core.base.abstractions import Token -from r2r_core.base.api.models.base import ResultsWrapper - class TokenResponse(BaseModel): access_token: Token diff --git a/r2r_core/base/api/models/base.py b/py/core/base/api/models/base.py similarity index 100% rename from r2r_core/base/api/models/base.py rename to py/core/base/api/models/base.py diff --git a/r2r_core/base/api/models/ingestion/__init__.py b/py/core/base/api/models/ingestion/__init__.py similarity index 100% rename from r2r_core/base/api/models/ingestion/__init__.py rename to py/core/base/api/models/ingestion/__init__.py diff --git a/r2r_core/base/api/models/ingestion/responses.py b/py/core/base/api/models/ingestion/responses.py similarity index 97% rename from r2r_core/base/api/models/ingestion/responses.py rename to py/core/base/api/models/ingestion/responses.py index dee32d466..011c4569a 100644 --- a/r2r_core/base/api/models/ingestion/responses.py +++ b/py/core/base/api/models/ingestion/responses.py @@ -1,10 +1,9 @@ from typing import Any, List, TypeVar from uuid import UUID +from core.base.api.models.base import ResultsWrapper from pydantic import BaseModel, Field -from r2r_core.base.api.models.base import ResultsWrapper - T = TypeVar("T") diff --git a/r2r_core/base/api/models/management/__init__.py b/py/core/base/api/models/management/__init__.py similarity index 100% rename from r2r_core/base/api/models/management/__init__.py rename to py/core/base/api/models/management/__init__.py diff --git a/r2r_core/base/api/models/management/responses.py b/py/core/base/api/models/management/responses.py similarity index 97% rename from r2r_core/base/api/models/management/responses.py rename to py/core/base/api/models/management/responses.py index 3f1a27279..22c7037ba 100644 --- a/r2r_core/base/api/models/management/responses.py +++ b/py/core/base/api/models/management/responses.py @@ -2,10 +2,9 @@ from typing import Any, Dict, List, Optional from uuid import UUID +from core.base.api.models.base import ResultsWrapper from pydantic import BaseModel -from r2r_core.base.api.models.base import ResultsWrapper - class PromptResponse(BaseModel): message: str diff --git a/r2r_core/base/api/models/retrieval/__init__.py b/py/core/base/api/models/retrieval/__init__.py similarity index 100% rename from r2r_core/base/api/models/retrieval/__init__.py rename to py/core/base/api/models/retrieval/__init__.py diff --git a/r2r_core/base/api/models/retrieval/responses.py b/py/core/base/api/models/retrieval/responses.py similarity index 97% rename from r2r_core/base/api/models/retrieval/responses.py rename to py/core/base/api/models/retrieval/responses.py index bc6571d2c..2ebac059a 100644 --- a/r2r_core/base/api/models/retrieval/responses.py +++ b/py/core/base/api/models/retrieval/responses.py @@ -1,13 +1,9 @@ from typing import Any, List, Optional +from core.base.abstractions.search import KGSearchResult, VectorSearchResult +from core.base.api.models.base import ResultsWrapper from pydantic import BaseModel, Field -from r2r_core.base.abstractions.search import ( - KGSearchResult, - VectorSearchResult, -) -from r2r_core.base.api.models.base import ResultsWrapper - class SearchResponse(BaseModel): vector_search_results: List[VectorSearchResult] = Field( diff --git a/r2r_core/base/logging/__init__.py b/py/core/base/logging/__init__.py similarity index 100% rename from r2r_core/base/logging/__init__.py rename to py/core/base/logging/__init__.py diff --git a/r2r_core/base/logging/base.py b/py/core/base/logging/base.py similarity index 100% rename from r2r_core/base/logging/base.py rename to py/core/base/logging/base.py diff --git a/r2r_core/base/logging/log_processor.py b/py/core/base/logging/log_processor.py similarity index 100% rename from r2r_core/base/logging/log_processor.py rename to py/core/base/logging/log_processor.py diff --git a/r2r_core/base/logging/run_logger.py b/py/core/base/logging/run_logger.py similarity index 100% rename from r2r_core/base/logging/run_logger.py rename to py/core/base/logging/run_logger.py diff --git a/r2r_core/base/logging/run_manager.py b/py/core/base/logging/run_manager.py similarity index 92% rename from r2r_core/base/logging/run_manager.py rename to py/core/base/logging/run_manager.py index 84e252ef0..bade2e162 100644 --- a/r2r_core/base/logging/run_manager.py +++ b/py/core/base/logging/run_manager.py @@ -3,9 +3,9 @@ from typing import Optional from uuid import UUID -from r2r_core.base.api.models.auth.responses import UserResponse -from r2r_core.base.logging.base import RunType -from r2r_core.base.utils import generate_run_id +from core.base.api.models.auth.responses import UserResponse +from core.base.logging.base import RunType +from core.base.utils import generate_run_id from .run_logger import RunLoggingSingleton diff --git a/r2r_core/base/parsers/__init__.py b/py/core/base/parsers/__init__.py similarity index 100% rename from r2r_core/base/parsers/__init__.py rename to py/core/base/parsers/__init__.py diff --git a/r2r_core/base/parsers/base_parser.py b/py/core/base/parsers/base_parser.py similarity index 100% rename from r2r_core/base/parsers/base_parser.py rename to py/core/base/parsers/base_parser.py diff --git a/r2r_core/base/pipeline/__init__.py b/py/core/base/pipeline/__init__.py similarity index 100% rename from r2r_core/base/pipeline/__init__.py rename to py/core/base/pipeline/__init__.py diff --git a/r2r_core/base/pipeline/base_pipeline.py b/py/core/base/pipeline/base_pipeline.py similarity index 100% rename from r2r_core/base/pipeline/base_pipeline.py rename to py/core/base/pipeline/base_pipeline.py diff --git a/r2r_core/base/pipes/__init__.py b/py/core/base/pipes/__init__.py similarity index 100% rename from r2r_core/base/pipes/__init__.py rename to py/core/base/pipes/__init__.py diff --git a/r2r_core/base/pipes/base_pipe.py b/py/core/base/pipes/base_pipe.py similarity index 97% rename from r2r_core/base/pipes/base_pipe.py rename to py/core/base/pipes/base_pipe.py index ec6aa6c01..37ae962a2 100644 --- a/r2r_core/base/pipes/base_pipe.py +++ b/py/core/base/pipes/base_pipe.py @@ -5,11 +5,10 @@ from typing import Any, AsyncGenerator, Optional from uuid import UUID +from core.base.logging.run_logger import RunLoggingSingleton +from core.base.logging.run_manager import RunManager, manage_run from pydantic import BaseModel -from r2r_core.base.logging.run_logger import RunLoggingSingleton -from r2r_core.base.logging.run_manager import RunManager, manage_run - logger = logging.getLogger(__name__) diff --git a/r2r_core/base/providers/__init__.py b/py/core/base/providers/__init__.py similarity index 100% rename from r2r_core/base/providers/__init__.py rename to py/core/base/providers/__init__.py diff --git a/r2r_core/base/providers/auth.py b/py/core/base/providers/auth.py similarity index 100% rename from r2r_core/base/providers/auth.py rename to py/core/base/providers/auth.py diff --git a/r2r_core/base/providers/base.py b/py/core/base/providers/base.py similarity index 100% rename from r2r_core/base/providers/base.py rename to py/core/base/providers/base.py diff --git a/r2r_core/base/providers/chunking.py b/py/core/base/providers/chunking.py similarity index 100% rename from r2r_core/base/providers/chunking.py rename to py/core/base/providers/chunking.py diff --git a/r2r_core/base/providers/crypto.py b/py/core/base/providers/crypto.py similarity index 100% rename from r2r_core/base/providers/crypto.py rename to py/core/base/providers/crypto.py diff --git a/r2r_core/base/providers/database.py b/py/core/base/providers/database.py similarity index 100% rename from r2r_core/base/providers/database.py rename to py/core/base/providers/database.py diff --git a/r2r_core/base/providers/embedding.py b/py/core/base/providers/embedding.py similarity index 100% rename from r2r_core/base/providers/embedding.py rename to py/core/base/providers/embedding.py diff --git a/r2r_core/base/providers/kg.py b/py/core/base/providers/kg.py similarity index 100% rename from r2r_core/base/providers/kg.py rename to py/core/base/providers/kg.py diff --git a/r2r_core/base/providers/llm.py b/py/core/base/providers/llm.py similarity index 99% rename from r2r_core/base/providers/llm.py rename to py/core/base/providers/llm.py index 978e0e76d..cf190d583 100644 --- a/r2r_core/base/providers/llm.py +++ b/py/core/base/providers/llm.py @@ -5,7 +5,7 @@ from concurrent.futures import ThreadPoolExecutor from typing import Any, AsyncGenerator, Generator, Optional -from r2r_core.base.abstractions.llm import ( +from core.base.abstractions.llm import ( GenerationConfig, LLMChatCompletion, LLMChatCompletionChunk, diff --git a/r2r_core/base/providers/parsing.py b/py/core/base/providers/parsing.py similarity index 100% rename from r2r_core/base/providers/parsing.py rename to py/core/base/providers/parsing.py diff --git a/r2r_core/base/providers/prompt.py b/py/core/base/providers/prompt.py similarity index 100% rename from r2r_core/base/providers/prompt.py rename to py/core/base/providers/prompt.py diff --git a/r2r_core/base/utils/__init__.py b/py/core/base/utils/__init__.py similarity index 100% rename from r2r_core/base/utils/__init__.py rename to py/core/base/utils/__init__.py diff --git a/r2r_core/base/utils/base_utils.py b/py/core/base/utils/base_utils.py similarity index 100% rename from r2r_core/base/utils/base_utils.py rename to py/core/base/utils/base_utils.py diff --git a/r2r_core/base/utils/splitter/__init__.py b/py/core/base/utils/splitter/__init__.py similarity index 100% rename from r2r_core/base/utils/splitter/__init__.py rename to py/core/base/utils/splitter/__init__.py diff --git a/r2r_core/base/utils/splitter/text.py b/py/core/base/utils/splitter/text.py similarity index 100% rename from r2r_core/base/utils/splitter/text.py rename to py/core/base/utils/splitter/text.py diff --git a/r2r_core/cli/__init__.py b/py/core/cli/__init__.py similarity index 100% rename from r2r_core/cli/__init__.py rename to py/core/cli/__init__.py diff --git a/r2r_core/cli/cli.py b/py/core/cli/cli.py similarity index 94% rename from r2r_core/cli/cli.py rename to py/core/cli/cli.py index 9fbb181e0..4314b89ae 100644 --- a/r2r_core/cli/cli.py +++ b/py/core/cli/cli.py @@ -1,5 +1,5 @@ -from r2r_core.cli.command_group import cli -from r2r_core.cli.commands import ( +from core.cli.command_group import cli +from core.cli.commands import ( auth_operations, document_operations, kg_operations, diff --git a/r2r_core/cli/command_group.py b/py/core/cli/command_group.py similarity index 95% rename from r2r_core/cli/command_group.py rename to py/core/cli/command_group.py index e5f94bc99..7ae0534c2 100644 --- a/r2r_core/cli/command_group.py +++ b/py/core/cli/command_group.py @@ -1,8 +1,7 @@ import os import click - -from r2r_core.main.execution import R2RExecutionWrapper +from core.main.execution import R2RExecutionWrapper # TODO: refactor this to remove config path and config name diff --git a/r2r_core/cli/commands/__init__.py b/py/core/cli/commands/__init__.py similarity index 100% rename from r2r_core/cli/commands/__init__.py rename to py/core/cli/commands/__init__.py diff --git a/r2r_core/cli/commands/auth_operations.py b/py/core/cli/commands/auth_operations.py similarity index 87% rename from r2r_core/cli/commands/auth_operations.py rename to py/core/cli/commands/auth_operations.py index 4cd6cd299..83f13dd1c 100644 --- a/r2r_core/cli/commands/auth_operations.py +++ b/py/core/cli/commands/auth_operations.py @@ -1,8 +1,7 @@ import secrets import click - -from r2r_core.cli.command_group import cli +from core.cli.command_group import cli @cli.command() diff --git a/r2r_core/cli/commands/document_operations.py b/py/core/cli/commands/document_operations.py similarity index 97% rename from r2r_core/cli/commands/document_operations.py rename to py/core/cli/commands/document_operations.py index 770131bf9..081f5e46b 100644 --- a/r2r_core/cli/commands/document_operations.py +++ b/py/core/cli/commands/document_operations.py @@ -1,7 +1,6 @@ import click - -from r2r_core.cli.command_group import cli -from r2r_core.cli.utils.timer import timer +from core.cli.command_group import cli +from core.cli.utils.timer import timer @cli.command() diff --git a/r2r_core/cli/commands/kg_operations.py b/py/core/cli/commands/kg_operations.py similarity index 76% rename from r2r_core/cli/commands/kg_operations.py rename to py/core/cli/commands/kg_operations.py index ad0af782c..7512bc33d 100644 --- a/r2r_core/cli/commands/kg_operations.py +++ b/py/core/cli/commands/kg_operations.py @@ -1,7 +1,6 @@ import click - -from r2r_core.cli.command_group import cli -from r2r_core.cli.utils.timer import timer +from core.cli.command_group import cli +from core.cli.utils.timer import timer @cli.command() diff --git a/r2r_core/cli/commands/oberservability_operations.py b/py/core/cli/commands/oberservability_operations.py similarity index 93% rename from r2r_core/cli/commands/oberservability_operations.py rename to py/core/cli/commands/oberservability_operations.py index a2108e73d..4df95c66d 100644 --- a/r2r_core/cli/commands/oberservability_operations.py +++ b/py/core/cli/commands/oberservability_operations.py @@ -2,10 +2,9 @@ from uuid import UUID import click - -from r2r_core.cli.command_group import cli -from r2r_core.cli.utils.param_types import JSON -from r2r_core.cli.utils.timer import timer +from core.cli.command_group import cli +from core.cli.utils.param_types import JSON +from core.cli.utils.timer import timer @cli.command() diff --git a/r2r_core/cli/commands/rag_operations.py b/py/core/cli/commands/rag_operations.py similarity index 97% rename from r2r_core/cli/commands/rag_operations.py rename to py/core/cli/commands/rag_operations.py index af79505be..88f72576c 100644 --- a/r2r_core/cli/commands/rag_operations.py +++ b/py/core/cli/commands/rag_operations.py @@ -1,8 +1,7 @@ import click - -from r2r_core.cli.command_group import cli -from r2r_core.cli.utils.param_types import JSON -from r2r_core.cli.utils.timer import timer +from core.cli.command_group import cli +from core.cli.utils.param_types import JSON +from core.cli.utils.timer import timer @cli.command() diff --git a/r2r_core/cli/commands/server_operations.py b/py/core/cli/commands/server_operations.py similarity index 98% rename from r2r_core/cli/commands/server_operations.py rename to py/core/cli/commands/server_operations.py index c3df1cb64..f66915acc 100644 --- a/r2r_core/cli/commands/server_operations.py +++ b/py/core/cli/commands/server_operations.py @@ -5,16 +5,15 @@ import sys import click -from dotenv import load_dotenv - -from r2r_core.cli.command_group import cli -from r2r_core.cli.utils.docker_utils import ( +from core.cli.command_group import cli +from core.cli.utils.docker_utils import ( bring_down_docker_compose, remove_r2r_network, run_docker_serve, run_local_serve, ) -from r2r_core.cli.utils.timer import timer +from core.cli.utils.timer import timer +from dotenv import load_dotenv @cli.command() diff --git a/r2r_core/cli/utils/__init__.py b/py/core/cli/utils/__init__.py similarity index 100% rename from r2r_core/cli/utils/__init__.py rename to py/core/cli/utils/__init__.py diff --git a/r2r_core/cli/utils/docker_utils.py b/py/core/cli/utils/docker_utils.py similarity index 99% rename from r2r_core/cli/utils/docker_utils.py rename to py/core/cli/utils/docker_utils.py index e4bcf4487..76708dac0 100644 --- a/r2r_core/cli/utils/docker_utils.py +++ b/py/core/cli/utils/docker_utils.py @@ -8,11 +8,10 @@ import click import requests +from core.main import R2RBuilder, R2RConfig +from core.main.execution import R2RExecutionWrapper from requests.exceptions import RequestException -from r2r_core.main import R2RBuilder, R2RConfig -from r2r_core.main.execution import R2RExecutionWrapper - def bring_down_docker_compose(project_name, volumes, remove_orphans): compose_files = get_compose_files() diff --git a/r2r_core/cli/utils/param_types.py b/py/core/cli/utils/param_types.py similarity index 100% rename from r2r_core/cli/utils/param_types.py rename to py/core/cli/utils/param_types.py diff --git a/r2r_core/cli/utils/timer.py b/py/core/cli/utils/timer.py similarity index 100% rename from r2r_core/cli/utils/timer.py rename to py/core/cli/utils/timer.py diff --git a/r2r_core/configs/auth.toml b/py/core/configs/auth.toml similarity index 100% rename from r2r_core/configs/auth.toml rename to py/core/configs/auth.toml diff --git a/r2r_core/configs/local_llm.toml b/py/core/configs/local_llm.toml similarity index 100% rename from r2r_core/configs/local_llm.toml rename to py/core/configs/local_llm.toml diff --git a/r2r_core/configs/local_llm_neo4j_kg.toml b/py/core/configs/local_llm_neo4j_kg.toml similarity index 100% rename from r2r_core/configs/local_llm_neo4j_kg.toml rename to py/core/configs/local_llm_neo4j_kg.toml diff --git a/r2r_core/configs/neo4j_kg.toml b/py/core/configs/neo4j_kg.toml similarity index 100% rename from r2r_core/configs/neo4j_kg.toml rename to py/core/configs/neo4j_kg.toml diff --git a/r2r_core/configs/neo4j_kg_no_vector_postgres.toml b/py/core/configs/neo4j_kg_no_vector_postgres.toml similarity index 100% rename from r2r_core/configs/neo4j_kg_no_vector_postgres.toml rename to py/core/configs/neo4j_kg_no_vector_postgres.toml diff --git a/r2r_core/configs/postgres_logging.toml b/py/core/configs/postgres_logging.toml similarity index 100% rename from r2r_core/configs/postgres_logging.toml rename to py/core/configs/postgres_logging.toml diff --git a/r2r_core/examples/__init__.py b/py/core/examples/__init__.py similarity index 100% rename from r2r_core/examples/__init__.py rename to py/core/examples/__init__.py diff --git a/r2r_core/examples/data/aristotle.txt b/py/core/examples/data/aristotle.txt similarity index 100% rename from r2r_core/examples/data/aristotle.txt rename to py/core/examples/data/aristotle.txt diff --git a/r2r_core/examples/data/aristotle_v2.txt b/py/core/examples/data/aristotle_v2.txt similarity index 100% rename from r2r_core/examples/data/aristotle_v2.txt rename to py/core/examples/data/aristotle_v2.txt diff --git a/r2r_core/examples/data/got.txt b/py/core/examples/data/got.txt similarity index 100% rename from r2r_core/examples/data/got.txt rename to py/core/examples/data/got.txt diff --git a/r2r_core/examples/data/lyft_2021.pdf b/py/core/examples/data/lyft_2021.pdf similarity index 100% rename from r2r_core/examples/data/lyft_2021.pdf rename to py/core/examples/data/lyft_2021.pdf diff --git a/r2r_core/examples/data/pg_essay_1.html b/py/core/examples/data/pg_essay_1.html similarity index 100% rename from r2r_core/examples/data/pg_essay_1.html rename to py/core/examples/data/pg_essay_1.html diff --git a/r2r_core/examples/data/pg_essay_2.html b/py/core/examples/data/pg_essay_2.html similarity index 100% rename from r2r_core/examples/data/pg_essay_2.html rename to py/core/examples/data/pg_essay_2.html diff --git a/r2r_core/examples/data/pg_essay_3.html b/py/core/examples/data/pg_essay_3.html similarity index 100% rename from r2r_core/examples/data/pg_essay_3.html rename to py/core/examples/data/pg_essay_3.html diff --git a/r2r_core/examples/data/pg_essay_4.html b/py/core/examples/data/pg_essay_4.html similarity index 100% rename from r2r_core/examples/data/pg_essay_4.html rename to py/core/examples/data/pg_essay_4.html diff --git a/r2r_core/examples/data/pg_essay_5.html b/py/core/examples/data/pg_essay_5.html similarity index 100% rename from r2r_core/examples/data/pg_essay_5.html rename to py/core/examples/data/pg_essay_5.html diff --git a/r2r_core/examples/data/sample.mp3 b/py/core/examples/data/sample.mp3 similarity index 100% rename from r2r_core/examples/data/sample.mp3 rename to py/core/examples/data/sample.mp3 diff --git a/r2r_core/examples/data/sample2.mp3 b/py/core/examples/data/sample2.mp3 similarity index 100% rename from r2r_core/examples/data/sample2.mp3 rename to py/core/examples/data/sample2.mp3 diff --git a/r2r_core/examples/data/screen_shot.png b/py/core/examples/data/screen_shot.png similarity index 100% rename from r2r_core/examples/data/screen_shot.png rename to py/core/examples/data/screen_shot.png diff --git a/r2r_core/examples/data/test.txt b/py/core/examples/data/test.txt similarity index 100% rename from r2r_core/examples/data/test.txt rename to py/core/examples/data/test.txt diff --git a/r2r_core/examples/data/uber_2021.pdf b/py/core/examples/data/uber_2021.pdf similarity index 100% rename from r2r_core/examples/data/uber_2021.pdf rename to py/core/examples/data/uber_2021.pdf diff --git a/r2r_core/examples/data/yc_companies.txt b/py/core/examples/data/yc_companies.txt similarity index 100% rename from r2r_core/examples/data/yc_companies.txt rename to py/core/examples/data/yc_companies.txt diff --git a/r2r_core/examples/hello_r2r.py b/py/core/examples/hello_r2r.py similarity index 96% rename from r2r_core/examples/hello_r2r.py rename to py/core/examples/hello_r2r.py index fccd73b2e..c114d2774 100644 --- a/r2r_core/examples/hello_r2r.py +++ b/py/core/examples/hello_r2r.py @@ -1,4 +1,4 @@ -from r2r_core import R2R, Document, GenerationConfig +from core import R2R, Document, GenerationConfig app = R2R() # You may pass a custom configuration to `R2R` with config=... diff --git a/r2r_core/examples/scripts/advanced_kg_cookbook.py b/py/core/examples/scripts/advanced_kg_cookbook.py similarity index 99% rename from r2r_core/examples/scripts/advanced_kg_cookbook.py rename to py/core/examples/scripts/advanced_kg_cookbook.py index 6818ad213..8eaa2ea73 100644 --- a/r2r_core/examples/scripts/advanced_kg_cookbook.py +++ b/py/core/examples/scripts/advanced_kg_cookbook.py @@ -3,7 +3,6 @@ import fire import requests from bs4 import BeautifulSoup, Comment - from r2r import EntityType, R2RClient, R2RPromptProvider, RelationshipType diff --git a/r2r_core/examples/scripts/run_auth_workflow.py b/py/core/examples/scripts/run_auth_workflow.py similarity index 97% rename from r2r_core/examples/scripts/run_auth_workflow.py rename to py/core/examples/scripts/run_auth_workflow.py index 819ac121d..db24394ec 100644 --- a/r2r_core/examples/scripts/run_auth_workflow.py +++ b/py/core/examples/scripts/run_auth_workflow.py @@ -1,5 +1,5 @@ # TODO: need to import this from the package, not from the local directory -from r2r_python_sdk.r2r.client import R2RClient +from r2r_python_sdk.sdk.client import R2RClient if __name__ == "__main__": client = R2RClient( diff --git a/r2r_core/examples/scripts/run_hyde.py b/py/core/examples/scripts/run_hyde.py similarity index 80% rename from r2r_core/examples/scripts/run_hyde.py rename to py/core/examples/scripts/run_hyde.py index 5fb79f73e..b5bcc23a7 100644 --- a/r2r_core/examples/scripts/run_hyde.py +++ b/py/core/examples/scripts/run_hyde.py @@ -1,10 +1,7 @@ import fire - -from r2r_core import R2RBuilder, R2RConfig -from r2r_core.base.abstractions.llm import GenerationConfig -from r2r_core.main.assembly.factory_extensions import ( - R2RPipeFactoryWithMultiSearch, -) +from core import R2RBuilder, R2RConfig +from core.base.abstractions.llm import GenerationConfig +from core.main.assembly.factory_extensions import R2RPipeFactoryWithMultiSearch def main(task_prompt_name="hyde", query="Who was aristotle?"): diff --git a/r2r_core/examples/scripts/run_web_multi_rag.py b/py/core/examples/scripts/run_web_multi_rag.py similarity index 90% rename from r2r_core/examples/scripts/run_web_multi_rag.py rename to py/core/examples/scripts/run_web_multi_rag.py index f8f77cb0f..915ee5ea9 100644 --- a/r2r_core/examples/scripts/run_web_multi_rag.py +++ b/py/core/examples/scripts/run_web_multi_rag.py @@ -1,10 +1,7 @@ import fire - -from r2r_core import R2RBuilder, SerperClient, WebSearchPipe -from r2r_core.base.abstractions.llm import GenerationConfig -from r2r_core.main.assembly.factory_extensions import ( - R2RPipeFactoryWithMultiSearch, -) +from core import R2RBuilder, SerperClient, WebSearchPipe +from core.base.abstractions.llm import GenerationConfig +from core.main.assembly.factory_extensions import R2RPipeFactoryWithMultiSearch def run_rag_pipeline(query="Who was Aristotle?"): diff --git a/r2r_core/examples/scripts/run_web_rag.py b/py/core/examples/scripts/run_web_rag.py similarity index 92% rename from r2r_core/examples/scripts/run_web_rag.py rename to py/core/examples/scripts/run_web_rag.py index 6738dc933..d16cad68f 100644 --- a/r2r_core/examples/scripts/run_web_rag.py +++ b/py/core/examples/scripts/run_web_rag.py @@ -1,8 +1,7 @@ import fire +from core.base.abstractions.llm import GenerationConfig from r2r import R2RBuilder, SerperClient, WebSearchPipe -from r2r_core.base.abstractions.llm import GenerationConfig - def run_rag_pipeline(query="Who was Aristotle?"): # Create search pipe override and pipes diff --git a/r2r_core/examples/scripts/sample_data_ingestor.py b/py/core/examples/scripts/sample_data_ingestor.py similarity index 97% rename from r2r_core/examples/scripts/sample_data_ingestor.py rename to py/core/examples/scripts/sample_data_ingestor.py index 2fdc653b2..309c8b61e 100644 --- a/r2r_core/examples/scripts/sample_data_ingestor.py +++ b/py/core/examples/scripts/sample_data_ingestor.py @@ -4,7 +4,7 @@ import fire if TYPE_CHECKING: - from r2r_core.main.execution import R2RExecutionWrapper + from core.main.execution import R2RExecutionWrapper class SampleDataIngestor: diff --git a/r2r_core/integrations/__init__.py b/py/core/integrations/__init__.py similarity index 100% rename from r2r_core/integrations/__init__.py rename to py/core/integrations/__init__.py diff --git a/r2r_core/integrations/serper.py b/py/core/integrations/serper.py similarity index 100% rename from r2r_core/integrations/serper.py rename to py/core/integrations/serper.py diff --git a/r2r_core/main/__init__.py b/py/core/main/__init__.py similarity index 100% rename from r2r_core/main/__init__.py rename to py/core/main/__init__.py diff --git a/r2r_core/main/abstractions.py b/py/core/main/abstractions.py similarity index 91% rename from r2r_core/main/abstractions.py rename to py/core/main/abstractions.py index e2df9f88b..cb7f2e774 100644 --- a/r2r_core/main/abstractions.py +++ b/py/core/main/abstractions.py @@ -1,10 +1,8 @@ from typing import Optional -from pydantic import BaseModel - -from r2r_core.agent import R2RRAGAgent, R2RStreamingRAGAgent -from r2r_core.base.pipes import AsyncPipe -from r2r_core.base.providers import ( +from core.agent import R2RRAGAgent, R2RStreamingRAGAgent +from core.base.pipes import AsyncPipe +from core.base.providers import ( AuthProvider, ChunkingProvider, CompletionProvider, @@ -14,12 +12,13 @@ ParsingProvider, PromptProvider, ) -from r2r_core.pipelines import ( +from core.pipelines import ( IngestionPipeline, KGEnrichmentPipeline, RAGPipeline, SearchPipeline, ) +from pydantic import BaseModel class R2RProviders(BaseModel): diff --git a/r2r_core/main/api/__init__.py b/py/core/main/api/__init__.py similarity index 100% rename from r2r_core/main/api/__init__.py rename to py/core/main/api/__init__.py diff --git a/r2r_core/main/api/routes/__init__.py b/py/core/main/api/routes/__init__.py similarity index 100% rename from r2r_core/main/api/routes/__init__.py rename to py/core/main/api/routes/__init__.py diff --git a/r2r_core/main/api/routes/auth/__init__.py b/py/core/main/api/routes/auth/__init__.py similarity index 100% rename from r2r_core/main/api/routes/auth/__init__.py rename to py/core/main/api/routes/auth/__init__.py diff --git a/r2r_core/main/api/routes/auth/base.py b/py/core/main/api/routes/auth/base.py similarity index 99% rename from r2r_core/main/api/routes/auth/base.py rename to py/core/main/api/routes/auth/base.py index 499b012f0..84707d008 100644 --- a/r2r_core/main/api/routes/auth/base.py +++ b/py/core/main/api/routes/auth/base.py @@ -1,16 +1,15 @@ import uuid from typing import TYPE_CHECKING -from fastapi import Body, Depends -from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm -from pydantic import EmailStr - -from r2r_core.base.api.models.auth.responses import ( +from core.base.api.models.auth.responses import ( GenericMessageResponse, WrappedGenericMessageResponse, WrappedTokenResponse, WrappedUserResponse, ) +from fastapi import Body, Depends +from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm +from pydantic import EmailStr from ..base_router import BaseRouter diff --git a/r2r_core/main/api/routes/base_router.py b/py/core/main/api/routes/base_router.py similarity index 95% rename from r2r_core/main/api/routes/base_router.py rename to py/core/main/api/routes/base_router.py index c5e089b27..f9acfa1ba 100644 --- a/r2r_core/main/api/routes/base_router.py +++ b/py/core/main/api/routes/base_router.py @@ -2,12 +2,11 @@ import logging from abc import abstractmethod +from core.base import R2RException, manage_run +from core.base.logging.base import RunType from fastapi import APIRouter, HTTPException from fastapi.responses import StreamingResponse -from r2r_core.base import R2RException, manage_run -from r2r_core.base.logging.base import RunType - logger = logging.getLogger(__name__) diff --git a/r2r_core/main/api/routes/ingestion/__init__.py b/py/core/main/api/routes/ingestion/__init__.py similarity index 100% rename from r2r_core/main/api/routes/ingestion/__init__.py rename to py/core/main/api/routes/ingestion/__init__.py diff --git a/r2r_core/main/api/routes/ingestion/base.py b/py/core/main/api/routes/ingestion/base.py similarity index 98% rename from r2r_core/main/api/routes/ingestion/base.py rename to py/core/main/api/routes/ingestion/base.py index f1feb6ca2..8eba7ef91 100644 --- a/r2r_core/main/api/routes/ingestion/base.py +++ b/py/core/main/api/routes/ingestion/base.py @@ -5,14 +5,11 @@ from uuid import UUID import yaml +from core.base import ChunkingConfig, R2RException +from core.base.api.models.ingestion.responses import WrappedIngestionResponse +from core.base.utils import generate_user_document_id from fastapi import Depends, File, Form, UploadFile -from r2r_core.base import ChunkingConfig, R2RException -from r2r_core.base.api.models.ingestion.responses import ( - WrappedIngestionResponse, -) -from r2r_core.base.utils import generate_user_document_id - from ....assembly.factory import R2RProviderFactory from ....engine import R2REngine from ..base_router import BaseRouter diff --git a/r2r_core/main/api/routes/ingestion/ingestion_router_openapi.yml b/py/core/main/api/routes/ingestion/ingestion_router_openapi.yml similarity index 100% rename from r2r_core/main/api/routes/ingestion/ingestion_router_openapi.yml rename to py/core/main/api/routes/ingestion/ingestion_router_openapi.yml diff --git a/r2r_core/main/api/routes/management/__init__.py b/py/core/main/api/routes/management/__init__.py similarity index 100% rename from r2r_core/main/api/routes/management/__init__.py rename to py/core/main/api/routes/management/__init__.py diff --git a/r2r_core/main/api/routes/management/base.py b/py/core/main/api/routes/management/base.py similarity index 99% rename from r2r_core/main/api/routes/management/base.py rename to py/core/main/api/routes/management/base.py index 5aa90e973..571d057be 100644 --- a/r2r_core/main/api/routes/management/base.py +++ b/py/core/main/api/routes/management/base.py @@ -5,10 +5,8 @@ from uuid import UUID import psutil -from fastapi import Body, Depends, Path, Query - -from r2r_core.base import R2RException -from r2r_core.base.api.models.management.responses import ( +from core.base import R2RException +from core.base.api.models.management.responses import ( WrappedAddUserResponse, WrappedAnalyticsResponse, WrappedAppSettingsResponse, @@ -24,6 +22,7 @@ WrappedServerStatsResponse, WrappedUserOverviewResponse, ) +from fastapi import Body, Depends, Path, Query from ....engine import R2REngine from ..base_router import BaseRouter diff --git a/r2r_core/main/api/routes/restructure/__init__.py b/py/core/main/api/routes/restructure/__init__.py similarity index 100% rename from r2r_core/main/api/routes/restructure/__init__.py rename to py/core/main/api/routes/restructure/__init__.py diff --git a/r2r_core/main/api/routes/restructure/base.py b/py/core/main/api/routes/restructure/base.py similarity index 88% rename from r2r_core/main/api/routes/restructure/base.py rename to py/core/main/api/routes/restructure/base.py index ebe726448..1d0801301 100644 --- a/r2r_core/main/api/routes/restructure/base.py +++ b/py/core/main/api/routes/restructure/base.py @@ -1,8 +1,7 @@ +from core.main.api.routes.base_router import BaseRouter +from core.main.engine import R2REngine from fastapi import Depends -from r2r_core.main.api.routes.base_router import BaseRouter -from r2r_core.main.engine import R2REngine - # TODO: Botched by Claude class RestructureRouter(BaseRouter): diff --git a/r2r_core/main/api/routes/retrieval/__init__.py b/py/core/main/api/routes/retrieval/__init__.py similarity index 100% rename from r2r_core/main/api/routes/retrieval/__init__.py rename to py/core/main/api/routes/retrieval/__init__.py diff --git a/r2r_core/main/api/routes/retrieval/base.py b/py/core/main/api/routes/retrieval/base.py similarity index 99% rename from r2r_core/main/api/routes/retrieval/base.py rename to py/core/main/api/routes/retrieval/base.py index a8e469c5c..8fbe4f3c1 100644 --- a/r2r_core/main/api/routes/retrieval/base.py +++ b/py/core/main/api/routes/retrieval/base.py @@ -2,21 +2,20 @@ from typing import Optional import yaml -from fastapi import Body, Depends -from fastapi.responses import StreamingResponse - -from r2r_core.base import ( +from core.base import ( GenerationConfig, KGSearchSettings, Message, RunType, VectorSearchSettings, ) -from r2r_core.base.api.models import ( +from core.base.api.models import ( WrappedRAGAgentResponse, WrappedRAGResponse, WrappedSearchResponse, ) +from fastapi import Body, Depends +from fastapi.responses import StreamingResponse from ....engine import R2REngine from ..base_router import BaseRouter diff --git a/r2r_core/main/api/routes/retrieval/retrieval_router_openapi.yml b/py/core/main/api/routes/retrieval/retrieval_router_openapi.yml similarity index 100% rename from r2r_core/main/api/routes/retrieval/retrieval_router_openapi.yml rename to py/core/main/api/routes/retrieval/retrieval_router_openapi.yml diff --git a/r2r_core/main/app.py b/py/core/main/app.py similarity index 100% rename from r2r_core/main/app.py rename to py/core/main/app.py diff --git a/r2r_core/main/app_entry.py b/py/core/main/app_entry.py similarity index 100% rename from r2r_core/main/app_entry.py rename to py/core/main/app_entry.py diff --git a/r2r_core/main/assembly/__init__.py b/py/core/main/assembly/__init__.py similarity index 100% rename from r2r_core/main/assembly/__init__.py rename to py/core/main/assembly/__init__.py diff --git a/r2r_core/main/assembly/builder.py b/py/core/main/assembly/builder.py similarity index 99% rename from r2r_core/main/assembly/builder.py rename to py/core/main/assembly/builder.py index 22ec703a2..c7ef206b3 100644 --- a/r2r_core/main/assembly/builder.py +++ b/py/core/main/assembly/builder.py @@ -1,8 +1,8 @@ import os from typing import Optional, Type -from r2r_core.agent import R2RRAGAgent -from r2r_core.base import ( +from core.agent import R2RRAGAgent +from core.base import ( AsyncPipe, AuthProvider, CompletionProvider, @@ -12,7 +12,7 @@ KGProvider, PromptProvider, ) -from r2r_core.pipelines import ( +from core.pipelines import ( IngestionPipeline, KGEnrichmentPipeline, RAGPipeline, diff --git a/r2r_core/main/assembly/config.py b/py/core/main/assembly/config.py similarity index 95% rename from r2r_core/main/assembly/config.py rename to py/core/main/assembly/config.py index 1f1408198..b52819f4b 100644 --- a/r2r_core/main/assembly/config.py +++ b/py/core/main/assembly/config.py @@ -113,7 +113,11 @@ def from_toml(cls, config_path: str = None) -> "R2RConfig": if config_path is None: # Get the root directory of the project file_dir = os.path.dirname(os.path.abspath(__file__)) - config_path = os.path.join(file_dir, "..", "..", "..", "r2r.toml") + print(file_dir) + print(os.path.join(file_dir, "..", "..", "..", "r2r.toml")) + config_path = os.path.join( + file_dir, "..", "..", "..", "..", "r2r.toml" + ) # Load configuration from TOML file with open(config_path) as f: @@ -146,7 +150,7 @@ def load_default_config(cls) -> dict: # Get the root directory of the project file_dir = os.path.dirname(os.path.abspath(__file__)) default_config_path = os.path.join( - file_dir, "..", "..", "..", "r2r.toml" + file_dir, "..", "..", "..", "..", "r2r.toml" ) # Load default configuration from TOML file with open(default_config_path) as f: diff --git a/r2r_core/main/assembly/factory.py b/py/core/main/assembly/factory.py similarity index 92% rename from r2r_core/main/assembly/factory.py rename to py/core/main/assembly/factory.py index 78966121f..7b012548c 100644 --- a/r2r_core/main/assembly/factory.py +++ b/py/core/main/assembly/factory.py @@ -2,8 +2,8 @@ import os from typing import Any, Optional -from r2r_core.agent import R2RRAGAgent, R2RStreamingRAGAgent -from r2r_core.base import ( +from core.agent import R2RRAGAgent, R2RStreamingRAGAgent +from core.base import ( AsyncPipe, AuthConfig, AuthProvider, @@ -24,7 +24,7 @@ PromptProvider, RunLoggingSingleton, ) -from r2r_core.pipelines import ( +from core.pipelines import ( IngestionPipeline, KGEnrichmentPipeline, RAGPipeline, @@ -51,7 +51,7 @@ def create_auth_provider( ) -> AuthProvider: auth_provider: Optional[AuthProvider] = None if auth_config.provider == "r2r": - from r2r_core.providers import R2RAuthProvider + from core.providers import R2RAuthProvider auth_provider = R2RAuthProvider( auth_config, crypto_provider, db_provider @@ -70,7 +70,7 @@ def create_crypto_provider( ) -> CryptoProvider: crypto_provider: Optional[CryptoProvider] = None if crypto_config.provider == "bcrypt": - from r2r_core.providers.crypto import BCryptConfig, BCryptProvider + from core.providers.crypto import BCryptConfig, BCryptProvider crypto_provider = BCryptProvider( BCryptConfig(**crypto_config.dict()) @@ -88,11 +88,11 @@ def create_parsing_provider( parsing_config: ParsingConfig, *args, **kwargs ) -> ParsingProvider: if parsing_config.provider == "r2r": - from r2r_core.providers import R2RParsingProvider + from core.providers import R2RParsingProvider return R2RParsingProvider(parsing_config) elif parsing_config.provider == "unstructured": - from r2r_core.providers import UnstructuredParsingProvider + from core.providers import UnstructuredParsingProvider return UnstructuredParsingProvider(parsing_config) else: @@ -106,11 +106,11 @@ def create_chunking_provider( ) -> ChunkingProvider: chunking_config.validate() if chunking_config.provider == "r2r": - from r2r_core.providers import R2RChunkingProvider + from core.providers import R2RChunkingProvider return R2RChunkingProvider(chunking_config) elif chunking_config.provider == "unstructured": - from r2r_core.providers import UnstructuredChunkingProvider + from core.providers import UnstructuredChunkingProvider return UnstructuredChunkingProvider(chunking_config) else: @@ -133,7 +133,7 @@ def create_database_provider( vector_db_dimension = self.config.embedding.base_dimension if db_config.provider == "postgres": - from r2r_core.providers import PostgresDBProvider + from core.providers import PostgresDBProvider database_provider = PostgresDBProvider( db_config, vector_db_dimension, crypto_provider=crypto_provider @@ -158,17 +158,17 @@ def create_embedding_provider( raise ValueError( "Must set OPENAI_API_KEY in order to initialize OpenAIEmbeddingProvider." ) - from r2r_core.providers import OpenAIEmbeddingProvider + from core.providers import OpenAIEmbeddingProvider embedding_provider = OpenAIEmbeddingProvider(embedding) elif embedding.provider == "litellm": - from r2r_core.providers import LiteLLMEmbeddingProvider + from core.providers import LiteLLMEmbeddingProvider embedding_provider = LiteLLMEmbeddingProvider(embedding) elif embedding.provider == "ollama": - from r2r_core.providers import OllamaEmbeddingProvider + from core.providers import OllamaEmbeddingProvider embedding_provider = OllamaEmbeddingProvider(embedding) @@ -188,11 +188,11 @@ def create_llm_provider( ) -> CompletionProvider: llm_provider: Optional[CompletionProvider] = None if llm_config.provider == "openai": - from r2r_core.providers import OpenAICompletionProvider + from core.providers import OpenAICompletionProvider llm_provider = OpenAICompletionProvider(llm_config) elif llm_config.provider == "litellm": - from r2r_core.providers import LiteCompletionProvider + from core.providers import LiteCompletionProvider llm_provider = LiteCompletionProvider(llm_config) else: @@ -209,7 +209,7 @@ def create_prompt_provider( ) -> PromptProvider: prompt_provider = None if prompt_config.provider == "r2r": - from r2r_core.providers import R2RPromptProvider + from core.providers import R2RPromptProvider prompt_provider = R2RPromptProvider(prompt_config) else: @@ -221,7 +221,7 @@ def create_prompt_provider( @staticmethod def create_kg_provider(kg_config, *args, **kwargs): if kg_config.provider == "neo4j": - from r2r_core.providers import Neo4jKGProvider + from core.providers import Neo4jKGProvider return Neo4jKGProvider(kg_config) elif kg_config.provider is None: @@ -362,12 +362,12 @@ def create_pipes( ) def create_parsing_pipe(self, *args, **kwargs) -> Any: - from r2r_core.pipes import ParsingPipe + from core.pipes import ParsingPipe return ParsingPipe(parsing_provider=self.providers.parsing) def create_chunking_pipe(self, *args, **kwargs) -> Any: - from r2r_core.pipes import ChunkingPipe + from core.pipes import ChunkingPipe return ChunkingPipe(chunking_provider=self.providers.chunking) @@ -375,7 +375,7 @@ def create_embedding_pipe(self, *args, **kwargs) -> Any: if self.config.embedding.provider is None: return None - from r2r_core.pipes import EmbeddingPipe + from core.pipes import EmbeddingPipe return EmbeddingPipe( embedding_provider=self.providers.embedding, @@ -387,7 +387,7 @@ def create_vector_storage_pipe(self, *args, **kwargs) -> Any: if self.config.embedding.provider is None: return None - from r2r_core.pipes import VectorStoragePipe + from core.pipes import VectorStoragePipe return VectorStoragePipe(database_provider=self.providers.database) @@ -395,7 +395,7 @@ def create_vector_search_pipe(self, *args, **kwargs) -> Any: if self.config.embedding.provider is None: return None - from r2r_core.pipes import VectorSearchPipe + from core.pipes import VectorSearchPipe return VectorSearchPipe( database_provider=self.providers.database, @@ -406,7 +406,7 @@ def create_kg_pipe(self, *args, **kwargs) -> Any: if self.config.kg.provider is None: return None - from r2r_core.pipes import KGTriplesExtractionPipe + from core.pipes import KGTriplesExtractionPipe return KGTriplesExtractionPipe( kg_provider=self.providers.kg, @@ -420,7 +420,7 @@ def create_kg_storage_pipe(self, *args, **kwargs) -> Any: if self.config.kg.provider is None: return None - from r2r_core.pipes import KGStoragePipe + from core.pipes import KGStoragePipe return KGStoragePipe( kg_provider=self.providers.kg, @@ -431,7 +431,7 @@ def create_kg_search_pipe(self, *args, **kwargs) -> Any: if self.config.kg.provider is None: return None - from r2r_core.pipes import KGSearchSearchPipe + from core.pipes import KGSearchSearchPipe return KGSearchSearchPipe( kg_provider=self.providers.kg, @@ -442,14 +442,14 @@ def create_kg_search_pipe(self, *args, **kwargs) -> Any: def create_rag_pipe(self, stream: bool = False, *args, **kwargs) -> Any: if stream: - from r2r_core.pipes import StreamingSearchRAGPipe + from core.pipes import StreamingSearchRAGPipe return StreamingSearchRAGPipe( llm_provider=self.providers.llm, prompt_provider=self.providers.prompt, ) else: - from r2r_core.pipes import SearchRAGPipe + from core.pipes import SearchRAGPipe return SearchRAGPipe( llm_provider=self.providers.llm, @@ -457,7 +457,7 @@ def create_rag_pipe(self, stream: bool = False, *args, **kwargs) -> Any: ) def create_kg_node_extraction_pipe(self, *args, **kwargs) -> Any: - from r2r_core.pipes import KGNodeExtractionPipe + from core.pipes import KGNodeExtractionPipe return KGNodeExtractionPipe( kg_provider=self.providers.kg, @@ -466,7 +466,7 @@ def create_kg_node_extraction_pipe(self, *args, **kwargs) -> Any: ) def create_kg_node_description_pipe(self, *args, **kwargs) -> Any: - from r2r_core.pipes import KGNodeDescriptionPipe + from core.pipes import KGNodeDescriptionPipe return KGNodeDescriptionPipe( kg_provider=self.providers.kg, @@ -476,7 +476,7 @@ def create_kg_node_description_pipe(self, *args, **kwargs) -> Any: ) def create_kg_clustering_pipe(self, *args, **kwargs) -> Any: - from r2r_core.pipes import KGClusteringPipe + from core.pipes import KGClusteringPipe return KGClusteringPipe( kg_provider=self.providers.kg, diff --git a/r2r_core/main/assembly/factory_extensions.py b/py/core/main/assembly/factory_extensions.py similarity index 95% rename from r2r_core/main/assembly/factory_extensions.py rename to py/core/main/assembly/factory_extensions.py index 755a1897c..51e17fc55 100644 --- a/r2r_core/main/assembly/factory_extensions.py +++ b/py/core/main/assembly/factory_extensions.py @@ -1,5 +1,5 @@ -from r2r_core.pipes.retrieval.multi_search import MultiSearchPipe -from r2r_core.pipes.retrieval.query_transform_pipe import QueryTransformPipe +from core.pipes.retrieval.multi_search import MultiSearchPipe +from core.pipes.retrieval.query_transform_pipe import QueryTransformPipe from .factory import R2RPipeFactory diff --git a/r2r_core/main/engine.py b/py/core/main/engine.py similarity index 98% rename from r2r_core/main/engine.py rename to py/core/main/engine.py index 008bb622e..3fbb6f1e0 100644 --- a/r2r_core/main/engine.py +++ b/py/core/main/engine.py @@ -1,7 +1,7 @@ from typing import TYPE_CHECKING, Optional -from r2r_core.base import RunLoggingSingleton, RunManager -from r2r_core.base.abstractions.base import AsyncSyncMeta, syncable +from core.base import RunLoggingSingleton, RunManager +from core.base.abstractions.base import AsyncSyncMeta, syncable from .abstractions import R2RAgents, R2RPipelines, R2RProviders from .services.auth_service import AuthService diff --git a/r2r_core/main/execution.py b/py/core/main/execution.py similarity index 98% rename from r2r_core/main/execution.py rename to py/core/main/execution.py index 412adea27..78915de75 100644 --- a/r2r_core/main/execution.py +++ b/py/core/main/execution.py @@ -8,18 +8,15 @@ from uuid import UUID import click -from fastapi import UploadFile - -from r2r_core.base import ( +from core.base import ( AnalysisTypes, GenerationConfig, KGSearchSettings, LogFilterCriteria, VectorSearchSettings, ) - -# TODO: need to import this from the package, not from the local directory -from r2r_python_sdk.r2r.client import R2RClient +from fastapi import UploadFile +from sdk.client import R2RClient from .assembly.builder import R2RBuilder from .assembly.config import R2RConfig @@ -431,7 +428,7 @@ def analytics( ) def ingest_sample_file(self, no_media: bool = True, option: int = 0): - from r2r_core.examples.scripts.sample_data_ingestor import ( + from core.examples.scripts.sample_data_ingestor import ( SampleDataIngestor, ) @@ -442,7 +439,7 @@ def ingest_sample_file(self, no_media: bool = True, option: int = 0): ) def ingest_sample_files(self, no_media: bool = True): - from r2r_core.examples.scripts.sample_data_ingestor import ( + from core.examples.scripts.sample_data_ingestor import ( SampleDataIngestor, ) diff --git a/r2r_core/main/r2r.py b/py/core/main/r2r.py similarity index 100% rename from r2r_core/main/r2r.py rename to py/core/main/r2r.py diff --git a/r2r_core/main/services/__init__.py b/py/core/main/services/__init__.py similarity index 100% rename from r2r_core/main/services/__init__.py rename to py/core/main/services/__init__.py diff --git a/r2r_core/main/services/auth_service.py b/py/core/main/services/auth_service.py similarity index 96% rename from r2r_core/main/services/auth_service.py rename to py/core/main/services/auth_service.py index 484c37608..5fd0fb9d7 100644 --- a/r2r_core/main/services/auth_service.py +++ b/py/core/main/services/auth_service.py @@ -2,9 +2,9 @@ from typing import Optional from uuid import UUID -from r2r_core.base import R2RException, RunLoggingSingleton, RunManager, Token -from r2r_core.base.api.models.auth.responses import UserResponse -from r2r_core.telemetry.telemetry_decorator import telemetry_event +from core.base import R2RException, RunLoggingSingleton, RunManager, Token +from core.base.api.models.auth.responses import UserResponse +from core.telemetry.telemetry_decorator import telemetry_event from ..abstractions import R2RAgents, R2RPipelines, R2RProviders from ..assembly.config import R2RConfig diff --git a/r2r_core/main/services/base.py b/py/core/main/services/base.py similarity index 91% rename from r2r_core/main/services/base.py rename to py/core/main/services/base.py index 3392cd2e0..26bb1fc41 100644 --- a/r2r_core/main/services/base.py +++ b/py/core/main/services/base.py @@ -1,6 +1,6 @@ from abc import ABC -from r2r_core.base import RunLoggingSingleton, RunManager +from core.base import RunLoggingSingleton, RunManager from ..abstractions import R2RAgents, R2RPipelines, R2RProviders from ..assembly.config import R2RConfig diff --git a/r2r_core/main/services/ingestion_service.py b/py/core/main/services/ingestion_service.py similarity index 98% rename from r2r_core/main/services/ingestion_service.py rename to py/core/main/services/ingestion_service.py index 30defa28f..85d64b747 100644 --- a/r2r_core/main/services/ingestion_service.py +++ b/py/core/main/services/ingestion_service.py @@ -4,9 +4,7 @@ from typing import Any, Optional from uuid import UUID -from fastapi import UploadFile - -from r2r_core.base import ( +from core.base import ( Document, DocumentInfo, DocumentType, @@ -18,9 +16,10 @@ increment_version, to_async_generator, ) -from r2r_core.base.api.models import IngestionResponse -from r2r_core.base.providers import ChunkingProvider -from r2r_core.telemetry.telemetry_decorator import telemetry_event +from core.base.api.models import IngestionResponse +from core.base.providers import ChunkingProvider +from core.telemetry.telemetry_decorator import telemetry_event +from fastapi import UploadFile from ...base.api.models.auth.responses import UserResponse from ..abstractions import R2RAgents, R2RPipelines, R2RProviders diff --git a/r2r_core/main/services/management_service.py b/py/core/main/services/management_service.py similarity index 99% rename from r2r_core/main/services/management_service.py rename to py/core/main/services/management_service.py index 78efb01e0..b6bd18811 100644 --- a/r2r_core/main/services/management_service.py +++ b/py/core/main/services/management_service.py @@ -6,8 +6,7 @@ from uuid import UUID import toml - -from r2r_core.base import ( +from core.base import ( AnalysisTypes, LogFilterCriteria, LogProcessor, @@ -15,7 +14,7 @@ RunLoggingSingleton, RunManager, ) -from r2r_core.telemetry.telemetry_decorator import telemetry_event +from core.telemetry.telemetry_decorator import telemetry_event from ..abstractions import R2RAgents, R2RPipelines, R2RProviders from ..assembly.config import R2RConfig diff --git a/r2r_core/main/services/restructure_service.py b/py/core/main/services/restructure_service.py similarity index 94% rename from r2r_core/main/services/restructure_service.py rename to py/core/main/services/restructure_service.py index 6667092dd..99341d0fe 100644 --- a/r2r_core/main/services/restructure_service.py +++ b/py/core/main/services/restructure_service.py @@ -1,7 +1,7 @@ import logging from typing import Any, Dict, List -from r2r_core.base import R2RException, RunLoggingSingleton, RunManager +from core.base import R2RException, RunLoggingSingleton, RunManager from ..abstractions import R2RAgents, R2RPipelines, R2RProviders from ..assembly.config import R2RConfig diff --git a/r2r_core/main/services/retrieval_service.py b/py/core/main/services/retrieval_service.py similarity index 98% rename from r2r_core/main/services/retrieval_service.py rename to py/core/main/services/retrieval_service.py index 7138af38c..c299f17e1 100644 --- a/r2r_core/main/services/retrieval_service.py +++ b/py/core/main/services/retrieval_service.py @@ -4,7 +4,7 @@ from typing import Optional from uuid import UUID -from r2r_core.base import ( +from core.base import ( CompletionRecord, GenerationConfig, KGSearchSettings, @@ -18,9 +18,9 @@ manage_run, to_async_generator, ) -from r2r_core.base.api.models import RAGResponse, SearchResponse -from r2r_core.base.api.models.auth.responses import UserResponse -from r2r_core.telemetry.telemetry_decorator import telemetry_event +from core.base.api.models import RAGResponse, SearchResponse +from core.base.api.models.auth.responses import UserResponse +from core.telemetry.telemetry_decorator import telemetry_event from ..abstractions import R2RAgents, R2RPipelines, R2RProviders from ..assembly.config import R2RConfig diff --git a/r2r_core/parsers/__init__.py b/py/core/parsers/__init__.py similarity index 100% rename from r2r_core/parsers/__init__.py rename to py/core/parsers/__init__.py diff --git a/r2r_core/parsers/media/__init__.py b/py/core/parsers/media/__init__.py similarity index 100% rename from r2r_core/parsers/media/__init__.py rename to py/core/parsers/media/__init__.py diff --git a/r2r_core/parsers/media/audio_parser.py b/py/core/parsers/media/audio_parser.py similarity index 88% rename from r2r_core/parsers/media/audio_parser.py rename to py/core/parsers/media/audio_parser.py index adc4ccb63..000857b99 100644 --- a/r2r_core/parsers/media/audio_parser.py +++ b/py/core/parsers/media/audio_parser.py @@ -1,8 +1,8 @@ import os from typing import AsyncGenerator -from r2r_core.base.parsers.base_parser import AsyncParser -from r2r_core.parsers.media.openai_helpers import process_audio_with_openai +from core.base.parsers.base_parser import AsyncParser +from core.parsers.media.openai_helpers import process_audio_with_openai class AudioParser(AsyncParser[bytes]): diff --git a/r2r_core/parsers/media/docx_parser.py b/py/core/parsers/media/docx_parser.py similarity index 87% rename from r2r_core/parsers/media/docx_parser.py rename to py/core/parsers/media/docx_parser.py index 0f555fbcd..5993328a0 100644 --- a/r2r_core/parsers/media/docx_parser.py +++ b/py/core/parsers/media/docx_parser.py @@ -1,8 +1,8 @@ from io import BytesIO from typing import AsyncGenerator -from r2r_core.base.abstractions.document import DataType -from r2r_core.base.parsers.base_parser import AsyncParser +from core.base.abstractions.document import DataType +from core.base.parsers.base_parser import AsyncParser class DOCXParser(AsyncParser[DataType]): diff --git a/r2r_core/parsers/media/img_parser.py b/py/core/parsers/media/img_parser.py similarity index 85% rename from r2r_core/parsers/media/img_parser.py rename to py/core/parsers/media/img_parser.py index fb6519501..67cc80e8e 100644 --- a/r2r_core/parsers/media/img_parser.py +++ b/py/core/parsers/media/img_parser.py @@ -1,9 +1,9 @@ import os from typing import AsyncGenerator -from r2r_core.base.abstractions.document import DataType -from r2r_core.base.parsers.base_parser import AsyncParser -from r2r_core.parsers.media.openai_helpers import process_frame_with_openai +from core.base.abstractions.document import DataType +from core.base.parsers.base_parser import AsyncParser +from core.parsers.media.openai_helpers import process_frame_with_openai class ImageParser(AsyncParser[DataType]): diff --git a/r2r_core/parsers/media/movie_parser.py b/py/core/parsers/media/movie_parser.py similarity index 97% rename from r2r_core/parsers/media/movie_parser.py rename to py/core/parsers/media/movie_parser.py index 1ff73d5ba..ddf3aa7bf 100644 --- a/r2r_core/parsers/media/movie_parser.py +++ b/py/core/parsers/media/movie_parser.py @@ -2,8 +2,8 @@ import os from typing import AsyncGenerator -from r2r_core.base.parsers.base_parser import AsyncParser -from r2r_core.parsers.media.openai_helpers import ( +from core.base.parsers.base_parser import AsyncParser +from core.parsers.media.openai_helpers import ( process_audio_with_openai, process_frame_with_openai, ) diff --git a/r2r_core/parsers/media/openai_helpers.py b/py/core/parsers/media/openai_helpers.py similarity index 100% rename from r2r_core/parsers/media/openai_helpers.py rename to py/core/parsers/media/openai_helpers.py diff --git a/r2r_core/parsers/media/pdf_parser.py b/py/core/parsers/media/pdf_parser.py similarity index 98% rename from r2r_core/parsers/media/pdf_parser.py rename to py/core/parsers/media/pdf_parser.py index 5f9e4c0a8..bbf0dd53d 100644 --- a/r2r_core/parsers/media/pdf_parser.py +++ b/py/core/parsers/media/pdf_parser.py @@ -5,8 +5,8 @@ from io import BytesIO from typing import AsyncGenerator -from r2r_core.base.abstractions.document import DataType -from r2r_core.base.parsers.base_parser import AsyncParser +from core.base.abstractions.document import DataType +from core.base.parsers.base_parser import AsyncParser logger = logging.getLogger(__name__) diff --git a/r2r_core/parsers/media/ppt_parser.py b/py/core/parsers/media/ppt_parser.py similarity index 88% rename from r2r_core/parsers/media/ppt_parser.py rename to py/core/parsers/media/ppt_parser.py index 3ad4d28a6..8ebf130f3 100644 --- a/r2r_core/parsers/media/ppt_parser.py +++ b/py/core/parsers/media/ppt_parser.py @@ -1,8 +1,8 @@ from io import BytesIO from typing import AsyncGenerator -from r2r_core.base.abstractions.document import DataType -from r2r_core.base.parsers.base_parser import AsyncParser +from core.base.abstractions.document import DataType +from core.base.parsers.base_parser import AsyncParser class PPTParser(AsyncParser[DataType]): diff --git a/r2r_core/parsers/structured/__init__.py b/py/core/parsers/structured/__init__.py similarity index 100% rename from r2r_core/parsers/structured/__init__.py rename to py/core/parsers/structured/__init__.py diff --git a/r2r_core/parsers/structured/csv_parser.py b/py/core/parsers/structured/csv_parser.py similarity index 95% rename from r2r_core/parsers/structured/csv_parser.py rename to py/core/parsers/structured/csv_parser.py index 1f26fc2c1..cc58c52a5 100644 --- a/r2r_core/parsers/structured/csv_parser.py +++ b/py/core/parsers/structured/csv_parser.py @@ -1,7 +1,7 @@ from typing import IO, AsyncGenerator, Union -from r2r_core.base.abstractions.document import DataType -from r2r_core.base.parsers.base_parser import AsyncParser +from core.base.abstractions.document import DataType +from core.base.parsers.base_parser import AsyncParser class CSVParser(AsyncParser[DataType]): diff --git a/r2r_core/parsers/structured/json_parser.py b/py/core/parsers/structured/json_parser.py similarity index 93% rename from r2r_core/parsers/structured/json_parser.py rename to py/core/parsers/structured/json_parser.py index 3dcaf96df..9ade198dd 100644 --- a/r2r_core/parsers/structured/json_parser.py +++ b/py/core/parsers/structured/json_parser.py @@ -1,8 +1,8 @@ import json from typing import AsyncGenerator -from r2r_core.base.abstractions.document import DataType -from r2r_core.base.parsers.base_parser import AsyncParser +from core.base.abstractions.document import DataType +from core.base.parsers.base_parser import AsyncParser class JSONParser(AsyncParser[DataType]): diff --git a/r2r_core/parsers/structured/xlsx_parser.py b/py/core/parsers/structured/xlsx_parser.py similarity index 96% rename from r2r_core/parsers/structured/xlsx_parser.py rename to py/core/parsers/structured/xlsx_parser.py index b7050518b..a95d9d66d 100644 --- a/r2r_core/parsers/structured/xlsx_parser.py +++ b/py/core/parsers/structured/xlsx_parser.py @@ -1,8 +1,8 @@ from io import BytesIO from typing import AsyncGenerator -from r2r_core.base.abstractions.document import DataType -from r2r_core.base.parsers.base_parser import AsyncParser +from core.base.abstractions.document import DataType +from core.base.parsers.base_parser import AsyncParser class XLSXParser(AsyncParser[DataType]): diff --git a/r2r_core/parsers/text/__init__.py b/py/core/parsers/text/__init__.py similarity index 100% rename from r2r_core/parsers/text/__init__.py rename to py/core/parsers/text/__init__.py diff --git a/r2r_core/parsers/text/html_parser.py b/py/core/parsers/text/html_parser.py similarity index 74% rename from r2r_core/parsers/text/html_parser.py rename to py/core/parsers/text/html_parser.py index 6fbeab7cd..6d87f38f2 100644 --- a/r2r_core/parsers/text/html_parser.py +++ b/py/core/parsers/text/html_parser.py @@ -1,9 +1,8 @@ from typing import AsyncGenerator from bs4 import BeautifulSoup - -from r2r_core.base.abstractions.document import DataType -from r2r_core.base.parsers.base_parser import AsyncParser +from core.base.abstractions.document import DataType +from core.base.parsers.base_parser import AsyncParser class HTMLParser(AsyncParser[DataType]): diff --git a/r2r_core/parsers/text/md_parser.py b/py/core/parsers/text/md_parser.py similarity index 82% rename from r2r_core/parsers/text/md_parser.py rename to py/core/parsers/text/md_parser.py index f74fff2e1..515dba3f1 100644 --- a/r2r_core/parsers/text/md_parser.py +++ b/py/core/parsers/text/md_parser.py @@ -1,9 +1,8 @@ from typing import AsyncGenerator from bs4 import BeautifulSoup - -from r2r_core.base.abstractions.document import DataType -from r2r_core.base.parsers.base_parser import AsyncParser +from core.base.abstractions.document import DataType +from core.base.parsers.base_parser import AsyncParser class MDParser(AsyncParser[DataType]): diff --git a/r2r_core/parsers/text/text_parser.py b/py/core/parsers/text/text_parser.py similarity index 71% rename from r2r_core/parsers/text/text_parser.py rename to py/core/parsers/text/text_parser.py index 269320946..7dbe9ac10 100644 --- a/r2r_core/parsers/text/text_parser.py +++ b/py/core/parsers/text/text_parser.py @@ -1,7 +1,7 @@ from typing import AsyncGenerator -from r2r_core.base.abstractions.document import DataType -from r2r_core.base.parsers.base_parser import AsyncParser +from core.base.abstractions.document import DataType +from core.base.parsers.base_parser import AsyncParser class TextParser(AsyncParser[DataType]): diff --git a/r2r_core/pipelines/__init__.py b/py/core/pipelines/__init__.py similarity index 100% rename from r2r_core/pipelines/__init__.py rename to py/core/pipelines/__init__.py diff --git a/r2r_core/pipelines/graph_enrichment.py b/py/core/pipelines/graph_enrichment.py similarity index 100% rename from r2r_core/pipelines/graph_enrichment.py rename to py/core/pipelines/graph_enrichment.py diff --git a/r2r_core/pipelines/ingestion_pipeline.py b/py/core/pipelines/ingestion_pipeline.py similarity index 92% rename from r2r_core/pipelines/ingestion_pipeline.py rename to py/core/pipelines/ingestion_pipeline.py index 6949a40bb..006ca309c 100644 --- a/r2r_core/pipelines/ingestion_pipeline.py +++ b/py/core/pipelines/ingestion_pipeline.py @@ -3,15 +3,12 @@ from asyncio import Queue from typing import Any, Optional -from r2r_core.base.api.models.auth.responses import UserResponse -from r2r_core.base.logging.run_logger import RunLoggingSingleton -from r2r_core.base.logging.run_manager import RunManager, manage_run -from r2r_core.base.pipeline.base_pipeline import ( - AsyncPipeline, - dequeue_requests, -) -from r2r_core.base.pipes.base_pipe import AsyncPipe, AsyncState -from r2r_core.base.providers.chunking import ChunkingProvider +from core.base.api.models.auth.responses import UserResponse +from core.base.logging.run_logger import RunLoggingSingleton +from core.base.logging.run_manager import RunManager, manage_run +from core.base.pipeline.base_pipeline import AsyncPipeline, dequeue_requests +from core.base.pipes.base_pipe import AsyncPipe, AsyncState +from core.base.providers.chunking import ChunkingProvider logger = logging.getLogger(__name__) diff --git a/r2r_core/pipelines/rag_pipeline.py b/py/core/pipelines/rag_pipeline.py similarity index 100% rename from r2r_core/pipelines/rag_pipeline.py rename to py/core/pipelines/rag_pipeline.py diff --git a/r2r_core/pipelines/search_pipeline.py b/py/core/pipelines/search_pipeline.py similarity index 100% rename from r2r_core/pipelines/search_pipeline.py rename to py/core/pipelines/search_pipeline.py diff --git a/r2r_core/pipes/__init__.py b/py/core/pipes/__init__.py similarity index 100% rename from r2r_core/pipes/__init__.py rename to py/core/pipes/__init__.py diff --git a/r2r_core/pipes/abstractions/__init__.py b/py/core/pipes/abstractions/__init__.py similarity index 100% rename from r2r_core/pipes/abstractions/__init__.py rename to py/core/pipes/abstractions/__init__.py diff --git a/r2r_core/pipes/abstractions/generator_pipe.py b/py/core/pipes/abstractions/generator_pipe.py similarity index 89% rename from r2r_core/pipes/abstractions/generator_pipe.py rename to py/core/pipes/abstractions/generator_pipe.py index d72777c2e..edc230dc0 100644 --- a/r2r_core/pipes/abstractions/generator_pipe.py +++ b/py/core/pipes/abstractions/generator_pipe.py @@ -2,15 +2,15 @@ from typing import Any, AsyncGenerator, Optional from uuid import UUID -from r2r_core.base import ( +from core.base import ( AsyncState, CompletionProvider, PipeType, PromptProvider, RunLoggingSingleton, ) -from r2r_core.base.abstractions.llm import GenerationConfig -from r2r_core.base.pipes.base_pipe import AsyncPipe +from core.base.abstractions.llm import GenerationConfig +from core.base.pipes.base_pipe import AsyncPipe class GeneratorPipe(AsyncPipe): diff --git a/r2r_core/pipes/abstractions/search_pipe.py b/py/core/pipes/abstractions/search_pipe.py similarity index 98% rename from r2r_core/pipes/abstractions/search_pipe.py rename to py/core/pipes/abstractions/search_pipe.py index e533cb92d..905a737b3 100644 --- a/r2r_core/pipes/abstractions/search_pipe.py +++ b/py/core/pipes/abstractions/search_pipe.py @@ -3,7 +3,7 @@ from typing import Any, AsyncGenerator, Optional, Union from uuid import UUID -from r2r_core.base import ( +from core.base import ( AsyncPipe, AsyncState, PipeType, diff --git a/r2r_core/pipes/ingestion/__init__.py b/py/core/pipes/ingestion/__init__.py similarity index 100% rename from r2r_core/pipes/ingestion/__init__.py rename to py/core/pipes/ingestion/__init__.py diff --git a/r2r_core/pipes/ingestion/chunking_pipe.py b/py/core/pipes/ingestion/chunking_pipe.py similarity index 94% rename from r2r_core/pipes/ingestion/chunking_pipe.py rename to py/core/pipes/ingestion/chunking_pipe.py index 04ce83a05..e95ba350e 100644 --- a/r2r_core/pipes/ingestion/chunking_pipe.py +++ b/py/core/pipes/ingestion/chunking_pipe.py @@ -1,6 +1,6 @@ from typing import Any, AsyncGenerator, Optional, Union -from r2r_core.base import ( +from core.base import ( AsyncState, ChunkingConfig, ChunkingProvider, @@ -11,8 +11,8 @@ RunLoggingSingleton, generate_id_from_label, ) -from r2r_core.base.pipes.base_pipe import AsyncPipe -from r2r_core.providers import R2RChunkingProvider +from core.base.pipes.base_pipe import AsyncPipe +from core.providers import R2RChunkingProvider class ChunkingPipe(AsyncPipe): diff --git a/r2r_core/pipes/ingestion/embedding_pipe.py b/py/core/pipes/ingestion/embedding_pipe.py similarity index 98% rename from r2r_core/pipes/ingestion/embedding_pipe.py rename to py/core/pipes/ingestion/embedding_pipe.py index e702b933f..243913312 100644 --- a/r2r_core/pipes/ingestion/embedding_pipe.py +++ b/py/core/pipes/ingestion/embedding_pipe.py @@ -2,7 +2,7 @@ import logging from typing import Any, AsyncGenerator, Optional, Union -from r2r_core.base import ( +from core.base import ( AsyncState, DocumentFragment, EmbeddingProvider, @@ -12,7 +12,7 @@ Vector, VectorEntry, ) -from r2r_core.base.pipes.base_pipe import AsyncPipe +from core.base.pipes.base_pipe import AsyncPipe logger = logging.getLogger(__name__) diff --git a/r2r_core/pipes/ingestion/kg_extraction_pipe.py b/py/core/pipes/ingestion/kg_extraction_pipe.py similarity index 97% rename from r2r_core/pipes/ingestion/kg_extraction_pipe.py rename to py/core/pipes/ingestion/kg_extraction_pipe.py index 504c0d03d..18030be78 100644 --- a/r2r_core/pipes/ingestion/kg_extraction_pipe.py +++ b/py/core/pipes/ingestion/kg_extraction_pipe.py @@ -3,7 +3,7 @@ import logging from typing import Any, AsyncGenerator, Optional, Union -from r2r_core.base import ( +from core.base import ( AsyncState, ChunkingProvider, CompletionProvider, @@ -14,12 +14,12 @@ R2RDocumentProcessingError, RunLoggingSingleton, ) -from r2r_core.base.abstractions.graph import ( +from core.base.abstractions.graph import ( KGExtraction, extract_entities, extract_triples, ) -from r2r_core.base.pipes.base_pipe import AsyncPipe +from core.base.pipes.base_pipe import AsyncPipe logger = logging.getLogger(__name__) diff --git a/r2r_core/pipes/ingestion/parsing_pipe.py b/py/core/pipes/ingestion/parsing_pipe.py similarity index 93% rename from r2r_core/pipes/ingestion/parsing_pipe.py rename to py/core/pipes/ingestion/parsing_pipe.py index 28bb997d9..9b4bdebff 100644 --- a/r2r_core/pipes/ingestion/parsing_pipe.py +++ b/py/core/pipes/ingestion/parsing_pipe.py @@ -6,7 +6,7 @@ from typing import AsyncGenerator, Optional, Union from uuid import UUID -from r2r_core.base import ( +from core.base import ( AsyncState, Document, DocumentExtraction, @@ -15,8 +15,8 @@ RunLoggingSingleton, generate_id_from_label, ) -from r2r_core.base.abstractions.exception import R2RDocumentProcessingError -from r2r_core.base.pipes.base_pipe import AsyncPipe +from core.base.abstractions.exception import R2RDocumentProcessingError +from core.base.pipes.base_pipe import AsyncPipe logger = logging.getLogger(__name__) diff --git a/r2r_core/pipes/ingestion/vector_storage_pipe.py b/py/core/pipes/ingestion/vector_storage_pipe.py similarity index 95% rename from r2r_core/pipes/ingestion/vector_storage_pipe.py rename to py/core/pipes/ingestion/vector_storage_pipe.py index ab55117dc..ccb1e71bf 100644 --- a/r2r_core/pipes/ingestion/vector_storage_pipe.py +++ b/py/core/pipes/ingestion/vector_storage_pipe.py @@ -3,15 +3,15 @@ from typing import Any, AsyncGenerator, Optional, Tuple, Union from uuid import UUID -from r2r_core.base import ( +from core.base import ( AsyncState, DatabaseProvider, PipeType, RunLoggingSingleton, VectorEntry, ) -from r2r_core.base.abstractions.exception import R2RDocumentProcessingError -from r2r_core.base.pipes.base_pipe import AsyncPipe +from core.base.abstractions.exception import R2RDocumentProcessingError +from core.base.pipes.base_pipe import AsyncPipe logger = logging.getLogger(__name__) diff --git a/r2r_core/pipes/kg/clustering.py b/py/core/pipes/kg/clustering.py similarity index 99% rename from r2r_core/pipes/kg/clustering.py rename to py/core/pipes/kg/clustering.py index e6c7c0c9b..a31411f00 100644 --- a/r2r_core/pipes/kg/clustering.py +++ b/py/core/pipes/kg/clustering.py @@ -10,9 +10,7 @@ from uuid import UUID import networkx as nx -from graspologic.partition import hierarchical_leiden - -from r2r_core.base import ( +from core.base import ( AsyncPipe, AsyncState, Community, @@ -25,6 +23,7 @@ RunLoggingSingleton, Triple, ) +from graspologic.partition import hierarchical_leiden logger = logging.getLogger(__name__) diff --git a/r2r_core/pipes/kg/extraction.py b/py/core/pipes/kg/extraction.py similarity index 98% rename from r2r_core/pipes/kg/extraction.py rename to py/core/pipes/kg/extraction.py index 4d9d0f3ab..9edd708b0 100644 --- a/r2r_core/pipes/kg/extraction.py +++ b/py/core/pipes/kg/extraction.py @@ -5,7 +5,7 @@ import uuid from typing import Any, AsyncGenerator, Optional, Union -from r2r_core.base import ( +from core.base import ( AsyncState, ChunkingProvider, CompletionProvider, @@ -20,7 +20,7 @@ RunLoggingSingleton, Triple, ) -from r2r_core.base.pipes.base_pipe import AsyncPipe +from core.base.pipes.base_pipe import AsyncPipe logger = logging.getLogger(__name__) diff --git a/r2r_core/pipes/kg/node_extraction.py b/py/core/pipes/kg/node_extraction.py similarity index 97% rename from r2r_core/pipes/kg/node_extraction.py rename to py/core/pipes/kg/node_extraction.py index 0078a68b8..b55cb4ce4 100644 --- a/r2r_core/pipes/kg/node_extraction.py +++ b/py/core/pipes/kg/node_extraction.py @@ -5,7 +5,7 @@ from typing import Any, AsyncGenerator, Optional from uuid import UUID -from r2r_core.base import ( +from core.base import ( AsyncState, CompletionProvider, EmbeddingProvider, @@ -14,9 +14,9 @@ PromptProvider, RunLoggingSingleton, ) -from r2r_core.base.abstractions.graph import Entity, Triple -from r2r_core.base.pipes.base_pipe import AsyncPipe -from r2r_core.base.providers.llm import GenerationConfig +from core.base.abstractions.graph import Entity, Triple +from core.base.pipes.base_pipe import AsyncPipe +from core.base.providers.llm import GenerationConfig logger = logging.getLogger(__name__) diff --git a/r2r_core/pipes/kg/storage.py b/py/core/pipes/kg/storage.py similarity index 95% rename from r2r_core/pipes/kg/storage.py rename to py/core/pipes/kg/storage.py index 635a47d73..ae6754609 100644 --- a/r2r_core/pipes/kg/storage.py +++ b/py/core/pipes/kg/storage.py @@ -3,15 +3,15 @@ from typing import Any, AsyncGenerator, Optional from uuid import UUID -from r2r_core.base import ( +from core.base import ( AsyncState, EmbeddingProvider, KGExtraction, PipeType, RunLoggingSingleton, ) -from r2r_core.base.pipes.base_pipe import AsyncPipe -from r2r_core.base.providers import KGProvider +from core.base.pipes.base_pipe import AsyncPipe +from core.base.providers import KGProvider logger = logging.getLogger(__name__) diff --git a/r2r_core/pipes/other/web_search_pipe.py b/py/core/pipes/other/web_search_pipe.py similarity index 97% rename from r2r_core/pipes/other/web_search_pipe.py rename to py/core/pipes/other/web_search_pipe.py index f51eafa5e..0c0e39178 100644 --- a/r2r_core/pipes/other/web_search_pipe.py +++ b/py/core/pipes/other/web_search_pipe.py @@ -3,14 +3,14 @@ from typing import Any, AsyncGenerator, Optional from uuid import UUID -from r2r_core.base import ( +from core.base import ( AsyncPipe, AsyncState, PipeType, VectorSearchResult, generate_id_from_label, ) -from r2r_core.integrations import SerperClient +from core.integrations import SerperClient from ..abstractions.search_pipe import SearchPipe diff --git a/r2r_core/pipes/retrieval/kg_search_search_pipe.py b/py/core/pipes/retrieval/kg_search_search_pipe.py similarity index 99% rename from r2r_core/pipes/retrieval/kg_search_search_pipe.py rename to py/core/pipes/retrieval/kg_search_search_pipe.py index 9435651dc..16c26d2c1 100644 --- a/r2r_core/pipes/retrieval/kg_search_search_pipe.py +++ b/py/core/pipes/retrieval/kg_search_search_pipe.py @@ -4,7 +4,7 @@ from typing import Any, Optional from uuid import UUID -from r2r_core.base import ( +from core.base import ( AsyncState, CompletionProvider, EmbeddingProvider, diff --git a/r2r_core/pipes/retrieval/multi_search.py b/py/core/pipes/retrieval/multi_search.py similarity index 93% rename from r2r_core/pipes/retrieval/multi_search.py rename to py/core/pipes/retrieval/multi_search.py index ff29e3461..b7a510966 100644 --- a/r2r_core/pipes/retrieval/multi_search.py +++ b/py/core/pipes/retrieval/multi_search.py @@ -2,9 +2,9 @@ from typing import Any, AsyncGenerator, Optional from uuid import UUID -from r2r_core.base.abstractions.llm import GenerationConfig -from r2r_core.base.abstractions.search import VectorSearchResult -from r2r_core.base.pipes.base_pipe import AsyncPipe +from core.base.abstractions.llm import GenerationConfig +from core.base.abstractions.search import VectorSearchResult +from core.base.pipes.base_pipe import AsyncPipe from ..abstractions.search_pipe import SearchPipe from .query_transform_pipe import QueryTransformPipe diff --git a/r2r_core/pipes/retrieval/query_transform_pipe.py b/py/core/pipes/retrieval/query_transform_pipe.py similarity index 96% rename from r2r_core/pipes/retrieval/query_transform_pipe.py rename to py/core/pipes/retrieval/query_transform_pipe.py index 2d2a4a2f5..16dbadccb 100644 --- a/r2r_core/pipes/retrieval/query_transform_pipe.py +++ b/py/core/pipes/retrieval/query_transform_pipe.py @@ -2,14 +2,14 @@ from typing import Any, AsyncGenerator, Optional from uuid import UUID -from r2r_core.base import ( +from core.base import ( AsyncPipe, AsyncState, CompletionProvider, PipeType, PromptProvider, ) -from r2r_core.base.abstractions.llm import GenerationConfig +from core.base.abstractions.llm import GenerationConfig from ..abstractions.generator_pipe import GeneratorPipe diff --git a/r2r_core/pipes/retrieval/search_rag_pipe.py b/py/core/pipes/retrieval/search_rag_pipe.py similarity index 97% rename from r2r_core/pipes/retrieval/search_rag_pipe.py rename to py/core/pipes/retrieval/search_rag_pipe.py index 031f49ba0..562a7e2ae 100644 --- a/r2r_core/pipes/retrieval/search_rag_pipe.py +++ b/py/core/pipes/retrieval/search_rag_pipe.py @@ -1,6 +1,6 @@ from typing import Any, AsyncGenerator, Optional, Tuple -from r2r_core.base import ( +from core.base import ( AggregateSearchResult, AsyncPipe, AsyncState, @@ -9,7 +9,7 @@ PipeType, PromptProvider, ) -from r2r_core.base.abstractions.llm import GenerationConfig, RAGCompletion +from core.base.abstractions.llm import GenerationConfig, RAGCompletion from ..abstractions.generator_pipe import GeneratorPipe diff --git a/r2r_core/pipes/retrieval/streaming_rag_pipe.py b/py/core/pipes/retrieval/streaming_rag_pipe.py similarity index 97% rename from r2r_core/pipes/retrieval/streaming_rag_pipe.py rename to py/core/pipes/retrieval/streaming_rag_pipe.py index a33b2e838..da4ef1d74 100644 --- a/r2r_core/pipes/retrieval/streaming_rag_pipe.py +++ b/py/core/pipes/retrieval/streaming_rag_pipe.py @@ -4,7 +4,7 @@ from typing import Any, AsyncGenerator, Generator, Optional from uuid import UUID -from r2r_core.base import ( +from core.base import ( AsyncState, CompletionProvider, CompletionRecord, @@ -12,7 +12,7 @@ PipeType, PromptProvider, ) -from r2r_core.base.abstractions.llm import GenerationConfig +from core.base.abstractions.llm import GenerationConfig from ..abstractions.generator_pipe import GeneratorPipe from .search_rag_pipe import SearchRAGPipe diff --git a/r2r_core/pipes/retrieval/vector_search_pipe.py b/py/core/pipes/retrieval/vector_search_pipe.py similarity index 99% rename from r2r_core/pipes/retrieval/vector_search_pipe.py rename to py/core/pipes/retrieval/vector_search_pipe.py index e32d622c5..d01317f5f 100644 --- a/r2r_core/pipes/retrieval/vector_search_pipe.py +++ b/py/core/pipes/retrieval/vector_search_pipe.py @@ -3,7 +3,7 @@ from typing import Any, AsyncGenerator, Optional from uuid import UUID -from r2r_core.base import ( +from core.base import ( AsyncPipe, AsyncState, DatabaseProvider, diff --git a/r2r_core/providers/__init__.py b/py/core/providers/__init__.py similarity index 100% rename from r2r_core/providers/__init__.py rename to py/core/providers/__init__.py diff --git a/r2r_core/providers/auth/__init__.py b/py/core/providers/auth/__init__.py similarity index 100% rename from r2r_core/providers/auth/__init__.py rename to py/core/providers/auth/__init__.py diff --git a/r2r_core/providers/auth/r2r_auth.py b/py/core/providers/auth/r2r_auth.py similarity index 99% rename from r2r_core/providers/auth/r2r_auth.py rename to py/core/providers/auth/r2r_auth.py index c68fba95d..cceea2d4c 100644 --- a/r2r_core/providers/auth/r2r_auth.py +++ b/py/core/providers/auth/r2r_auth.py @@ -4,10 +4,7 @@ from typing import Dict import jwt -from fastapi import Depends -from fastapi.security import OAuth2PasswordBearer - -from r2r_core.base import ( +from core.base import ( AuthConfig, AuthProvider, CryptoProvider, @@ -16,7 +13,9 @@ Token, TokenData, ) -from r2r_core.base.api.models.auth.responses import UserResponse +from core.base.api.models.auth.responses import UserResponse +from fastapi import Depends +from fastapi.security import OAuth2PasswordBearer logger = logging.getLogger(__name__) oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") diff --git a/r2r_core/providers/chunking/__init__.py b/py/core/providers/chunking/__init__.py similarity index 100% rename from r2r_core/providers/chunking/__init__.py rename to py/core/providers/chunking/__init__.py diff --git a/r2r_core/providers/chunking/r2r_chunking.py b/py/core/providers/chunking/r2r_chunking.py similarity index 99% rename from r2r_core/providers/chunking/r2r_chunking.py rename to py/core/providers/chunking/r2r_chunking.py index de8dcbb7c..f391c56a2 100644 --- a/r2r_core/providers/chunking/r2r_chunking.py +++ b/py/core/providers/chunking/r2r_chunking.py @@ -1,6 +1,6 @@ from typing import Any, AsyncGenerator -from r2r_core.base import ( +from core.base import ( ChunkingConfig, ChunkingProvider, Method, diff --git a/r2r_core/providers/chunking/unstructured_chunking.py b/py/core/providers/chunking/unstructured_chunking.py similarity index 97% rename from r2r_core/providers/chunking/unstructured_chunking.py rename to py/core/providers/chunking/unstructured_chunking.py index a54f81676..7f0bdf6e3 100644 --- a/r2r_core/providers/chunking/unstructured_chunking.py +++ b/py/core/providers/chunking/unstructured_chunking.py @@ -1,6 +1,6 @@ from typing import AsyncGenerator -from r2r_core.base import ChunkingProvider +from core.base import ChunkingProvider class UnstructuredChunkingProvider(ChunkingProvider): diff --git a/r2r_core/providers/crypto/__init__.py b/py/core/providers/crypto/__init__.py similarity index 100% rename from r2r_core/providers/crypto/__init__.py rename to py/core/providers/crypto/__init__.py diff --git a/r2r_core/providers/crypto/bcrypt.py b/py/core/providers/crypto/bcrypt.py similarity index 96% rename from r2r_core/providers/crypto/bcrypt.py rename to py/core/providers/crypto/bcrypt.py index 7b769b09a..d69559de3 100644 --- a/r2r_core/providers/crypto/bcrypt.py +++ b/py/core/providers/crypto/bcrypt.py @@ -1,7 +1,7 @@ import secrets import string -from r2r_core.base import CryptoConfig, CryptoProvider +from core.base import CryptoConfig, CryptoProvider class BCryptConfig(CryptoConfig): diff --git a/r2r_core/providers/database/__init__.py b/py/core/providers/database/__init__.py similarity index 100% rename from r2r_core/providers/database/__init__.py rename to py/core/providers/database/__init__.py diff --git a/r2r_core/providers/database/base.py b/py/core/providers/database/base.py similarity index 100% rename from r2r_core/providers/database/base.py rename to py/core/providers/database/base.py diff --git a/r2r_core/providers/database/document.py b/py/core/providers/database/document.py similarity index 98% rename from r2r_core/providers/database/document.py rename to py/core/providers/database/document.py index 07b214021..0af205ec3 100644 --- a/r2r_core/providers/database/document.py +++ b/py/core/providers/database/document.py @@ -1,7 +1,7 @@ from typing import Optional from uuid import UUID -from r2r_core.base import DocumentInfo, DocumentStatus, DocumentType +from core.base import DocumentInfo, DocumentStatus, DocumentType from .base import DatabaseMixin diff --git a/r2r_core/providers/database/group.py b/py/core/providers/database/group.py similarity index 98% rename from r2r_core/providers/database/group.py rename to py/core/providers/database/group.py index 5a9247fa1..ab3cb811e 100644 --- a/r2r_core/providers/database/group.py +++ b/py/core/providers/database/group.py @@ -2,14 +2,10 @@ from typing import Optional from uuid import UUID -from r2r_core.base import R2RException -from r2r_core.base.abstractions import ( - DocumentInfo, - DocumentStatus, - DocumentType, -) -from r2r_core.base.api.models.auth.responses import UserResponse -from r2r_core.base.api.models.management.responses import ( +from core.base import R2RException +from core.base.abstractions import DocumentInfo, DocumentStatus, DocumentType +from core.base.api.models.auth.responses import UserResponse +from core.base.api.models.management.responses import ( GroupOverviewResponse, GroupResponse, ) diff --git a/r2r_core/providers/database/postgres.py b/py/core/providers/database/postgres.py similarity index 99% rename from r2r_core/providers/database/postgres.py rename to py/core/providers/database/postgres.py index 96539512e..7fc699422 100644 --- a/r2r_core/providers/database/postgres.py +++ b/py/core/providers/database/postgres.py @@ -2,7 +2,7 @@ import os from typing import Optional -from r2r_core.base import ( +from core.base import ( CryptoProvider, DatabaseConfig, DatabaseProvider, diff --git a/r2r_core/providers/database/relational.py b/py/core/providers/database/relational.py similarity index 80% rename from r2r_core/providers/database/relational.py rename to py/core/providers/database/relational.py index a8ab40e33..04e7c3fef 100644 --- a/r2r_core/providers/database/relational.py +++ b/py/core/providers/database/relational.py @@ -1,13 +1,12 @@ import logging +from core.providers.database.base import DatabaseMixin, execute_query +from core.providers.database.document import DocumentMixin +from core.providers.database.group import GroupMixin +from core.providers.database.tokens import BlacklistedTokensMixin +from core.providers.database.user import UserMixin from sqlalchemy import exc, text -from r2r_core.providers.database.base import DatabaseMixin, execute_query -from r2r_core.providers.database.document import DocumentMixin -from r2r_core.providers.database.group import GroupMixin -from r2r_core.providers.database.tokens import BlacklistedTokensMixin -from r2r_core.providers.database.user import UserMixin - logger = logging.getLogger(__name__) diff --git a/r2r_core/providers/database/tokens.py b/py/core/providers/database/tokens.py similarity index 100% rename from r2r_core/providers/database/tokens.py rename to py/core/providers/database/tokens.py diff --git a/r2r_core/providers/database/user.py b/py/core/providers/database/user.py similarity index 98% rename from r2r_core/providers/database/user.py rename to py/core/providers/database/user.py index 45df73d01..8098d228d 100644 --- a/r2r_core/providers/database/user.py +++ b/py/core/providers/database/user.py @@ -2,12 +2,11 @@ from typing import Optional from uuid import UUID +from core.base.abstractions import R2RException, UserStats +from core.base.api.models.auth.responses import UserResponse +from core.base.utils import generate_id_from_label from sqlalchemy import text -from r2r_core.base.abstractions import R2RException, UserStats -from r2r_core.base.api.models.auth.responses import UserResponse -from r2r_core.base.utils import generate_id_from_label - from .base import DatabaseMixin, QueryBuilder diff --git a/r2r_core/providers/database/vecs/__init__.py b/py/core/providers/database/vecs/__init__.py similarity index 100% rename from r2r_core/providers/database/vecs/__init__.py rename to py/core/providers/database/vecs/__init__.py diff --git a/r2r_core/providers/database/vecs/adapter/__init__.py b/py/core/providers/database/vecs/adapter/__init__.py similarity index 100% rename from r2r_core/providers/database/vecs/adapter/__init__.py rename to py/core/providers/database/vecs/adapter/__init__.py diff --git a/r2r_core/providers/database/vecs/adapter/base.py b/py/core/providers/database/vecs/adapter/base.py similarity index 100% rename from r2r_core/providers/database/vecs/adapter/base.py rename to py/core/providers/database/vecs/adapter/base.py diff --git a/r2r_core/providers/database/vecs/adapter/markdown.py b/py/core/providers/database/vecs/adapter/markdown.py similarity index 100% rename from r2r_core/providers/database/vecs/adapter/markdown.py rename to py/core/providers/database/vecs/adapter/markdown.py diff --git a/r2r_core/providers/database/vecs/adapter/noop.py b/py/core/providers/database/vecs/adapter/noop.py similarity index 100% rename from r2r_core/providers/database/vecs/adapter/noop.py rename to py/core/providers/database/vecs/adapter/noop.py diff --git a/r2r_core/providers/database/vecs/adapter/text.py b/py/core/providers/database/vecs/adapter/text.py similarity index 100% rename from r2r_core/providers/database/vecs/adapter/text.py rename to py/core/providers/database/vecs/adapter/text.py diff --git a/r2r_core/providers/database/vecs/client.py b/py/core/providers/database/vecs/client.py similarity index 95% rename from r2r_core/providers/database/vecs/client.py rename to py/core/providers/database/vecs/client.py index b67a1e83b..50938f576 100644 --- a/r2r_core/providers/database/vecs/client.py +++ b/py/core/providers/database/vecs/client.py @@ -21,7 +21,7 @@ from .exc import CollectionNotFound if TYPE_CHECKING: - from r2r_core.providers.database.vecs.collection import Collection + from core.providers.database.vecs.collection import Collection logger = logging.getLogger(__name__) @@ -168,7 +168,7 @@ def get_or_create_collection( Raises: CollectionAlreadyExists: If a collection with the same name already exists """ - from r2r_core.providers.database.vecs.collection import Collection + from core.providers.database.vecs.collection import Collection adapter_dimension = adapter.exported_dimension if adapter else None @@ -196,7 +196,7 @@ def create_collection(self, name: str, dimension: int) -> Collection: Raises: CollectionAlreadyExists: If a collection with the same name already exists """ - from r2r_core.providers.database.vecs.collection import Collection + from core.providers.database.vecs.collection import Collection return Collection(name, dimension, self)._create() @@ -214,7 +214,7 @@ def get_collection(self, name: str) -> Collection: Raises: CollectionNotFound: If no collection with the given name exists. """ - from r2r_core.providers.database.vecs.collection import Collection + from core.providers.database.vecs.collection import Collection query = text( """ @@ -255,7 +255,7 @@ def list_collections(self) -> List["Collection"]: Returns: list[Collection]: A list of all collections. """ - from r2r_core.providers.database.vecs.collection import Collection + from core.providers.database.vecs.collection import Collection return Collection._list_collections(self) @@ -271,7 +271,7 @@ def delete_collection(self, name: str) -> None: Returns: None """ - from r2r_core.providers.database.vecs.collection import Collection + from core.providers.database.vecs.collection import Collection Collection(name, -1, self)._drop() return diff --git a/r2r_core/providers/database/vecs/collection.py b/py/core/providers/database/vecs/collection.py similarity index 99% rename from r2r_core/providers/database/vecs/collection.py rename to py/core/providers/database/vecs/collection.py index bf8d00f42..e342ad49a 100644 --- a/r2r_core/providers/database/vecs/collection.py +++ b/py/core/providers/database/vecs/collection.py @@ -24,6 +24,7 @@ from uuid import UUID, uuid4 import psycopg2 +from core.base.abstractions import VectorSearchSettings from flupy import flu from sqlalchemy import ( Column, @@ -43,8 +44,6 @@ from sqlalchemy.dialects import postgresql from sqlalchemy.types import Float, UserDefinedType -from r2r_core.base.abstractions import VectorSearchSettings - from .adapter import Adapter, AdapterContext, NoOp, Record from .exc import ( ArgError, @@ -230,7 +229,7 @@ def __init__( dimension (int): The dimension of the vectors in the collection. client (Client): The client to use for interacting with the database. """ - from r2r_core.providers.database.vecs.adapter import Adapter + from core.providers.database.vecs.adapter import Adapter self.client = client self.name = name diff --git a/r2r_core/providers/database/vecs/exc.py b/py/core/providers/database/vecs/exc.py similarity index 100% rename from r2r_core/providers/database/vecs/exc.py rename to py/core/providers/database/vecs/exc.py diff --git a/r2r_core/providers/database/vector.py b/py/core/providers/database/vector.py similarity index 99% rename from r2r_core/providers/database/vector.py rename to py/core/providers/database/vector.py index 754ce6489..0eec9a880 100644 --- a/r2r_core/providers/database/vector.py +++ b/py/core/providers/database/vector.py @@ -4,17 +4,16 @@ import time from typing import Any, Optional -from sqlalchemy import exc, text -from sqlalchemy.engine.url import make_url - -from r2r_core.base import ( +from core.base import ( DatabaseConfig, VectorDBProvider, VectorEntry, VectorSearchResult, generate_id_from_label, ) -from r2r_core.base.abstractions import VectorSearchSettings +from core.base.abstractions import VectorSearchSettings +from sqlalchemy import exc, text +from sqlalchemy.engine.url import make_url from .vecs import Client, Collection, create_client diff --git a/r2r_core/providers/embeddings/__init__.py b/py/core/providers/embeddings/__init__.py similarity index 100% rename from r2r_core/providers/embeddings/__init__.py rename to py/core/providers/embeddings/__init__.py diff --git a/r2r_core/providers/embeddings/litellm.py b/py/core/providers/embeddings/litellm.py similarity index 99% rename from r2r_core/providers/embeddings/litellm.py rename to py/core/providers/embeddings/litellm.py index c70ac16f3..359a7a964 100644 --- a/r2r_core/providers/embeddings/litellm.py +++ b/py/core/providers/embeddings/litellm.py @@ -2,15 +2,14 @@ import logging from typing import Any, List -from litellm import aembedding, embedding - -from r2r_core.base import ( +from core.base import ( EmbeddingConfig, EmbeddingProvider, EmbeddingPurpose, R2RException, VectorSearchResult, ) +from litellm import aembedding, embedding logger = logging.getLogger(__name__) diff --git a/r2r_core/providers/embeddings/ollama.py b/py/core/providers/embeddings/ollama.py similarity index 99% rename from r2r_core/providers/embeddings/ollama.py rename to py/core/providers/embeddings/ollama.py index 20ddbc7db..3e60f22da 100644 --- a/r2r_core/providers/embeddings/ollama.py +++ b/py/core/providers/embeddings/ollama.py @@ -2,15 +2,14 @@ import os from typing import Any, List -from ollama import AsyncClient, Client - -from r2r_core.base import ( +from core.base import ( EmbeddingConfig, EmbeddingProvider, EmbeddingPurpose, R2RException, VectorSearchResult, ) +from ollama import AsyncClient, Client logger = logging.getLogger(__name__) diff --git a/r2r_core/providers/embeddings/openai.py b/py/core/providers/embeddings/openai.py similarity index 99% rename from r2r_core/providers/embeddings/openai.py rename to py/core/providers/embeddings/openai.py index 01ed840dd..2ae812ee2 100644 --- a/r2r_core/providers/embeddings/openai.py +++ b/py/core/providers/embeddings/openai.py @@ -3,15 +3,14 @@ import os from typing import Any, List -from openai import AsyncOpenAI, AuthenticationError, OpenAI -from openai._types import NOT_GIVEN - -from r2r_core.base import ( +from core.base import ( EmbeddingConfig, EmbeddingProvider, EmbeddingPurpose, VectorSearchResult, ) +from openai import AsyncOpenAI, AuthenticationError, OpenAI +from openai._types import NOT_GIVEN logger = logging.getLogger(__name__) diff --git a/r2r_core/providers/kg/__init__.py b/py/core/providers/kg/__init__.py similarity index 100% rename from r2r_core/providers/kg/__init__.py rename to py/core/providers/kg/__init__.py diff --git a/r2r_core/providers/kg/neo4j/__init__.py b/py/core/providers/kg/neo4j/__init__.py similarity index 100% rename from r2r_core/providers/kg/neo4j/__init__.py rename to py/core/providers/kg/neo4j/__init__.py diff --git a/r2r_core/providers/kg/neo4j/graph_queries.py b/py/core/providers/kg/neo4j/graph_queries.py similarity index 100% rename from r2r_core/providers/kg/neo4j/graph_queries.py rename to py/core/providers/kg/neo4j/graph_queries.py diff --git a/r2r_core/providers/kg/neo4j/provider.py b/py/core/providers/kg/neo4j/provider.py similarity index 98% rename from r2r_core/providers/kg/neo4j/provider.py rename to py/core/providers/kg/neo4j/provider.py index e06f2a468..ee1e7bf1c 100644 --- a/r2r_core/providers/kg/neo4j/provider.py +++ b/py/core/providers/kg/neo4j/provider.py @@ -6,14 +6,14 @@ from typing import Any, Dict, List, Optional from uuid import UUID -from r2r_core.base import ( +from core.base import ( KGConfig, KGProvider, format_entity_types, format_relations, ) -from r2r_core.base.abstractions.document import DocumentFragment -from r2r_core.base.abstractions.graph import ( +from core.base.abstractions.document import DocumentFragment +from core.base.abstractions.graph import ( Community, Entity, KGExtraction, diff --git a/r2r_core/providers/llm/__init__.py b/py/core/providers/llm/__init__.py similarity index 100% rename from r2r_core/providers/llm/__init__.py rename to py/core/providers/llm/__init__.py diff --git a/r2r_core/providers/llm/litellm.py b/py/core/providers/llm/litellm.py similarity index 95% rename from r2r_core/providers/llm/litellm.py rename to py/core/providers/llm/litellm.py index 7c60c7ad4..1bbdd33c4 100644 --- a/r2r_core/providers/llm/litellm.py +++ b/py/core/providers/llm/litellm.py @@ -1,8 +1,8 @@ import logging from typing import Any -from r2r_core.base.abstractions.llm import GenerationConfig -from r2r_core.base.providers.llm import CompletionConfig, CompletionProvider +from core.base.abstractions.llm import GenerationConfig +from core.base.providers.llm import CompletionConfig, CompletionProvider logger = logging.getLogger(__name__) diff --git a/r2r_core/providers/llm/openai.py b/py/core/providers/llm/openai.py similarity index 95% rename from r2r_core/providers/llm/openai.py rename to py/core/providers/llm/openai.py index 57d9cd33e..f6e522796 100644 --- a/r2r_core/providers/llm/openai.py +++ b/py/core/providers/llm/openai.py @@ -2,11 +2,10 @@ import os from typing import Any +from core.base.abstractions.llm import GenerationConfig +from core.base.providers.llm import CompletionConfig, CompletionProvider from openai import AsyncOpenAI, OpenAI -from r2r_core.base.abstractions.llm import GenerationConfig -from r2r_core.base.providers.llm import CompletionConfig, CompletionProvider - logger = logging.getLogger(__name__) diff --git a/r2r_core/providers/parsing/__init__.py b/py/core/providers/parsing/__init__.py similarity index 100% rename from r2r_core/providers/parsing/__init__.py rename to py/core/providers/parsing/__init__.py diff --git a/r2r_core/providers/parsing/r2r_parsing.py b/py/core/providers/parsing/r2r_parsing.py similarity index 98% rename from r2r_core/providers/parsing/r2r_parsing.py rename to py/core/providers/parsing/r2r_parsing.py index 8420c7ed7..55cbeb37c 100644 --- a/r2r_core/providers/parsing/r2r_parsing.py +++ b/py/core/providers/parsing/r2r_parsing.py @@ -2,8 +2,8 @@ import time from typing import Any, AsyncGenerator -from r2r_core import parsers -from r2r_core.base import ( +from core import parsers +from core.base import ( Document, DocumentExtraction, DocumentType, diff --git a/r2r_core/providers/parsing/unstructured_parsing.py b/py/core/providers/parsing/unstructured_parsing.py similarity index 98% rename from r2r_core/providers/parsing/unstructured_parsing.py rename to py/core/providers/parsing/unstructured_parsing.py index ef2d1d307..0fc68a447 100644 --- a/r2r_core/providers/parsing/unstructured_parsing.py +++ b/py/core/providers/parsing/unstructured_parsing.py @@ -3,7 +3,7 @@ from io import BytesIO from typing import AsyncGenerator -from r2r_core.base import ( +from core.base import ( Document, DocumentExtraction, DocumentType, diff --git a/r2r_core/providers/prompts/__init__.py b/py/core/providers/prompts/__init__.py similarity index 100% rename from r2r_core/providers/prompts/__init__.py rename to py/core/providers/prompts/__init__.py diff --git a/r2r_core/providers/prompts/defaults.yaml b/py/core/providers/prompts/defaults.yaml similarity index 100% rename from r2r_core/providers/prompts/defaults.yaml rename to py/core/providers/prompts/defaults.yaml diff --git a/r2r_core/providers/prompts/defaults/default_rag.yaml b/py/core/providers/prompts/defaults/default_rag.yaml similarity index 100% rename from r2r_core/providers/prompts/defaults/default_rag.yaml rename to py/core/providers/prompts/defaults/default_rag.yaml diff --git a/r2r_core/providers/prompts/defaults/few_shot_ner_kg_extraction.yaml b/py/core/providers/prompts/defaults/few_shot_ner_kg_extraction.yaml similarity index 100% rename from r2r_core/providers/prompts/defaults/few_shot_ner_kg_extraction.yaml rename to py/core/providers/prompts/defaults/few_shot_ner_kg_extraction.yaml diff --git a/r2r_core/providers/prompts/defaults/few_shot_ner_kg_extraction_with_spec.yaml b/py/core/providers/prompts/defaults/few_shot_ner_kg_extraction_with_spec.yaml similarity index 100% rename from r2r_core/providers/prompts/defaults/few_shot_ner_kg_extraction_with_spec.yaml rename to py/core/providers/prompts/defaults/few_shot_ner_kg_extraction_with_spec.yaml diff --git a/r2r_core/providers/prompts/defaults/graphrag_community_reports.yaml b/py/core/providers/prompts/defaults/graphrag_community_reports.yaml similarity index 100% rename from r2r_core/providers/prompts/defaults/graphrag_community_reports.yaml rename to py/core/providers/prompts/defaults/graphrag_community_reports.yaml diff --git a/r2r_core/providers/prompts/defaults/graphrag_map_system_prompt.yaml b/py/core/providers/prompts/defaults/graphrag_map_system_prompt.yaml similarity index 100% rename from r2r_core/providers/prompts/defaults/graphrag_map_system_prompt.yaml rename to py/core/providers/prompts/defaults/graphrag_map_system_prompt.yaml diff --git a/r2r_core/providers/prompts/defaults/graphrag_reduce_system_prompt.yaml b/py/core/providers/prompts/defaults/graphrag_reduce_system_prompt.yaml similarity index 100% rename from r2r_core/providers/prompts/defaults/graphrag_reduce_system_prompt.yaml rename to py/core/providers/prompts/defaults/graphrag_reduce_system_prompt.yaml diff --git a/r2r_core/providers/prompts/defaults/graphrag_triplet_extraction_few_shot.yaml b/py/core/providers/prompts/defaults/graphrag_triplet_extraction_few_shot.yaml similarity index 100% rename from r2r_core/providers/prompts/defaults/graphrag_triplet_extraction_few_shot.yaml rename to py/core/providers/prompts/defaults/graphrag_triplet_extraction_few_shot.yaml diff --git a/r2r_core/providers/prompts/defaults/graphrag_triplet_extraction_zero_shot.yaml b/py/core/providers/prompts/defaults/graphrag_triplet_extraction_zero_shot.yaml similarity index 100% rename from r2r_core/providers/prompts/defaults/graphrag_triplet_extraction_zero_shot.yaml rename to py/core/providers/prompts/defaults/graphrag_triplet_extraction_zero_shot.yaml diff --git a/r2r_core/providers/prompts/defaults/hyde.yaml b/py/core/providers/prompts/defaults/hyde.yaml similarity index 100% rename from r2r_core/providers/prompts/defaults/hyde.yaml rename to py/core/providers/prompts/defaults/hyde.yaml diff --git a/r2r_core/providers/prompts/defaults/kg_search.yaml b/py/core/providers/prompts/defaults/kg_search.yaml similarity index 100% rename from r2r_core/providers/prompts/defaults/kg_search.yaml rename to py/core/providers/prompts/defaults/kg_search.yaml diff --git a/r2r_core/providers/prompts/defaults/kg_search_with_spec.yaml b/py/core/providers/prompts/defaults/kg_search_with_spec.yaml similarity index 100% rename from r2r_core/providers/prompts/defaults/kg_search_with_spec.yaml rename to py/core/providers/prompts/defaults/kg_search_with_spec.yaml diff --git a/r2r_core/providers/prompts/defaults/rag_agent.yaml b/py/core/providers/prompts/defaults/rag_agent.yaml similarity index 100% rename from r2r_core/providers/prompts/defaults/rag_agent.yaml rename to py/core/providers/prompts/defaults/rag_agent.yaml diff --git a/r2r_core/providers/prompts/defaults/rag_context.yaml b/py/core/providers/prompts/defaults/rag_context.yaml similarity index 100% rename from r2r_core/providers/prompts/defaults/rag_context.yaml rename to py/core/providers/prompts/defaults/rag_context.yaml diff --git a/r2r_core/providers/prompts/defaults/rag_fusion.yaml b/py/core/providers/prompts/defaults/rag_fusion.yaml similarity index 100% rename from r2r_core/providers/prompts/defaults/rag_fusion.yaml rename to py/core/providers/prompts/defaults/rag_fusion.yaml diff --git a/r2r_core/providers/prompts/defaults/system.yaml b/py/core/providers/prompts/defaults/system.yaml similarity index 100% rename from r2r_core/providers/prompts/defaults/system.yaml rename to py/core/providers/prompts/defaults/system.yaml diff --git a/r2r_core/providers/prompts/defaults/zero_shot_ner_kg_extraction.yaml b/py/core/providers/prompts/defaults/zero_shot_ner_kg_extraction.yaml similarity index 100% rename from r2r_core/providers/prompts/defaults/zero_shot_ner_kg_extraction.yaml rename to py/core/providers/prompts/defaults/zero_shot_ner_kg_extraction.yaml diff --git a/r2r_core/providers/prompts/defaults/zero_shot_ner_kg_extraction_with_spec.yaml b/py/core/providers/prompts/defaults/zero_shot_ner_kg_extraction_with_spec.yaml similarity index 100% rename from r2r_core/providers/prompts/defaults/zero_shot_ner_kg_extraction_with_spec.yaml rename to py/core/providers/prompts/defaults/zero_shot_ner_kg_extraction_with_spec.yaml diff --git a/r2r_core/providers/prompts/r2r_prompts.py b/py/core/providers/prompts/r2r_prompts.py similarity index 98% rename from r2r_core/providers/prompts/r2r_prompts.py rename to py/core/providers/prompts/r2r_prompts.py index a1be76937..4cf93460c 100644 --- a/r2r_core/providers/prompts/r2r_prompts.py +++ b/py/core/providers/prompts/r2r_prompts.py @@ -5,8 +5,7 @@ import toml import yaml - -from r2r_core.base import Prompt, PromptConfig, PromptProvider +from core.base import Prompt, PromptConfig, PromptProvider logger = logging.getLogger(__name__) diff --git a/r2r_core/telemetry/__init__.py b/py/core/telemetry/__init__.py similarity index 100% rename from r2r_core/telemetry/__init__.py rename to py/core/telemetry/__init__.py diff --git a/r2r_core/telemetry/events.py b/py/core/telemetry/events.py similarity index 100% rename from r2r_core/telemetry/events.py rename to py/core/telemetry/events.py diff --git a/r2r_core/telemetry/posthog.py b/py/core/telemetry/posthog.py similarity index 96% rename from r2r_core/telemetry/posthog.py rename to py/core/telemetry/posthog.py index 90fde942b..ce2df4d40 100644 --- a/r2r_core/telemetry/posthog.py +++ b/py/core/telemetry/posthog.py @@ -2,8 +2,7 @@ import os import posthog - -from r2r_core.telemetry.events import BaseTelemetryEvent +from core.telemetry.events import BaseTelemetryEvent logger = logging.getLogger(__name__) diff --git a/r2r_core/telemetry/telemetry_decorator.py b/py/core/telemetry/telemetry_decorator.py similarity index 93% rename from r2r_core/telemetry/telemetry_decorator.py rename to py/core/telemetry/telemetry_decorator.py index aba557d39..a56aefb60 100644 --- a/r2r_core/telemetry/telemetry_decorator.py +++ b/py/core/telemetry/telemetry_decorator.py @@ -2,8 +2,8 @@ import logging from functools import wraps -from r2r_core.telemetry.events import ErrorEvent, FeatureUsageEvent -from r2r_core.telemetry.posthog import telemetry_client +from core.telemetry.events import ErrorEvent, FeatureUsageEvent +from core.telemetry.posthog import telemetry_client logger = logging.getLogger(__name__) diff --git a/py/sdk/__init__.py b/py/sdk/__init__.py new file mode 100644 index 000000000..df1bc2d75 --- /dev/null +++ b/py/sdk/__init__.py @@ -0,0 +1,6 @@ +from .client import R2RAsyncClient, R2RClient + +__all__ = [ + "R2RAsyncClient", + "R2RClient", +] diff --git a/r2r_python_sdk/r2r/auth.py b/py/sdk/auth.py similarity index 100% rename from r2r_python_sdk/r2r/auth.py rename to py/sdk/auth.py diff --git a/r2r_python_sdk/r2r/client.py b/py/sdk/client.py similarity index 100% rename from r2r_python_sdk/r2r/client.py rename to py/sdk/client.py diff --git a/r2r_python_sdk/r2r/ingestion.py b/py/sdk/ingestion.py similarity index 100% rename from r2r_python_sdk/r2r/ingestion.py rename to py/sdk/ingestion.py diff --git a/r2r_python_sdk/r2r/management.py b/py/sdk/management.py similarity index 100% rename from r2r_python_sdk/r2r/management.py rename to py/sdk/management.py diff --git a/r2r_python_sdk/r2r/models.py b/py/sdk/models.py similarity index 100% rename from r2r_python_sdk/r2r/models.py rename to py/sdk/models.py diff --git a/r2r_python_sdk/r2r/restructure.py b/py/sdk/restructure.py similarity index 100% rename from r2r_python_sdk/r2r/restructure.py rename to py/sdk/restructure.py diff --git a/r2r_python_sdk/r2r/retrieval.py b/py/sdk/retrieval.py similarity index 98% rename from r2r_python_sdk/r2r/retrieval.py rename to py/sdk/retrieval.py index d042c0355..7769cf127 100644 --- a/r2r_python_sdk/r2r/retrieval.py +++ b/py/sdk/retrieval.py @@ -1,7 +1,7 @@ from typing import AsyncGenerator, Optional, Union -from r2r_core.base import VectorSearchSettings -from r2r_core.base.api.models import RAGResponse, SearchResponse +from core.base import VectorSearchSettings +from core.base.api.models import RAGResponse, SearchResponse from .models import ( GenerationConfig, diff --git a/pyproject.toml b/pyproject.toml index 41a348bbe..bf2a568bb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,77 +3,73 @@ requires = ["poetry-core", "setuptools", "wheel"] build-backend = "poetry.core.masonry.api" [tool.poetry] -name = "r2r_core" -version = "0.1.0" +name = "r2r" +version = "0.3.0" description = "SciPhi R2R" authors = ["Owen Colegrove "] license = "MIT" readme = "README.md" include = ["r2r.toml", "compose.yaml", "compose.neo4j.yaml", "compose.ollama.yaml", "compose.postgres.yaml", "pyproject.toml"] +packages = [ + { include = "core", from = "py" }, + { include = "sdk", from = "py" }, +] [tool.poetry.dependencies] # Python Versions python = ">=3.9,<3.13" -# Required dependencies - -# python -pydantic = {extras = ["email"], version = "^2.8.2"} -python-multipart = "^0.0.9" - -# infrastructure +httpx = "^0.27.0" +nest-asyncio = "^1.6.0" fastapi = "^0.109.2" -fire = "^0.5.0" -gunicorn = "^21.2.0" -requests = "^2.31.0" -types-requests = "^2.31.0" -uvicorn = "^0.27.0.post1" - -# TODO - Make some of these optional -# async db providers -aiosqlite = "^0.20.0" -asyncpg = "^0.29.0" -redis = "^5.0.4" -# ingestion -beautifulsoup4 = "^4.12.3" -openpyxl = "^3.1.2" -markdown = "^3.6" -pypdf = "^4.2.0" -python-pptx = "^0.6.23" -python-docx = "^1.1.0" -nest-asyncio = "^1.6.0" +# Core dependencies (optional) +pydantic = { extras = ["email"], version = "^2.8.2", optional = true } +python-multipart = { version = "^0.0.9", optional = true } +fire = { version = "^0.5.0", optional = true } +gunicorn = { version = "^21.2.0", optional = true } +requests = { version = "^2.31.0", optional = true } +types-requests = { version = "^2.31.0", optional = true } +uvicorn = { version = "^0.27.0.post1", optional = true } +aiosqlite = { version = "^0.20.0", optional = true } +asyncpg = { version = "^0.29.0", optional = true } +redis = { version = "^5.0.4", optional = true } +beautifulsoup4 = { version = "^4.12.3", optional = true } +openpyxl = { version = "^3.1.2", optional = true } +markdown = { version = "^3.6", optional = true } +pypdf = { version = "^4.2.0", optional = true } +python-pptx = { version = "^0.6.23", optional = true } +python-docx = { version = "^1.1.0", optional = true } opencv-python = { version = "^4.10.0.82", optional = true } moviepy = { version = "^1.0.3", optional = true } - -# vector db providers -vecs = "^0.4.0" - -# llm providers -litellm = "^1.42.3" -openai = "^1.11.1" - -# integrations -fsspec = "^2024.6.0" -posthog = "^3.5.0" -sqlalchemy = "^2.0.30" -ollama = "^0.3.1" -neo4j = "^5.21.0" -passlib = "^1.7.4" -bcrypt = "^4.1.3" -pyjwt = "^2.8.0" -toml = "^0.10.2" -pyyaml = "^6.0.1" -poppler-utils = "^0.1.0" -# unstructured = {version = "^0.15.0"} -psutil = "^6.0.0" -deepdiff = "^7.0.1" -graspologic = "^3.4.1" +vecs = { version = "^0.4.0", optional = true } +litellm = { version = "^1.42.3", optional = true } +openai = { version = "^1.11.1", optional = true } +fsspec = { version = "^2024.6.0", optional = true } +posthog = { version = "^3.5.0", optional = true } +sqlalchemy = { version = "^2.0.30", optional = true } +ollama = { version = "^0.3.1", optional = true } +neo4j = { version = "^5.21.0", optional = true } +passlib = { version = "^1.7.4", optional = true } +bcrypt = { version = "^4.1.3", optional = true } +pyjwt = { version = "^2.8.0", optional = true } +toml = { version = "^0.10.2", optional = true } +pyyaml = { version = "^6.0.1", optional = true } +poppler-utils = { version = "^0.1.0", optional = true } +psutil = { version = "^6.0.0", optional = true } +deepdiff = { version = "^7.0.1", optional = true } +graspologic = { version = "^3.4.1", optional = true } [tool.poetry.extras] -all = ["moviepy", "opencv-python"] -ingest-movies = ["moviepy", "opencv-python"] - +core = [ + "pydantic", "python-multipart", "fire", "gunicorn", "requests", "types-requests", + "uvicorn", "aiosqlite", "asyncpg", "redis", "beautifulsoup4", "openpyxl", + "markdown", "pypdf", "python-pptx", "python-docx", "vecs", "litellm", "openai", + "fsspec", "posthog", "sqlalchemy", "ollama", "neo4j", "passlib", "bcrypt", + "pyjwt", "toml", "pyyaml", "poppler-utils", "psutil", "deepdiff", "graspologic" +] +ingest-movies = ["opencv-python", "moviepy"] +all = ["core", "ingest-movies"] [tool.poetry.group.dev.dependencies] black = "^24.3.0" @@ -90,7 +86,7 @@ pytest-cov = "^5.0.0" colorama = "^0.4.6" [tool.poetry.scripts] -r2r = "r2r_core.cli.cli:main" +r2r = "core.cli.cli:main" [tool.black] line-length = 79 diff --git a/r2r_go_sdk/go.mod b/r2r_go_sdk/go.mod deleted file mode 100644 index 4a052a9aa..000000000 --- a/r2r_go_sdk/go.mod +++ /dev/null @@ -1,3 +0,0 @@ -module github.com/yourusername/r2r-go-sdk - -go 1.23.0 diff --git a/r2r_python_sdk/README.md b/r2r_python_sdk/README.md deleted file mode 100644 index e69de29bb..000000000 diff --git a/r2r_python_sdk/poetry.lock b/r2r_python_sdk/poetry.lock deleted file mode 100644 index 00baa0d2b..000000000 --- a/r2r_python_sdk/poetry.lock +++ /dev/null @@ -1,1098 +0,0 @@ -# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. - -[[package]] -name = "annotated-types" -version = "0.7.0" -description = "Reusable constraint types to use with typing.Annotated" -optional = false -python-versions = ">=3.8" -files = [ - {file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"}, - {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, -] - -[[package]] -name = "anyio" -version = "4.4.0" -description = "High level compatibility layer for multiple asynchronous event loop implementations" -optional = false -python-versions = ">=3.8" -files = [ - {file = "anyio-4.4.0-py3-none-any.whl", hash = "sha256:c1b2d8f46a8a812513012e1107cb0e68c17159a7a594208005a57dc776e1bdc7"}, - {file = "anyio-4.4.0.tar.gz", hash = "sha256:5aadc6a1bbb7cdb0bede386cac5e2940f5e2ff3aa20277e991cf028e0585ce94"}, -] - -[package.dependencies] -exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} -idna = ">=2.8" -sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} - -[package.extras] -doc = ["Sphinx (>=7)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] -trio = ["trio (>=0.23)"] - -[[package]] -name = "black" -version = "24.8.0" -description = "The uncompromising code formatter." -optional = false -python-versions = ">=3.8" -files = [ - {file = "black-24.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:09cdeb74d494ec023ded657f7092ba518e8cf78fa8386155e4a03fdcc44679e6"}, - {file = "black-24.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:81c6742da39f33b08e791da38410f32e27d632260e599df7245cccee2064afeb"}, - {file = "black-24.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:707a1ca89221bc8a1a64fb5e15ef39cd755633daa672a9db7498d1c19de66a42"}, - {file = "black-24.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:d6417535d99c37cee4091a2f24eb2b6d5ec42b144d50f1f2e436d9fe1916fe1a"}, - {file = "black-24.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fb6e2c0b86bbd43dee042e48059c9ad7830abd5c94b0bc518c0eeec57c3eddc1"}, - {file = "black-24.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:837fd281f1908d0076844bc2b801ad2d369c78c45cf800cad7b61686051041af"}, - {file = "black-24.8.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:62e8730977f0b77998029da7971fa896ceefa2c4c4933fcd593fa599ecbf97a4"}, - {file = "black-24.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:72901b4913cbac8972ad911dc4098d5753704d1f3c56e44ae8dce99eecb0e3af"}, - {file = "black-24.8.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:7c046c1d1eeb7aea9335da62472481d3bbf3fd986e093cffd35f4385c94ae368"}, - {file = "black-24.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:649f6d84ccbae73ab767e206772cc2d7a393a001070a4c814a546afd0d423aed"}, - {file = "black-24.8.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2b59b250fdba5f9a9cd9d0ece6e6d993d91ce877d121d161e4698af3eb9c1018"}, - {file = "black-24.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:6e55d30d44bed36593c3163b9bc63bf58b3b30e4611e4d88a0c3c239930ed5b2"}, - {file = "black-24.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:505289f17ceda596658ae81b61ebbe2d9b25aa78067035184ed0a9d855d18afd"}, - {file = "black-24.8.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b19c9ad992c7883ad84c9b22aaa73562a16b819c1d8db7a1a1a49fb7ec13c7d2"}, - {file = "black-24.8.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1f13f7f386f86f8121d76599114bb8c17b69d962137fc70efe56137727c7047e"}, - {file = "black-24.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:f490dbd59680d809ca31efdae20e634f3fae27fba3ce0ba3208333b713bc3920"}, - {file = "black-24.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:eab4dd44ce80dea27dc69db40dab62d4ca96112f87996bca68cd75639aeb2e4c"}, - {file = "black-24.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3c4285573d4897a7610054af5a890bde7c65cb466040c5f0c8b732812d7f0e5e"}, - {file = "black-24.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9e84e33b37be070ba135176c123ae52a51f82306def9f7d063ee302ecab2cf47"}, - {file = "black-24.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:73bbf84ed136e45d451a260c6b73ed674652f90a2b3211d6a35e78054563a9bb"}, - {file = "black-24.8.0-py3-none-any.whl", hash = "sha256:972085c618ee94f402da1af548a4f218c754ea7e5dc70acb168bfaca4c2542ed"}, - {file = "black-24.8.0.tar.gz", hash = "sha256:2500945420b6784c38b9ee885af039f5e7471ef284ab03fa35ecdde4688cd83f"}, -] - -[package.dependencies] -click = ">=8.0.0" -mypy-extensions = ">=0.4.3" -packaging = ">=22.0" -pathspec = ">=0.9.0" -platformdirs = ">=2" -tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""} - -[package.extras] -colorama = ["colorama (>=0.4.3)"] -d = ["aiohttp (>=3.7.4)", "aiohttp (>=3.7.4,!=3.9.0)"] -jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] -uvloop = ["uvloop (>=0.15.2)"] - -[[package]] -name = "certifi" -version = "2024.7.4" -description = "Python package for providing Mozilla's CA Bundle." -optional = false -python-versions = ">=3.6" -files = [ - {file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"}, - {file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"}, -] - -[[package]] -name = "cfgv" -version = "3.4.0" -description = "Validate configuration and produce human readable error messages." -optional = false -python-versions = ">=3.8" -files = [ - {file = "cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9"}, - {file = "cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560"}, -] - -[[package]] -name = "charset-normalizer" -version = "3.3.2" -description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -optional = false -python-versions = ">=3.7.0" -files = [ - {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, - {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, -] - -[[package]] -name = "click" -version = "8.1.7" -description = "Composable command line interface toolkit" -optional = false -python-versions = ">=3.7" -files = [ - {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, - {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "platform_system == \"Windows\""} - -[[package]] -name = "codecov" -version = "2.1.13" -description = "Hosted coverage reports for GitHub, Bitbucket and Gitlab" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "codecov-2.1.13-py2.py3-none-any.whl", hash = "sha256:c2ca5e51bba9ebb43644c43d0690148a55086f7f5e6fd36170858fa4206744d5"}, - {file = "codecov-2.1.13.tar.gz", hash = "sha256:2362b685633caeaf45b9951a9b76ce359cd3581dd515b430c6c3f5dfb4d92a8c"}, -] - -[package.dependencies] -coverage = "*" -requests = ">=2.7.9" - -[[package]] -name = "colorama" -version = "0.4.6" -description = "Cross-platform colored terminal text." -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -files = [ - {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, - {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, -] - -[[package]] -name = "coverage" -version = "7.6.1" -description = "Code coverage measurement for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "coverage-7.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b06079abebbc0e89e6163b8e8f0e16270124c154dc6e4a47b413dd538859af16"}, - {file = "coverage-7.6.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cf4b19715bccd7ee27b6b120e7e9dd56037b9c0681dcc1adc9ba9db3d417fa36"}, - {file = "coverage-7.6.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61c0abb4c85b095a784ef23fdd4aede7a2628478e7baba7c5e3deba61070a02"}, - {file = "coverage-7.6.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fd21f6ae3f08b41004dfb433fa895d858f3f5979e7762d052b12aef444e29afc"}, - {file = "coverage-7.6.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f59d57baca39b32db42b83b2a7ba6f47ad9c394ec2076b084c3f029b7afca23"}, - {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a1ac0ae2b8bd743b88ed0502544847c3053d7171a3cff9228af618a068ed9c34"}, - {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e6a08c0be454c3b3beb105c0596ebdc2371fab6bb90c0c0297f4e58fd7e1012c"}, - {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f5796e664fe802da4f57a168c85359a8fbf3eab5e55cd4e4569fbacecc903959"}, - {file = "coverage-7.6.1-cp310-cp310-win32.whl", hash = "sha256:7bb65125fcbef8d989fa1dd0e8a060999497629ca5b0efbca209588a73356232"}, - {file = "coverage-7.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:3115a95daa9bdba70aea750db7b96b37259a81a709223c8448fa97727d546fe0"}, - {file = "coverage-7.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7dea0889685db8550f839fa202744652e87c60015029ce3f60e006f8c4462c93"}, - {file = "coverage-7.6.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ed37bd3c3b063412f7620464a9ac1314d33100329f39799255fb8d3027da50d3"}, - {file = "coverage-7.6.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d85f5e9a5f8b73e2350097c3756ef7e785f55bd71205defa0bfdaf96c31616ff"}, - {file = "coverage-7.6.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bc572be474cafb617672c43fe989d6e48d3c83af02ce8de73fff1c6bb3c198d"}, - {file = "coverage-7.6.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c0420b573964c760df9e9e86d1a9a622d0d27f417e1a949a8a66dd7bcee7bc6"}, - {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1f4aa8219db826ce6be7099d559f8ec311549bfc4046f7f9fe9b5cea5c581c56"}, - {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:fc5a77d0c516700ebad189b587de289a20a78324bc54baee03dd486f0855d234"}, - {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b48f312cca9621272ae49008c7f613337c53fadca647d6384cc129d2996d1133"}, - {file = "coverage-7.6.1-cp311-cp311-win32.whl", hash = "sha256:1125ca0e5fd475cbbba3bb67ae20bd2c23a98fac4e32412883f9bcbaa81c314c"}, - {file = "coverage-7.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:8ae539519c4c040c5ffd0632784e21b2f03fc1340752af711f33e5be83a9d6c6"}, - {file = "coverage-7.6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:95cae0efeb032af8458fc27d191f85d1717b1d4e49f7cb226cf526ff28179778"}, - {file = "coverage-7.6.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5621a9175cf9d0b0c84c2ef2b12e9f5f5071357c4d2ea6ca1cf01814f45d2391"}, - {file = "coverage-7.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:260933720fdcd75340e7dbe9060655aff3af1f0c5d20f46b57f262ab6c86a5e8"}, - {file = "coverage-7.6.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07e2ca0ad381b91350c0ed49d52699b625aab2b44b65e1b4e02fa9df0e92ad2d"}, - {file = "coverage-7.6.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c44fee9975f04b33331cb8eb272827111efc8930cfd582e0320613263ca849ca"}, - {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:877abb17e6339d96bf08e7a622d05095e72b71f8afd8a9fefc82cf30ed944163"}, - {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3e0cadcf6733c09154b461f1ca72d5416635e5e4ec4e536192180d34ec160f8a"}, - {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c3c02d12f837d9683e5ab2f3d9844dc57655b92c74e286c262e0fc54213c216d"}, - {file = "coverage-7.6.1-cp312-cp312-win32.whl", hash = "sha256:e05882b70b87a18d937ca6768ff33cc3f72847cbc4de4491c8e73880766718e5"}, - {file = "coverage-7.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:b5d7b556859dd85f3a541db6a4e0167b86e7273e1cdc973e5b175166bb634fdb"}, - {file = "coverage-7.6.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a4acd025ecc06185ba2b801f2de85546e0b8ac787cf9d3b06e7e2a69f925b106"}, - {file = "coverage-7.6.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a6d3adcf24b624a7b778533480e32434a39ad8fa30c315208f6d3e5542aeb6e9"}, - {file = "coverage-7.6.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0c212c49b6c10e6951362f7c6df3329f04c2b1c28499563d4035d964ab8e08c"}, - {file = "coverage-7.6.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e81d7a3e58882450ec4186ca59a3f20a5d4440f25b1cff6f0902ad890e6748a"}, - {file = "coverage-7.6.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78b260de9790fd81e69401c2dc8b17da47c8038176a79092a89cb2b7d945d060"}, - {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a78d169acd38300060b28d600344a803628c3fd585c912cacc9ea8790fe96862"}, - {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2c09f4ce52cb99dd7505cd0fc8e0e37c77b87f46bc9c1eb03fe3bc9991085388"}, - {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6878ef48d4227aace338d88c48738a4258213cd7b74fd9a3d4d7582bb1d8a155"}, - {file = "coverage-7.6.1-cp313-cp313-win32.whl", hash = "sha256:44df346d5215a8c0e360307d46ffaabe0f5d3502c8a1cefd700b34baf31d411a"}, - {file = "coverage-7.6.1-cp313-cp313-win_amd64.whl", hash = "sha256:8284cf8c0dd272a247bc154eb6c95548722dce90d098c17a883ed36e67cdb129"}, - {file = "coverage-7.6.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:d3296782ca4eab572a1a4eca686d8bfb00226300dcefdf43faa25b5242ab8a3e"}, - {file = "coverage-7.6.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:502753043567491d3ff6d08629270127e0c31d4184c4c8d98f92c26f65019962"}, - {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a89ecca80709d4076b95f89f308544ec8f7b4727e8a547913a35f16717856cb"}, - {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a318d68e92e80af8b00fa99609796fdbcdfef3629c77c6283566c6f02c6d6704"}, - {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13b0a73a0896988f053e4fbb7de6d93388e6dd292b0d87ee51d106f2c11b465b"}, - {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4421712dbfc5562150f7554f13dde997a2e932a6b5f352edcce948a815efee6f"}, - {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:166811d20dfea725e2e4baa71fffd6c968a958577848d2131f39b60043400223"}, - {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:225667980479a17db1048cb2bf8bfb39b8e5be8f164b8f6628b64f78a72cf9d3"}, - {file = "coverage-7.6.1-cp313-cp313t-win32.whl", hash = "sha256:170d444ab405852903b7d04ea9ae9b98f98ab6d7e63e1115e82620807519797f"}, - {file = "coverage-7.6.1-cp313-cp313t-win_amd64.whl", hash = "sha256:b9f222de8cded79c49bf184bdbc06630d4c58eec9459b939b4a690c82ed05657"}, - {file = "coverage-7.6.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6db04803b6c7291985a761004e9060b2bca08da6d04f26a7f2294b8623a0c1a0"}, - {file = "coverage-7.6.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f1adfc8ac319e1a348af294106bc6a8458a0f1633cc62a1446aebc30c5fa186a"}, - {file = "coverage-7.6.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a95324a9de9650a729239daea117df21f4b9868ce32e63f8b650ebe6cef5595b"}, - {file = "coverage-7.6.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b43c03669dc4618ec25270b06ecd3ee4fa94c7f9b3c14bae6571ca00ef98b0d3"}, - {file = "coverage-7.6.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8929543a7192c13d177b770008bc4e8119f2e1f881d563fc6b6305d2d0ebe9de"}, - {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a09ece4a69cf399510c8ab25e0950d9cf2b42f7b3cb0374f95d2e2ff594478a6"}, - {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:9054a0754de38d9dbd01a46621636689124d666bad1936d76c0341f7d71bf569"}, - {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0dbde0f4aa9a16fa4d754356a8f2e36296ff4d83994b2c9d8398aa32f222f989"}, - {file = "coverage-7.6.1-cp38-cp38-win32.whl", hash = "sha256:da511e6ad4f7323ee5702e6633085fb76c2f893aaf8ce4c51a0ba4fc07580ea7"}, - {file = "coverage-7.6.1-cp38-cp38-win_amd64.whl", hash = "sha256:3f1156e3e8f2872197af3840d8ad307a9dd18e615dc64d9ee41696f287c57ad8"}, - {file = "coverage-7.6.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:abd5fd0db5f4dc9289408aaf34908072f805ff7792632250dcb36dc591d24255"}, - {file = "coverage-7.6.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:547f45fa1a93154bd82050a7f3cddbc1a7a4dd2a9bf5cb7d06f4ae29fe94eaf8"}, - {file = "coverage-7.6.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:645786266c8f18a931b65bfcefdbf6952dd0dea98feee39bd188607a9d307ed2"}, - {file = "coverage-7.6.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9e0b2df163b8ed01d515807af24f63de04bebcecbd6c3bfeff88385789fdf75a"}, - {file = "coverage-7.6.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:609b06f178fe8e9f89ef676532760ec0b4deea15e9969bf754b37f7c40326dbc"}, - {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:702855feff378050ae4f741045e19a32d57d19f3e0676d589df0575008ea5004"}, - {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:2bdb062ea438f22d99cba0d7829c2ef0af1d768d1e4a4f528087224c90b132cb"}, - {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:9c56863d44bd1c4fe2abb8a4d6f5371d197f1ac0ebdee542f07f35895fc07f36"}, - {file = "coverage-7.6.1-cp39-cp39-win32.whl", hash = "sha256:6e2cd258d7d927d09493c8df1ce9174ad01b381d4729a9d8d4e38670ca24774c"}, - {file = "coverage-7.6.1-cp39-cp39-win_amd64.whl", hash = "sha256:06a737c882bd26d0d6ee7269b20b12f14a8704807a01056c80bb881a4b2ce6ca"}, - {file = "coverage-7.6.1-pp38.pp39.pp310-none-any.whl", hash = "sha256:e9a6e0eb86070e8ccaedfbd9d38fec54864f3125ab95419970575b42af7541df"}, - {file = "coverage-7.6.1.tar.gz", hash = "sha256:953510dfb7b12ab69d20135a0662397f077c59b1e6379a768e97c59d852ee51d"}, -] - -[package.dependencies] -tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""} - -[package.extras] -toml = ["tomli"] - -[[package]] -name = "distlib" -version = "0.3.8" -description = "Distribution utilities" -optional = false -python-versions = "*" -files = [ - {file = "distlib-0.3.8-py2.py3-none-any.whl", hash = "sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784"}, - {file = "distlib-0.3.8.tar.gz", hash = "sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64"}, -] - -[[package]] -name = "exceptiongroup" -version = "1.2.2" -description = "Backport of PEP 654 (exception groups)" -optional = false -python-versions = ">=3.7" -files = [ - {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, - {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, -] - -[package.extras] -test = ["pytest (>=6)"] - -[[package]] -name = "fastapi" -version = "0.109.2" -description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production" -optional = false -python-versions = ">=3.8" -files = [ - {file = "fastapi-0.109.2-py3-none-any.whl", hash = "sha256:2c9bab24667293b501cad8dd388c05240c850b58ec5876ee3283c47d6e1e3a4d"}, - {file = "fastapi-0.109.2.tar.gz", hash = "sha256:f3817eac96fe4f65a2ebb4baa000f394e55f5fccdaf7f75250804bc58f354f73"}, -] - -[package.dependencies] -pydantic = ">=1.7.4,<1.8 || >1.8,<1.8.1 || >1.8.1,<2.0.0 || >2.0.0,<2.0.1 || >2.0.1,<2.1.0 || >2.1.0,<3.0.0" -starlette = ">=0.36.3,<0.37.0" -typing-extensions = ">=4.8.0" - -[package.extras] -all = ["email-validator (>=2.0.0)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=2.11.2)", "orjson (>=3.2.1)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.7)", "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)"] - -[[package]] -name = "filelock" -version = "3.15.4" -description = "A platform independent file lock." -optional = false -python-versions = ">=3.8" -files = [ - {file = "filelock-3.15.4-py3-none-any.whl", hash = "sha256:6ca1fffae96225dab4c6eaf1c4f4f28cd2568d3ec2a44e15a08520504de468e7"}, - {file = "filelock-3.15.4.tar.gz", hash = "sha256:2207938cbc1844345cb01a5a95524dae30f0ce089eba5b00378295a17e3e90cb"}, -] - -[package.extras] -docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] -testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8.0.1)", "pytest (>=7.4.3)", "pytest-asyncio (>=0.21)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)", "virtualenv (>=20.26.2)"] -typing = ["typing-extensions (>=4.8)"] - -[[package]] -name = "flake8" -version = "6.1.0" -description = "the modular source code checker: pep8 pyflakes and co" -optional = false -python-versions = ">=3.8.1" -files = [ - {file = "flake8-6.1.0-py2.py3-none-any.whl", hash = "sha256:ffdfce58ea94c6580c77888a86506937f9a1a227dfcd15f245d694ae20a6b6e5"}, - {file = "flake8-6.1.0.tar.gz", hash = "sha256:d5b3857f07c030bdb5bf41c7f53799571d75c4491748a3adcd47de929e34cd23"}, -] - -[package.dependencies] -mccabe = ">=0.7.0,<0.8.0" -pycodestyle = ">=2.11.0,<2.12.0" -pyflakes = ">=3.1.0,<3.2.0" - -[[package]] -name = "h11" -version = "0.14.0" -description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" -optional = false -python-versions = ">=3.7" -files = [ - {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, - {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, -] - -[[package]] -name = "httpcore" -version = "1.0.5" -description = "A minimal low-level HTTP client." -optional = false -python-versions = ">=3.8" -files = [ - {file = "httpcore-1.0.5-py3-none-any.whl", hash = "sha256:421f18bac248b25d310f3cacd198d55b8e6125c107797b609ff9b7a6ba7991b5"}, - {file = "httpcore-1.0.5.tar.gz", hash = "sha256:34a38e2f9291467ee3b44e89dd52615370e152954ba21721378a87b2960f7a61"}, -] - -[package.dependencies] -certifi = "*" -h11 = ">=0.13,<0.15" - -[package.extras] -asyncio = ["anyio (>=4.0,<5.0)"] -http2 = ["h2 (>=3,<5)"] -socks = ["socksio (==1.*)"] -trio = ["trio (>=0.22.0,<0.26.0)"] - -[[package]] -name = "httpx" -version = "0.27.0" -description = "The next generation HTTP client." -optional = false -python-versions = ">=3.8" -files = [ - {file = "httpx-0.27.0-py3-none-any.whl", hash = "sha256:71d5465162c13681bff01ad59b2cc68dd838ea1f10e51574bac27103f00c91a5"}, - {file = "httpx-0.27.0.tar.gz", hash = "sha256:a0cb88a46f32dc874e04ee956e4c2764aba2aa228f650b06788ba6bda2962ab5"}, -] - -[package.dependencies] -anyio = "*" -certifi = "*" -httpcore = "==1.*" -idna = "*" -sniffio = "*" - -[package.extras] -brotli = ["brotli", "brotlicffi"] -cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] -http2 = ["h2 (>=3,<5)"] -socks = ["socksio (==1.*)"] - -[[package]] -name = "identify" -version = "2.6.0" -description = "File identification library for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "identify-2.6.0-py2.py3-none-any.whl", hash = "sha256:e79ae4406387a9d300332b5fd366d8994f1525e8414984e1a59e058b2eda2dd0"}, - {file = "identify-2.6.0.tar.gz", hash = "sha256:cb171c685bdc31bcc4c1734698736a7d5b6c8bf2e0c15117f4d469c8640ae5cf"}, -] - -[package.extras] -license = ["ukkonen"] - -[[package]] -name = "idna" -version = "3.7" -description = "Internationalized Domain Names in Applications (IDNA)" -optional = false -python-versions = ">=3.5" -files = [ - {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, - {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, -] - -[[package]] -name = "iniconfig" -version = "2.0.0" -description = "brain-dead simple config-ini parsing" -optional = false -python-versions = ">=3.7" -files = [ - {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, - {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, -] - -[[package]] -name = "isort" -version = "5.12.0" -description = "A Python utility / library to sort Python imports." -optional = false -python-versions = ">=3.8.0" -files = [ - {file = "isort-5.12.0-py3-none-any.whl", hash = "sha256:f84c2818376e66cf843d497486ea8fed8700b340f308f076c6fb1229dff318b6"}, - {file = "isort-5.12.0.tar.gz", hash = "sha256:8bef7dde241278824a6d83f44a544709b065191b95b6e50894bdc722fcba0504"}, -] - -[package.extras] -colors = ["colorama (>=0.4.3)"] -pipfile-deprecated-finder = ["pip-shims (>=0.5.2)", "pipreqs", "requirementslib"] -plugins = ["setuptools"] -requirements-deprecated-finder = ["pip-api", "pipreqs"] - -[[package]] -name = "mccabe" -version = "0.7.0" -description = "McCabe checker, plugin for flake8" -optional = false -python-versions = ">=3.6" -files = [ - {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, - {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, -] - -[[package]] -name = "mypy" -version = "1.11.1" -description = "Optional static typing for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "mypy-1.11.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a32fc80b63de4b5b3e65f4be82b4cfa362a46702672aa6a0f443b4689af7008c"}, - {file = "mypy-1.11.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c1952f5ea8a5a959b05ed5f16452fddadbaae48b5d39235ab4c3fc444d5fd411"}, - {file = "mypy-1.11.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e1e30dc3bfa4e157e53c1d17a0dad20f89dc433393e7702b813c10e200843b03"}, - {file = "mypy-1.11.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2c63350af88f43a66d3dfeeeb8d77af34a4f07d760b9eb3a8697f0386c7590b4"}, - {file = "mypy-1.11.1-cp310-cp310-win_amd64.whl", hash = "sha256:a831671bad47186603872a3abc19634f3011d7f83b083762c942442d51c58d58"}, - {file = "mypy-1.11.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7b6343d338390bb946d449677726edf60102a1c96079b4f002dedff375953fc5"}, - {file = "mypy-1.11.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e4fe9f4e5e521b458d8feb52547f4bade7ef8c93238dfb5bbc790d9ff2d770ca"}, - {file = "mypy-1.11.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:886c9dbecc87b9516eff294541bf7f3655722bf22bb898ee06985cd7269898de"}, - {file = "mypy-1.11.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fca4a60e1dd9fd0193ae0067eaeeb962f2d79e0d9f0f66223a0682f26ffcc809"}, - {file = "mypy-1.11.1-cp311-cp311-win_amd64.whl", hash = "sha256:0bd53faf56de9643336aeea1c925012837432b5faf1701ccca7fde70166ccf72"}, - {file = "mypy-1.11.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f39918a50f74dc5969807dcfaecafa804fa7f90c9d60506835036cc1bc891dc8"}, - {file = "mypy-1.11.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0bc71d1fb27a428139dd78621953effe0d208aed9857cb08d002280b0422003a"}, - {file = "mypy-1.11.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b868d3bcff720dd7217c383474008ddabaf048fad8d78ed948bb4b624870a417"}, - {file = "mypy-1.11.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a707ec1527ffcdd1c784d0924bf5cb15cd7f22683b919668a04d2b9c34549d2e"}, - {file = "mypy-1.11.1-cp312-cp312-win_amd64.whl", hash = "sha256:64f4a90e3ea07f590c5bcf9029035cf0efeae5ba8be511a8caada1a4893f5525"}, - {file = "mypy-1.11.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:749fd3213916f1751fff995fccf20c6195cae941dc968f3aaadf9bb4e430e5a2"}, - {file = "mypy-1.11.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b639dce63a0b19085213ec5fdd8cffd1d81988f47a2dec7100e93564f3e8fb3b"}, - {file = "mypy-1.11.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4c956b49c5d865394d62941b109728c5c596a415e9c5b2be663dd26a1ff07bc0"}, - {file = "mypy-1.11.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:45df906e8b6804ef4b666af29a87ad9f5921aad091c79cc38e12198e220beabd"}, - {file = "mypy-1.11.1-cp38-cp38-win_amd64.whl", hash = "sha256:d44be7551689d9d47b7abc27c71257adfdb53f03880841a5db15ddb22dc63edb"}, - {file = "mypy-1.11.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2684d3f693073ab89d76da8e3921883019ea8a3ec20fa5d8ecca6a2db4c54bbe"}, - {file = "mypy-1.11.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:79c07eb282cb457473add5052b63925e5cc97dfab9812ee65a7c7ab5e3cb551c"}, - {file = "mypy-1.11.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11965c2f571ded6239977b14deebd3f4c3abd9a92398712d6da3a772974fad69"}, - {file = "mypy-1.11.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a2b43895a0f8154df6519706d9bca8280cda52d3d9d1514b2d9c3e26792a0b74"}, - {file = "mypy-1.11.1-cp39-cp39-win_amd64.whl", hash = "sha256:1a81cf05975fd61aec5ae16501a091cfb9f605dc3e3c878c0da32f250b74760b"}, - {file = "mypy-1.11.1-py3-none-any.whl", hash = "sha256:0624bdb940255d2dd24e829d99a13cfeb72e4e9031f9492148f410ed30bcab54"}, - {file = "mypy-1.11.1.tar.gz", hash = "sha256:f404a0b069709f18bbdb702eb3dcfe51910602995de00bd39cea3050b5772d08"}, -] - -[package.dependencies] -mypy-extensions = ">=1.0.0" -tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typing-extensions = ">=4.6.0" - -[package.extras] -dmypy = ["psutil (>=4.0)"] -install-types = ["pip"] -mypyc = ["setuptools (>=50)"] -reports = ["lxml"] - -[[package]] -name = "mypy-extensions" -version = "1.0.0" -description = "Type system extensions for programs checked with the mypy type checker." -optional = false -python-versions = ">=3.5" -files = [ - {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, - {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, -] - -[[package]] -name = "nest-asyncio" -version = "1.6.0" -description = "Patch asyncio to allow nested event loops" -optional = false -python-versions = ">=3.5" -files = [ - {file = "nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c"}, - {file = "nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe"}, -] - -[[package]] -name = "nodeenv" -version = "1.9.1" -description = "Node.js virtual environment builder" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -files = [ - {file = "nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9"}, - {file = "nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f"}, -] - -[[package]] -name = "packaging" -version = "24.1" -description = "Core utilities for Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, - {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, -] - -[[package]] -name = "pathspec" -version = "0.12.1" -description = "Utility library for gitignore style pattern matching of file paths." -optional = false -python-versions = ">=3.8" -files = [ - {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, - {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, -] - -[[package]] -name = "platformdirs" -version = "4.2.2" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." -optional = false -python-versions = ">=3.8" -files = [ - {file = "platformdirs-4.2.2-py3-none-any.whl", hash = "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee"}, - {file = "platformdirs-4.2.2.tar.gz", hash = "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3"}, -] - -[package.extras] -docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] -type = ["mypy (>=1.8)"] - -[[package]] -name = "pluggy" -version = "1.5.0" -description = "plugin and hook calling mechanisms for python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, - {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, -] - -[package.extras] -dev = ["pre-commit", "tox"] -testing = ["pytest", "pytest-benchmark"] - -[[package]] -name = "pre-commit" -version = "2.21.0" -description = "A framework for managing and maintaining multi-language pre-commit hooks." -optional = false -python-versions = ">=3.7" -files = [ - {file = "pre_commit-2.21.0-py2.py3-none-any.whl", hash = "sha256:e2f91727039fc39a92f58a588a25b87f936de6567eed4f0e673e0507edc75bad"}, - {file = "pre_commit-2.21.0.tar.gz", hash = "sha256:31ef31af7e474a8d8995027fefdfcf509b5c913ff31f2015b4ec4beb26a6f658"}, -] - -[package.dependencies] -cfgv = ">=2.0.0" -identify = ">=1.0.0" -nodeenv = ">=0.11.1" -pyyaml = ">=5.1" -virtualenv = ">=20.10.0" - -[[package]] -name = "pycodestyle" -version = "2.11.1" -description = "Python style guide checker" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pycodestyle-2.11.1-py2.py3-none-any.whl", hash = "sha256:44fe31000b2d866f2e41841b18528a505fbd7fef9017b04eff4e2648a0fadc67"}, - {file = "pycodestyle-2.11.1.tar.gz", hash = "sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f"}, -] - -[[package]] -name = "pydantic" -version = "2.8.2" -description = "Data validation using Python type hints" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pydantic-2.8.2-py3-none-any.whl", hash = "sha256:73ee9fddd406dc318b885c7a2eab8a6472b68b8fb5ba8150949fc3db939f23c8"}, - {file = "pydantic-2.8.2.tar.gz", hash = "sha256:6f62c13d067b0755ad1c21a34bdd06c0c12625a22b0fc09c6b149816604f7c2a"}, -] - -[package.dependencies] -annotated-types = ">=0.4.0" -pydantic-core = "2.20.1" -typing-extensions = {version = ">=4.6.1", markers = "python_version < \"3.13\""} - -[package.extras] -email = ["email-validator (>=2.0.0)"] - -[[package]] -name = "pydantic-core" -version = "2.20.1" -description = "Core functionality for Pydantic validation and serialization" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pydantic_core-2.20.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3acae97ffd19bf091c72df4d726d552c473f3576409b2a7ca36b2f535ffff4a3"}, - {file = "pydantic_core-2.20.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:41f4c96227a67a013e7de5ff8f20fb496ce573893b7f4f2707d065907bffdbd6"}, - {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f239eb799a2081495ea659d8d4a43a8f42cd1fe9ff2e7e436295c38a10c286a"}, - {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:53e431da3fc53360db73eedf6f7124d1076e1b4ee4276b36fb25514544ceb4a3"}, - {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f1f62b2413c3a0e846c3b838b2ecd6c7a19ec6793b2a522745b0869e37ab5bc1"}, - {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5d41e6daee2813ecceea8eda38062d69e280b39df793f5a942fa515b8ed67953"}, - {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d482efec8b7dc6bfaedc0f166b2ce349df0011f5d2f1f25537ced4cfc34fd98"}, - {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e93e1a4b4b33daed65d781a57a522ff153dcf748dee70b40c7258c5861e1768a"}, - {file = "pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e7c4ea22b6739b162c9ecaaa41d718dfad48a244909fe7ef4b54c0b530effc5a"}, - {file = "pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4f2790949cf385d985a31984907fecb3896999329103df4e4983a4a41e13e840"}, - {file = "pydantic_core-2.20.1-cp310-none-win32.whl", hash = "sha256:5e999ba8dd90e93d57410c5e67ebb67ffcaadcea0ad973240fdfd3a135506250"}, - {file = "pydantic_core-2.20.1-cp310-none-win_amd64.whl", hash = "sha256:512ecfbefef6dac7bc5eaaf46177b2de58cdf7acac8793fe033b24ece0b9566c"}, - {file = "pydantic_core-2.20.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d2a8fa9d6d6f891f3deec72f5cc668e6f66b188ab14bb1ab52422fe8e644f312"}, - {file = "pydantic_core-2.20.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:175873691124f3d0da55aeea1d90660a6ea7a3cfea137c38afa0a5ffabe37b88"}, - {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37eee5b638f0e0dcd18d21f59b679686bbd18917b87db0193ae36f9c23c355fc"}, - {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:25e9185e2d06c16ee438ed39bf62935ec436474a6ac4f9358524220f1b236e43"}, - {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:150906b40ff188a3260cbee25380e7494ee85048584998c1e66df0c7a11c17a6"}, - {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ad4aeb3e9a97286573c03df758fc7627aecdd02f1da04516a86dc159bf70121"}, - {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3f3ed29cd9f978c604708511a1f9c2fdcb6c38b9aae36a51905b8811ee5cbf1"}, - {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b0dae11d8f5ded51699c74d9548dcc5938e0804cc8298ec0aa0da95c21fff57b"}, - {file = "pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:faa6b09ee09433b87992fb5a2859efd1c264ddc37280d2dd5db502126d0e7f27"}, - {file = "pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9dc1b507c12eb0481d071f3c1808f0529ad41dc415d0ca11f7ebfc666e66a18b"}, - {file = "pydantic_core-2.20.1-cp311-none-win32.whl", hash = "sha256:fa2fddcb7107e0d1808086ca306dcade7df60a13a6c347a7acf1ec139aa6789a"}, - {file = "pydantic_core-2.20.1-cp311-none-win_amd64.whl", hash = "sha256:40a783fb7ee353c50bd3853e626f15677ea527ae556429453685ae32280c19c2"}, - {file = "pydantic_core-2.20.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:595ba5be69b35777474fa07f80fc260ea71255656191adb22a8c53aba4479231"}, - {file = "pydantic_core-2.20.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a4f55095ad087474999ee28d3398bae183a66be4823f753cd7d67dd0153427c9"}, - {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9aa05d09ecf4c75157197f27cdc9cfaeb7c5f15021c6373932bf3e124af029f"}, - {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e97fdf088d4b31ff4ba35db26d9cc472ac7ef4a2ff2badeabf8d727b3377fc52"}, - {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bc633a9fe1eb87e250b5c57d389cf28998e4292336926b0b6cdaee353f89a237"}, - {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d573faf8eb7e6b1cbbcb4f5b247c60ca8be39fe2c674495df0eb4318303137fe"}, - {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26dc97754b57d2fd00ac2b24dfa341abffc380b823211994c4efac7f13b9e90e"}, - {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:33499e85e739a4b60c9dac710c20a08dc73cb3240c9a0e22325e671b27b70d24"}, - {file = "pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:bebb4d6715c814597f85297c332297c6ce81e29436125ca59d1159b07f423eb1"}, - {file = "pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:516d9227919612425c8ef1c9b869bbbee249bc91912c8aaffb66116c0b447ebd"}, - {file = "pydantic_core-2.20.1-cp312-none-win32.whl", hash = "sha256:469f29f9093c9d834432034d33f5fe45699e664f12a13bf38c04967ce233d688"}, - {file = "pydantic_core-2.20.1-cp312-none-win_amd64.whl", hash = "sha256:035ede2e16da7281041f0e626459bcae33ed998cca6a0a007a5ebb73414ac72d"}, - {file = "pydantic_core-2.20.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:0827505a5c87e8aa285dc31e9ec7f4a17c81a813d45f70b1d9164e03a813a686"}, - {file = "pydantic_core-2.20.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:19c0fa39fa154e7e0b7f82f88ef85faa2a4c23cc65aae2f5aea625e3c13c735a"}, - {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa223cd1e36b642092c326d694d8bf59b71ddddc94cdb752bbbb1c5c91d833b"}, - {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c336a6d235522a62fef872c6295a42ecb0c4e1d0f1a3e500fe949415761b8a19"}, - {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7eb6a0587eded33aeefea9f916899d42b1799b7b14b8f8ff2753c0ac1741edac"}, - {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:70c8daf4faca8da5a6d655f9af86faf6ec2e1768f4b8b9d0226c02f3d6209703"}, - {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9fa4c9bf273ca41f940bceb86922a7667cd5bf90e95dbb157cbb8441008482c"}, - {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:11b71d67b4725e7e2a9f6e9c0ac1239bbc0c48cce3dc59f98635efc57d6dac83"}, - {file = "pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:270755f15174fb983890c49881e93f8f1b80f0b5e3a3cc1394a255706cabd203"}, - {file = "pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c81131869240e3e568916ef4c307f8b99583efaa60a8112ef27a366eefba8ef0"}, - {file = "pydantic_core-2.20.1-cp313-none-win32.whl", hash = "sha256:b91ced227c41aa29c672814f50dbb05ec93536abf8f43cd14ec9521ea09afe4e"}, - {file = "pydantic_core-2.20.1-cp313-none-win_amd64.whl", hash = "sha256:65db0f2eefcaad1a3950f498aabb4875c8890438bc80b19362cf633b87a8ab20"}, - {file = "pydantic_core-2.20.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:4745f4ac52cc6686390c40eaa01d48b18997cb130833154801a442323cc78f91"}, - {file = "pydantic_core-2.20.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a8ad4c766d3f33ba8fd692f9aa297c9058970530a32c728a2c4bfd2616d3358b"}, - {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41e81317dd6a0127cabce83c0c9c3fbecceae981c8391e6f1dec88a77c8a569a"}, - {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:04024d270cf63f586ad41fff13fde4311c4fc13ea74676962c876d9577bcc78f"}, - {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eaad4ff2de1c3823fddf82f41121bdf453d922e9a238642b1dedb33c4e4f98ad"}, - {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:26ab812fa0c845df815e506be30337e2df27e88399b985d0bb4e3ecfe72df31c"}, - {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c5ebac750d9d5f2706654c638c041635c385596caf68f81342011ddfa1e5598"}, - {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2aafc5a503855ea5885559eae883978c9b6d8c8993d67766ee73d82e841300dd"}, - {file = "pydantic_core-2.20.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:4868f6bd7c9d98904b748a2653031fc9c2f85b6237009d475b1008bfaeb0a5aa"}, - {file = "pydantic_core-2.20.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:aa2f457b4af386254372dfa78a2eda2563680d982422641a85f271c859df1987"}, - {file = "pydantic_core-2.20.1-cp38-none-win32.whl", hash = "sha256:225b67a1f6d602de0ce7f6c1c3ae89a4aa25d3de9be857999e9124f15dab486a"}, - {file = "pydantic_core-2.20.1-cp38-none-win_amd64.whl", hash = "sha256:6b507132dcfc0dea440cce23ee2182c0ce7aba7054576efc65634f080dbe9434"}, - {file = "pydantic_core-2.20.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:b03f7941783b4c4a26051846dea594628b38f6940a2fdc0df00b221aed39314c"}, - {file = "pydantic_core-2.20.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1eedfeb6089ed3fad42e81a67755846ad4dcc14d73698c120a82e4ccf0f1f9f6"}, - {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:635fee4e041ab9c479e31edda27fcf966ea9614fff1317e280d99eb3e5ab6fe2"}, - {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:77bf3ac639c1ff567ae3b47f8d4cc3dc20f9966a2a6dd2311dcc055d3d04fb8a"}, - {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ed1b0132f24beeec5a78b67d9388656d03e6a7c837394f99257e2d55b461611"}, - {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c6514f963b023aeee506678a1cf821fe31159b925c4b76fe2afa94cc70b3222b"}, - {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10d4204d8ca33146e761c79f83cc861df20e7ae9f6487ca290a97702daf56006"}, - {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2d036c7187b9422ae5b262badb87a20a49eb6c5238b2004e96d4da1231badef1"}, - {file = "pydantic_core-2.20.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9ebfef07dbe1d93efb94b4700f2d278494e9162565a54f124c404a5656d7ff09"}, - {file = "pydantic_core-2.20.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6b9d9bb600328a1ce523ab4f454859e9d439150abb0906c5a1983c146580ebab"}, - {file = "pydantic_core-2.20.1-cp39-none-win32.whl", hash = "sha256:784c1214cb6dd1e3b15dd8b91b9a53852aed16671cc3fbe4786f4f1db07089e2"}, - {file = "pydantic_core-2.20.1-cp39-none-win_amd64.whl", hash = "sha256:d2fe69c5434391727efa54b47a1e7986bb0186e72a41b203df8f5b0a19a4f669"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a45f84b09ac9c3d35dfcf6a27fd0634d30d183205230a0ebe8373a0e8cfa0906"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d02a72df14dfdbaf228424573a07af10637bd490f0901cee872c4f434a735b94"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2b27e6af28f07e2f195552b37d7d66b150adbaa39a6d327766ffd695799780f"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:084659fac3c83fd674596612aeff6041a18402f1e1bc19ca39e417d554468482"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:242b8feb3c493ab78be289c034a1f659e8826e2233786e36f2893a950a719bb6"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:38cf1c40a921d05c5edc61a785c0ddb4bed67827069f535d794ce6bcded919fc"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e0bbdd76ce9aa5d4209d65f2b27fc6e5ef1312ae6c5333c26db3f5ade53a1e99"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:254ec27fdb5b1ee60684f91683be95e5133c994cc54e86a0b0963afa25c8f8a6"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:407653af5617f0757261ae249d3fba09504d7a71ab36ac057c938572d1bc9331"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:c693e916709c2465b02ca0ad7b387c4f8423d1db7b4649c551f27a529181c5ad"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b5ff4911aea936a47d9376fd3ab17e970cc543d1b68921886e7f64bd28308d1"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:177f55a886d74f1808763976ac4efd29b7ed15c69f4d838bbd74d9d09cf6fa86"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:964faa8a861d2664f0c7ab0c181af0bea66098b1919439815ca8803ef136fc4e"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:4dd484681c15e6b9a977c785a345d3e378d72678fd5f1f3c0509608da24f2ac0"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f6d6cff3538391e8486a431569b77921adfcdef14eb18fbf19b7c0a5294d4e6a"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a6d511cc297ff0883bc3708b465ff82d7560193169a8b93260f74ecb0a5e08a7"}, - {file = "pydantic_core-2.20.1.tar.gz", hash = "sha256:26ca695eeee5f9f1aeeb211ffc12f10bcb6f71e2989988fda61dabd65db878d4"}, -] - -[package.dependencies] -typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" - -[[package]] -name = "pyflakes" -version = "3.1.0" -description = "passive checker of Python programs" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pyflakes-3.1.0-py2.py3-none-any.whl", hash = "sha256:4132f6d49cb4dae6819e5379898f2b8cce3c5f23994194c24b77d5da2e36f774"}, - {file = "pyflakes-3.1.0.tar.gz", hash = "sha256:a0aae034c444db0071aa077972ba4768d40c830d9539fd45bf4cd3f8f6992efc"}, -] - -[[package]] -name = "pytest" -version = "8.3.2" -description = "pytest: simple powerful testing with Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pytest-8.3.2-py3-none-any.whl", hash = "sha256:4ba08f9ae7dcf84ded419494d229b48d0903ea6407b030eaec46df5e6a73bba5"}, - {file = "pytest-8.3.2.tar.gz", hash = "sha256:c132345d12ce551242c87269de812483f5bcc87cdbb4722e48487ba194f9fdce"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "sys_platform == \"win32\""} -exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} -iniconfig = "*" -packaging = "*" -pluggy = ">=1.5,<2" -tomli = {version = ">=1", markers = "python_version < \"3.11\""} - -[package.extras] -dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] - -[[package]] -name = "pytest-asyncio" -version = "0.23.8" -description = "Pytest support for asyncio" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pytest_asyncio-0.23.8-py3-none-any.whl", hash = "sha256:50265d892689a5faefb84df80819d1ecef566eb3549cf915dfb33569359d1ce2"}, - {file = "pytest_asyncio-0.23.8.tar.gz", hash = "sha256:759b10b33a6dc61cce40a8bd5205e302978bbbcc00e279a8b61d9a6a3c82e4d3"}, -] - -[package.dependencies] -pytest = ">=7.0.0,<9" - -[package.extras] -docs = ["sphinx (>=5.3)", "sphinx-rtd-theme (>=1.0)"] -testing = ["coverage (>=6.2)", "hypothesis (>=5.7.1)"] - -[[package]] -name = "pytest-cov" -version = "5.0.0" -description = "Pytest plugin for measuring coverage." -optional = false -python-versions = ">=3.8" -files = [ - {file = "pytest-cov-5.0.0.tar.gz", hash = "sha256:5837b58e9f6ebd335b0f8060eecce69b662415b16dc503883a02f45dfeb14857"}, - {file = "pytest_cov-5.0.0-py3-none-any.whl", hash = "sha256:4f0764a1219df53214206bf1feea4633c3b558a2925c8b59f144f682861ce652"}, -] - -[package.dependencies] -coverage = {version = ">=5.2.1", extras = ["toml"]} -pytest = ">=4.6" - -[package.extras] -testing = ["fields", "hunter", "process-tests", "pytest-xdist", "virtualenv"] - -[[package]] -name = "pytest-dependency" -version = "0.6.0" -description = "Manage dependencies of tests" -optional = false -python-versions = ">=3.4" -files = [ - {file = "pytest-dependency-0.6.0.tar.gz", hash = "sha256:934b0e6a39d95995062c193f7eaeed8a8ffa06ff1bcef4b62b0dc74a708bacc1"}, -] - -[package.dependencies] -pytest = ">=3.7.0" -setuptools = "*" - -[[package]] -name = "pytest-mock" -version = "3.14.0" -description = "Thin-wrapper around the mock package for easier use with pytest" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pytest-mock-3.14.0.tar.gz", hash = "sha256:2719255a1efeceadbc056d6bf3df3d1c5015530fb40cf347c0f9afac88410bd0"}, - {file = "pytest_mock-3.14.0-py3-none-any.whl", hash = "sha256:0b72c38033392a5f4621342fe11e9219ac11ec9d375f8e2a0c164539e0d70f6f"}, -] - -[package.dependencies] -pytest = ">=6.2.5" - -[package.extras] -dev = ["pre-commit", "pytest-asyncio", "tox"] - -[[package]] -name = "pyyaml" -version = "6.0.2" -description = "YAML parser and emitter for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, - {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, - {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, - {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, - {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, - {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, - {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, - {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, - {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, - {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, - {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, - {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, - {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, - {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, - {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, - {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, - {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, - {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, - {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, - {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, - {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, - {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, - {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, - {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, - {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"}, - {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"}, - {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"}, - {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"}, - {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, - {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, - {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, - {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, - {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, - {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, - {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, -] - -[[package]] -name = "requests" -version = "2.32.3" -description = "Python HTTP for Humans." -optional = false -python-versions = ">=3.8" -files = [ - {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, - {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, -] - -[package.dependencies] -certifi = ">=2017.4.17" -charset-normalizer = ">=2,<4" -idna = ">=2.5,<4" -urllib3 = ">=1.21.1,<3" - -[package.extras] -socks = ["PySocks (>=1.5.6,!=1.5.7)"] -use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] - -[[package]] -name = "setuptools" -version = "73.0.0" -description = "Easily download, build, install, upgrade, and uninstall Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "setuptools-73.0.0-py3-none-any.whl", hash = "sha256:f2bfcce7ae1784d90b04c57c2802e8649e1976530bb25dc72c2b078d3ecf4864"}, - {file = "setuptools-73.0.0.tar.gz", hash = "sha256:3c08705fadfc8c7c445cf4d98078f0fafb9225775b2b4e8447e40348f82597c0"}, -] - -[package.extras] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.text (>=3.7)", "more-itertools (>=8.8)", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.11.*)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (<0.4)", "pytest-ruff (>=0.2.1)", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] - -[[package]] -name = "sniffio" -version = "1.3.1" -description = "Sniff out which async library your code is running under" -optional = false -python-versions = ">=3.7" -files = [ - {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}, - {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, -] - -[[package]] -name = "starlette" -version = "0.36.3" -description = "The little ASGI library that shines." -optional = false -python-versions = ">=3.8" -files = [ - {file = "starlette-0.36.3-py3-none-any.whl", hash = "sha256:13d429aa93a61dc40bf503e8c801db1f1bca3dc706b10ef2434a36123568f044"}, - {file = "starlette-0.36.3.tar.gz", hash = "sha256:90a671733cfb35771d8cc605e0b679d23b992f8dcfad48cc60b38cb29aeb7080"}, -] - -[package.dependencies] -anyio = ">=3.4.0,<5" -typing-extensions = {version = ">=3.10.0", markers = "python_version < \"3.10\""} - -[package.extras] -full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart (>=0.0.7)", "pyyaml"] - -[[package]] -name = "tomli" -version = "2.0.1" -description = "A lil' TOML parser" -optional = false -python-versions = ">=3.7" -files = [ - {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, - {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, -] - -[[package]] -name = "typing-extensions" -version = "4.12.2" -description = "Backported and Experimental Type Hints for Python 3.8+" -optional = false -python-versions = ">=3.8" -files = [ - {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, - {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, -] - -[[package]] -name = "urllib3" -version = "2.2.2" -description = "HTTP library with thread-safe connection pooling, file post, and more." -optional = false -python-versions = ">=3.8" -files = [ - {file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"}, - {file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"}, -] - -[package.extras] -brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] -h2 = ["h2 (>=4,<5)"] -socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] -zstd = ["zstandard (>=0.18.0)"] - -[[package]] -name = "virtualenv" -version = "20.26.3" -description = "Virtual Python Environment builder" -optional = false -python-versions = ">=3.7" -files = [ - {file = "virtualenv-20.26.3-py3-none-any.whl", hash = "sha256:8cc4a31139e796e9a7de2cd5cf2489de1217193116a8fd42328f1bd65f434589"}, - {file = "virtualenv-20.26.3.tar.gz", hash = "sha256:4c43a2a236279d9ea36a0d76f98d84bd6ca94ac4e0f4a3b9d46d05e10fea542a"}, -] - -[package.dependencies] -distlib = ">=0.3.7,<1" -filelock = ">=3.12.2,<4" -platformdirs = ">=3.9.1,<5" - -[package.extras] -docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2,!=7.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] -test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"] - -[metadata] -lock-version = "2.0" -python-versions = ">=3.9,<3.13" -content-hash = "943e573d66e0f64a5ce610f95d5afbdbd2b5ceb65732fd4bde167da390503414" diff --git a/r2r_python_sdk/pyproject.toml b/r2r_python_sdk/pyproject.toml deleted file mode 100644 index 7a05bb2d5..000000000 --- a/r2r_python_sdk/pyproject.toml +++ /dev/null @@ -1,54 +0,0 @@ -[build-system] -requires = ["poetry-core", "setuptools", "wheel"] -build-backend = "poetry.core.masonry.api" - -[tool.poetry] -name = "r2r" -version = "0.3.0" -description = "Lightweight Python SDK for R2R" -authors = ["Owen Colegrove "] -license = "MIT" -readme = "README.md" - -[tool.poetry.dependencies] -# Python Versions -python = ">=3.9,<3.13" -httpx = "^0.27.0" -nest-asyncio = "^1.6.0" -fastapi = "^0.109.2" - -[tool.poetry.group.dev.dependencies] -black = "^24.3.0" -codecov = "^2.1.13" -flake8 = "6.1.0" -isort = "5.12.0" -mypy = "^1.5.1" -pre-commit = "^2.9" -pytest = "^8.2.0" -pytest-asyncio = "^0.23.6" -pytest-dependency = "^0.6.0" -pytest-mock = "^3.14.0" -pytest-cov = "^5.0.0" -colorama = "^0.4.6" - -[tool.black] -line-length = 79 -target-version = ['py39'] -include = '\.pyi?$' -extend-exclude = ''' -/( - # directories - \.eggs - | \.git - | \.hg - | \.mypy_cache - | \.tox - | \.venv - | venv - | env - | build - | dist -)/ -''' -skip-string-normalization = true -skip-magic-trailing-comma = false diff --git a/r2r_python_sdk/r2r/__init__.py b/r2r_python_sdk/r2r/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/tests/regression/runner.py b/tests/regression/runner.py index 46e7cb3b2..8a0ceae5f 100644 --- a/tests/regression/runner.py +++ b/tests/regression/runner.py @@ -4,10 +4,10 @@ from typing import List from colorama import Fore, Style, init -from test_cases.base import BaseTest, RegressionTest # TODO: need to import this from the package, not from the local directory -from r2r_python_sdk.r2r.client import R2RClient +from r2r_python_sdk.sdk.client import R2RClient +from test_cases.base import BaseTest, RegressionTest class RegressionTestRunner: diff --git a/tests/regression/test_cases/base.py b/tests/regression/test_cases/base.py index aa2f96fb5..0859a2767 100644 --- a/tests/regression/test_cases/base.py +++ b/tests/regression/test_cases/base.py @@ -7,7 +7,7 @@ from deepdiff import DeepDiff # TODO: need to import this from the package, not from the local directory -from r2r_python_sdk.r2r.client import R2RClient +from r2r_python_sdk.sdk.client import R2RClient def _to_snake_case(name: str) -> str: diff --git a/tests/regression/test_cases/test_document_management.py b/tests/regression/test_cases/test_document_management.py index c6085af9c..67fadf64f 100644 --- a/tests/regression/test_cases/test_document_management.py +++ b/tests/regression/test_cases/test_document_management.py @@ -1,6 +1,7 @@ import os -from r2r_core import R2RException +from core import R2RException + from tests.regression.test_cases.base import BaseTest diff --git a/tests/test_abstractions.py b/tests/test_abstractions.py index 6597ba007..2e167e70e 100644 --- a/tests/test_abstractions.py +++ b/tests/test_abstractions.py @@ -3,8 +3,7 @@ from datetime import datetime import pytest - -from r2r_core import ( +from core import ( AsyncPipe, AsyncState, Prompt, @@ -14,8 +13,8 @@ VectorType, generate_id_from_label, ) -from r2r_core.base.abstractions.completion import CompletionRecord, MessageType -from r2r_core.base.abstractions.search import AggregateSearchResult +from core.base.abstractions.completion import CompletionRecord, MessageType +from core.base.abstractions.search import AggregateSearchResult @pytest.fixture(scope="session", autouse=True) diff --git a/tests/test_auth.py b/tests/test_auth.py index 1e4f4e693..152617f0e 100644 --- a/tests/test_auth.py +++ b/tests/test_auth.py @@ -3,8 +3,7 @@ from unittest.mock import Mock, patch import pytest - -from r2r_core import ( +from core import ( AuthConfig, BCryptConfig, BCryptProvider, @@ -13,7 +12,7 @@ R2RAuthProvider, R2RException, ) -from r2r_core.main.services import AuthService +from core.main.services import AuthService # Fixture for PostgresDBProvider diff --git a/tests/test_cli.py b/tests/test_cli.py index 79850a008..fa933eb0d 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -3,9 +3,8 @@ import click import pytest from click.testing import CliRunner - -from r2r_core.cli.cli import cli -from r2r_core.cli.utils.param_types import JSON +from core.cli.cli import cli +from core.cli.utils.param_types import JSON @pytest.fixture diff --git a/tests/test_client.py b/tests/test_client.py index 135121700..7751e6cf2 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -3,11 +3,7 @@ from unittest.mock import MagicMock import pytest -from fastapi import Body, Depends -from fastapi.security import OAuth2PasswordBearer -from fastapi.testclient import TestClient - -from r2r_core import ( +from core import ( DocumentInfo, R2RApp, R2RBuilder, @@ -16,9 +12,12 @@ Token, UserResponse, ) +from fastapi import Body, Depends +from fastapi.security import OAuth2PasswordBearer +from fastapi.testclient import TestClient # TODO: need to import this from the package, not from the local directory -from r2r_python_sdk.r2r.client import R2RClient +from r2r_python_sdk.sdk.client import R2RClient oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") diff --git a/tests/test_config.py b/tests/test_config.py index e26209110..e8e07273f 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -3,8 +3,7 @@ import pytest import toml - -from r2r_core import DocumentType, R2RConfig +from core import DocumentType, R2RConfig @pytest.fixture(scope="session", autouse=True) diff --git a/tests/test_database.py b/tests/test_database.py index d6f86135a..8999c52b0 100644 --- a/tests/test_database.py +++ b/tests/test_database.py @@ -2,16 +2,15 @@ import uuid import pytest -from dotenv import load_dotenv - -from r2r_core import ( +from core import ( DatabaseConfig, DatabaseProvider, Vector, VectorEntry, generate_id_from_label, ) -from r2r_core.providers import PostgresDBProvider +from core.providers import PostgresDBProvider +from dotenv import load_dotenv load_dotenv() diff --git a/tests/test_embedding.py b/tests/test_embedding.py index f565ecb40..8cca96d4f 100644 --- a/tests/test_embedding.py +++ b/tests/test_embedding.py @@ -2,8 +2,7 @@ from unittest.mock import patch import pytest - -from r2r_core import EmbeddingConfig +from core import EmbeddingConfig @pytest.fixture(scope="session", autouse=True) @@ -19,7 +18,7 @@ async def cleanup_tasks(): await asyncio.gather(*tasks, return_exceptions=True) -from r2r_core.providers import LiteLLMEmbeddingProvider +from core.providers import LiteLLMEmbeddingProvider @pytest.fixture @@ -200,7 +199,7 @@ async def test_litellm_async_get_embedding_error_handling(mocker): await provider.async_get_embedding("test") -from r2r_core.providers import OpenAIEmbeddingProvider +from core.providers import OpenAIEmbeddingProvider @pytest.fixture @@ -321,7 +320,7 @@ def test_openai_rerank_model_not_supported(): OpenAIEmbeddingProvider(config) -from r2r_core.providers import OllamaEmbeddingProvider +from core.providers import OllamaEmbeddingProvider @pytest.fixture diff --git a/tests/test_end_to_end.py b/tests/test_end_to_end.py index c9eabe7a2..3ff675544 100644 --- a/tests/test_end_to_end.py +++ b/tests/test_end_to_end.py @@ -3,9 +3,7 @@ import uuid import pytest -from fastapi.datastructures import UploadFile - -from r2r_core import ( +from core import ( Document, DocumentInfo, DocumentStatus, @@ -21,6 +19,7 @@ VectorSearchSettings, generate_id_from_label, ) +from fastapi.datastructures import UploadFile @pytest.fixture(scope="session", autouse=True) diff --git a/tests/test_groups.py b/tests/test_groups.py index 541e00960..2562bd38a 100644 --- a/tests/test_groups.py +++ b/tests/test_groups.py @@ -3,14 +3,9 @@ from uuid import UUID import pytest - -from r2r_core import DatabaseConfig, R2RException -from r2r_core.base.abstractions import ( - DocumentInfo, - DocumentStatus, - DocumentType, -) -from r2r_core.providers import BCryptConfig, BCryptProvider, PostgresDBProvider +from core import DatabaseConfig, R2RException +from core.base.abstractions import DocumentInfo, DocumentStatus, DocumentType +from core.providers import BCryptConfig, BCryptProvider, PostgresDBProvider # Add this fixture to create test documents diff --git a/tests/test_groups_client.py b/tests/test_groups_client.py index 2b1c756cd..de1a81fa4 100644 --- a/tests/test_groups_client.py +++ b/tests/test_groups_client.py @@ -3,20 +3,12 @@ from unittest.mock import MagicMock import pytest +from core import R2RApp, R2RBuilder, R2RClient, R2REngine, Token, UserResponse +from core.base import GroupResponse from fastapi import Depends from fastapi.security import OAuth2PasswordBearer from fastapi.testclient import TestClient -from r2r_core import ( - R2RApp, - R2RBuilder, - R2RClient, - R2REngine, - Token, - UserResponse, -) -from r2r_core.base import GroupResponse - oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") diff --git a/tests/test_ingestion_service.py b/tests/test_ingestion_service.py index 4d33d42ae..2fdc7fa01 100644 --- a/tests/test_ingestion_service.py +++ b/tests/test_ingestion_service.py @@ -6,10 +6,8 @@ from unittest.mock import AsyncMock, MagicMock, Mock import pytest -from fastapi import UploadFile - -from r2r_core import R2RAgents -from r2r_core.base import ( +from core import R2RAgents +from core.base import ( Document, DocumentInfo, R2RDocumentProcessingError, @@ -18,8 +16,9 @@ UserResponse, generate_id_from_label, ) -from r2r_core.main import R2RPipelines, R2RProviders -from r2r_core.main.services.ingestion_service import IngestionService +from core.main import R2RPipelines, R2RProviders +from core.main.services.ingestion_service import IngestionService +from fastapi import UploadFile logger = logging.getLogger(__name__) diff --git a/tests/test_llms.py b/tests/test_llms.py index 0708f9a84..0430d0459 100644 --- a/tests/test_llms.py +++ b/tests/test_llms.py @@ -3,13 +3,12 @@ from unittest.mock import AsyncMock, MagicMock, patch import pytest - -from r2r_core import CompletionConfig, GenerationConfig -from r2r_core.base.abstractions.llm import ( +from core import CompletionConfig, GenerationConfig +from core.base.abstractions.llm import ( LLMChatCompletion, LLMChatCompletionChunk, ) -from r2r_core.providers import LiteCompletionProvider, OpenAICompletionProvider +from core.providers import LiteCompletionProvider, OpenAICompletionProvider class MockCompletionResponse: diff --git a/tests/test_logging.py b/tests/test_logging.py index 659151c23..d58a32728 100644 --- a/tests/test_logging.py +++ b/tests/test_logging.py @@ -5,8 +5,7 @@ from uuid import UUID import pytest - -from r2r_core import ( +from core import ( LocalRunLoggingProvider, LoggingConfig, PostgresLoggingConfig, diff --git a/tests/test_parser.py b/tests/test_parser.py index c7fdec41c..be6108a1a 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -3,16 +3,15 @@ from unittest.mock import MagicMock, patch import pytest - -from r2r_core.parsers.media.docx_parser import DOCXParser -from r2r_core.parsers.media.pdf_parser import PDFParser -from r2r_core.parsers.media.ppt_parser import PPTParser -from r2r_core.parsers.structured.csv_parser import CSVParser -from r2r_core.parsers.structured.json_parser import JSONParser -from r2r_core.parsers.structured.xlsx_parser import XLSXParser -from r2r_core.parsers.text.html_parser import HTMLParser -from r2r_core.parsers.text.md_parser import MDParser -from r2r_core.parsers.text.text_parser import TextParser +from core.parsers.media.docx_parser import DOCXParser +from core.parsers.media.pdf_parser import PDFParser +from core.parsers.media.ppt_parser import PPTParser +from core.parsers.structured.csv_parser import CSVParser +from core.parsers.structured.json_parser import JSONParser +from core.parsers.structured.xlsx_parser import XLSXParser +from core.parsers.text.html_parser import HTMLParser +from core.parsers.text.md_parser import MDParser +from core.parsers.text.text_parser import TextParser @pytest.fixture(scope="session", autouse=True) diff --git a/tests/test_pipeline.py b/tests/test_pipeline.py index ff9773f6a..5a228821f 100644 --- a/tests/test_pipeline.py +++ b/tests/test_pipeline.py @@ -2,8 +2,7 @@ from typing import Any, AsyncGenerator import pytest - -from r2r_core import AsyncPipe, AsyncPipeline, PipeType +from core import AsyncPipe, AsyncPipeline, PipeType class MultiplierPipe(AsyncPipe): diff --git a/tests/test_vector_db.py b/tests/test_vector_db.py index 8396793e2..d4d1b0459 100644 --- a/tests/test_vector_db.py +++ b/tests/test_vector_db.py @@ -2,9 +2,8 @@ from uuid import UUID, uuid4 import pytest - -from r2r_core.base import DatabaseConfig, Vector, VectorEntry -from r2r_core.providers import PostgresDBProvider +from core.base import DatabaseConfig, Vector, VectorEntry +from core.providers import PostgresDBProvider @pytest.fixture From 289ccfb678ffca3defa21c87954d07b6d06c3047 Mon Sep 17 00:00:00 2001 From: NolanTrem <34580718+NolanTrem@users.noreply.github.com> Date: Tue, 20 Aug 2024 11:15:57 -0700 Subject: [PATCH 13/74] Make graspologic optional --- go/cli/go.mod | 2 +- go/cli/rag_operations.go | 181 --------------------------------- py/core/pipes/kg/clustering.py | 22 ++-- pyproject.toml | 3 +- 4 files changed, 16 insertions(+), 192 deletions(-) delete mode 100644 go/cli/rag_operations.go diff --git a/go/cli/go.mod b/go/cli/go.mod index da0ecc818..82992dc40 100644 --- a/go/cli/go.mod +++ b/go/cli/go.mod @@ -2,7 +2,7 @@ module r2r-cli go 1.23.0 -replace github.com/yourusername/r2r_go_sdk => ../r2r_go_sdk +replace github.com/yourusername/r2r_go_sdk => ../sdk require ( github.com/spf13/cobra v1.8.1 diff --git a/go/cli/rag_operations.go b/go/cli/rag_operations.go deleted file mode 100644 index dee23cd65..000000000 --- a/go/cli/rag_operations.go +++ /dev/null @@ -1,181 +0,0 @@ -package main - -import ( - "encoding/json" - "fmt" - - "github.com/spf13/cobra" - "github.com/yourusername/r2r_go_sdk/pkg/sdk" -) - -func init() { - rootCmd.AddCommand(ragCmd) -} - -func init() { - // rootCmd.AddCommand(inspectKnowledgeGraphCmd) - rootCmd.AddCommand(ragCmd) - rootCmd.AddCommand(searchCmd) -} - -var inspectKnowledgeGraphCmd = &cobra.Command{ - Use: "inspect-knowledge-graph", - Short: "Print relationships from the knowledge graph", - Run: withTimer(func(cmd *cobra.Command, args []string) { - client := sdk.NewClient("http://localhost:8000/v1", sdk.LogConfig{Verbose: true}) - limit, _ := cmd.Flags().GetInt("limit") - // printDescriptions, _ := cmd.Flags().GetBool("print-descriptions") - - response, err := client.InspectKnowledgeGraph() - if err != nil { - fmt.Printf("Error inspecting knowledge graph: %v\n", err) - return - } - fmt.Println(response) - }), -} - -var ragCmd = &cobra.Command{ - Use: "rag", - Short: "Perform a RAG query", - Run: withTimer(func(cmd *cobra.Command, args []string) { - client := sdk.NewClient("http://localhost:8000/v1", sdk.LogConfig{Verbose: true}) - query, _ := cmd.Flags().GetString("query") - useVectorSearch, _ := cmd.Flags().GetBool("use-vector-search") - filtersStr, _ := cmd.Flags().GetString("filters") - var filters map[string]interface{} - if filtersStr != "" { - json.Unmarshal([]byte(filtersStr), &filters) - } - searchLimit, _ := cmd.Flags().GetInt("search-limit") - doHybridSearch, _ := cmd.Flags().GetBool("do-hybrid-search") - useKgSearch, _ := cmd.Flags().GetBool("use-kg-search") - kgSearchModel, _ := cmd.Flags().GetString("kg-search-model") - stream, _ := cmd.Flags().GetBool("stream") - ragModel, _ := cmd.Flags().GetString("rag-model") - kgSearchType, _ := cmd.Flags().GetString("kg-search-type") - kgSearchLevel, _ := cmd.Flags().GetString("kg-search-level") - - generationConfig := sdk.GenerationConfig{ - Stream: stream, - } - if ragModel != "" { - generationConfig.Model = ragModel - } - - vectorSearchSettings := &sdk.VectorSearchSettings{ - UseVectorSearch: useVectorSearch, - Filters: filters, - SearchLimit: searchLimit, - DoHybridSearch: doHybridSearch, - } - - kgSearchSettings := &sdk.KGSearchSettings{ - UseKGSearch: useKgSearch, - Model: kgSearchModel, - SearchType: kgSearchType, - SearchLevel: kgSearchLevel, - } - - response, err := client.RAG(query, generationConfig, vectorSearchSettings, kgSearchSettings) - if err != nil { - fmt.Printf("Error performing RAG query: %v\n", err) - return - } - - if stream { - for chunk := range response.StreamingChannel { - fmt.Print(chunk) - } - fmt.Println() - } else { - fmt.Printf("Search Results:\n%s\n", response.SearchResults) - fmt.Printf("Completion:\n%s\n", response.Completion) - } - }), -} - -var searchCmd = &cobra.Command{ - Use: "search", - Short: "Perform a search query", - Run: withTimer(func(cmd *cobra.Command, args []string) { - client := sdk.NewClient("http://localhost:8000/v1", sdk.LogConfig{Verbose: true}) - query, _ := cmd.Flags().GetString("query") - useVectorSearch, _ := cmd.Flags().GetBool("use-vector-search") - filtersStr, _ := cmd.Flags().GetString("filters") - var filters map[string]interface{} - if filtersStr != "" { - json.Unmarshal([]byte(filtersStr), &filters) - } - searchLimit, _ := cmd.Flags().GetInt("search-limit") - doHybridSearch, _ := cmd.Flags().GetBool("do-hybrid-search") - useKgSearch, _ := cmd.Flags().GetBool("use-kg-search") - kgSearchModel, _ := cmd.Flags().GetString("kg-search-model") - kgSearchType, _ := cmd.Flags().GetString("kg-search-type") - kgSearchLevel, _ := cmd.Flags().GetString("kg-search-level") - - vectorSearchSettings := &sdk.VectorSearchSettings{ - UseVectorSearch: useVectorSearch, - Filters: filters, - SearchLimit: searchLimit, - DoHybridSearch: doHybridSearch, - } - - kgSearchSettings := &sdk.KGSearchSettings{ - UseKGSearch: useKgSearch, - Model: kgSearchModel, - SearchType: kgSearchType, - SearchLevel: kgSearchLevel, - } - - results, err := client.Search(query, vectorSearchSettings, kgSearchSettings) - if err != nil { - fmt.Printf("Error performing search: %v\n", err) - return - } - - fmt.Printf("KG_Search Enabled: %v\n", useKgSearch) - fmt.Printf("KG_Search Type: %s\n", kgSearchType) - - if len(results.VectorSearchResults) > 0 { - fmt.Println("Vector search results:") - for _, result := range results.VectorSearchResults { - fmt.Println(result) - } - } - - if len(results.KGSearchResults) > 0 { - fmt.Println("KG search results:") - for _, result := range results.KGSearchResults { - fmt.Println(result) - } - } - }), -} - -func init() { - inspectKnowledgeGraphCmd.Flags().Int("limit", 100, "Limit the number of relationships returned") - inspectKnowledgeGraphCmd.Flags().Bool("print-descriptions", false, "Print descriptions of entities and relationships") - - ragCmd.Flags().String("query", "", "The query for RAG") - ragCmd.Flags().Bool("use-vector-search", true, "Use vector search") - ragCmd.Flags().String("filters", "", "Search filters as JSON") - ragCmd.Flags().Int("search-limit", 10, "Number of search results to return") - ragCmd.Flags().Bool("do-hybrid-search", false, "Perform hybrid search") - ragCmd.Flags().Bool("use-kg-search", false, "Use knowledge graph search") - ragCmd.Flags().String("kg-search-model", "", "Model for KG agent") - ragCmd.Flags().Bool("stream", false, "Stream the RAG response") - ragCmd.Flags().String("rag-model", "", "Model for RAG") - ragCmd.Flags().String("kg-search-type", "global", "Local or Global") - ragCmd.Flags().String("kg-search-level", "", "Level of cluster to use for Global KG search") - - searchCmd.Flags().String("query", "", "The search query") - searchCmd.Flags().Bool("use-vector-search", true, "Use vector search") - searchCmd.Flags().String("filters", "", "Search filters as JSON") - searchCmd.Flags().Int("search-limit", 10, "Number of search results to return") - searchCmd.Flags().Bool("do-hybrid-search", false, "Perform hybrid search") - searchCmd.Flags().Bool("use-kg-search", false, "Use knowledge graph search") - searchCmd.Flags().String("kg-search-model", "", "Model for KG agent") - searchCmd.Flags().String("kg-search-type", "global", "Local or Global") - searchCmd.Flags().String("kg-search-level", "", "Level of KG search") -} diff --git a/py/core/pipes/kg/clustering.py b/py/core/pipes/kg/clustering.py index a31411f00..ed31eb3fd 100644 --- a/py/core/pipes/kg/clustering.py +++ b/py/core/pipes/kg/clustering.py @@ -23,7 +23,6 @@ RunLoggingSingleton, Triple, ) -from graspologic.partition import hierarchical_leiden logger = logging.getLogger(__name__) @@ -70,15 +69,20 @@ def _compute_leiden_communities( seed: int = 0xDEADBEEF, ) -> dict[int, dict[str, int]]: """Compute Leiden communities.""" - community_mapping = hierarchical_leiden( - graph, max_cluster_size=self.max_cluster_size, random_seed=seed - ) - results: dict[int, dict[str, int]] = {} - for partition in community_mapping: - results[partition.level] = results.get(partition.level, {}) - results[partition.level][partition.node] = partition.cluster + try: + from graspologic.partition import hierarchical_leiden - return results + community_mapping = hierarchical_leiden( + graph, max_cluster_size=self.max_cluster_size, random_seed=seed + ) + results: dict[int, dict[str, int]] = {} + for partition in community_mapping: + results[partition.level] = results.get(partition.level, {}) + results[partition.level][partition.node] = partition.cluster + + return results + except ImportError as e: + raise ImportError("Please install the graspologic package.") from e async def cluster_kg(self, triples: list[Triple]) -> list[Community]: """ diff --git a/pyproject.toml b/pyproject.toml index bf2a568bb..955fd579f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -66,9 +66,10 @@ core = [ "uvicorn", "aiosqlite", "asyncpg", "redis", "beautifulsoup4", "openpyxl", "markdown", "pypdf", "python-pptx", "python-docx", "vecs", "litellm", "openai", "fsspec", "posthog", "sqlalchemy", "ollama", "neo4j", "passlib", "bcrypt", - "pyjwt", "toml", "pyyaml", "poppler-utils", "psutil", "deepdiff", "graspologic" + "pyjwt", "toml", "pyyaml", "poppler-utils", "psutil", "deepdiff", ] ingest-movies = ["opencv-python", "moviepy"] +kgs = ["graspologic"] all = ["core", "ingest-movies"] [tool.poetry.group.dev.dependencies] From a1b649755aa8c6357f7a535ad0bcd59c4de51991 Mon Sep 17 00:00:00 2001 From: emrgnt-cmplxty <68796651+emrgnt-cmplxty@users.noreply.github.com> Date: Tue, 20 Aug 2024 11:38:26 -0700 Subject: [PATCH 14/74] fix rag stream (#895) --- py/sdk/client.py | 38 +++++++++++++++++++++++++++++++------- py/sdk/retrieval.py | 40 ++++++++++++++++++++++++---------------- 2 files changed, 55 insertions(+), 23 deletions(-) diff --git a/py/sdk/client.py b/py/sdk/client.py index a477c2a79..c037dc7d4 100644 --- a/py/sdk/client.py +++ b/py/sdk/client.py @@ -12,7 +12,7 @@ from .models import R2RException from .restructure import RestructureMethods from .retrieval import RetrievalMethods - +from typing import AsyncGenerator, Generator nest_asyncio.apply() # The empty args become necessary after a recent modification to `base_endpoint` @@ -76,7 +76,7 @@ def __init__( base_url: str = "http://localhost:8000", prefix: str = "/v1", custom_client=None, - timeout: float = 60.0, + timeout: float = 300.0, ): self.base_url = base_url self.prefix = prefix @@ -136,6 +136,19 @@ async def _make_request(self, method, endpoint, **kwargs): status_code=500, message=f"Request failed: {str(e)}" ) + + async def _make_streaming_request(self, method: str, endpoint: str, **kwargs) -> AsyncGenerator[str, None]: + url = f"{self.base_url}{self.prefix}/{endpoint}" + headers = kwargs.pop("headers", {}) + if self.access_token and endpoint not in ["register", "login", "verify_email"]: + headers.update(self._get_auth_header()) + + async with httpx.AsyncClient() as client: + async with client.stream(method, url, headers=headers, timeout=self.timeout, **kwargs) as response: + handle_request_error(response) + async for chunk in response.aiter_text(): + yield chunk + def _get_auth_header(self) -> dict: if not self.access_token: return {} @@ -175,15 +188,26 @@ class R2RClient: def __init__(self, *args, **kwargs): self.async_client = R2RAsyncClient(*args, **kwargs) + def _sync_generator(self, async_gen: AsyncGenerator) -> Generator: + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) + + try: + while True: + yield loop.run_until_complete(async_gen.__anext__()) + except StopAsyncIteration: + pass + finally: + loop.close() + def __getattr__(self, name): async_attr = getattr(self.async_client, name) if callable(async_attr): - def sync_wrapper(*args, **kwargs): - return asyncio.get_event_loop().run_until_complete( - async_attr(*args, **kwargs) - ) - + result = asyncio.get_event_loop().run_until_complete(async_attr(*args, **kwargs)) + if isinstance(result, AsyncGenerator): + return self._sync_generator(result) + return result return sync_wrapper return async_attr diff --git a/py/sdk/retrieval.py b/py/sdk/retrieval.py index 7769cf127..650d79185 100644 --- a/py/sdk/retrieval.py +++ b/py/sdk/retrieval.py @@ -103,16 +103,14 @@ async def rag( } if rag_generation_config.stream: - - async def stream_response(): - async for chunk in await client._make_request( - "POST", "rag", json=data, stream=True - ): - yield RAGResponse(**chunk) - - return stream_response() + return client._make_streaming_request( + "POST", + "rag", + json=data + ) else: return await client._make_request("POST", "rag", json=data) + @staticmethod async def agent( @@ -172,13 +170,23 @@ async def agent( } if rag_generation_config.stream: + return client._make_streaming_request( + "POST", + "agent", + json=data + ) + else: + return await client._make_request("POST", "rag", json=data) - async def stream_response(): - async for chunk in await client._make_request( - "POST", "agent", json=data, stream=True - ): - yield Message(**chunk) - return stream_response() - else: - return await client._make_request("POST", "agent", json=data) + # if rag_generation_config.stream: + + # async def stream_response(): + # async for chunk in await client._make_request( + # "POST", "agent", json=data, stream=True + # ): + # yield Message(**chunk) + + # return stream_response() + # else: + # return await client._make_request("POST", "agent", json=data) From 6a1a7b75e907311459ccb057124ff94e43d7df10 Mon Sep 17 00:00:00 2001 From: emrgnt-cmplxty <68796651+emrgnt-cmplxty@users.noreply.github.com> Date: Tue, 20 Aug 2024 12:12:36 -0700 Subject: [PATCH 15/74] add py r2r (#896) --- py/core/main/execution.py | 2 +- poetry.lock => py/poetry.lock | 27 ++++---- py/pyproject.toml | 127 ++++++++++++++++++++++++++++++++++ py/r2r/__init__.py | 16 +++++ py/sdk/retrieval.py | 4 -- 5 files changed, 157 insertions(+), 19 deletions(-) rename poetry.lock => py/poetry.lock (99%) create mode 100644 py/pyproject.toml create mode 100644 py/r2r/__init__.py diff --git a/py/core/main/execution.py b/py/core/main/execution.py index 78915de75..5f9c3f333 100644 --- a/py/core/main/execution.py +++ b/py/core/main/execution.py @@ -16,7 +16,6 @@ VectorSearchSettings, ) from fastapi import UploadFile -from sdk.client import R2RClient from .assembly.builder import R2RBuilder from .assembly.config import R2RConfig @@ -43,6 +42,7 @@ def __init__( self.base_url = base_url if self.client_mode: + from sdk.client import R2RClient self.client = R2RClient(base_url) self.app = None else: diff --git a/poetry.lock b/py/poetry.lock similarity index 99% rename from poetry.lock rename to py/poetry.lock index 54e7c651a..d6b949067 100644 --- a/poetry.lock +++ b/py/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. [[package]] name = "aiohappyeyeballs" @@ -827,7 +827,7 @@ files = [ name = "distro" version = "1.9.0" description = "Distro - an OS platform information API" -optional = true +optional = false python-versions = ">=3.6" files = [ {file = "distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2"}, @@ -1540,13 +1540,13 @@ setuptools = "*" [[package]] name = "importlib-metadata" -version = "8.3.0" +version = "8.4.0" description = "Read metadata from Python packages" optional = true python-versions = ">=3.8" files = [ - {file = "importlib_metadata-8.3.0-py3-none-any.whl", hash = "sha256:42817a4a0be5845d22c6e212db66a94ad261e2318d80b3e0d363894a79df2b67"}, - {file = "importlib_metadata-8.3.0.tar.gz", hash = "sha256:9c8fa6e8ea0f9516ad5c8db9246a731c948193c7754d3babb0114a05b27dd364"}, + {file = "importlib_metadata-8.4.0-py3-none-any.whl", hash = "sha256:66f342cc6ac9818fc6ff340576acd24d65ba0b3efabb2b4ac08b598965a4a2f1"}, + {file = "importlib_metadata-8.4.0.tar.gz", hash = "sha256:9a547d3bc3608b025f93d403fdd1aae741c24fbb8314df4b155675742ce303c5"}, ] [package.dependencies] @@ -1624,7 +1624,7 @@ i18n = ["Babel (>=2.7)"] name = "jiter" version = "0.5.0" description = "Fast iterable JSON parser." -optional = true +optional = false python-versions = ">=3.8" files = [ {file = "jiter-0.5.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b599f4e89b3def9a94091e6ee52e1d7ad7bc33e238ebb9c4c63f211d74822c3f"}, @@ -2571,7 +2571,7 @@ httpx = ">=0.27.0,<0.28.0" name = "openai" version = "1.41.1" description = "The official Python library for the openai API" -optional = true +optional = false python-versions = ">=3.7.1" files = [ {file = "openai-1.41.1-py3-none-any.whl", hash = "sha256:56fb04105263f79559aff3ceea2e1dd16f8c5385e8238cb66cf0e6888fa8bfcf"}, @@ -2610,11 +2610,11 @@ files = [ [package.dependencies] numpy = [ {version = ">=1.21.0", markers = "python_version == \"3.9\" and platform_system == \"Darwin\" and platform_machine == \"arm64\""}, + {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, + {version = ">=1.23.5", markers = "python_version >= \"3.11\" and python_version < \"3.12\""}, {version = ">=1.21.4", markers = "python_version >= \"3.10\" and platform_system == \"Darwin\" and python_version < \"3.11\""}, {version = ">=1.21.2", markers = "platform_system != \"Darwin\" and python_version >= \"3.10\" and python_version < \"3.11\""}, {version = ">=1.19.3", markers = "platform_system == \"Linux\" and platform_machine == \"aarch64\" and python_version >= \"3.8\" and python_version < \"3.10\" or python_version > \"3.9\" and python_version < \"3.10\" or python_version >= \"3.9\" and platform_system != \"Darwin\" and python_version < \"3.10\" or python_version >= \"3.9\" and platform_machine != \"arm64\" and python_version < \"3.10\""}, - {version = ">=1.23.5", markers = "python_version >= \"3.11\" and python_version < \"3.12\""}, - {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, ] [[package]] @@ -2697,8 +2697,8 @@ files = [ [package.dependencies] numpy = [ {version = ">=1.22.4", markers = "python_version < \"3.11\""}, - {version = ">=1.23.2", markers = "python_version == \"3.11\""}, {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, + {version = ">=1.23.2", markers = "python_version == \"3.11\""}, ] python-dateutil = ">=2.8.2" pytz = ">=2020.1" @@ -4416,7 +4416,7 @@ files = [ name = "tqdm" version = "4.66.5" description = "Fast, Extensible Progress Meter" -optional = true +optional = false python-versions = ">=3.7" files = [ {file = "tqdm-4.66.5-py3-none-any.whl", hash = "sha256:90279a3770753eafc9194a0364852159802111925aa30eb3f9d85b0e805ac7cd"}, @@ -4779,11 +4779,10 @@ doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linke test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy", "pytest-ruff (>=0.2.1)"] [extras] -all = [] core = ["aiosqlite", "asyncpg", "bcrypt", "beautifulsoup4", "deepdiff", "fire", "fsspec", "graspologic", "gunicorn", "litellm", "markdown", "neo4j", "ollama", "openai", "openpyxl", "passlib", "poppler-utils", "posthog", "psutil", "pydantic", "pyjwt", "pypdf", "python-docx", "python-multipart", "python-pptx", "pyyaml", "redis", "requests", "sqlalchemy", "toml", "types-requests", "uvicorn", "vecs"] -ingest-movies = ["moviepy", "opencv-python"] +core-ingest-movies = ["moviepy", "opencv-python"] [metadata] lock-version = "2.0" python-versions = ">=3.9,<3.13" -content-hash = "63c0d66d4c195c646341dcf5e1e863a898d30fc96abf58170eaa1e26faca8de0" +content-hash = "34b93bcd771abd4c1eb4f3ffb79f36a716835e721e46cd0767007201abf6d806" diff --git a/py/pyproject.toml b/py/pyproject.toml new file mode 100644 index 000000000..f96330fbf --- /dev/null +++ b/py/pyproject.toml @@ -0,0 +1,127 @@ +[build-system] +requires = ["poetry-core", "setuptools", "wheel"] +build-backend = "poetry.core.masonry.api" + +[tool.poetry] +name = "r2r" +readme = "../README.md" +version = "0.3.0" +description = "SciPhi R2R" +authors = ["Owen Colegrove "] +license = "MIT" +include = ["r2r.toml", "compose.yaml", "compose.neo4j.yaml", "compose.ollama.yaml", "compose.postgres.yaml", "pyproject.toml"] +packages = [ + { include = "r2r", from = "." }, + { include = "core", from = "." }, + { include = "sdk", from = "." }, +] + +[tool.poetry.dependencies] +# Python Versions +python = ">=3.9,<3.13" + +httpx = "^0.27.0" +nest-asyncio = "^1.6.0" +fastapi = "^0.109.2" + +# Core dependencies (optional) +openai = { version = "^1.11.1" } + +pydantic = { extras = ["email"], version = "^2.8.2", optional = true } +python-multipart = { version = "^0.0.9", optional = true } +fire = { version = "^0.5.0", optional = true } +gunicorn = { version = "^21.2.0", optional = true } +requests = { version = "^2.31.0", optional = true } +types-requests = { version = "^2.31.0", optional = true } +uvicorn = { version = "^0.27.0.post1", optional = true } +aiosqlite = { version = "^0.20.0", optional = true } +asyncpg = { version = "^0.29.0", optional = true } +redis = { version = "^5.0.4", optional = true } +beautifulsoup4 = { version = "^4.12.3", optional = true } +openpyxl = { version = "^3.1.2", optional = true } +markdown = { version = "^3.6", optional = true } +pypdf = { version = "^4.2.0", optional = true } +python-pptx = { version = "^0.6.23", optional = true } +python-docx = { version = "^1.1.0", optional = true } +opencv-python = { version = "^4.10.0.82", optional = true } +moviepy = { version = "^1.0.3", optional = true } +vecs = { version = "^0.4.0", optional = true } +litellm = { version = "^1.42.3", optional = true } +fsspec = { version = "^2024.6.0", optional = true } +posthog = { version = "^3.5.0", optional = true } +sqlalchemy = { version = "^2.0.30", optional = true } +ollama = { version = "^0.3.1", optional = true } +neo4j = { version = "^5.21.0", optional = true } +passlib = { version = "^1.7.4", optional = true } +bcrypt = { version = "^4.1.3", optional = true } +pyjwt = { version = "^2.8.0", optional = true } +toml = { version = "^0.10.2", optional = true } +pyyaml = { version = "^6.0.1", optional = true } +poppler-utils = { version = "^0.1.0", optional = true } +psutil = { version = "^6.0.0", optional = true } +deepdiff = { version = "^7.0.1", optional = true } +graspologic = { version = "^3.4.1", optional = true } + +[tool.poetry.extras] +core = [ + "pydantic", "python-multipart", "fire", "gunicorn", "requests", "types-requests", + "uvicorn", "aiosqlite", "asyncpg", "redis", "beautifulsoup4", "openpyxl", + "markdown", "pypdf", "python-pptx", "python-docx", "vecs", "litellm", "openai", + "fsspec", "posthog", "sqlalchemy", "ollama", "neo4j", "passlib", "bcrypt", + "pyjwt", "toml", "pyyaml", "poppler-utils", "psutil", "deepdiff", "graspologic" +] +core-ingest-movies = ["opencv-python", "moviepy"] + +[tool.poetry.group.dev.dependencies] +black = "^24.3.0" +codecov = "^2.1.13" +flake8 = "6.1.0" +isort = "5.12.0" +mypy = "^1.5.1" +pre-commit = "^2.9" +pytest = "^8.2.0" +pytest-asyncio = "^0.23.6" +pytest-dependency = "^0.6.0" +pytest-mock = "^3.14.0" +pytest-cov = "^5.0.0" +colorama = "^0.4.6" + +[tool.poetry.scripts] +r2r = "core.cli.cli:main" + +[tool.black] +line-length = 79 +target-version = ['py39'] +include = '\.pyi?$' +extend-exclude = ''' +/( + # directories + \.eggs + | \.git + | \.hg + | \.mypy_cache + | \.tox + | \.venv + | build + | dist +)/ +''' + +[tool.mypy] +ignore_missing_imports = true +exclude = 'playground/.*|deprecated/.*|dump/.*|docs/source|vecs/*' + +[[tool.mypy.overrides]] +module = "yaml" +ignore_missing_imports = true + +[tool.pytest.ini_options] +asyncio_mode = "auto" +addopts = "--cov=r2r --cov-report=term-missing --cov-report=xml" +testpaths = [ + "tests", +] +filterwarnings = [ + "ignore::DeprecationWarning", + "ignore::pytest.PytestUnraisableExceptionWarning", +] diff --git a/py/r2r/__init__.py b/py/r2r/__init__.py new file mode 100644 index 000000000..70e023ef8 --- /dev/null +++ b/py/r2r/__init__.py @@ -0,0 +1,16 @@ +from sdk import * + +__all__ = [ + # R2R SDK + "R2RAsyncClient", + "R2RClient", +] + +try: + from core import * + import core + __all__ += core.__all__ +except ImportError: + # Core dependencies not installed + pass + diff --git a/py/sdk/retrieval.py b/py/sdk/retrieval.py index 650d79185..ddd251a01 100644 --- a/py/sdk/retrieval.py +++ b/py/sdk/retrieval.py @@ -1,8 +1,5 @@ from typing import AsyncGenerator, Optional, Union -from core.base import VectorSearchSettings -from core.base.api.models import RAGResponse, SearchResponse - from .models import ( GenerationConfig, KGSearchSettings, @@ -12,7 +9,6 @@ VectorSearchSettings, ) - class RetrievalMethods: @staticmethod async def search( From 2df83a1d08c013eed8451db3c3f4bd553e918369 Mon Sep 17 00:00:00 2001 From: Nolan Tremelling <34580718+NolanTrem@users.noreply.github.com> Date: Tue, 20 Aug 2024 12:16:03 -0700 Subject: [PATCH 16/74] Clean up (#897) --- go/cli/rag_operations.go | 181 +++++++++++++++++++++ py/core/main/api/routes/retrieval/base.py | 38 +++-- py/core/main/assembly/config.py | 11 +- py/core/main/services/retrieval_service.py | 1 - py/sdk/client.py | 2 +- 5 files changed, 208 insertions(+), 25 deletions(-) create mode 100644 go/cli/rag_operations.go diff --git a/go/cli/rag_operations.go b/go/cli/rag_operations.go new file mode 100644 index 000000000..dee23cd65 --- /dev/null +++ b/go/cli/rag_operations.go @@ -0,0 +1,181 @@ +package main + +import ( + "encoding/json" + "fmt" + + "github.com/spf13/cobra" + "github.com/yourusername/r2r_go_sdk/pkg/sdk" +) + +func init() { + rootCmd.AddCommand(ragCmd) +} + +func init() { + // rootCmd.AddCommand(inspectKnowledgeGraphCmd) + rootCmd.AddCommand(ragCmd) + rootCmd.AddCommand(searchCmd) +} + +var inspectKnowledgeGraphCmd = &cobra.Command{ + Use: "inspect-knowledge-graph", + Short: "Print relationships from the knowledge graph", + Run: withTimer(func(cmd *cobra.Command, args []string) { + client := sdk.NewClient("http://localhost:8000/v1", sdk.LogConfig{Verbose: true}) + limit, _ := cmd.Flags().GetInt("limit") + // printDescriptions, _ := cmd.Flags().GetBool("print-descriptions") + + response, err := client.InspectKnowledgeGraph() + if err != nil { + fmt.Printf("Error inspecting knowledge graph: %v\n", err) + return + } + fmt.Println(response) + }), +} + +var ragCmd = &cobra.Command{ + Use: "rag", + Short: "Perform a RAG query", + Run: withTimer(func(cmd *cobra.Command, args []string) { + client := sdk.NewClient("http://localhost:8000/v1", sdk.LogConfig{Verbose: true}) + query, _ := cmd.Flags().GetString("query") + useVectorSearch, _ := cmd.Flags().GetBool("use-vector-search") + filtersStr, _ := cmd.Flags().GetString("filters") + var filters map[string]interface{} + if filtersStr != "" { + json.Unmarshal([]byte(filtersStr), &filters) + } + searchLimit, _ := cmd.Flags().GetInt("search-limit") + doHybridSearch, _ := cmd.Flags().GetBool("do-hybrid-search") + useKgSearch, _ := cmd.Flags().GetBool("use-kg-search") + kgSearchModel, _ := cmd.Flags().GetString("kg-search-model") + stream, _ := cmd.Flags().GetBool("stream") + ragModel, _ := cmd.Flags().GetString("rag-model") + kgSearchType, _ := cmd.Flags().GetString("kg-search-type") + kgSearchLevel, _ := cmd.Flags().GetString("kg-search-level") + + generationConfig := sdk.GenerationConfig{ + Stream: stream, + } + if ragModel != "" { + generationConfig.Model = ragModel + } + + vectorSearchSettings := &sdk.VectorSearchSettings{ + UseVectorSearch: useVectorSearch, + Filters: filters, + SearchLimit: searchLimit, + DoHybridSearch: doHybridSearch, + } + + kgSearchSettings := &sdk.KGSearchSettings{ + UseKGSearch: useKgSearch, + Model: kgSearchModel, + SearchType: kgSearchType, + SearchLevel: kgSearchLevel, + } + + response, err := client.RAG(query, generationConfig, vectorSearchSettings, kgSearchSettings) + if err != nil { + fmt.Printf("Error performing RAG query: %v\n", err) + return + } + + if stream { + for chunk := range response.StreamingChannel { + fmt.Print(chunk) + } + fmt.Println() + } else { + fmt.Printf("Search Results:\n%s\n", response.SearchResults) + fmt.Printf("Completion:\n%s\n", response.Completion) + } + }), +} + +var searchCmd = &cobra.Command{ + Use: "search", + Short: "Perform a search query", + Run: withTimer(func(cmd *cobra.Command, args []string) { + client := sdk.NewClient("http://localhost:8000/v1", sdk.LogConfig{Verbose: true}) + query, _ := cmd.Flags().GetString("query") + useVectorSearch, _ := cmd.Flags().GetBool("use-vector-search") + filtersStr, _ := cmd.Flags().GetString("filters") + var filters map[string]interface{} + if filtersStr != "" { + json.Unmarshal([]byte(filtersStr), &filters) + } + searchLimit, _ := cmd.Flags().GetInt("search-limit") + doHybridSearch, _ := cmd.Flags().GetBool("do-hybrid-search") + useKgSearch, _ := cmd.Flags().GetBool("use-kg-search") + kgSearchModel, _ := cmd.Flags().GetString("kg-search-model") + kgSearchType, _ := cmd.Flags().GetString("kg-search-type") + kgSearchLevel, _ := cmd.Flags().GetString("kg-search-level") + + vectorSearchSettings := &sdk.VectorSearchSettings{ + UseVectorSearch: useVectorSearch, + Filters: filters, + SearchLimit: searchLimit, + DoHybridSearch: doHybridSearch, + } + + kgSearchSettings := &sdk.KGSearchSettings{ + UseKGSearch: useKgSearch, + Model: kgSearchModel, + SearchType: kgSearchType, + SearchLevel: kgSearchLevel, + } + + results, err := client.Search(query, vectorSearchSettings, kgSearchSettings) + if err != nil { + fmt.Printf("Error performing search: %v\n", err) + return + } + + fmt.Printf("KG_Search Enabled: %v\n", useKgSearch) + fmt.Printf("KG_Search Type: %s\n", kgSearchType) + + if len(results.VectorSearchResults) > 0 { + fmt.Println("Vector search results:") + for _, result := range results.VectorSearchResults { + fmt.Println(result) + } + } + + if len(results.KGSearchResults) > 0 { + fmt.Println("KG search results:") + for _, result := range results.KGSearchResults { + fmt.Println(result) + } + } + }), +} + +func init() { + inspectKnowledgeGraphCmd.Flags().Int("limit", 100, "Limit the number of relationships returned") + inspectKnowledgeGraphCmd.Flags().Bool("print-descriptions", false, "Print descriptions of entities and relationships") + + ragCmd.Flags().String("query", "", "The query for RAG") + ragCmd.Flags().Bool("use-vector-search", true, "Use vector search") + ragCmd.Flags().String("filters", "", "Search filters as JSON") + ragCmd.Flags().Int("search-limit", 10, "Number of search results to return") + ragCmd.Flags().Bool("do-hybrid-search", false, "Perform hybrid search") + ragCmd.Flags().Bool("use-kg-search", false, "Use knowledge graph search") + ragCmd.Flags().String("kg-search-model", "", "Model for KG agent") + ragCmd.Flags().Bool("stream", false, "Stream the RAG response") + ragCmd.Flags().String("rag-model", "", "Model for RAG") + ragCmd.Flags().String("kg-search-type", "global", "Local or Global") + ragCmd.Flags().String("kg-search-level", "", "Level of cluster to use for Global KG search") + + searchCmd.Flags().String("query", "", "The search query") + searchCmd.Flags().Bool("use-vector-search", true, "Use vector search") + searchCmd.Flags().String("filters", "", "Search filters as JSON") + searchCmd.Flags().Int("search-limit", 10, "Number of search results to return") + searchCmd.Flags().Bool("do-hybrid-search", false, "Perform hybrid search") + searchCmd.Flags().Bool("use-kg-search", false, "Use knowledge graph search") + searchCmd.Flags().String("kg-search-model", "", "Model for KG agent") + searchCmd.Flags().String("kg-search-type", "global", "Local or Global") + searchCmd.Flags().String("kg-search-level", "", "Level of KG search") +} diff --git a/py/core/main/api/routes/retrieval/base.py b/py/core/main/api/routes/retrieval/base.py index 8fbe4f3c1..ab45eda1b 100644 --- a/py/core/main/api/routes/retrieval/base.py +++ b/py/core/main/api/routes/retrieval/base.py @@ -6,6 +6,7 @@ GenerationConfig, KGSearchSettings, Message, + R2RException, RunType, VectorSearchSettings, ) @@ -224,23 +225,26 @@ async def agent_app( vector_search_settings.filters = filters - response = await self.engine.arag_agent( - messages=messages, - vector_search_settings=vector_search_settings, - kg_search_settings=kg_search_settings, - rag_generation_config=rag_generation_config, - task_prompt_override=task_prompt_override, - include_title_if_available=include_title_if_available, - ) + try: + response = await self.engine.arag_agent( + messages=messages, + vector_search_settings=vector_search_settings, + kg_search_settings=kg_search_settings, + rag_generation_config=rag_generation_config, + task_prompt_override=task_prompt_override, + include_title_if_available=include_title_if_available, + ) - if rag_generation_config.stream: + if rag_generation_config.stream: - async def stream_generator(): - async for chunk in response: - yield chunk + async def stream_generator(): + async for chunk in response: + yield chunk - return StreamingResponse( - stream_generator(), media_type="application/json" - ) - else: - return response + return StreamingResponse( + stream_generator(), media_type="application/json" + ) + else: + return response + except Exception as e: + raise R2RException(str(e), 500) diff --git a/py/core/main/assembly/config.py b/py/core/main/assembly/config.py index b52819f4b..ab2494587 100644 --- a/py/core/main/assembly/config.py +++ b/py/core/main/assembly/config.py @@ -102,8 +102,9 @@ def _validate_config_section( ): if section not in config_data: raise ValueError(f"Missing '{section}' section in config") - missing_keys = [key for key in keys if key not in config_data[section]] - if missing_keys: + if missing_keys := [ + key for key in keys if key not in config_data[section] + ]: raise ValueError( f"Missing required keys in '{section}' config: {', '.join(missing_keys)}" ) @@ -171,13 +172,11 @@ def _serialize_config(config_section: Any) -> dict: return config_section.value elif isinstance(config_section, BaseModel): return R2RConfig._serialize_config( - config_section.dict(exclude_none=True) + config_section.model_dump(exclude_none=True) ) else: return config_section @staticmethod def _serialize_key(key: Any) -> str: - if isinstance(key, Enum): - return key.value - return str(key) + return key.value if isinstance(key, Enum) else str(key) diff --git a/py/core/main/services/retrieval_service.py b/py/core/main/services/retrieval_service.py index c299f17e1..ca58ab1fa 100644 --- a/py/core/main/services/retrieval_service.py +++ b/py/core/main/services/retrieval_service.py @@ -306,7 +306,6 @@ async def stream_response(): value=latency, ) return results - except Exception as e: logger.error(f"Pipeline error: {str(e)}") if "NoneType" in str(e): diff --git a/py/sdk/client.py b/py/sdk/client.py index c037dc7d4..fcca73f46 100644 --- a/py/sdk/client.py +++ b/py/sdk/client.py @@ -134,7 +134,7 @@ async def _make_request(self, method, endpoint, **kwargs): except httpx.RequestError as e: raise R2RException( status_code=500, message=f"Request failed: {str(e)}" - ) + ) from e async def _make_streaming_request(self, method: str, endpoint: str, **kwargs) -> AsyncGenerator[str, None]: From 4e0034f296b83648521c8f2c21246b30c0a63bbe Mon Sep 17 00:00:00 2001 From: emrgnt-cmplxty <68796651+emrgnt-cmplxty@users.noreply.github.com> Date: Tue, 20 Aug 2024 12:27:52 -0700 Subject: [PATCH 17/74] fix agent (#898) --- py/core/base/abstractions/__init__.py | 2 + py/core/base/abstractions/llm.py | 29 ++++++++- .../base/api/models/retrieval/responses.py | 63 ++----------------- py/core/main/api/routes/retrieval/base.py | 1 - py/sdk/retrieval.py | 15 +---- 5 files changed, 35 insertions(+), 75 deletions(-) diff --git a/py/core/base/abstractions/__init__.py b/py/core/base/abstractions/__init__.py index 6ea82c364..1245a7e4c 100644 --- a/py/core/base/abstractions/__init__.py +++ b/py/core/base/abstractions/__init__.py @@ -24,6 +24,7 @@ GenerationConfig, LLMChatCompletion, LLMChatCompletionChunk, + Message, RAGCompletion, ) from .prompt import Prompt @@ -70,6 +71,7 @@ "GenerationConfig", "LLMChatCompletion", "LLMChatCompletionChunk", + "Message", "RAGCompletion", # Prompt abstractions "Prompt", diff --git a/py/core/base/abstractions/llm.py b/py/core/base/abstractions/llm.py index 487cd046f..6ab140c84 100644 --- a/py/core/base/abstractions/llm.py +++ b/py/core/base/abstractions/llm.py @@ -1,7 +1,8 @@ """Abstractions for the LLM model.""" -from typing import TYPE_CHECKING, ClassVar, Optional +from typing import TYPE_CHECKING, ClassVar, Optional, Union, Any +from enum import Enum from openai.types.chat import ChatCompletion, ChatCompletionChunk from pydantic import BaseModel, Field @@ -100,3 +101,29 @@ class Config: "add_generation_kwargs": None, "api_base": None, } + +class MessageType(Enum): + SYSTEM = "system" + USER = "user" + ASSISTANT = "assistant" + FUNCTION = "function" + TOOL = "tool" + + def __str__(self): + return self.value + +class Message(BaseModel): + role: Union[MessageType, str] + content: Optional[str] = None + name: Optional[str] = None + function_call: Optional[dict[str, Any]] = None + tool_calls: Optional[list[dict[str, Any]]] = None + + class Config: + json_schema_extra = { + "role": "user", + "content": "This is a test message.", + "name": None, + "function_call": None, + "tool_calls": None, + } \ No newline at end of file diff --git a/py/core/base/api/models/retrieval/responses.py b/py/core/base/api/models/retrieval/responses.py index 2ebac059a..dbf601990 100644 --- a/py/core/base/api/models/retrieval/responses.py +++ b/py/core/base/api/models/retrieval/responses.py @@ -1,12 +1,12 @@ -from typing import Any, List, Optional +from typing import Any, Optional -from core.base.abstractions.search import KGSearchResult, VectorSearchResult +from core.base.abstractions import KGSearchResult, VectorSearchResult, Message from core.base.api.models.base import ResultsWrapper from pydantic import BaseModel, Field class SearchResponse(BaseModel): - vector_search_results: List[VectorSearchResult] = Field( + vector_search_results: list[VectorSearchResult] = Field( ..., description="List of vector search results", ) @@ -87,62 +87,7 @@ class Config: } } - -class RAGAgentResponse(BaseModel): - completion: Any = Field( - ..., - description="The generated completion from the RAG agent process", - ) - search_results: SearchResponse = Field( - ..., - description="The search results used for the RAG agent process", - ) - thought_process: Optional[str] = Field( - None, - description="The agent's thought process or reasoning", - ) - - class Config: - json_schema_extra = { - "example": { - "completion": { - "id": "chatcmpl-example456", - "choices": [ - { - "finish_reason": "stop", - "index": 0, - "logprobs": None, - "message": { - "content": "The capital of France is Paris. Paris is not only the capital but also the largest city in France, known for its iconic landmarks such as the Eiffel Tower, the Louvre Museum, and Notre-Dame Cathedral.", - "role": "assistant", - }, - } - ], - }, - "search_results": { - "vector_search_results": [ - { - "fragment_id": "d79ef23a-fc23-5452-8f49-d7bd46088a96", - "extraction_id": "4f3d47f3-8baf-58eb-8bc2-0171fb1c6e09", - "document_id": "5e157b3a-8469-51db-90d9-52e7d896b49b", - "user_id": "3acb499e-8428-543b-bd85-0d9098718220", - "group_ids": [], - "score": 0.89943702876567796, - "text": "Paris is the capital and most populous city of France. It is known for its iconic landmarks such as the Eiffel Tower, the Louvre Museum, and Notre-Dame Cathedral.", - "metadata": { - "title": "france_geography.pdf", - "associatedQuery": "What is the capital of France?", - }, - } - ], - "kg_search_results": None, - }, - "thought_process": "To answer this question, I'll need to search for information about France's capital. The search results provide clear information about Paris being the capital of France, along with some additional details about its landmarks.", - } - } - - # Create wrapped versions of the responses WrappedSearchResponse = ResultsWrapper[SearchResponse] WrappedRAGResponse = ResultsWrapper[RAGResponse] -WrappedRAGAgentResponse = ResultsWrapper[RAGAgentResponse] +WrappedRAGAgentResponse = ResultsWrapper[list[Message]] diff --git a/py/core/main/api/routes/retrieval/base.py b/py/core/main/api/routes/retrieval/base.py index ab45eda1b..fb13b6755 100644 --- a/py/core/main/api/routes/retrieval/base.py +++ b/py/core/main/api/routes/retrieval/base.py @@ -155,7 +155,6 @@ async def rag_app( ) if rag_generation_config.stream: - async def stream_generator(): async for chunk in response: yield chunk diff --git a/py/sdk/retrieval.py b/py/sdk/retrieval.py index ddd251a01..5852592dc 100644 --- a/py/sdk/retrieval.py +++ b/py/sdk/retrieval.py @@ -172,17 +172,4 @@ async def agent( json=data ) else: - return await client._make_request("POST", "rag", json=data) - - - # if rag_generation_config.stream: - - # async def stream_response(): - # async for chunk in await client._make_request( - # "POST", "agent", json=data, stream=True - # ): - # yield Message(**chunk) - - # return stream_response() - # else: - # return await client._make_request("POST", "agent", json=data) + return await client._make_request("POST", "agent", json=data) \ No newline at end of file From 3519338437db55c7f06cd8c2ed806bb7fd7c9d20 Mon Sep 17 00:00:00 2001 From: emrgnt-cmplxty <68796651+emrgnt-cmplxty@users.noreply.github.com> Date: Tue, 20 Aug 2024 12:31:39 -0700 Subject: [PATCH 18/74] define `RAGAgentResponse` (#899) --- py/core/base/api/models/retrieval/responses.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/py/core/base/api/models/retrieval/responses.py b/py/core/base/api/models/retrieval/responses.py index dbf601990..6048b4433 100644 --- a/py/core/base/api/models/retrieval/responses.py +++ b/py/core/base/api/models/retrieval/responses.py @@ -87,7 +87,8 @@ class Config: } } +RAGAgentResponse = list[Message] # Create wrapped versions of the responses WrappedSearchResponse = ResultsWrapper[SearchResponse] WrappedRAGResponse = ResultsWrapper[RAGResponse] -WrappedRAGAgentResponse = ResultsWrapper[list[Message]] +WrappedRAGAgentResponse = ResultsWrapper[RAGAgentResponse] From 675a18c4b701ed24f5377d6a99e91a14c7aa9217 Mon Sep 17 00:00:00 2001 From: Shreyas Pimpalgaonkar Date: Tue, 20 Aug 2024 16:34:54 -0400 Subject: [PATCH 19/74] Shreyas/unstructured (#900) * api + oss lib * rm pdb * rm poetry lock * update version * fixes --- py/core/base/providers/chunking.py | 6 +- py/core/base/providers/parsing.py | 4 +- py/core/configs/unstructured.toml | 8 ++ py/core/main/assembly/config.py | 2 +- py/core/main/assembly/factory.py | 4 +- py/core/pipes/ingestion/chunking_pipe.py | 6 +- py/core/providers/chunking/r2r_chunking.py | 12 ++- .../chunking/unstructured_chunking.py | 39 ++++++---- .../providers/parsing/unstructured_parsing.py | 74 ++++++++++++++++++- pyproject.toml | 2 +- 10 files changed, 125 insertions(+), 32 deletions(-) create mode 100644 py/core/configs/unstructured.toml diff --git a/py/core/base/providers/chunking.py b/py/core/base/providers/chunking.py index 6b2bab04b..6d20a07a0 100644 --- a/py/core/base/providers/chunking.py +++ b/py/core/base/providers/chunking.py @@ -1,9 +1,9 @@ from abc import ABC, abstractmethod from enum import Enum -from typing import AsyncGenerator, Optional +from typing import AsyncGenerator, Optional, Union from .base import Provider, ProviderConfig - +from ..abstractions.document import DocumentExtraction class Method(str, Enum): BY_TITLE = "by_title" @@ -57,6 +57,6 @@ def __init__(self, config: ChunkingConfig): self.config = config @abstractmethod - async def chunk(self, parsed_document: str) -> AsyncGenerator[str, None]: + async def chunk(self, parsed_document: Union[str, DocumentExtraction]) -> AsyncGenerator[str, None]: """Chunk the parsed document using the configured chunking strategy.""" pass diff --git a/py/core/base/providers/parsing.py b/py/core/base/providers/parsing.py index 4a572d35d..ef9e4ef95 100644 --- a/py/core/base/providers/parsing.py +++ b/py/core/base/providers/parsing.py @@ -5,6 +5,7 @@ from ..abstractions.document import Document, DocumentType from .base import Provider, ProviderConfig +from .chunking import ChunkingConfig class OverrideParser(BaseModel): @@ -16,10 +17,11 @@ class ParsingConfig(ProviderConfig): provider: str = "r2r" excluded_parsers: List[DocumentType] = Field(default_factory=list) override_parsers: List[OverrideParser] = Field(default_factory=list) + chunking_config: ChunkingConfig = Field(default_factory=ChunkingConfig) @property def supported_providers(self) -> list[str]: - return ["r2r", "unstructured", None] + return ["r2r", "unstructured", 'unstructured_api', None] def validate(self) -> None: if self.provider not in self.supported_providers: diff --git a/py/core/configs/unstructured.toml b/py/core/configs/unstructured.toml new file mode 100644 index 000000000..8c2a00237 --- /dev/null +++ b/py/core/configs/unstructured.toml @@ -0,0 +1,8 @@ +[parsing] +provider = "unstructured_api" + +[chunking] +provider = "unstructured" +method = "recursive" +chunk_size = 512 +chunk_overlap = 50 \ No newline at end of file diff --git a/py/core/main/assembly/config.py b/py/core/main/assembly/config.py index ab2494587..a26481a24 100644 --- a/py/core/main/assembly/config.py +++ b/py/core/main/assembly/config.py @@ -93,7 +93,7 @@ def __init__(self, config_data: dict[str, Any]): self.embedding = EmbeddingConfig.create(**self.embedding) self.kg = KGConfig.create(**self.kg) self.logging = LoggingConfig.create(**self.logging) - self.parsing = ParsingConfig.create(**self.parsing) + self.parsing = ParsingConfig.create(chunking_config=self.chunking, **self.parsing) self.prompt = PromptConfig.create(**self.prompt) self.agent = AgentConfig.create(**self.agent) diff --git a/py/core/main/assembly/factory.py b/py/core/main/assembly/factory.py index 7b012548c..8a7e24805 100644 --- a/py/core/main/assembly/factory.py +++ b/py/core/main/assembly/factory.py @@ -91,10 +91,10 @@ def create_parsing_provider( from core.providers import R2RParsingProvider return R2RParsingProvider(parsing_config) - elif parsing_config.provider == "unstructured": + elif parsing_config.provider == "unstructured" or parsing_config.provider == "unstructured_api": from core.providers import UnstructuredParsingProvider - return UnstructuredParsingProvider(parsing_config) + return UnstructuredParsingProvider(parsing_config.provider == "unstructured_api", parsing_config) else: raise ValueError( f"Parsing provider {parsing_config.provider} not supported" diff --git a/py/core/pipes/ingestion/chunking_pipe.py b/py/core/pipes/ingestion/chunking_pipe.py index e95ba350e..e79be5407 100644 --- a/py/core/pipes/ingestion/chunking_pipe.py +++ b/py/core/pipes/ingestion/chunking_pipe.py @@ -1,3 +1,4 @@ +import logging from typing import Any, AsyncGenerator, Optional, Union from core.base import ( @@ -14,6 +15,7 @@ from core.base.pipes.base_pipe import AsyncPipe from core.providers import R2RChunkingProvider +logger = logging.getLogger(__name__) class ChunkingPipe(AsyncPipe): class Input(AsyncPipe.Input): @@ -64,7 +66,7 @@ async def _run_logic( try: iteration = 0 - async for chunk in chunking_provider.chunk(item.data): + async for chunk in chunking_provider.chunk(item): item.metadata["chunk_order"] = iteration yield DocumentFragment( id=generate_id_from_label(f"{item.id}-{iteration}"), @@ -77,6 +79,8 @@ async def _run_logic( ) iteration += 1 except Exception as e: + logger.error(f"Error chunking document: {str(e)}") + # print the traceback yield R2RDocumentProcessingError( document_id=item.document_id, error_message=f"Error chunking document: {str(e)}", diff --git a/py/core/providers/chunking/r2r_chunking.py b/py/core/providers/chunking/r2r_chunking.py index f391c56a2..4baed4768 100644 --- a/py/core/providers/chunking/r2r_chunking.py +++ b/py/core/providers/chunking/r2r_chunking.py @@ -1,4 +1,4 @@ -from typing import Any, AsyncGenerator +from typing import Any, AsyncGenerator, Union from core.base import ( ChunkingConfig, @@ -8,6 +8,8 @@ TextSplitter, ) +from core.base import ChunkingProvider, Method +from core.base.abstractions.document import DocumentExtraction class R2RChunkingProvider(ChunkingProvider): def __init__(self, config: ChunkingConfig): @@ -43,7 +45,11 @@ def update_config(self, config_override: ChunkingConfig): self.config = config_override self.text_splitter = self._initialize_text_splitter() - async def chunk(self, parsed_document: Any) -> AsyncGenerator[Any, None]: + async def chunk(self, parsed_document: Union[str, DocumentExtraction]) -> AsyncGenerator[Any, None]: + + if isinstance(parsed_document, DocumentExtraction): + parsed_document = parsed_document.data + if isinstance(parsed_document, str): chunks = self.text_splitter.create_documents([parsed_document]) else: @@ -56,7 +62,7 @@ async def chunk(self, parsed_document: Any) -> AsyncGenerator[Any, None]: ) async def chunk_with_override( - self, parsed_document: Any, config_override: ChunkingConfig + self, parsed_document: Union[str, DocumentExtraction], config_override: ChunkingConfig ) -> AsyncGenerator[Any, None]: original_config = self.config original_splitter = self.text_splitter diff --git a/py/core/providers/chunking/unstructured_chunking.py b/py/core/providers/chunking/unstructured_chunking.py index 7f0bdf6e3..f3e732d3d 100644 --- a/py/core/providers/chunking/unstructured_chunking.py +++ b/py/core/providers/chunking/unstructured_chunking.py @@ -1,6 +1,7 @@ -from typing import AsyncGenerator +from typing import AsyncGenerator, Union -from core.base import ChunkingProvider +from core.base import ChunkingProvider, Method +from core.base.abstractions.document import DocumentExtraction class UnstructuredChunkingProvider(ChunkingProvider): @@ -22,22 +23,28 @@ def __init__(self, config): ) super().__init__(config) - async def chunk(self, parsed_document: str) -> AsyncGenerator[str, None]: - if self.config.method == "by_title": - chunks = self.chunk_by_title( - [self.Text(text=parsed_document)], - max_characters=self.config.chunk_size, - new_after_n_chars=self.config.max_chunk_size - or self.config.chunk_size, - overlap=self.config.chunk_overlap, - ) + async def chunk(self, parsed_document: Union[str, DocumentExtraction]) -> AsyncGenerator[str, None]: + + # as unstructured has already partitioned the document, we can yield the text directly + if parsed_document.metadata.get('partitioned_by_unstructured', False): + yield parsed_document.data + else: - chunks = self.chunk_elements( - [self.Text(text=parsed_document)], + if self.config.method == Method.BY_TITLE: + chunks = self.chunk_by_title( + [self.Text(text=parsed_document.data)], max_characters=self.config.chunk_size, new_after_n_chars=self.config.max_chunk_size or self.config.chunk_size, overlap=self.config.chunk_overlap, - ) - for chunk in chunks: - yield chunk.text + ) + else: + chunks = self.chunk_elements( + [self.Text(text=parsed_document.data)], + max_characters=self.config.chunk_size, + new_after_n_chars=self.config.max_chunk_size + or self.config.chunk_size, + overlap=self.config.chunk_overlap, + ) + for chunk in chunks: + yield chunk.text \ No newline at end of file diff --git a/py/core/providers/parsing/unstructured_parsing.py b/py/core/providers/parsing/unstructured_parsing.py index 0fc68a447..179b69875 100644 --- a/py/core/providers/parsing/unstructured_parsing.py +++ b/py/core/providers/parsing/unstructured_parsing.py @@ -2,6 +2,8 @@ import time from io import BytesIO from typing import AsyncGenerator +import os + from core.base import ( Document, @@ -15,7 +17,7 @@ class UnstructuredParsingProvider(ParsingProvider): - def __init__(self, config): + def __init__(self, use_api, config): try: from unstructured.partition.auto import partition @@ -28,6 +30,26 @@ def __init__(self, config): logger.warning( "Excluded parsers are not supported by the unstructured parsing provider." ) + + self.use_api = use_api + if self.use_api: + from unstructured_client import UnstructuredClient + from unstructured_client.models import shared, operations + from unstructured_client.models.errors import SDKError + from unstructured.staging.base import dict_to_elements + + try: + self.unstructured_api_auth = os.environ["UNSTRUCTURED_API_KEY"] + except KeyError: + raise ValueError("UNSTRUCTURED_API_KEY environment variable is not set") + + self.unstructured_api_url = os.environ.get("UNSTRUCTURED_API_URL", "https://api.unstructured.io/general/v0/general") + + self.client = UnstructuredClient(api_key_auth=self.unstructured_api_auth, server_url=self.unstructured_api_url) + self.shared = shared + self.operations = operations + self.dict_to_elements = dict_to_elements + super().__init__(config) async def parse( @@ -38,19 +60,63 @@ async def parse( data = BytesIO(data) # TODO - Include check on excluded parsers here. - t0 = time.time() - elements = self.partition(file=data) + if self.use_api: + logger.info(f"Using API to parse document {document.id}") + files = self.shared.Files( + content=data.read() if isinstance(data, BytesIO) else data, + file_name=document.metadata.get('filename', 'unknown_file') + ) + + req = self.operations.PartitionRequest( + self.shared.PartitionParameters( + files=files, + split_pdf_page=True, + split_pdf_allow_failed=True, + split_pdf_concurrency_level=15 + ) + ) + elements = self.client.general.partition(req) + elements = [element for element in elements.elements] + + else: + logger.info(f"Using local unstructured to parse document {document.id}") + elements = self.partition(file=data, **self.config.chunking_config.dict()) for iteration, element in enumerate(elements): + + if isinstance(element, dict): + element_dict = element + + for key, value in element.items(): + if key != "text": + if key == 'metadata': + for k, v in value.items(): + if k not in document.metadata: + document.metadata[k] = v + else: + document.metadata[f"unstructured_{k}"] = v + elif key in document.metadata: + document.metadata[f"unstructured_{key}"] = value + else: + document.metadata[key] = value + else: + text = value + + # indicate that the document was chunked using unstructured + # nullifies the need for chunking in the pipeline + document.metadata['partitioned_by_unstructured'] = True + + # creating the text extraction extraction = DocumentExtraction( id=generate_id_from_label(f"{document.id}-{iteration}"), document_id=document.id, user_id=document.user_id, group_ids=document.group_ids, - data=element.text, + data=text, metadata=document.metadata, ) + yield extraction logger.debug( diff --git a/pyproject.toml b/pyproject.toml index 955fd579f..bf751095e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,7 +38,7 @@ beautifulsoup4 = { version = "^4.12.3", optional = true } openpyxl = { version = "^3.1.2", optional = true } markdown = { version = "^3.6", optional = true } pypdf = { version = "^4.2.0", optional = true } -python-pptx = { version = "^0.6.23", optional = true } +python-pptx = { version = "^1.0.1", optional = true } python-docx = { version = "^1.1.0", optional = true } opencv-python = { version = "^4.10.0.82", optional = true } moviepy = { version = "^1.0.3", optional = true } From 044b4d2a293430fc0d4648f8f1fed924231acc03 Mon Sep 17 00:00:00 2001 From: emrgnt-cmplxty <68796651+emrgnt-cmplxty@users.noreply.github.com> Date: Tue, 20 Aug 2024 14:40:41 -0700 Subject: [PATCH 20/74] Feature/cleanup client obj logic (#901) * define `RAGAgentResponse` * cleanup client logic --- py/core/__init__.py | 2 +- py/core/base/abstractions/llm.py | 10 +- .../base/api/models/retrieval/responses.py | 3 +- py/core/base/providers/chunking.py | 7 +- py/core/base/providers/parsing.py | 2 +- py/core/main/api/routes/auth/base.py | 1 - py/core/main/api/routes/retrieval/base.py | 1 + py/core/main/assembly/config.py | 6 +- py/core/main/assembly/factory.py | 9 +- py/core/main/execution.py | 1 + py/core/pipes/ingestion/chunking_pipe.py | 1 + py/core/providers/chunking/r2r_chunking.py | 21 +++-- .../chunking/unstructured_chunking.py | 18 ++-- py/core/providers/embeddings/ollama.py | 4 +- py/core/providers/llm/litellm.py | 4 - .../providers/parsing/unstructured_parsing.py | 37 +++++--- py/r2r/__init__.py | 4 +- py/sdk/client.py | 26 ++++-- py/sdk/retrieval.py | 92 ++++++------------- 19 files changed, 126 insertions(+), 123 deletions(-) diff --git a/py/core/__init__.py b/py/core/__init__.py index 0201c23f1..7fd3a9c41 100644 --- a/py/core/__init__.py +++ b/py/core/__init__.py @@ -11,7 +11,7 @@ from .pipes import * from .providers import * -logger = logging.getLogger("r2r") +logger = logging.getLogger("core") logger.setLevel(logging.INFO) # Create a console handler and set the level to info diff --git a/py/core/base/abstractions/llm.py b/py/core/base/abstractions/llm.py index 6ab140c84..24623dfda 100644 --- a/py/core/base/abstractions/llm.py +++ b/py/core/base/abstractions/llm.py @@ -1,8 +1,8 @@ """Abstractions for the LLM model.""" -from typing import TYPE_CHECKING, ClassVar, Optional, Union, Any - from enum import Enum +from typing import TYPE_CHECKING, Any, ClassVar, Optional, Union + from openai.types.chat import ChatCompletion, ChatCompletionChunk from pydantic import BaseModel, Field @@ -102,6 +102,7 @@ class Config: "api_base": None, } + class MessageType(Enum): SYSTEM = "system" USER = "user" @@ -111,7 +112,8 @@ class MessageType(Enum): def __str__(self): return self.value - + + class Message(BaseModel): role: Union[MessageType, str] content: Optional[str] = None @@ -126,4 +128,4 @@ class Config: "name": None, "function_call": None, "tool_calls": None, - } \ No newline at end of file + } diff --git a/py/core/base/api/models/retrieval/responses.py b/py/core/base/api/models/retrieval/responses.py index 6048b4433..9e64e96cf 100644 --- a/py/core/base/api/models/retrieval/responses.py +++ b/py/core/base/api/models/retrieval/responses.py @@ -1,6 +1,6 @@ from typing import Any, Optional -from core.base.abstractions import KGSearchResult, VectorSearchResult, Message +from core.base.abstractions import KGSearchResult, Message, VectorSearchResult from core.base.api.models.base import ResultsWrapper from pydantic import BaseModel, Field @@ -87,6 +87,7 @@ class Config: } } + RAGAgentResponse = list[Message] # Create wrapped versions of the responses WrappedSearchResponse = ResultsWrapper[SearchResponse] diff --git a/py/core/base/providers/chunking.py b/py/core/base/providers/chunking.py index 6d20a07a0..a133063af 100644 --- a/py/core/base/providers/chunking.py +++ b/py/core/base/providers/chunking.py @@ -2,8 +2,9 @@ from enum import Enum from typing import AsyncGenerator, Optional, Union -from .base import Provider, ProviderConfig from ..abstractions.document import DocumentExtraction +from .base import Provider, ProviderConfig + class Method(str, Enum): BY_TITLE = "by_title" @@ -57,6 +58,8 @@ def __init__(self, config: ChunkingConfig): self.config = config @abstractmethod - async def chunk(self, parsed_document: Union[str, DocumentExtraction]) -> AsyncGenerator[str, None]: + async def chunk( + self, parsed_document: Union[str, DocumentExtraction] + ) -> AsyncGenerator[str, None]: """Chunk the parsed document using the configured chunking strategy.""" pass diff --git a/py/core/base/providers/parsing.py b/py/core/base/providers/parsing.py index ef9e4ef95..12f2573ca 100644 --- a/py/core/base/providers/parsing.py +++ b/py/core/base/providers/parsing.py @@ -21,7 +21,7 @@ class ParsingConfig(ProviderConfig): @property def supported_providers(self) -> list[str]: - return ["r2r", "unstructured", 'unstructured_api', None] + return ["r2r", "unstructured", "unstructured_api", None] def validate(self) -> None: if self.provider not in self.supported_providers: diff --git a/py/core/main/api/routes/auth/base.py b/py/core/main/api/routes/auth/base.py index 84707d008..3e840fd2a 100644 --- a/py/core/main/api/routes/auth/base.py +++ b/py/core/main/api/routes/auth/base.py @@ -180,7 +180,6 @@ async def request_password_reset_app( This endpoint initiates the password reset process by sending a reset link to the specified email address. """ - print("email = ", email) result = await self.engine.arequest_password_reset(email) return GenericMessageResponse(message=result["message"]) diff --git a/py/core/main/api/routes/retrieval/base.py b/py/core/main/api/routes/retrieval/base.py index fb13b6755..ab45eda1b 100644 --- a/py/core/main/api/routes/retrieval/base.py +++ b/py/core/main/api/routes/retrieval/base.py @@ -155,6 +155,7 @@ async def rag_app( ) if rag_generation_config.stream: + async def stream_generator(): async for chunk in response: yield chunk diff --git a/py/core/main/assembly/config.py b/py/core/main/assembly/config.py index a26481a24..8b9ed61bd 100644 --- a/py/core/main/assembly/config.py +++ b/py/core/main/assembly/config.py @@ -93,7 +93,9 @@ def __init__(self, config_data: dict[str, Any]): self.embedding = EmbeddingConfig.create(**self.embedding) self.kg = KGConfig.create(**self.kg) self.logging = LoggingConfig.create(**self.logging) - self.parsing = ParsingConfig.create(chunking_config=self.chunking, **self.parsing) + self.parsing = ParsingConfig.create( + chunking_config=self.chunking, **self.parsing + ) self.prompt = PromptConfig.create(**self.prompt) self.agent = AgentConfig.create(**self.agent) @@ -114,8 +116,6 @@ def from_toml(cls, config_path: str = None) -> "R2RConfig": if config_path is None: # Get the root directory of the project file_dir = os.path.dirname(os.path.abspath(__file__)) - print(file_dir) - print(os.path.join(file_dir, "..", "..", "..", "r2r.toml")) config_path = os.path.join( file_dir, "..", "..", "..", "..", "r2r.toml" ) diff --git a/py/core/main/assembly/factory.py b/py/core/main/assembly/factory.py index 8a7e24805..fa3296163 100644 --- a/py/core/main/assembly/factory.py +++ b/py/core/main/assembly/factory.py @@ -91,10 +91,15 @@ def create_parsing_provider( from core.providers import R2RParsingProvider return R2RParsingProvider(parsing_config) - elif parsing_config.provider == "unstructured" or parsing_config.provider == "unstructured_api": + elif ( + parsing_config.provider == "unstructured" + or parsing_config.provider == "unstructured_api" + ): from core.providers import UnstructuredParsingProvider - return UnstructuredParsingProvider(parsing_config.provider == "unstructured_api", parsing_config) + return UnstructuredParsingProvider( + parsing_config.provider == "unstructured_api", parsing_config + ) else: raise ValueError( f"Parsing provider {parsing_config.provider} not supported" diff --git a/py/core/main/execution.py b/py/core/main/execution.py index 5f9c3f333..b6bd5c0fd 100644 --- a/py/core/main/execution.py +++ b/py/core/main/execution.py @@ -43,6 +43,7 @@ def __init__( if self.client_mode: from sdk.client import R2RClient + self.client = R2RClient(base_url) self.app = None else: diff --git a/py/core/pipes/ingestion/chunking_pipe.py b/py/core/pipes/ingestion/chunking_pipe.py index e79be5407..e6f064183 100644 --- a/py/core/pipes/ingestion/chunking_pipe.py +++ b/py/core/pipes/ingestion/chunking_pipe.py @@ -17,6 +17,7 @@ logger = logging.getLogger(__name__) + class ChunkingPipe(AsyncPipe): class Input(AsyncPipe.Input): message: AsyncGenerator[ diff --git a/py/core/providers/chunking/r2r_chunking.py b/py/core/providers/chunking/r2r_chunking.py index 4baed4768..fac009ffe 100644 --- a/py/core/providers/chunking/r2r_chunking.py +++ b/py/core/providers/chunking/r2r_chunking.py @@ -1,3 +1,4 @@ +import logging from typing import Any, AsyncGenerator, Union from core.base import ( @@ -7,22 +8,20 @@ RecursiveCharacterTextSplitter, TextSplitter, ) - -from core.base import ChunkingProvider, Method from core.base.abstractions.document import DocumentExtraction +logger = logging.getLogger(__name__) + + class R2RChunkingProvider(ChunkingProvider): def __init__(self, config: ChunkingConfig): super().__init__(config) self.text_splitter = self._initialize_text_splitter() - print( + logger.info( f"R2RChunkingProvider initialized with config: {self.config}" - ) # Debug log + ) def _initialize_text_splitter(self) -> TextSplitter: - print( - f"Initializing text splitter with method: {self.config.method}" - ) # Debug log if self.config.method == Method.RECURSIVE: return RecursiveCharacterTextSplitter( chunk_size=self.config.chunk_size, @@ -45,7 +44,9 @@ def update_config(self, config_override: ChunkingConfig): self.config = config_override self.text_splitter = self._initialize_text_splitter() - async def chunk(self, parsed_document: Union[str, DocumentExtraction]) -> AsyncGenerator[Any, None]: + async def chunk( + self, parsed_document: Union[str, DocumentExtraction] + ) -> AsyncGenerator[Any, None]: if isinstance(parsed_document, DocumentExtraction): parsed_document = parsed_document.data @@ -62,7 +63,9 @@ async def chunk(self, parsed_document: Union[str, DocumentExtraction]) -> AsyncG ) async def chunk_with_override( - self, parsed_document: Union[str, DocumentExtraction], config_override: ChunkingConfig + self, + parsed_document: Union[str, DocumentExtraction], + config_override: ChunkingConfig, ) -> AsyncGenerator[Any, None]: original_config = self.config original_splitter = self.text_splitter diff --git a/py/core/providers/chunking/unstructured_chunking.py b/py/core/providers/chunking/unstructured_chunking.py index f3e732d3d..fdcba1ed0 100644 --- a/py/core/providers/chunking/unstructured_chunking.py +++ b/py/core/providers/chunking/unstructured_chunking.py @@ -23,20 +23,22 @@ def __init__(self, config): ) super().__init__(config) - async def chunk(self, parsed_document: Union[str, DocumentExtraction]) -> AsyncGenerator[str, None]: + async def chunk( + self, parsed_document: Union[str, DocumentExtraction] + ) -> AsyncGenerator[str, None]: # as unstructured has already partitioned the document, we can yield the text directly - if parsed_document.metadata.get('partitioned_by_unstructured', False): + if parsed_document.metadata.get("partitioned_by_unstructured", False): yield parsed_document.data else: if self.config.method == Method.BY_TITLE: chunks = self.chunk_by_title( - [self.Text(text=parsed_document.data)], - max_characters=self.config.chunk_size, - new_after_n_chars=self.config.max_chunk_size - or self.config.chunk_size, - overlap=self.config.chunk_overlap, + [self.Text(text=parsed_document.data)], + max_characters=self.config.chunk_size, + new_after_n_chars=self.config.max_chunk_size + or self.config.chunk_size, + overlap=self.config.chunk_overlap, ) else: chunks = self.chunk_elements( @@ -47,4 +49,4 @@ async def chunk(self, parsed_document: Union[str, DocumentExtraction]) -> AsyncG overlap=self.config.chunk_overlap, ) for chunk in chunks: - yield chunk.text \ No newline at end of file + yield chunk.text diff --git a/py/core/providers/embeddings/ollama.py b/py/core/providers/embeddings/ollama.py index 3e60f22da..6a6cc624c 100644 --- a/py/core/providers/embeddings/ollama.py +++ b/py/core/providers/embeddings/ollama.py @@ -84,9 +84,7 @@ def _execute_task_sync(self, task: dict[str, Any]) -> List[List[float]]: prefixed_batch = [ self.prefixes.get(purpose, "") + text for text in batch ] - response = self.client.embed( - model=kwargs["model"], input=prefixed_batch, **kwargs - ) + response = self.client.embed(input=prefixed_batch, **kwargs) embeddings.extend(response["embeddings"]) return embeddings except Exception as e: diff --git a/py/core/providers/llm/litellm.py b/py/core/providers/llm/litellm.py index 1bbdd33c4..c6db63880 100644 --- a/py/core/providers/llm/litellm.py +++ b/py/core/providers/llm/litellm.py @@ -51,13 +51,10 @@ async def _execute_task(self, task: dict[str, Any]): args["messages"] = messages args = {**args, **kwargs} - logger.debug(f"Executing async LiteLLM task with args: {args}") try: response = await self.acompletion(**args) - logger.debug("Async LiteLLM task executed successfully") return response except Exception as e: - logger.error(f"Async LiteLLM task execution failed: {str(e)}") raise def _execute_task_sync(self, task: dict[str, Any]): @@ -69,7 +66,6 @@ def _execute_task_sync(self, task: dict[str, Any]): args["messages"] = messages args = {**args, **kwargs} - logger.debug(f"Executing sync LiteLLM task with args: {args}") try: response = self.completion(**args) logger.debug("Sync LiteLLM task executed successfully") diff --git a/py/core/providers/parsing/unstructured_parsing.py b/py/core/providers/parsing/unstructured_parsing.py index 179b69875..a1c7347eb 100644 --- a/py/core/providers/parsing/unstructured_parsing.py +++ b/py/core/providers/parsing/unstructured_parsing.py @@ -1,9 +1,8 @@ import logging +import os import time from io import BytesIO from typing import AsyncGenerator -import os - from core.base import ( Document, @@ -33,19 +32,27 @@ def __init__(self, use_api, config): self.use_api = use_api if self.use_api: + from unstructured.staging.base import dict_to_elements from unstructured_client import UnstructuredClient - from unstructured_client.models import shared, operations + from unstructured_client.models import operations, shared from unstructured_client.models.errors import SDKError - from unstructured.staging.base import dict_to_elements try: self.unstructured_api_auth = os.environ["UNSTRUCTURED_API_KEY"] except KeyError: - raise ValueError("UNSTRUCTURED_API_KEY environment variable is not set") + raise ValueError( + "UNSTRUCTURED_API_KEY environment variable is not set" + ) - self.unstructured_api_url = os.environ.get("UNSTRUCTURED_API_URL", "https://api.unstructured.io/general/v0/general") + self.unstructured_api_url = os.environ.get( + "UNSTRUCTURED_API_URL", + "https://api.unstructured.io/general/v0/general", + ) - self.client = UnstructuredClient(api_key_auth=self.unstructured_api_auth, server_url=self.unstructured_api_url) + self.client = UnstructuredClient( + api_key_auth=self.unstructured_api_auth, + server_url=self.unstructured_api_url, + ) self.shared = shared self.operations = operations self.dict_to_elements = dict_to_elements @@ -65,7 +72,7 @@ async def parse( logger.info(f"Using API to parse document {document.id}") files = self.shared.Files( content=data.read() if isinstance(data, BytesIO) else data, - file_name=document.metadata.get('filename', 'unknown_file') + file_name=document.metadata.get("filename", "unknown_file"), ) req = self.operations.PartitionRequest( @@ -73,15 +80,19 @@ async def parse( files=files, split_pdf_page=True, split_pdf_allow_failed=True, - split_pdf_concurrency_level=15 + split_pdf_concurrency_level=15, ) ) elements = self.client.general.partition(req) elements = [element for element in elements.elements] else: - logger.info(f"Using local unstructured to parse document {document.id}") - elements = self.partition(file=data, **self.config.chunking_config.dict()) + logger.info( + f"Using local unstructured to parse document {document.id}" + ) + elements = self.partition( + file=data, **self.config.chunking_config.dict() + ) for iteration, element in enumerate(elements): @@ -90,7 +101,7 @@ async def parse( for key, value in element.items(): if key != "text": - if key == 'metadata': + if key == "metadata": for k, v in value.items(): if k not in document.metadata: document.metadata[k] = v @@ -105,7 +116,7 @@ async def parse( # indicate that the document was chunked using unstructured # nullifies the need for chunking in the pipeline - document.metadata['partitioned_by_unstructured'] = True + document.metadata["partitioned_by_unstructured"] = True # creating the text extraction extraction = DocumentExtraction( diff --git a/py/r2r/__init__.py b/py/r2r/__init__.py index 70e023ef8..d568f22a2 100644 --- a/py/r2r/__init__.py +++ b/py/r2r/__init__.py @@ -7,10 +7,10 @@ ] try: - from core import * import core + from core import * + __all__ += core.__all__ except ImportError: # Core dependencies not installed pass - diff --git a/py/sdk/client.py b/py/sdk/client.py index fcca73f46..d92fec48c 100644 --- a/py/sdk/client.py +++ b/py/sdk/client.py @@ -1,6 +1,7 @@ import asyncio import inspect import json +from typing import AsyncGenerator, Generator import httpx import nest_asyncio @@ -12,7 +13,7 @@ from .models import R2RException from .restructure import RestructureMethods from .retrieval import RetrievalMethods -from typing import AsyncGenerator, Generator + nest_asyncio.apply() # The empty args become necessary after a recent modification to `base_endpoint` @@ -136,15 +137,22 @@ async def _make_request(self, method, endpoint, **kwargs): status_code=500, message=f"Request failed: {str(e)}" ) from e - - async def _make_streaming_request(self, method: str, endpoint: str, **kwargs) -> AsyncGenerator[str, None]: + async def _make_streaming_request( + self, method: str, endpoint: str, **kwargs + ) -> AsyncGenerator[str, None]: url = f"{self.base_url}{self.prefix}/{endpoint}" headers = kwargs.pop("headers", {}) - if self.access_token and endpoint not in ["register", "login", "verify_email"]: + if self.access_token and endpoint not in [ + "register", + "login", + "verify_email", + ]: headers.update(self._get_auth_header()) - + async with httpx.AsyncClient() as client: - async with client.stream(method, url, headers=headers, timeout=self.timeout, **kwargs) as response: + async with client.stream( + method, url, headers=headers, timeout=self.timeout, **kwargs + ) as response: handle_request_error(response) async for chunk in response.aiter_text(): yield chunk @@ -203,11 +211,15 @@ def _sync_generator(self, async_gen: AsyncGenerator) -> Generator: def __getattr__(self, name): async_attr = getattr(self.async_client, name) if callable(async_attr): + def sync_wrapper(*args, **kwargs): - result = asyncio.get_event_loop().run_until_complete(async_attr(*args, **kwargs)) + result = asyncio.get_event_loop().run_until_complete( + async_attr(*args, **kwargs) + ) if isinstance(result, AsyncGenerator): return self._sync_generator(result) return result + return sync_wrapper return async_attr diff --git a/py/sdk/retrieval.py b/py/sdk/retrieval.py index 5852592dc..edc2f9db3 100644 --- a/py/sdk/retrieval.py +++ b/py/sdk/retrieval.py @@ -9,6 +9,7 @@ VectorSearchSettings, ) + class RetrievalMethods: @staticmethod async def search( @@ -32,23 +33,15 @@ async def search( Returns: SearchResponse: The search response. """ - if isinstance(vector_search_settings, dict): - vector_search_settings = VectorSearchSettings( - **vector_search_settings - ) - if isinstance(kg_search_settings, dict): - kg_search_settings = KGSearchSettings(**kg_search_settings) + if not isinstance(vector_search_settings, dict): + vector_search_settings = vector_search_settings.model_dump() + if not isinstance(kg_search_settings, dict): + kg_search_settings = kg_search_settings.model_dump() data = { "query": query, - "vector_search_settings": ( - vector_search_settings.model_dump() - if vector_search_settings - else None - ), - "kg_search_settings": ( - kg_search_settings.model_dump() if kg_search_settings else None - ), + "vector_search_settings": vector_search_settings, + "kg_search_settings": kg_search_settings, } return await client._make_request("POST", "search", json=data) @@ -76,37 +69,24 @@ async def rag( Returns: Union[RAGResponse, AsyncGenerator[RAGResponse, None]]: The RAG response """ - if isinstance(rag_generation_config, dict): - rag_generation_config = GenerationConfig(**rag_generation_config) - if isinstance(vector_search_settings, dict): - vector_search_settings = VectorSearchSettings( - **vector_search_settings - ) - if isinstance(kg_search_settings, dict): - kg_search_settings = KGSearchSettings(**kg_search_settings) + if not isinstance(rag_generation_config, dict): + rag_generation_config = rag_generation_config.model_dump() + if not isinstance(vector_search_settings, dict): + vector_search_settings = vector_search_settings.model_dump() + if not isinstance(kg_search_settings, dict): + kg_search_settings = kg_search_settings.model_dump() data = { "query": query, - "rag_generation_config": rag_generation_config.model_dump(), - "vector_search_settings": ( - vector_search_settings.model_dump() - if vector_search_settings - else None - ), - "kg_search_settings": ( - kg_search_settings.model_dump() if kg_search_settings else None - ), + "rag_generation_config": rag_generation_config, + "vector_search_settings": vector_search_settings, + "kg_search_settings": kg_search_settings, } - if rag_generation_config.stream: - return client._make_streaming_request( - "POST", - "rag", - json=data - ) + if rag_generation_config.get("stream", False): + return client._make_streaming_request("POST", "rag", json=data) else: return await client._make_request("POST", "rag", json=data) - @staticmethod async def agent( @@ -136,14 +116,12 @@ async def agent( Returns: Union[List[Message], AsyncGenerator[Message, None]]: The agent response. """ - if isinstance(rag_generation_config, dict): - rag_generation_config = GenerationConfig(**rag_generation_config) - if isinstance(vector_search_settings, dict): - vector_search_settings = VectorSearchSettings( - **vector_search_settings - ) - if isinstance(kg_search_settings, dict): - kg_search_settings = KGSearchSettings(**kg_search_settings) + if not isinstance(rag_generation_config, dict): + rag_generation_config = rag_generation_config.model_dump() + if not isinstance(vector_search_settings, dict): + vector_search_settings = vector_search_settings.model_dump() + if not isinstance(kg_search_settings, dict): + kg_search_settings = kg_search_settings.model_dump() messages = [ Message(**msg) if isinstance(msg, dict) else msg @@ -152,24 +130,14 @@ async def agent( data = { "messages": [msg.model_dump() for msg in messages], - "rag_generation_config": rag_generation_config.model_dump(), - "vector_search_settings": ( - vector_search_settings.model_dump() - if vector_search_settings - else None - ), - "kg_search_settings": ( - kg_search_settings.model_dump() if kg_search_settings else None - ), + "rag_generation_config": rag_generation_config, + "vector_search_settings": vector_search_settings, + "kg_search_settings": kg_search_settings, "task_prompt_override": task_prompt_override, "include_title_if_available": include_title_if_available, } - if rag_generation_config.stream: - return client._make_streaming_request( - "POST", - "agent", - json=data - ) + if rag_generation_config.get("stream", False): + return client._make_streaming_request("POST", "agent", json=data) else: - return await client._make_request("POST", "agent", json=data) \ No newline at end of file + return await client._make_request("POST", "agent", json=data) From f048f7a31c3861473f27d9a6309a1b53c9d1d8c6 Mon Sep 17 00:00:00 2001 From: Shreyas Pimpalgaonkar Date: Tue, 20 Aug 2024 17:54:25 -0400 Subject: [PATCH 21/74] Shreyas/tests (#889) * init * tests * rename service * api model * add * merge * rm restructure router * print descriptions --- py/core/base/api/models/__init__.py | 8 + .../base/api/models/restructure/__init__.py | 0 .../base/api/models/restructure/responses.py | 13 + py/core/main/api/__init__.py | 2 + py/core/main/api/routes/management/base.py | 3 +- py/core/main/services/management_service.py | 38 ++- py/core/main/services/restructure_service.py | 2 +- py/core/providers/kg/neo4j/provider.py | 2 - py/sdk/restructure.py | 10 +- tests/test_kg.py | 290 +++++++++--------- 10 files changed, 203 insertions(+), 165 deletions(-) create mode 100644 py/core/base/api/models/restructure/__init__.py create mode 100644 py/core/base/api/models/restructure/responses.py diff --git a/py/core/base/api/models/__init__.py b/py/core/base/api/models/__init__.py index 9944d0fb7..e83f16244 100644 --- a/py/core/base/api/models/__init__.py +++ b/py/core/base/api/models/__init__.py @@ -42,6 +42,11 @@ WrappedSearchResponse, ) +from .restructure.responses import ( + KGEnrichementResponse, + WrappedKGEnrichementResponse, +) + __all__ = [ # Auth Responses "GenericMessageResponse", @@ -52,6 +57,9 @@ "FailedDocument", "IngestionResponse", "WrappedIngestionResponse", + # Restructure Responses + "KGEnrichementResponse", + "WrappedKGEnrichementResponse", # Management Responses "PromptResponse", "ServerStats", diff --git a/py/core/base/api/models/restructure/__init__.py b/py/core/base/api/models/restructure/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/py/core/base/api/models/restructure/responses.py b/py/core/base/api/models/restructure/responses.py new file mode 100644 index 000000000..88dd906ae --- /dev/null +++ b/py/core/base/api/models/restructure/responses.py @@ -0,0 +1,13 @@ +from typing import Any, Dict, List, Optional +from uuid import UUID +from pydantic import BaseModel +from datetime import datetime + +from core.base.api.models.base import ResultsWrapper + + +class KGEnrichementResponse(BaseModel): + enriched_content: Dict[str, Any] + + +WrappedKGEnrichementResponse = ResultsWrapper[KGEnrichementResponse] \ No newline at end of file diff --git a/py/core/main/api/__init__.py b/py/core/main/api/__init__.py index 7eb5cea8a..1ca250e35 100644 --- a/py/core/main/api/__init__.py +++ b/py/core/main/api/__init__.py @@ -1,6 +1,7 @@ from .routes.auth.base import AuthRouter from .routes.base_router import BaseRouter from .routes.ingestion.base import IngestionRouter +from .routes.restructure.base import RestructureRouter from .routes.management.base import ManagementRouter from .routes.retrieval.base import RetrievalRouter @@ -11,4 +12,5 @@ "ManagementRouter", "RetrievalRouter", "BaseRouter", + "RestructureRouter", ] diff --git a/py/core/main/api/routes/management/base.py b/py/core/main/api/routes/management/base.py index 571d057be..ff052ab22 100644 --- a/py/core/main/api/routes/management/base.py +++ b/py/core/main/api/routes/management/base.py @@ -231,6 +231,7 @@ async def document_chunks_app( @self.base_endpoint async def inspect_knowledge_graph( limit: int = 100, + print_descriptions: bool = False, auth_user=Depends(self.engine.providers.auth.auth_wrapper), ) -> WrappedKnowledgeGraphResponse: if not auth_user.is_superuser: @@ -238,7 +239,7 @@ async def inspect_knowledge_graph( "Only a superuser can call the `inspect_knowledge_graph` endpoint.", 403, ) - return await self.engine.ainspect_knowledge_graph(limit=limit) + return await self.engine.ainspect_knowledge_graph(limit=limit, print_descriptions=print_descriptions) @self.router.get("/groups_overview") @self.base_endpoint diff --git a/py/core/main/services/management_service.py b/py/core/main/services/management_service.py index b6bd18811..2e76b9fd9 100644 --- a/py/core/main/services/management_service.py +++ b/py/core/main/services/management_service.py @@ -363,16 +363,16 @@ async def inspect_knowledge_graph( descriptions_dict = {} relationships = [] + for relationship in relationships_raw: - descriptions_dict[relationship["subject"]["name"]] = ( - relationship["subject"]["description"] - ) - descriptions_dict[relationship["object"]["name"]] = ( - relationship["object"]["description"] - ) - descriptions_dict[relationship["relation"]["name"]] = ( - relationship["relation"]["description"] - ) + if print_descriptions: + descriptions_dict[relationship["subject"]["name"]] = ( + relationship["subject"]["description"] + ) + descriptions_dict[relationship["object"]["name"]] = ( + relationship["object"]["description"] + ) + relationships.append( ( relationship["subject"]["name"], @@ -460,17 +460,15 @@ def generate_output( output = [] # Print grouped relationships for subject, relations in grouped_relationships.items(): - output.extend( - [ - f"\n== {subject} ==", - *(f" {relation}:" for relation in relations), - *( - f" - {obj}" - for objects in relations.values() - for obj in objects - ), - ] - ) + output.append(f"\n== {subject} ==") + if print_descriptions and subject in descriptions_dict: + output.append(f"\tDescription: {descriptions_dict[subject]}") + for relation, objects in relations.items(): + output.append(f" {relation}:") + for obj in objects: + output.append(f" - {obj}") + if print_descriptions and obj in descriptions_dict: + output.append(f" Description: {descriptions_dict[obj]}") # Print basic graph statistics output.extend( diff --git a/py/core/main/services/restructure_service.py b/py/core/main/services/restructure_service.py index 99341d0fe..e85d0a7bd 100644 --- a/py/core/main/services/restructure_service.py +++ b/py/core/main/services/restructure_service.py @@ -39,7 +39,7 @@ async def enrich_graph(self) -> Dict[str, Any]: """ try: # Assuming there's a graph enrichment pipeline - return self.pipelines.kg_enrichment_pipeline.run( + return await self.pipelines.kg_enrichment_pipeline.run( input=[], run_manager=self.run_manager, ) diff --git a/py/core/providers/kg/neo4j/provider.py b/py/core/providers/kg/neo4j/provider.py index ee1e7bf1c..aa862b202 100644 --- a/py/core/providers/kg/neo4j/provider.py +++ b/py/core/providers/kg/neo4j/provider.py @@ -150,8 +150,6 @@ def batched_import(self, statement, df, batch_size=1000): rows=batch, database_=self._database, ) - print(result.summary.counters) - print(f"{total} rows in { time.time() - start_s} s.") return total def get_chunks( diff --git a/py/sdk/restructure.py b/py/sdk/restructure.py index 251c1667f..156fba98d 100644 --- a/py/sdk/restructure.py +++ b/py/sdk/restructure.py @@ -1,10 +1,16 @@ +from typing import Any, Dict, List, Optional + +from core.base import Document +from core.base.api.models import KGEnrichementResponse + + class RestructureMethods: @staticmethod - async def enrich_graph(client) -> dict: + async def enrich_graph(client) -> KGEnrichementResponse: """ Perform graph enrichment over the entire graph. Returns: - dict: Results of the graph enrichment process. + KGEnrichementResponse: Results of the graph enrichment process. """ return await client._make_request("POST", "enrich_graph") diff --git a/tests/test_kg.py b/tests/test_kg.py index fffb8bea8..ae4289657 100644 --- a/tests/test_kg.py +++ b/tests/test_kg.py @@ -1,139 +1,151 @@ -# import json -# import uuid -# from unittest.mock import Mock, patch - -# import pytest - -# from r2r_core.base.abstractions.document import DocumentFragment -# from r2r_core.base.abstractions.graph import Entity, Triple -# from r2r_core.base.providers.kg import KGConfig -# from r2r_core.providers.kg.neo4j.provider import Neo4jKGProvider - - -# @pytest.fixture -# def neo4j_kg_provider(): -# extra_fields = { -# "user": "neo4j", -# "password": "ineedastrongerpassword", -# "url": "bolt://localhost:7688", -# "database": "neo4j", -# } -# config = KGConfig(provider="neo4j", extra_fields=extra_fields) -# return Neo4jKGProvider(config) - - -# @pytest.fixture(autouse=True) -# def clean_graph(neo4j_kg_provider): -# neo4j_kg_provider.delete_all_nodes() -# yield -# neo4j_kg_provider.delete_all_nodes() - - -# def get_uuid(): -# return str(uuid.uuid4()) - - -# @pytest.fixture -# def test_chunks(): -# return [ -# DocumentFragment( -# id=get_uuid(), -# data="Test chunk 1", -# metadata={"testkey": "testvalue"}, -# document_id=get_uuid(), -# extraction_id=get_uuid(), -# ), -# DocumentFragment( -# id=get_uuid(), -# data="Test chunk 2", -# metadata={"testkey": "testvalue"}, -# document_id=get_uuid(), -# extraction_id=get_uuid(), -# ), -# ] - - -# @pytest.fixture -# def test_entities(): -# return [ -# Entity( -# id=get_uuid(), -# category="Test category 1", -# subcategory=None, -# value="Test entity 1", -# description="Test entity 1 description", -# description_embedding=[1.0, 2.0, 3.0], -# name_embedding=[1.0, 2.0, 3.0], -# graph_embedding=[1.0, 2.0, 3.0], -# community_ids=[get_uuid()], -# text_unit_ids=[get_uuid()], -# document_ids=[get_uuid(), get_uuid()], -# rank=1, -# attributes={"testkey": "testvalue"}, -# ), -# # Entity(id=get_uuid(), category="Test category 2", subcategory=None, value="Test entity 2", description="Test entity 2 description", description_embedding=[1.0, 2.0, 3.0], name_embedding=[1.0, 2.0, 3.0], graph_embedding=[1.0, 2.0, 3.0], community_ids=[get_uuid()], text_unit_ids=[get_uuid()], document_ids=[get_uuid(), get_uuid()], rank=1, attributes={"testkey": "testvalue"}) -# ] - - -# @pytest.fixture -# def test_triples(): -# return [ -# Triple( -# id=get_uuid(), -# subject=get_uuid(), -# predicate="test_predicate", -# object=get_uuid(), -# weight=1.0, -# description="Test triple description", -# predicate_embedding=[1.0, 2.0, 3.0], -# text_unit_ids=[get_uuid()], -# document_ids=[get_uuid()], -# attributes={"testkey": "testvalue"}, -# ) -# ] - - -# def test_upsert_chunks(neo4j_kg_provider, test_chunks, clean_graph): -# neo4j_kg_provider.upsert_chunks(test_chunks) -# neo4j_output = neo4j_kg_provider.get_chunks() -# chunks = [record["c"]._properties for record in neo4j_output.records] -# assert len(chunks) == len(test_chunks) -# for chunk, test_chunk in zip(chunks, test_chunks): -# assert chunk["id"] == str(test_chunk.id) -# assert chunk["data"] == test_chunk.data -# assert json.loads(chunk["metadata"]) == test_chunk.metadata -# assert chunk["document_id"] == str(test_chunk.document_id) -# assert chunk["extraction_id"] == str(test_chunk.extraction_id) - - -# def test_upsert_entities(neo4j_kg_provider, test_entities): -# neo4j_kg_provider.upsert_entities(test_entities) -# neo4j_output = neo4j_kg_provider.get_entities() -# entities = [record["e"]._properties for record in neo4j_output.records] -# assert len(entities) == len(test_entities) -# for entity, test_entity in zip(entities, test_entities): -# assert entity["id"] == test_entity.id -# assert entity["category"] == test_entity.category -# assert entity["value"] == test_entity.value -# assert entity["description"] == test_entity.description - - -# def test_upsert_triples(neo4j_kg_provider, test_triples): -# triples_count = neo4j_kg_provider.upsert_triples(test_triples) -# triples = neo4j_kg_provider.get_triples() -# assert len(triples) == len(test_triples) -# for triple, test_triple in zip(triples, test_triples): -# assert triple.id == test_triple.id -# assert triple.subject == test_triple.subject -# assert triple.predicate == test_triple.predicate -# assert triple.object == test_triple.object - - -# def test_upsert_communities(neo4j_kg_provider, test_communities): -# neo4j_kg_provider.upsert_communities(test_communities) -# neo4j_output = neo4j_kg_provider.get_communities() -# communities = [record["c"]._properties for record in neo4j_output.records] -# assert len(communities) == len(test_communities) -# for community, test_community in zip(communities, test_communities): -# assert community["id"] == test_community.id -# assert community["name"] == test_community.name +import pytest +import asyncio +from unittest.mock import AsyncMock, MagicMock +from core.pipes.kg.extraction import KGTriplesExtractionPipe +from core.pipes.kg.clustering import KGClusteringPipe +from core.base import DocumentFragment, KGExtraction, Entity, Triple, Community +from uuid import uuid4 + +@pytest.fixture +def kg_extraction_pipe(): + return KGTriplesExtractionPipe( + kg_provider=MagicMock(), + llm_provider=MagicMock(), + prompt_provider=MagicMock(), + chunking_provider=MagicMock() + ) + +@pytest.fixture +def document_fragment(): + return DocumentFragment( + id=uuid4(), + extraction_id=uuid4(), + document_id=uuid4(), + user_id=uuid4(), + group_ids=[uuid4()], + data="Test data", + metadata={} + ) +@pytest.mark.asyncio +async def test_extract_kg_success(kg_extraction_pipe, document_fragment): + kg_extraction_pipe.llm_provider.aget_completion = AsyncMock(return_value=MagicMock( + choices=[MagicMock(message=MagicMock(content=( + '("entity"$$$$Entity1$$$$Category1$$$$Description1)' + '("relationship"$$$$Entity1$$$$Entity2$$$$Predicate$$$$Description$$$$0.8)' + )))] + )) + result = await kg_extraction_pipe.extract_kg(document_fragment) + + assert isinstance(result, KGExtraction) + assert len(result.entities) == 1 + assert len(result.triples) == 1 + assert result.entities[0].name == "Entity1" + assert result.triples[0].subject == "Entity1" + assert result.triples[0].object == "Entity2" + +@pytest.mark.asyncio +async def test_run_logic(kg_extraction_pipe, document_fragment): + async def mock_input_generator(): + for _ in range(2): + yield document_fragment + + input_mock = MagicMock() + input_mock.message = mock_input_generator() + + kg_extraction_pipe.extract_kg = AsyncMock(return_value=KGExtraction( + entities=[Entity(name="TestEntity", category="TestCategory", description="TestDescription")], + triples=[Triple(subject="TestSubject", predicate="TestPredicate", object="TestObject")] + )) + + results = [result async for result in kg_extraction_pipe._run_logic(input_mock, MagicMock(), "run_id")] + + assert len(results) == 2 + for result in results: + assert isinstance(result, KGExtraction) + assert len(result.entities) == 1 + assert len(result.triples) == 1 + +@pytest.fixture +def mock_kg_provider(mocker): + provider = mocker.Mock() + provider.get_all_entities.return_value = [ + Entity(name=f"Entity{i}", category=f"Category{i%2+1}", description=f"Description{i}") + for i in range(1, 4) + ] + + provider.get_entities.return_value = [ + Entity(name=f"Entity{i}", category=f"Category{i%2+1}", description=f"Description{i}") + for i in range(1, 4) + ] + + provider.get_triples.return_value = [ + Triple(subject=f"Entity{i}", predicate=f"Predicate{i%2+1}", object=f"Entity{i+1}") + for i in range(1, 4) + ] + + provider.get_communities.return_value = [ + Community(id=f"Community{i}", level=f"Level{i%2+1}", short_id=f"Short{i}", title=f"Title{i}", entity_ids=[f"Entity{i}"], relationship_ids=[f"Relationship{i}"]) + for i in range(1, 4) + ] + + return provider + +@pytest.fixture +def mock_embedding_provider(mocker): + provider = mocker.Mock() + provider.get_embeddings.return_value = [ + [0.1*i, 0.2*i, 0.3*i] for i in range(1, 4) + ] + provider.async_get_embedding = AsyncMock(return_value=[0.1, 0.2, 0.3]) + return provider + +@pytest.fixture +def mock_completion_provider(mocker): + provider = mocker.Mock() + + async def mock_aget_completion(*args, **kwargs): + return mocker.Mock( + choices=[mocker.Mock(message=mocker.Mock(content="Cluster summary"))] + ) + + provider.aget_completion = mock_aget_completion + return provider + +@pytest.fixture +def mock_prompt_provider(mocker): + provider = mocker.Mock() + provider.get_message_payload.return_value = mocker.Mock( + task_prompt_name="graphrag_community_reports", + task_inputs={"input_text": "Test input text"} + ) + provider._get_message_payload.return_value = { + "task_prompt_name": "graphrag_community_reports", + "task_inputs": {"input_text": "Test input text"} + } + return provider + +@pytest.fixture +def kg_clustering_pipe(mocker, mock_kg_provider, mock_embedding_provider, mock_completion_provider, mock_prompt_provider): + return KGClusteringPipe( + kg_provider=mock_kg_provider, + embedding_provider=mock_embedding_provider, + llm_provider=mock_completion_provider, + prompt_provider=mock_prompt_provider, + n_clusters=2 + ) + +@pytest.mark.asyncio +async def test_cluster_kg(kg_clustering_pipe): + triples = [ + Triple(subject="Entity1", predicate="relatedTo", object="Entity2"), + Triple(subject="Entity2", predicate="relatedTo", object="Entity3"), + Triple(subject="Entity3", predicate="relatedTo", object="Entity1") + ] + + result = [] + async for community in kg_clustering_pipe.cluster_kg(triples): + result.append(community) + + assert len(result) == 1 + assert result[0]['id'] == '0_0' + assert result[0]['title'] == '_' \ No newline at end of file From 4b31b9f497a2fc6dd09570031d76464445370bd8 Mon Sep 17 00:00:00 2001 From: Nolan Tremelling <34580718+NolanTrem@users.noreply.github.com> Date: Tue, 20 Aug 2024 17:14:23 -0700 Subject: [PATCH 22/74] Refactor CLI (#903) --- .pre-commit-config.yaml | 8 +- py/cli/__init__.py | 18 ++ py/cli/cli.py | 51 +++++ py/{core => }/cli/command_group.py | 19 +- py/{core => }/cli/commands/__init__.py | 0 .../commands/auth.py} | 2 +- py/cli/commands/ingestion.py | 115 ++++++++++ py/cli/commands/management.py | 154 +++++++++++++ py/cli/commands/restructure.py | 18 ++ py/cli/commands/retrieval.py | 203 ++++++++++++++++++ .../commands/server.py} | 76 +++++-- py/{core => }/cli/utils/__init__.py | 0 py/{core => }/cli/utils/docker_utils.py | 56 +++-- py/{core => }/cli/utils/param_types.py | 0 py/{core => }/cli/utils/timer.py | 0 py/core/__init__.py | 3 - .../base/api/models/restructure/responses.py | 4 +- py/core/base/providers/kg.py | 13 +- py/core/cli/__init__.py | 23 -- py/core/cli/cli.py | 50 ----- py/core/cli/commands/document_operations.py | 133 ------------ py/core/cli/commands/kg_operations.py | 15 -- .../commands/oberservability_operations.py | 73 ------- py/core/cli/commands/rag_operations.py | 167 -------------- .../examples/scripts/sample_data_ingestor.py | 64 ------ py/core/main/__init__.py | 3 - py/core/main/api/routes/management/base.py | 4 +- py/core/main/api/routes/restructure/base.py | 1 - py/core/main/app_entry.py | 21 +- py/core/main/services/management_service.py | 8 +- py/core/main/services/retrieval_service.py | 33 +-- .../providers/parsing/unstructured_parsing.py | 4 +- py/pyproject.toml | 3 +- py/sdk/client.py | 22 +- py/sdk/ingestion.py | 39 ++-- py/sdk/management.py | 79 ++----- py/sdk/retrieval.py | 6 + py/sdk/server.py | 40 ++++ tests/regression/runner.py | 24 +-- tests/regression/test_cases/base.py | 44 ++-- tests/test_cli.py | 24 +-- tests/test_client.py | 24 +-- tests/test_kg.py | 131 ++++++++--- 43 files changed, 905 insertions(+), 870 deletions(-) create mode 100644 py/cli/__init__.py create mode 100644 py/cli/cli.py rename py/{core => }/cli/command_group.py (53%) rename py/{core => }/cli/commands/__init__.py (100%) rename py/{core/cli/commands/auth_operations.py => cli/commands/auth.py} (88%) create mode 100644 py/cli/commands/ingestion.py create mode 100644 py/cli/commands/management.py create mode 100644 py/cli/commands/restructure.py create mode 100644 py/cli/commands/retrieval.py rename py/{core/cli/commands/server_operations.py => cli/commands/server.py} (81%) rename py/{core => }/cli/utils/__init__.py (100%) rename py/{core => }/cli/utils/docker_utils.py (93%) rename py/{core => }/cli/utils/param_types.py (100%) rename py/{core => }/cli/utils/timer.py (100%) delete mode 100644 py/core/cli/__init__.py delete mode 100644 py/core/cli/cli.py delete mode 100644 py/core/cli/commands/document_operations.py delete mode 100644 py/core/cli/commands/kg_operations.py delete mode 100644 py/core/cli/commands/oberservability_operations.py delete mode 100644 py/core/cli/commands/rag_operations.py delete mode 100644 py/core/examples/scripts/sample_data_ingestor.py create mode 100644 py/sdk/server.py diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f6fdbfd4e..5961fe9e2 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -12,14 +12,14 @@ repos: hooks: - id: isort name: isort - entry: poetry run isort + entry: bash -c 'cd py && poetry run isort $(git diff --cached --name-only --diff-filter=ACM | grep ".py$" | xargs -I {} echo ../{}) || true' language: system types: [python] - args: ["--profile", "black", "--filter-files"] + pass_filenames: false - id: black name: black - entry: poetry run black + entry: bash -c 'cd py && poetry run black $(git diff --cached --name-only --diff-filter=ACM | grep ".py$" | xargs -I {} echo ../{})' language: system types: [python] - exclude: ^(.venv|venv|env)/ + pass_filenames: false diff --git a/py/cli/__init__.py b/py/cli/__init__.py new file mode 100644 index 000000000..8f4bb2e43 --- /dev/null +++ b/py/cli/__init__.py @@ -0,0 +1,18 @@ +from .cli import cli, main +from .command_group import cli as command_group_cli +from .commands import auth, ingestion, management, retrieval, server + +__all__ = [ + # From cli.py + "cli", + "main", + # From Command Group + "command_group_cli", + # From Commands + "auth", + "ingestion", + "management", + "restructure", + "retrieval", + "server", +] diff --git a/py/cli/cli.py b/py/cli/cli.py new file mode 100644 index 000000000..ac567c18c --- /dev/null +++ b/py/cli/cli.py @@ -0,0 +1,51 @@ +from cli.command_group import cli +from cli.commands import ( + auth, + ingestion, + management, + restructure, + retrieval, + server, +) + +# Auth +cli.add_command(auth.generate_private_key) + +# Ingesetion +cli.add_command(ingestion.ingest_files) +cli.add_command(ingestion.update_files) +cli.add_command(ingestion.ingest_sample_file) +cli.add_command(ingestion.ingest_sample_files) + +# Management +cli.add_command(management.analytics) +cli.add_command(management.app_settings) +cli.add_command(management.users_overview) +cli.add_command(management.documents_overview) +cli.add_command(management.document_chunks) +cli.add_command(management.inspect_knowledge_graph) + +# Restructure +cli.add_command(restructure.enrich_graph) + +# Retrieval +cli.add_command(retrieval.search) +cli.add_command(retrieval.rag) + +# Server +cli.add_command(server.health) +cli.add_command(server.server_stats) +cli.add_command(server.logs) +cli.add_command(server.docker_down) +cli.add_command(server.generate_report) +cli.add_command(server.serve) +cli.add_command(server.update) +cli.add_command(server.version) + + +def main(): + cli() + + +if __name__ == "__main__": + main() diff --git a/py/core/cli/command_group.py b/py/cli/command_group.py similarity index 53% rename from py/core/cli/command_group.py rename to py/cli/command_group.py index 7ae0534c2..0291bc874 100644 --- a/py/core/cli/command_group.py +++ b/py/cli/command_group.py @@ -1,7 +1,7 @@ import os import click -from core.main.execution import R2RExecutionWrapper +from sdk.client import R2RClient # TODO: refactor this to remove config path and config name @@ -12,14 +12,13 @@ @click.option( "--config-name", default=None, help="Name of the configuration to use" ) -@click.option("--client-mode", default=True, help="Run in client mode") @click.option( "--base-url", default="http://localhost:8000", help="Base URL for client mode", ) @click.pass_context -def cli(ctx, config_path, config_name, client_mode, base_url): +def cli(ctx, config_path, config_name, base_url): """R2R CLI for all core operations.""" if config_path and config_name: raise click.UsageError( @@ -29,16 +28,4 @@ def cli(ctx, config_path, config_name, client_mode, base_url): if config_path: config_path = os.path.abspath(config_path) - if ctx.invoked_subcommand != "serve": - ctx.obj = R2RExecutionWrapper( - config_path, - config_name, - client_mode if ctx.invoked_subcommand != "serve" else False, - base_url, - ) - else: - ctx.obj = { - "config_path": config_path, - "config_name": config_name, - "base_url": base_url, - } + ctx.obj = R2RClient(base_url) diff --git a/py/core/cli/commands/__init__.py b/py/cli/commands/__init__.py similarity index 100% rename from py/core/cli/commands/__init__.py rename to py/cli/commands/__init__.py diff --git a/py/core/cli/commands/auth_operations.py b/py/cli/commands/auth.py similarity index 88% rename from py/core/cli/commands/auth_operations.py rename to py/cli/commands/auth.py index 83f13dd1c..5a241477f 100644 --- a/py/core/cli/commands/auth_operations.py +++ b/py/cli/commands/auth.py @@ -1,7 +1,7 @@ import secrets import click -from core.cli.command_group import cli +from cli.command_group import cli @cli.command() diff --git a/py/cli/commands/ingestion.py b/py/cli/commands/ingestion.py new file mode 100644 index 000000000..3e84f54e6 --- /dev/null +++ b/py/cli/commands/ingestion.py @@ -0,0 +1,115 @@ +import json +import os +import tempfile +from urllib.parse import urlparse + +import click +import requests +from cli.command_group import cli +from cli.utils.param_types import JSON +from cli.utils.timer import timer + + +@cli.command() +@click.argument("file_paths", nargs=-1, required=True, type=click.Path(exists=True)) +@click.option("--document-ids", multiple=True, help="Document IDs for ingestion") +@click.option("--metadatas", type=JSON, help="Metadatas for ingestion as a JSON string") +@click.option( + "--versions", + multiple=True, + help="Starting version for ingested files (e.g. `v1`)", +) +@click.pass_obj +def ingest_files(client, file_paths, document_ids, metadatas, versions): + """Ingest files into R2R.""" + with timer(): + file_paths = list(file_paths) + document_ids = list(document_ids) if document_ids else None + versions = list(versions) if versions else None + + response = client.ingest_files(file_paths, metadatas, document_ids, versions) + click.echo(json.dumps(response, indent=2)) + + +@cli.command() +@click.argument("file-paths", nargs=-1, required=True, type=click.Path(exists=True)) +@click.option( + "--document-ids", + required=True, + help="Document IDs to update (comma-separated)", +) +@click.option("--metadatas", type=JSON, help="Metadatas for updating as a JSON string") +@click.pass_obj +def update_files(client, file_paths, document_ids, metadatas): + """Update existing files in R2R.""" + with timer(): + file_paths = list(file_paths) + + document_ids = document_ids.split(",") + + if metadatas: + if isinstance(metadatas, str): + metadatas = json.loads(metadatas) + if isinstance(metadatas, dict): + metadatas = [metadatas] + elif not isinstance(metadatas, list): + raise click.BadParameter( + "Metadatas must be a JSON string representing a list of dictionaries or a single dictionary" + ) + + response = client.update_files(file_paths, document_ids, metadatas) + click.echo(json.dumps(response, indent=2)) + + +def ingest_files_from_urls(client, urls): + """Download and ingest files from given URLs.""" + ingested_files = [] + for url in urls: + filename = os.path.basename(urlparse(url).path) + + with tempfile.NamedTemporaryFile( + mode="w+", delete=False, suffix=f"_{filename}" + ) as temp_file: + response = requests.get(url) + response.raise_for_status() + temp_file.write(response.text) + temp_file_path = temp_file.name + + try: + response = client.ingest_files([temp_file_path]) + click.echo(f"File '{filename}' ingested successfully. Response: {response}") + ingested_files.append(filename) + finally: + os.unlink(temp_file_path) + + return ingested_files + + +@cli.command() +@click.pass_obj +def ingest_sample_file(client): + """Ingest the first sample file into R2R.""" + sample_file_url = "https://raw.githubusercontent.com/SciPhi-AI/R2R/main/r2r/examples/data/aristotle.txt" + + with timer(): + ingested_files = ingest_files_from_urls(client, [sample_file_url]) + + click.echo( + f"Sample file ingestion completed. Ingested files: {', '.join(ingested_files)}" + ) + + +@cli.command() +@click.pass_obj +def ingest_sample_files(client): + """Ingest multiple sample files into R2R.""" + urls = [ + "https://raw.githubusercontent.com/SciPhi-AI/R2R/main/r2r/examples/data/aristotle.txt", + "https://raw.githubusercontent.com/SciPhi-AI/R2R/main/r2r/examples/data/got.txt", + ] + with timer(): + ingested_files = ingest_files_from_urls(client, urls) + + click.echo( + f"Sample files ingestion completed. Ingested files: {', '.join(ingested_files)}" + ) diff --git a/py/cli/commands/management.py b/py/cli/commands/management.py new file mode 100644 index 000000000..79eab188e --- /dev/null +++ b/py/cli/commands/management.py @@ -0,0 +1,154 @@ +from typing import Any, Dict + +import click +from cli.command_group import cli +from cli.utils.param_types import JSON +from cli.utils.timer import timer + +# TODO: Implement update_prompt + + +# TODO: Update +@cli.command() +@click.option("--filters", type=JSON, help="Filters for analytics as JSON") +@click.option("--analysis-types", type=JSON, help="Analysis types as JSON") +@click.pass_obj +def analytics(client, filters: Dict[str, Any], analysis_types: Dict[str, Any]): + """Retrieve analytics data.""" + with timer(): + response = client.analytics(filters, analysis_types) + + click.echo(response) + + +@cli.command() +@click.pass_obj +def app_settings(client): + """Retrieve application settings.""" + with timer(): + response = client.app_settings() + + click.echo(response) + + +# TODO: Implement score_completion + + +@cli.command() +@click.option("--user-ids", multiple=True, help="User IDs to overview") +@click.pass_obj +def users_overview(client, user_ids): + """Get an overview of users.""" + user_ids = list(user_ids) if user_ids else None + + with timer(): + response = client.users_overview(user_ids) + + for user in response: + click.echo(user) + + +@cli.command() +@click.option( + "--filter", + "-f", + multiple=True, + help="Filters for deletion in the format key:operator:value", +) +@click.pass_obj +def delete(client, filter): + """Delete documents based on filters.""" + filters = {} + for f in filter: + key, operator, value = f.split(":", 2) + if key not in filters: + filters[key] = {} + filters[key][f"${operator}"] = value + + with timer(): + response = client.delete(filters=filters) + + click.echo(response) + + +@cli.command() +@click.option("--document-ids", multiple=True, help="Document IDs to overview") +@click.pass_obj +def documents_overview(client, document_ids): + """Get an overview of documents.""" + document_ids = list(document_ids) if document_ids else None + + with timer(): + response = client.documents_overview(document_ids) + + for document in response["results"]: + click.echo(document) + + +@cli.command() +@click.option("--document-id", help="Document ID to retrieve chunks for") +@click.pass_obj +def document_chunks(client, document_id): + """Get chunks of a specific document.""" + with timer(): + response = client.document_chunks(document_id) + + for chunk in response: + click.echo(chunk) + + +@cli.command() +@click.option( + "--limit", + default=None, + help="The maximum number of nodes to return. Defaults to 100.", +) +@click.pass_obj +def inspect_knowledge_graph(client, limit): + """Inspect the knowledge graph.""" + with timer(): + response = client.inspect_knowledge_graph(limit) + + click.echo(response) + + +## TODO: Implement groups_overview + + +## TODO: Implement create_group + + +## TODO: Implement get_group + + +## TODO: Implement update_group + + +## TODO: Implement delete_group + + +## TODO: Implement list_groups + + +## TODO: Implement add_user_to_group + + +## TODO: Implement remove_user_from_group + + +## TODO: Implement get_users_in_group + + +## TODO: Implement get_groups_for_user + + +## TODO: Implement assign_document_to_group + + +## TODO: Implement remove_document_from_group + + +## TODO: Implement get_document_groups + + +## TODO: Implement get_documents_in_group diff --git a/py/cli/commands/restructure.py b/py/cli/commands/restructure.py new file mode 100644 index 000000000..451c95c3b --- /dev/null +++ b/py/cli/commands/restructure.py @@ -0,0 +1,18 @@ +from typing import Any, Dict + +import click +from cli.command_group import cli +from cli.utils.param_types import JSON +from cli.utils.timer import timer + + +@cli.command() +@click.pass_obj +def enrich_graph(client): + """ + Perform graph enrichment over the entire graph. + """ + with timer(): + response = client.restructure() + + click.echo(response) diff --git a/py/cli/commands/retrieval.py b/py/cli/commands/retrieval.py new file mode 100644 index 000000000..b7ff0cd07 --- /dev/null +++ b/py/cli/commands/retrieval.py @@ -0,0 +1,203 @@ +import click +from cli.command_group import cli +from cli.utils.param_types import JSON +from cli.utils.timer import timer + + +@cli.command() +@click.option("--query", prompt="Enter your search query", help="The search query") +# VectorSearchSettings +@click.option( + "--use-vector-search", + is_flag=True, + default=True, + help="Whether to use vector search", +) +@click.option( + "--filters", + type=JSON, + help="Filters to apply to the vector search as a JSON", +) +@click.option("--search-limit", default=None, help="Number of search results to return") +@click.option("--do-hybrid-search", is_flag=True, help="Perform hybrid search") +@click.option( + "--selected-group-ids", type=JSON, help="Group IDs to search for as a JSON" +) +# KGSearchSettings +@click.option("--use-kg-search", is_flag=True, help="Use knowledge graph search") +@click.option("--kg-search-type", default=None, help="Local or Global") +@click.option("--kg-search-level", default=None, help="Level of KG search") +@click.option( + "--kg-search-generation-config", + type=JSON, + help="KG search generation config", +) +@click.option("--entity-types", type=JSON, help="Entity types to search for as a JSON") +@click.option( + "--relationships", type=JSON, help="Relationships to search for as a JSON" +) +@click.option( + "--max-community-description-length", + type=JSON, + help="Max community description length", +) +@click.option( + "--max-llm-queries-for-global-search", type=JSON, help="Max community size" +) +@click.option("--local-search-limits", type=JSON, help="Local search limits") +@click.pass_obj +def search(client, query, **kwargs): + """Perform a search query.""" + vector_search_settings = { + k: v + for k, v in kwargs.items() + if k + in [ + "use_vector_search", + "filters", + "search_limit", + "do_hybrid_search", + "selected_group_ids", + ] + and v is not None + } + + kg_search_settings = { + k: v + for k, v in kwargs.items() + if k + in [ + "use_kg_search", + "kg_search_type", + "kg_search_level", + "kg_search_generation_config", + "entity_types", + "relationships", + "max_community_description_length", + "max_llm_queries_for_global_search", + "local_search_limits", + ] + and v is not None + } + + with timer(): + results = client.search( + query, + vector_search_settings, + kg_search_settings, + ) + + if isinstance(results, dict) and "results" in results: + results = results["results"] + + if "vector_search_results" in results: + click.echo("Vector search results:") + for result in results["vector_search_results"]: + click.echo(result) + + if "kg_search_results" in results and results["kg_search_results"]: + click.echo("KG search results:") + for result in results["kg_search_results"]: + click.echo(result) + + +@cli.command() +@click.option("--query", prompt="Enter your query", help="The query for RAG") +# RAG Generation Config +@click.option("--stream", is_flag=True, help="Stream the RAG response") +@click.option("--rag-model", default=None, help="Model for RAG") +# Vector Search Settings +@click.option( + "--use-vector-search", is_flag=True, default=True, help="Use vector search" +) +@click.option("--filters", type=JSON, help="Search filters as JSON") +@click.option("--search-limit", default=10, help="Number of search results to return") +@click.option("--do-hybrid-search", is_flag=True, help="Perform hybrid search") +@click.option( + "--selected-group-ids", type=JSON, help="Group IDs to search for as a JSON" +) +# KG Search Settings +@click.option("--use-kg-search", is_flag=True, help="Use knowledge graph search") +@click.option("--kg-search-type", default="global", help="Local or Global") +@click.option( + "--kg-search-level", + default=None, + help="Level of cluster to use for Global KG search", +) +@click.option("--kg-search-model", default=None, help="Model for KG agent") +@click.option("--entity-types", type=JSON, help="Entity types to search for as a JSON") +@click.option( + "--relationships", type=JSON, help="Relationships to search for as a JSON" +) +@click.option( + "--max-community-description-length", + type=int, + help="Max community description length", +) +@click.option( + "--max-llm-queries-for-global-search", type=int, help="Max community size" +) +@click.option("--local-search-limits", type=JSON, help="Local search limits") +@click.pass_obj +def rag(client, query, **kwargs): + """Perform a RAG query.""" + rag_generation_config = { + "stream": kwargs.get("stream", False), + } + if kwargs.get("rag_model"): + rag_generation_config["model"] = kwargs["rag_model"] + + vector_search_settings = { + k: v + for k, v in kwargs.items() + if k + in [ + "use_vector_search", + "filters", + "search_limit", + "do_hybrid_search", + "selected_group_ids", + ] + and v is not None + } + + kg_search_settings = { + k: v + for k, v in kwargs.items() + if k + in [ + "use_kg_search", + "kg_search_type", + "kg_search_level", + "kg_search_model", + "entity_types", + "relationships", + "max_community_description_length", + "max_llm_queries_for_global_search", + "local_search_limits", + ] + and v is not None + } + + if kg_search_settings.get("kg_search_model"): + kg_search_settings["kg_search_generation_config"] = { + "model": kg_search_settings.pop("kg_search_model") + } + + with timer(): + response = client.rag( + query, + rag_generation_config, + vector_search_settings, + kg_search_settings, + ) + + if rag_generation_config.get("stream"): + for chunk in response: + click.echo(chunk, nl=False) + click.echo() + else: + click.echo(response) + + +# TODO: Implement agent diff --git a/py/core/cli/commands/server_operations.py b/py/cli/commands/server.py similarity index 81% rename from py/core/cli/commands/server_operations.py rename to py/cli/commands/server.py index f66915acc..f0d948505 100644 --- a/py/core/cli/commands/server_operations.py +++ b/py/cli/commands/server.py @@ -5,17 +5,61 @@ import sys import click -from core.cli.command_group import cli -from core.cli.utils.docker_utils import ( +from cli.command_group import cli +from cli.utils.docker_utils import ( bring_down_docker_compose, remove_r2r_network, run_docker_serve, run_local_serve, ) -from core.cli.utils.timer import timer +from cli.utils.timer import timer from dotenv import load_dotenv +@cli.command() +@click.pass_obj +def health(client): + """Check the health of the server.""" + with timer(): + response = client.health() + + click.echo(response) + + +@cli.command() +@click.pass_obj +def server_stats(client): + """Check the server stats.""" + with timer(): + response = client.server_stats() + + click.echo(response) + + +@cli.command() +@click.option("--run-type-filter", help="Filter for log types") +@click.option( + "--max-runs", default=None, help="Maximum number of runs to fetch" +) +@click.pass_obj +def logs(client, run_type_filter, max_runs): + """Retrieve logs with optional type filter.""" + with timer(): + response = client.logs(run_type_filter, max_runs) + + for log in response["results"]: + click.echo(f"Run ID: {log['run_id']}") + click.echo(f"Run Type: {log['run_type']}") + click.echo(f"Timestamp: {log['timestamp']}") + click.echo(f"User ID: {log['user_id']}") + click.echo("Entries:") + for entry in log["entries"]: + click.echo(f" - {entry['key']}: {entry['value'][:100]}") + click.echo("---") + + click.echo(f"Total runs: {len(response)}") + + @cli.command() @click.option( "--volumes", @@ -29,7 +73,7 @@ ) @click.option("--project-name", default="r2r", help="Project name for Docker") @click.pass_context -def docker_down(ctx, volumes, remove_orphans, project_name): +def docker_down(volumes, remove_orphans, project_name): """Bring down the Docker Compose setup and attempt to remove the network if necessary.""" result = bring_down_docker_compose(project_name, volumes, remove_orphans) remove_r2r_network() @@ -121,16 +165,6 @@ def generate_report(): click.echo(json.dumps(report, indent=2)) -@cli.command() -@click.pass_obj -def health(obj): - """Check the health of the server.""" - with timer(): - response = obj.health() - - click.echo(response) - - @cli.command() @click.option("--host", default="0.0.0.0", help="Host to run the server on") @click.option("--port", default=8000, help="Port to run the server on") @@ -148,9 +182,10 @@ def health(obj): ) @click.option("--project-name", default="r2r", help="Project name for Docker") @click.option("--image", help="Docker image to use") +@click.option("--config-path", help="Path to the configuration file") @click.pass_obj def serve( - obj, + client, host, port, docker, @@ -159,12 +194,13 @@ def serve( exclude_postgres, project_name, image, + config_path, ): """Start the R2R server.""" load_dotenv() - if obj["config_path"]: - config_path = os.path.abspath(obj["config_path"]) + if config_path: + config_path = os.path.abspath(config_path) # For Windows, convert backslashes to forward slashes and prepend /host_mnt/ if platform.system() == "Windows": @@ -172,11 +208,9 @@ def serve( "\\", "/" ).replace(":", "") - obj["config_path"] = config_path - if docker: run_docker_serve( - obj, + client, host, port, exclude_neo4j, @@ -205,7 +239,7 @@ def serve( click.echo(f"Opening browser to {url}") webbrowser.open(url) else: - run_local_serve(obj, host, port) + run_local_serve(client, host, port) @cli.command() diff --git a/py/core/cli/utils/__init__.py b/py/cli/utils/__init__.py similarity index 100% rename from py/core/cli/utils/__init__.py rename to py/cli/utils/__init__.py diff --git a/py/core/cli/utils/docker_utils.py b/py/cli/utils/docker_utils.py similarity index 93% rename from py/core/cli/utils/docker_utils.py rename to py/cli/utils/docker_utils.py index 76708dac0..a4352c83e 100644 --- a/py/core/cli/utils/docker_utils.py +++ b/py/cli/utils/docker_utils.py @@ -5,12 +5,13 @@ import subprocess import sys import time +from typing import Optional import click import requests from core.main import R2RBuilder, R2RConfig -from core.main.execution import R2RExecutionWrapper from requests.exceptions import RequestException +from sdk import R2RClient def bring_down_docker_compose(project_name, volumes, remove_orphans): @@ -71,38 +72,49 @@ def remove_r2r_network(): ) -def run_local_serve(obj, host, port): - wrapper = R2RExecutionWrapper(**obj, client_mode=False) - llm_provider = wrapper.app.config.completion.provider - llm_model = wrapper.app.config.completion.generation_config.model +def run_local_serve( + obj: R2RClient, host: str, port: int, config_path: Optional[str] = None +): + try: + from r2r import R2R + except ImportError: + click.echo( + "You must install the `r2r core` package to run the R2R server locally." + ) + sys.exit(1) + + r2r_instance = R2R() + llm_provider = r2r_instance.config.completion.provider + llm_model = r2r_instance.config.completion.generation_config.model model_provider = llm_model.split("/")[0] available_port = find_available_port(port) check_llm_reqs(llm_provider, model_provider, include_ollama=True) - wrapper.serve(host, available_port) + r2r_instance.serve(host, available_port) def run_docker_serve( - obj, - host, - port, - exclude_neo4j, - exclude_ollama, - exclude_postgres, - project_name, - image, + client: R2RClient, + host: str, + port: int, + exclude_neo4j: bool, + exclude_ollama: bool, + exclude_postgres: bool, + project_name: str, + image: str, + config_path: Optional[str] = None, ): check_set_docker_env_vars(exclude_neo4j, exclude_postgres) - set_config_env_vars(obj) set_ollama_api_base(exclude_ollama) - config = ( - R2RConfig.from_toml(obj["config_path"]) - if obj["config_path"] - else R2RConfig.from_toml( - R2RBuilder.CONFIG_OPTIONS[obj["config_name"] or "default"] + + if config_path: + config = R2RConfig.from_toml(config_path) + else: + config = R2RConfig.from_toml( + R2RBuilder.CONFIG_OPTIONS[client.config_name or "default"] ) - ) + completion_provider = config.completion.provider completion_model = config.completion.generation_config.model completion_model_provider = completion_model.split("/")[0] @@ -139,7 +151,7 @@ def run_docker_serve( exclude_ollama, exclude_postgres, project_name, - obj["config_path"], + config_path, image, ) diff --git a/py/core/cli/utils/param_types.py b/py/cli/utils/param_types.py similarity index 100% rename from py/core/cli/utils/param_types.py rename to py/cli/utils/param_types.py diff --git a/py/core/cli/utils/timer.py b/py/cli/utils/timer.py similarity index 100% rename from py/core/cli/utils/timer.py rename to py/cli/utils/timer.py diff --git a/py/core/__init__.py b/py/core/__init__.py index 7fd3a9c41..2ed623e65 100644 --- a/py/core/__init__.py +++ b/py/core/__init__.py @@ -31,7 +31,6 @@ logger.propagate = False -# TODO - Cleanup export strategy && slimmify release __all__ = [ ## AGENT # Base @@ -194,8 +193,6 @@ # "r2r_app", ## R2R ENGINE "R2REngine", - ## R2R EXECUTION - "R2RExecutionWrapper", ## R2R ASSEMBLY # Builder "R2RBuilder", diff --git a/py/core/base/api/models/restructure/responses.py b/py/core/base/api/models/restructure/responses.py index 88dd906ae..7f57c6f98 100644 --- a/py/core/base/api/models/restructure/responses.py +++ b/py/core/base/api/models/restructure/responses.py @@ -3,11 +3,11 @@ from pydantic import BaseModel from datetime import datetime -from core.base.api.models.base import ResultsWrapper +from core.base.api.models.base import ResultsWrapper class KGEnrichementResponse(BaseModel): enriched_content: Dict[str, Any] -WrappedKGEnrichementResponse = ResultsWrapper[KGEnrichementResponse] \ No newline at end of file +WrappedKGEnrichementResponse = ResultsWrapper[KGEnrichementResponse] diff --git a/py/core/base/providers/kg.py b/py/core/base/providers/kg.py index 9093b22b2..9f34b8af0 100644 --- a/py/core/base/providers/kg.py +++ b/py/core/base/providers/kg.py @@ -37,9 +37,7 @@ class KGProvider(ABC): def __init__(self, config: KGConfig) -> None: if not isinstance(config, KGConfig): - raise ValueError( - "KGProvider must be initialized with a `KGConfig`." - ) + raise ValueError("KGProvider must be initialized with a `KGConfig`.") logger.info(f"Initializing KG provider with config: {config}") self.config = config self.validate_config() @@ -111,15 +109,14 @@ def get_schema(self, refresh: bool = False) -> str: @abstractmethod def structured_query( - self, query: str, param_map: Optional[dict[str, Any]] = {} + self, query: str, param_map: Optional[dict[str, Any]] = None ) -> Any: """Abstract method to query the graph store with statement and parameters.""" - pass + if param_map is None: + param_map = {} @abstractmethod - def vector_query( - self, query, **kwargs: Any - ) -> Tuple[list[Entity], list[float]]: + def vector_query(self, query, **kwargs: Any) -> Tuple[list[Entity], list[float]]: """Abstract method to query the graph store with a vector store query.""" # TODO - Type this method. diff --git a/py/core/cli/__init__.py b/py/core/cli/__init__.py deleted file mode 100644 index 275abbc6c..000000000 --- a/py/core/cli/__init__.py +++ /dev/null @@ -1,23 +0,0 @@ -from .cli import cli, main -from .command_group import cli as command_group_cli -from .commands import ( - auth_operations, - document_operations, - oberservability_operations, - rag_operations, - server_operations, -) - -__all__ = [ - # From cli.py - "cli", - "main", - # From Command Group - "command_group_cli", - # From Commands - "auth_operations", - "document_operations", - "oberservability_operations", - "rag_operations", - "server_operations", -] diff --git a/py/core/cli/cli.py b/py/core/cli/cli.py deleted file mode 100644 index 4314b89ae..000000000 --- a/py/core/cli/cli.py +++ /dev/null @@ -1,50 +0,0 @@ -from core.cli.command_group import cli -from core.cli.commands import ( - auth_operations, - document_operations, - kg_operations, - oberservability_operations, - rag_operations, - server_operations, -) - -# Server operations -cli.add_command(server_operations.docker_down) -cli.add_command(server_operations.generate_report) -cli.add_command(server_operations.health) -cli.add_command(server_operations.serve) -cli.add_command(server_operations.update) -cli.add_command(server_operations.version) - -# Document operations -cli.add_command(document_operations.delete) -cli.add_command(document_operations.document_chunks) -cli.add_command(document_operations.documents_overview) -cli.add_command(document_operations.ingest_files) -cli.add_command(document_operations.ingest_sample_file) -cli.add_command(document_operations.ingest_sample_files) -cli.add_command(document_operations.update_files) - -# Search and RAG operations -cli.add_command(rag_operations.inspect_knowledge_graph) -cli.add_command(rag_operations.rag) -cli.add_command(rag_operations.search) - -# Auth operations -cli.add_command(auth_operations.generate_private_key) - -# Observability operations -cli.add_command(oberservability_operations.analytics) -cli.add_command(oberservability_operations.app_settings) -cli.add_command(oberservability_operations.logs) -cli.add_command(oberservability_operations.users_overview) - -cli.add_command(kg_operations.enrich_graph) - - -def main(): - cli() - - -if __name__ == "__main__": - main() diff --git a/py/core/cli/commands/document_operations.py b/py/core/cli/commands/document_operations.py deleted file mode 100644 index 081f5e46b..000000000 --- a/py/core/cli/commands/document_operations.py +++ /dev/null @@ -1,133 +0,0 @@ -import click -from core.cli.command_group import cli -from core.cli.utils.timer import timer - - -@cli.command() -@click.option( - "--filter", - "-f", - multiple=True, - help="Filters for deletion in the format key:operator:value", -) -@click.pass_obj -def delete(obj, filter): - """Delete documents based on filters.""" - filters = {} - for f in filter: - key, operator, value = f.split(":", 2) - if key not in filters: - filters[key] = {} - filters[key][f"${operator}"] = value - - with timer(): - response = obj.delete(filters=filters) - - click.echo(response) - - -@cli.command() -@click.option("--document-ids", multiple=True, help="Document IDs to overview") -@click.pass_obj -def documents_overview(obj, document_ids): - """Get an overview of documents.""" - document_ids = list(document_ids) if document_ids else None - - with timer(): - response = obj.documents_overview(document_ids) - - for document in response: - click.echo(document) - - -@cli.command() -@click.argument("document-id") -@click.pass_obj -def document_chunks(obj, document_id): - """Get chunks of a specific document.""" - print(document_id) - with timer(): - response = obj.document_chunks(document_id) - - for chunk in response: - click.echo(chunk) - - -@cli.command() -@click.option( - "--file-paths", multiple=True, help="Paths to files for ingestion" -) -@click.option( - "--document-ids", multiple=True, help="Document IDs for ingestion" -) -@click.option("--metadatas", multiple=True, help="Metadatas for ingestion") -@click.option( - "--versions", - multiple=True, - help="Starting version for ingested files (e.g. `v1`)", -) -@click.pass_obj -def ingest_files(obj, file_paths, document_ids, metadatas, versions): - """Ingest files into R2R.""" - with timer(): - file_paths = list(file_paths) - document_ids = list(document_ids) if document_ids else None - metadatas = list(metadatas) if metadatas else None - versions = list(versions) if versions else None - - response = obj.ingest_files( - file_paths, document_ids, metadatas, versions - ) - click.echo(response) - - -@cli.command() -@click.option( - "--no-media", - is_flag=True, - default=False, - help="Exclude media files from ingestion", -) -@click.option("--option", type=int, default=0, help="Which file to ingest?") -@click.pass_obj -def ingest_sample_file(obj, no_media, option): - """Ingest sample files into R2R.""" - with timer(): - response = obj.ingest_sample_file(no_media=no_media, option=option) - - click.echo(response) - - -@cli.command() -@click.option( - "--no-media", - default=True, - help="Exclude media files from ingestion", -) -@click.pass_obj -def ingest_sample_files(obj, no_media): - """Ingest all sample files into R2R.""" - with timer(): - response = obj.ingest_sample_files(no_media=no_media) - - click.echo(response) - - -@cli.command() -@click.argument("file-paths", nargs=-1) -@click.option( - "--document-ids", multiple=True, help="Document IDs for ingestion" -) -@click.option("--metadatas", multiple=True, help="Metadatas for ingestion") -@click.pass_obj -def update_files(obj, file_paths, document_ids, metadatas): - """Update existing files in R2R.""" - with timer(): - # Default to None if empty tuples are provided - metadatas = list(metadatas) if metadatas else None - - response = obj.update_files( - list(file_paths), list(document_ids), metadatas - ) - - click.echo(response) diff --git a/py/core/cli/commands/kg_operations.py b/py/core/cli/commands/kg_operations.py deleted file mode 100644 index 7512bc33d..000000000 --- a/py/core/cli/commands/kg_operations.py +++ /dev/null @@ -1,15 +0,0 @@ -import click -from core.cli.command_group import cli -from core.cli.utils.timer import timer - - -@cli.command() -@click.pass_obj -def enrich_graph(obj): - """Enrich the knowledge graph with specified documents.""" - # document_ids = list(document_ids) if document_ids else None - - with timer(): - response = obj.enrich_graph() - - click.echo(response) diff --git a/py/core/cli/commands/oberservability_operations.py b/py/core/cli/commands/oberservability_operations.py deleted file mode 100644 index 4df95c66d..000000000 --- a/py/core/cli/commands/oberservability_operations.py +++ /dev/null @@ -1,73 +0,0 @@ -from typing import Any, Dict -from uuid import UUID - -import click -from core.cli.command_group import cli -from core.cli.utils.param_types import JSON -from core.cli.utils.timer import timer - - -@cli.command() -@click.option("--filters", type=JSON, help="Filters for analytics as JSON") -@click.option("--analysis-types", type=JSON, help="Analysis types as JSON") -@click.pass_obj -def analytics(obj, filters: Dict[str, Any], analysis_types: Dict[str, Any]): - """Retrieve analytics data.""" - with timer(): - response = obj.analytics(filters, analysis_types) - - click.echo(response) - - -@cli.command() -@click.pass_obj -def app_settings(obj): - """Retrieve application settings.""" - with timer(): - response = obj.app_settings() - - click.echo(response) - - -@cli.command() -@click.option("--run-type-filter", help="Filter for log types") -@click.option( - "--max-runs", default=100, help="Maximum number of runs to fetch" -) -@click.pass_obj -def logs(obj, run_type_filter, max_runs): - """Retrieve logs with optional type filter.""" - with timer(): - response = obj.logs(run_type_filter, max_runs) - - for log in response: - click.echo(f"Run ID: {log['run_id']}") - click.echo(f"Run Type: {log['run_type']}") - if "timestamp" in log: - click.echo(f"Timestamp: {log['timestamp']}") - else: - click.echo("Timestamp: Not available") - if "user_id" in log: - click.echo(f"User ID: {log['user_id']}") - else: - click.echo("User ID: Not available") - click.echo("Entries:") - for entry in log["entries"]: - click.echo(f" - {entry['key']}: {entry['value'][:100]}") - click.echo("---") - - click.echo(f"Total runs: {len(response)}") - - -@cli.command() -@click.option("--user-ids", multiple=True, help="User IDs to overview") -@click.pass_obj -def users_overview(obj, user_ids): - """Get an overview of users.""" - user_ids = [UUID(user_id) for user_id in user_ids] if user_ids else None - - with timer(): - response = obj.users_overview(user_ids) - - for user in response: - click.echo(user) diff --git a/py/core/cli/commands/rag_operations.py b/py/core/cli/commands/rag_operations.py deleted file mode 100644 index 88f72576c..000000000 --- a/py/core/cli/commands/rag_operations.py +++ /dev/null @@ -1,167 +0,0 @@ -import click -from core.cli.command_group import cli -from core.cli.utils.param_types import JSON -from core.cli.utils.timer import timer - - -@cli.command() -@click.option( - "--limit", default=100, help="Limit the number of relationships returned" -) -@click.option( - "--print-descriptions", - is_flag=True, - help="Print descriptions of entities and relationships", -) -@click.pass_obj -def inspect_knowledge_graph(obj, limit, print_descriptions): - """Print relationships from the knowledge graph.""" - with timer(): - response = obj.inspect_knowledge_graph(limit, print_descriptions) - - click.echo(response) - - -@cli.command() -@click.option("--query", prompt="Enter your query", help="The query for RAG") -@click.option( - "--use-vector-search", is_flag=True, default=True, help="Use vector search" -) -@click.option("--filters", type=JSON, help="Search filters as JSON") -@click.option( - "--search-limit", default=10, help="Number of search results to return" -) -@click.option( - "--use-hybrid-search", is_flag=True, help="Perform hybrid search" -) -@click.option( - "--use-kg-search", is_flag=True, help="Use knowledge graph search" -) -@click.option("--kg-search-model", default=None, help="Model for KG agent") -@click.option("--stream", is_flag=True, help="Stream the RAG response") -@click.option("--rag-model", default=None, help="Model for RAG") -@click.option( - "--kg-search-level", - default=None, - help="Level of cluster to use for Global KG search", -) -@click.option("--kg-search-type", default="global", help="Local or Global") -@click.pass_obj -def rag( - obj, - query, - use_vector_search, - filters, - search_limit, - use_hybrid_search, - use_kg_search, - kg_search_model, - stream, - rag_model, - kg_search_type, - kg_search_level, -): - """Perform a RAG query.""" - kg_search_generation_config = {} - if kg_search_model: - kg_search_generation_config = {"model": kg_search_model} - rag_generation_config = {"stream": stream} - if rag_model: - rag_generation_config["model"] = rag_model - - with timer(): - response = obj.rag( - query, - use_vector_search, - filters, - search_limit, - use_hybrid_search, - use_kg_search, - kg_search_generation_config, - stream, - rag_generation_config, - kg_search_type, - kg_search_level, - ) - if stream: - for chunk in response: - click.echo(chunk, nl=False) - click.echo() - elif obj.client_mode: - click.echo(f"Search Results:\n{response['search_results']}") - click.echo(f"Completion:\n{response['completion']}") - else: - click.echo(f"Search Results:\n{response.search_results}") - click.echo(f"Completion:\n{response.completion}") - - -@cli.command() -@click.option( - "--query", prompt="Enter your search query", help="The search query" -) -@click.option( - "--use-vector-search", is_flag=True, default=True, help="Use vector search" -) -@click.option("--filters", type=JSON, help="Search filters as JSON") -@click.option( - "--search-limit", default=10, help="Number of search results to return" -) -@click.option( - "--use-hybrid-search", is_flag=True, help="Perform hybrid search" -) -@click.option( - "--use-kg-search", is_flag=True, help="Use knowledge graph search" -) -@click.option("--kg-search-model", default=None, help="Model for KG agent") -@click.option("--kg-search-type", default="global", help="Local or Global") -@click.option("--kg-search-level", default=None, help="Level of KG search") -@click.pass_obj -def search( - obj, - query, - use_vector_search, - filters, - search_limit, - use_hybrid_search, - use_kg_search, - kg_search_model, - kg_search_type, - kg_search_level, - entity_types=[], - relationships=[], -): - """Perform a search query.""" - kg_search_generation_config = {} - if kg_search_model: - kg_search_generation_config["model"] = kg_search_model - - with timer(): - results = obj.search( - query, - use_vector_search=use_vector_search, - filters=filters, - search_limit=search_limit, - use_hybrid_search=use_hybrid_search, - use_kg_search=use_kg_search, - entity_types=entity_types, - relationships=relationships, - kg_search_type=kg_search_type, - kg_search_generation_config=kg_search_generation_config, - kg_search_level=kg_search_level, - ) - - print("KG_Search Enabled", use_kg_search) - print("KG_Search Type", kg_search_type) - - if isinstance(results, dict) and "results" in results: - results = results["results"] - - if "vector_search_results" in results: - click.echo("Vector search results:") - for result in results["vector_search_results"]: - click.echo(result) - - if "kg_search_results" in results and results["kg_search_results"]: - click.echo("KG search results:") - for result in results["kg_search_results"]: - click.echo(result) diff --git a/py/core/examples/scripts/sample_data_ingestor.py b/py/core/examples/scripts/sample_data_ingestor.py deleted file mode 100644 index 309c8b61e..000000000 --- a/py/core/examples/scripts/sample_data_ingestor.py +++ /dev/null @@ -1,64 +0,0 @@ -import os -from typing import TYPE_CHECKING - -import fire - -if TYPE_CHECKING: - from core.main.execution import R2RExecutionWrapper - - -class SampleDataIngestor: - def __init__( - self, - executor: "R2RExecutionWrapper", - ): - self.executor = executor - - @staticmethod - def get_sample_files(no_media: bool = True) -> list[str]: - examples_dir = os.path.join( - os.path.dirname(os.path.abspath(__file__)), ".." - ) - - files = [ - os.path.join(examples_dir, "data", "aristotle.txt"), - os.path.join(examples_dir, "data", "got.txt"), - os.path.join(examples_dir, "data", "screen_shot.png"), - os.path.join(examples_dir, "data", "pg_essay_1.html"), - os.path.join(examples_dir, "data", "pg_essay_2.html"), - os.path.join(examples_dir, "data", "pg_essay_3.html"), - os.path.join(examples_dir, "data", "pg_essay_4.html"), - os.path.join(examples_dir, "data", "pg_essay_5.html"), - os.path.join(examples_dir, "data", "lyft_2021.pdf"), - os.path.join(examples_dir, "data", "uber_2021.pdf"), - os.path.join(examples_dir, "data", "sample.mp3"), - os.path.join(examples_dir, "data", "sample2.mp3"), - ] - if no_media: - excluded_types = ["jpeg", "jpg", "png", "svg", "mp3", "mp4"] - files = [ - file_path - for file_path in files - if file_path.split(".")[-1].lower() not in excluded_types - ] - return files - - def ingest_sample_files(self, no_media: bool = True): - sample_files = self.get_sample_files(no_media) - - response = self.executor.ingest_files( - sample_files, - ) - return response - - def ingest_sample_file(self, no_media: bool = True, option: int = 0): - sample_files = self.get_sample_files() - - response = self.executor.ingest_files( - [sample_files[option]], - ) - return response - - -if __name__ == "__main__": - fire.Fire(SampleDataIngestor) diff --git a/py/core/main/__init__.py b/py/core/main/__init__.py index 4843948d7..373502757 100644 --- a/py/core/main/__init__.py +++ b/py/core/main/__init__.py @@ -5,7 +5,6 @@ # from .app_entry import r2r_app from .assembly import * from .engine import R2REngine -from .execution import R2RExecutionWrapper from .r2r import R2R from .services import ( AuthService, @@ -33,8 +32,6 @@ # "r2r_app", ## R2R ENGINE "R2REngine", - ## R2R EXECUTION - "R2RExecutionWrapper", ## R2R ASSEMBLY # Builder "R2RBuilder", diff --git a/py/core/main/api/routes/management/base.py b/py/core/main/api/routes/management/base.py index ff052ab22..bf5aa7973 100644 --- a/py/core/main/api/routes/management/base.py +++ b/py/core/main/api/routes/management/base.py @@ -239,7 +239,9 @@ async def inspect_knowledge_graph( "Only a superuser can call the `inspect_knowledge_graph` endpoint.", 403, ) - return await self.engine.ainspect_knowledge_graph(limit=limit, print_descriptions=print_descriptions) + return await self.engine.ainspect_knowledge_graph( + limit=limit, print_descriptions=print_descriptions + ) @self.router.get("/groups_overview") @self.base_endpoint diff --git a/py/core/main/api/routes/restructure/base.py b/py/core/main/api/routes/restructure/base.py index 1d0801301..abf44fc66 100644 --- a/py/core/main/api/routes/restructure/base.py +++ b/py/core/main/api/routes/restructure/base.py @@ -3,7 +3,6 @@ from fastapi import Depends -# TODO: Botched by Claude class RestructureRouter(BaseRouter): def __init__(self, engine: R2REngine): super().__init__(engine) diff --git a/py/core/main/app_entry.py b/py/core/main/app_entry.py index 9c312108d..3f487ddbd 100644 --- a/py/core/main/app_entry.py +++ b/py/core/main/app_entry.py @@ -6,7 +6,7 @@ from fastapi import FastAPI from .assembly import R2RBuilder, R2RConfig -from .execution import R2RExecutionWrapper +from .r2r import R2R logger = logging.getLogger(__name__) current_file_path = os.path.dirname(__file__) @@ -22,7 +22,6 @@ class PipelineType(Enum): def r2r_app( config_name: Optional[str] = "default", config_path: Optional[str] = None, - client_mode: bool = False, base_url: Optional[str] = None, pipeline_type: PipelineType = PipelineType.QNA, ) -> FastAPI: @@ -31,8 +30,7 @@ def r2r_app( if config_path and config_name: raise ValueError("Cannot specify both config and config_name") - config_path = os.getenv("CONFIG_PATH") or config_path - if config_path: + if config_path := os.getenv("CONFIG_PATH") or config_path: config = R2RConfig.from_toml(config_path) else: config_name = os.getenv("CONFIG_NAME") or config_name @@ -40,22 +38,15 @@ def r2r_app( raise ValueError(f"Invalid config name: {config_name}") config = R2RConfig.from_toml(R2RBuilder.CONFIG_OPTIONS[config_name]) - if ( - config.embedding.provider == "openai" - and "OPENAI_API_KEY" not in os.environ - ): + if config.embedding.provider == "openai" and "OPENAI_API_KEY" not in os.environ: raise ValueError( "Must set OPENAI_API_KEY in order to initialize OpenAIEmbeddingProvider." ) - wrapper = R2RExecutionWrapper( - config_name=config_name, - config_path=config_path, - client_mode=client_mode, - base_url=base_url, - ) + r2r_deployment = R2R(config=config) - return wrapper.get_app() + # Return the FastAPI app + return r2r_deployment.app.app logging.basicConfig(level=logging.INFO) diff --git a/py/core/main/services/management_service.py b/py/core/main/services/management_service.py index 2e76b9fd9..b8b499e2f 100644 --- a/py/core/main/services/management_service.py +++ b/py/core/main/services/management_service.py @@ -363,7 +363,7 @@ async def inspect_knowledge_graph( descriptions_dict = {} relationships = [] - + for relationship in relationships_raw: if print_descriptions: descriptions_dict[relationship["subject"]["name"]] = ( @@ -372,7 +372,7 @@ async def inspect_knowledge_graph( descriptions_dict[relationship["object"]["name"]] = ( relationship["object"]["description"] ) - + relationships.append( ( relationship["subject"]["name"], @@ -468,7 +468,9 @@ def generate_output( for obj in objects: output.append(f" - {obj}") if print_descriptions and obj in descriptions_dict: - output.append(f" Description: {descriptions_dict[obj]}") + output.append( + f" Description: {descriptions_dict[obj]}" + ) # Print basic graph statistics output.extend( diff --git a/py/core/main/services/retrieval_service.py b/py/core/main/services/retrieval_service.py index ca58ab1fa..f52a85766 100644 --- a/py/core/main/services/retrieval_service.py +++ b/py/core/main/services/retrieval_service.py @@ -61,10 +61,7 @@ async def search( async with manage_run(self.run_manager, "search_app") as run_id: t0 = time.time() - if ( - kg_search_settings.use_kg_search - and self.config.kg.provider is None - ): + if kg_search_settings.use_kg_search and self.config.kg.provider is None: raise R2RException( status_code=400, message="Knowledge Graph search is not enabled in the configuration.", @@ -167,13 +164,9 @@ async def rag( ) if len(results) == 0: - raise R2RException( - status_code=404, message="No results found" - ) + raise R2RException(status_code=404, message="No results found") if len(results) > 1: - logger.warning( - f"Multiple results found for query: {query}" - ) + logger.warning(f"Multiple results found for query: {query}") completion_record.search_results = ( results[0].search_results @@ -181,9 +174,7 @@ async def rag( else None ) completion_record.llm_response = ( - results[0].completion - if hasattr(results[0], "completion") - else None + results[0].completion if hasattr(results[0], "completion") else None ) completion_record.completion_end_time = datetime.now() @@ -202,10 +193,10 @@ async def rag( raise R2RException( status_code=502, message="Remote server not reachable or returned an invalid response", - ) + ) from e raise R2RException( status_code=500, message="Internal Server Error" - ) + ) from e async def stream_rag_response( self, @@ -219,9 +210,7 @@ async def stream_rag_response( ): async def stream_response(): async with manage_run(self.run_manager, "arag"): - async for ( - chunk - ) in await self.pipelines.streaming_rag_pipeline.run( + async for chunk in await self.pipelines.streaming_rag_pipeline.run( input=to_async_generator([query]), run_manager=self.run_manager, vector_search_settings=vector_search_settings, @@ -271,9 +260,7 @@ async def agent( async def stream_response(): async with manage_run(self.run_manager, "arag_agent"): - async for ( - chunk - ) in self.agents.streaming_rag_agent.arun( + async for chunk in self.agents.streaming_rag_agent.arun( messages=messages, system_instruction=task_prompt_override, vector_search_settings=vector_search_settings, @@ -313,6 +300,4 @@ async def stream_response(): status_code=502, message="Ollama server not reachable or returned an invalid response", ) - raise R2RException( - status_code=500, message="Internal Server Error" - ) + raise R2RException(status_code=500, message="Internal Server Error") diff --git a/py/core/providers/parsing/unstructured_parsing.py b/py/core/providers/parsing/unstructured_parsing.py index a1c7347eb..3fe073a52 100644 --- a/py/core/providers/parsing/unstructured_parsing.py +++ b/py/core/providers/parsing/unstructured_parsing.py @@ -21,10 +21,10 @@ def __init__(self, use_api, config): from unstructured.partition.auto import partition self.partition = partition - except ImportError: + except ImportError as e: raise ImportError( "Please install the unstructured package to use the unstructured parsing provider." - ) + ) from e if config.excluded_parsers: logger.warning( "Excluded parsers are not supported by the unstructured parsing provider." diff --git a/py/pyproject.toml b/py/pyproject.toml index f96330fbf..eb04f31d0 100644 --- a/py/pyproject.toml +++ b/py/pyproject.toml @@ -12,6 +12,7 @@ license = "MIT" include = ["r2r.toml", "compose.yaml", "compose.neo4j.yaml", "compose.ollama.yaml", "compose.postgres.yaml", "pyproject.toml"] packages = [ { include = "r2r", from = "." }, + { include = "cli", from = "." }, { include = "core", from = "." }, { include = "sdk", from = "." }, ] @@ -87,7 +88,7 @@ pytest-cov = "^5.0.0" colorama = "^0.4.6" [tool.poetry.scripts] -r2r = "core.cli.cli:main" +r2r = "cli.cli:main" [tool.black] line-length = 79 diff --git a/py/sdk/client.py b/py/sdk/client.py index d92fec48c..60b34cf22 100644 --- a/py/sdk/client.py +++ b/py/sdk/client.py @@ -13,6 +13,7 @@ from .models import R2RException from .restructure import RestructureMethods from .retrieval import RetrievalMethods +from .server import ServerMethods nest_asyncio.apply() @@ -88,23 +89,23 @@ def __init__( # Initialize method groups self._auth = AuthMethods - self._retrieval = RetrievalMethods self._ingestion = IngestionMethods - self._restructure = RestructureMethods self._management = ManagementMethods + self._restructure = RestructureMethods + self._retrieval = RetrievalMethods + self._server = ServerMethods # Collect all methods from the method groups self._methods = {} for group in [ self._auth, - self._retrieval, self._ingestion, - self._restructure, self._management, + self._restructure, + self._retrieval, + self._server, ]: - for name, method in inspect.getmembers( - group, predicate=inspect.isfunction - ): + for name, method in inspect.getmembers(group, predicate=inspect.isfunction): if not name.startswith("_"): self._methods[name] = method @@ -169,9 +170,6 @@ def _ensure_authenticated(self): message="Not authenticated. Please login first.", ) - async def health(self) -> dict: - return await self._make_request("GET", "health") - async def close(self): await self.client.aclose() @@ -183,9 +181,7 @@ async def __aexit__(self, exc_type, exc_val, exc_tb): def __getattr__(self, name): if name in self._methods: - return lambda *args, **kwargs: self._methods[name]( - self, *args, **kwargs - ) + return lambda *args, **kwargs: self._methods[name](self, *args, **kwargs) raise AttributeError(f"'R2RClient' object has no attribute '{name}'") def __dir__(self): diff --git a/py/sdk/ingestion.py b/py/sdk/ingestion.py index 01c9629f1..ed15a3147 100644 --- a/py/sdk/ingestion.py +++ b/py/sdk/ingestion.py @@ -34,9 +34,7 @@ async def ingest_files( for path in file_paths: if os.path.isdir(path): for root, _, files in os.walk(path): - all_file_paths.extend( - os.path.join(root, file) for file in files - ) + all_file_paths.extend(os.path.join(root, file) for file in files) else: all_file_paths.append(path) @@ -79,7 +77,7 @@ async def ingest_files( async def update_files( client, file_paths: list[str], - document_ids: Optional[list[str]] = None, + document_ids: list[str], metadatas: Optional[list[dict]] = None, chunking_config_override: Optional[Union[dict, ChunkingConfig]] = None, ) -> dict: @@ -88,17 +86,15 @@ async def update_files( Args: file_paths (List[str]): List of file paths to update. - document_ids (Optional[List[str]): An optional list of document IDs to update. + document_ids (List[str]): List of document IDs to update. metadatas (Optional[List[dict]]): List of updated metadata dictionaries for each file. chunking_config_override (Optional[Union[dict, ChunkingConfig]]): Custom chunking configuration. Returns: dict: Update results containing processed, failed, and skipped documents. """ - if document_ids and len(file_paths) != len(document_ids): - raise ValueError( - "Number of file paths must match number of document IDs." - ) + if len(file_paths) != len(document_ids): + raise ValueError("Number of file paths must match number of document IDs.") with ExitStack() as stack: files = [ @@ -114,22 +110,17 @@ async def update_files( ] data = { - "metadatas": json.dumps(metadatas) if metadatas else None, - "document_ids": ( - json.dumps([str(doc_id) for doc_id in document_ids]) - if document_ids - else None - ), - "chunking_config_override": ( - json.dumps( - chunking_config_override.model_dump() - if isinstance(chunking_config_override, ChunkingConfig) - else chunking_config_override - ) - if chunking_config_override - else None - ), + "document_ids": document_ids, } + if metadatas: + data["metadatas"] = metadatas + if chunking_config_override: + data["chunking_config_override"] = ( + chunking_config_override.model_dump() + if isinstance(chunking_config_override, ChunkingConfig) + else chunking_config_override + ) + return await client._make_request( "POST", "update_files", data=data, files=files ) diff --git a/py/sdk/management.py b/py/sdk/management.py index 40d62d406..e39247ec3 100644 --- a/py/sdk/management.py +++ b/py/sdk/management.py @@ -3,16 +3,6 @@ class ManagementMethods: - @staticmethod - async def server_stats(client) -> dict: - """ - Get statistics about the server, including the start time, uptime, CPU usage, and memory usage. - - Returns: - dict: The server statistics. - """ - return await client._make_request("GET", "server_stats") - @staticmethod async def update_prompt( client, @@ -69,29 +59,6 @@ async def analytics( return await client._make_request("GET", "analytics", params=params) - @staticmethod - async def logs( - client, - run_type_filter: Optional[str] = None, - max_runs: int = None, - ) -> dict: - """ - Get logs from the server. - - Args: - run_type_filter (Optional[str]): The run type to filter by. - max_runs (int): Specifies the maximum number of runs to return. Values outside the range of 1 to 1000 will be adjusted to the nearest valid value with a default of 100. - - Returns: - dict: The logs from the server. - """ - params = {} - if run_type_filter is not None: - params["run_type_filter"] = run_type_filter - if max_runs is not None: - params["max_runs"] = max_runs - return await client._make_request("GET", "logs", params=params) - @staticmethod async def app_settings(client) -> dict: """ @@ -119,9 +86,7 @@ async def score_completion( dict: The response from the server. """ data = {"message_id": message_id, "score": score} - return await client._make_request( - "POST", "score_completion", json=data - ) + return await client._make_request("POST", "score_completion", json=data) @staticmethod async def users_overview( @@ -137,12 +102,10 @@ async def users_overview( Returns: dict: The overview of users in the system. """ - params = { - "user_ids": [str(uid) for uid in user_ids] if user_ids else None - } - return await client._make_request( - "GET", "users_overview", params=params - ) + params = {} + if user_ids is not None: + params["user_ids"] = [str(uid) for uid in user_ids] + return await client._make_request("GET", "users_overview", params=params) @staticmethod async def delete( @@ -182,9 +145,7 @@ async def documents_overview( if document_ids: params["document_ids"] = document_ids - return await client._make_request( - "GET", "documents_overview", params=params - ) + return await client._make_request("GET", "documents_overview", params=params) @staticmethod async def document_chunks( @@ -200,9 +161,7 @@ async def document_chunks( Returns: dict: The chunks for the document. """ - return await client._make_request( - "GET", f"document_chunks/{document_id}" - ) + return await client._make_request("GET", f"document_chunks/{document_id}") @staticmethod async def inspect_knowledge_graph( @@ -250,9 +209,7 @@ async def groups_overview( params["limit"] = limit if offset: params["offset"] = offset - return await client._make_request( - "GET", "groups_overview", params=params - ) + return await client._make_request("GET", "groups_overview", params=params) @staticmethod async def create_group( @@ -377,9 +334,7 @@ async def add_user_to_group( "user_id": user_id, "group_id": group_id, } - return await client._make_request( - "POST", "add_user_to_group", json=data - ) + return await client._make_request("POST", "add_user_to_group", json=data) @staticmethod async def remove_user_from_group( @@ -401,9 +356,7 @@ async def remove_user_from_group( "user_id": user_id, "group_id": group_id, } - return await client._make_request( - "POST", "remove_user_from_group", json=data - ) + return await client._make_request("POST", "remove_user_from_group", json=data) @staticmethod async def get_users_in_group( @@ -446,9 +399,7 @@ async def get_groups_for_user( Returns: dict: The list of groups that the user is a member of. """ - return await client._make_request( - "GET", f"get_groups_for_user/{user_id}" - ) + return await client._make_request("GET", f"get_groups_for_user/{user_id}") @staticmethod async def assign_document_to_group( @@ -470,9 +421,7 @@ async def assign_document_to_group( "document_id": document_id, "group_id": group_id, } - return await client._make_request( - "POST", "assign_document_to_group", json=data - ) + return await client._make_request("POST", "assign_document_to_group", json=data) # TODO: Verify that this method is implemented, also, should be a PUT request @staticmethod @@ -513,9 +462,7 @@ async def get_document_groups( Returns: dict: The list of groups that the document is assigned to. """ - return await client._make_request( - "GET", f"get_document_groups/{document_id}" - ) + return await client._make_request("GET", f"get_document_groups/{document_id}") @staticmethod async def get_documents_in_group( diff --git a/py/sdk/retrieval.py b/py/sdk/retrieval.py index edc2f9db3..5e446e3e9 100644 --- a/py/sdk/retrieval.py +++ b/py/sdk/retrieval.py @@ -33,6 +33,12 @@ async def search( Returns: SearchResponse: The search response. """ + if isinstance(vector_search_settings, dict): + vector_search_settings = VectorSearchSettings( + **vector_search_settings + ) + if isinstance(kg_search_settings, dict): + kg_search_settings = KGSearchSettings(**kg_search_settings) if not isinstance(vector_search_settings, dict): vector_search_settings = vector_search_settings.model_dump() if not isinstance(kg_search_settings, dict): diff --git a/py/sdk/server.py b/py/sdk/server.py new file mode 100644 index 000000000..89e33b782 --- /dev/null +++ b/py/sdk/server.py @@ -0,0 +1,40 @@ +from typing import Optional + + +class ServerMethods: + @staticmethod + async def health(self) -> dict: + return await self._make_request("GET", "health") + + @staticmethod + async def server_stats(client) -> dict: + """ + Get statistics about the server, including the start time, uptime, CPU usage, and memory usage. + + Returns: + dict: The server statistics. + """ + return await client._make_request("GET", "server_stats") + + @staticmethod + async def logs( + client, + run_type_filter: Optional[str] = None, + max_runs: int = None, + ) -> dict: + """ + Get logs from the server. + + Args: + run_type_filter (Optional[str]): The run type to filter by. + max_runs (int): Specifies the maximum number of runs to return. Values outside the range of 1 to 1000 will be adjusted to the nearest valid value with a default of 100. + + Returns: + dict: The logs from the server. + """ + params = {} + if run_type_filter is not None: + params["run_type_filter"] = run_type_filter + if max_runs is not None: + params["max_runs"] = max_runs + return await client._make_request("GET", "logs", params=params) diff --git a/tests/regression/runner.py b/tests/regression/runner.py index 8a0ceae5f..52d19942b 100644 --- a/tests/regression/runner.py +++ b/tests/regression/runner.py @@ -6,7 +6,7 @@ from colorama import Fore, Style, init # TODO: need to import this from the package, not from the local directory -from r2r_python_sdk.sdk.client import R2RClient +from sdk.client import R2RClient from test_cases.base import BaseTest, RegressionTest @@ -32,11 +32,7 @@ def __init__( if not check_only: self.outputs_dir = os.path.join( os.path.dirname(__file__), - ( - "expected_outputs" - if self.update_expected - else "observed_outputs" - ), + ("expected_outputs" if self.update_expected else "observed_outputs"), ) os.makedirs(self.outputs_dir, exist_ok=True) @@ -71,20 +67,12 @@ def compare_all(self) -> bool: observed_outputs_dir = os.path.join( os.path.dirname(__file__), "observed_outputs" ) - print( - f"\n{Fore.CYAN}Comparing results for test suites:{Style.RESET_ALL}" - ) + print(f"\n{Fore.CYAN}Comparing results for test suites:{Style.RESET_ALL}") for test in self.tests: - if test.compare_outputs( - observed_outputs_dir, expected_outputs_dir - ): - print( - f"{Fore.GREEN}{test.__class__.__name__} ✓{Style.RESET_ALL}" - ) + if test.compare_outputs(observed_outputs_dir, expected_outputs_dir): + print(f"{Fore.GREEN}{test.__class__.__name__} ✓{Style.RESET_ALL}") else: - print( - f"{Fore.RED}{test.__class__.__name__} ✗{Style.RESET_ALL}" - ) + print(f"{Fore.RED}{test.__class__.__name__} ✗{Style.RESET_ALL}") all_passed = False return all_passed diff --git a/tests/regression/test_cases/base.py b/tests/regression/test_cases/base.py index 0859a2767..f2241416d 100644 --- a/tests/regression/test_cases/base.py +++ b/tests/regression/test_cases/base.py @@ -3,11 +3,11 @@ import re from typing import Any, Callable, Dict, Optional -from colorama import Fore, Style, init +from colorama import Fore, Style from deepdiff import DeepDiff # TODO: need to import this from the package, not from the local directory -from r2r_python_sdk.sdk.client import R2RClient +from sdk.client import R2RClient def _to_snake_case(name: str) -> str: @@ -47,9 +47,7 @@ def _save_expected_output(self, output: Dict[str, Any]): with open(self.expected_output_file, "w") as f: json.dump(output, f, indent=2) - def _compare_output( - self, actual: Dict[str, Any], expected: Dict[str, Any] - ) -> bool: + def _compare_output(self, actual: Dict[str, Any], expected: Dict[str, Any]) -> bool: diff = self._custom_diff(expected, actual) if diff: print(f"\nTest {self.name} failed. Differences found:") @@ -67,9 +65,7 @@ def _custom_diff( if "completion" in expected_results and "completion" in actual_results: # Custom comparison for content field - expected_completion = self._get_completion_content( - expected_results - ) + expected_completion = self._get_completion_content(expected_results) actual_completion = self._get_completion_content(actual_results) if ( expected_completion @@ -92,9 +88,7 @@ def _custom_diff( exclude_paths=self.exclude_paths, ) if deep_diff: - diff["other_differences"] = self._serialize_deep_diff( - deep_diff - ) + diff["other_differences"] = self._serialize_deep_diff(deep_diff) # Print the specific fields that are different for change_type, changes in deep_diff.items(): if change_type == "values_changed": @@ -104,13 +98,9 @@ def _custom_diff( print(f" Actual: {change['new_value']}") except Exception as e: - diff["deepdiff_error"] = ( - f"Error in DeepDiff comparison: {str(e)}" - ) + diff["deepdiff_error"] = f"Error in DeepDiff comparison: {str(e)}" return diff - elif ( - "completion" in expected_results or "completion" in actual_results - ): + elif "completion" in expected_results or "completion" in actual_results: diff["content_mismatch"] = { "expected_results": expected_results, "actual_results": actual_results, @@ -125,9 +115,7 @@ def _custom_diff( ) if deep_diff: - diff["other_differences"] = self._serialize_deep_diff( - deep_diff - ) + diff["other_differences"] = self._serialize_deep_diff(deep_diff) # Print the specific fields that are different for change_type, changes in deep_diff.items(): if change_type == "values_changed": @@ -170,9 +158,7 @@ def _fuzzy_content_match( expected_words = set(re.findall(r"\w+", expected.lower())) actual_words = set(re.findall(r"\w+", actual.lower())) common_words = expected_words.intersection(actual_words) - similarity = len(common_words) / max( - len(expected_words), len(actual_words) - ) + similarity = len(common_words) / max(len(expected_words), len(actual_words)) return similarity >= threshold @@ -233,13 +219,9 @@ def compare_outputs( observed_outputs.get(snake_case_name, {}), expected_outputs.get(snake_case_name, {}), ): - print( - f"{Fore.GREEN} Test {snake_case_name} passed ✓{Style.RESET_ALL}" - ) + print(f"{Fore.GREEN} Test {snake_case_name} passed ✓{Style.RESET_ALL}") else: - print( - f"{Fore.RED} Test {snake_case_name} failed ✗{Style.RESET_ALL}" - ) + print(f"{Fore.RED} Test {snake_case_name} failed ✗{Style.RESET_ALL}") all_passed = False return all_passed @@ -265,9 +247,7 @@ def set_exclude_paths(self, test_name: str, exclude_paths: list[str] = []): self.exclude_paths_map[_to_snake_case(test_name)] = exclude_paths def get_test_cases(self) -> Dict[str, callable]: - raise NotImplementedError( - "Subclasses must implement get_test_cases method" - ) + raise NotImplementedError("Subclasses must implement get_test_cases method") def _load_expected_outputs(self) -> Dict[str, Any]: with open(self.expected_outputs_file, "r") as f: diff --git a/tests/test_cli.py b/tests/test_cli.py index fa933eb0d..2c63a1193 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -2,9 +2,9 @@ import click import pytest +from cli.cli import cli +from cli.utils.param_types import JSON from click.testing import CliRunner -from core.cli.cli import cli -from core.cli.utils.param_types import JSON @pytest.fixture @@ -28,10 +28,7 @@ def test_generate_private_key(runner): result = runner.invoke(cli, ["generate-private-key"]) assert result.exit_code == 0 assert "Generated Private Key:" in result.output - assert ( - "Keep this key secure and use it as your R2R_SECRET_KEY." - in result.output - ) + assert "Keep this key secure and use it as your R2R_SECRET_KEY." in result.output def test_delete_command(runner, mock_r2r_execution_wrapper): @@ -41,9 +38,7 @@ def test_delete_command(runner, mock_r2r_execution_wrapper): result = runner.invoke(cli, ["delete", "--filter", "key1:eq:value1"]) assert result.exit_code == 0 assert "Deleted successfully" in result.output - mock_instance.delete.assert_called_once_with( - filters={"key1": {"$eq": "value1"}} - ) + mock_instance.delete.assert_called_once_with(filters={"key1": {"$eq": "value1"}}) def test_multiple_deletes(runner, mock_r2r_execution_wrapper): @@ -124,15 +119,11 @@ def test_ingest_sample_file(runner, mock_r2r_execution_wrapper): mock_instance = mock_r2r_execution_wrapper.return_value mock_instance.ingest_sample_file.return_value = "Sample file ingested" - result = runner.invoke( - cli, ["ingest-sample-file", "--no-media", "--option", "1"] - ) + result = runner.invoke(cli, ["ingest-sample-file", "--no-media", "--option", "1"]) print(f"Output: {result.output}") assert result.exit_code == 0 assert "Sample file ingested" in result.output - mock_instance.ingest_sample_file.assert_called_once_with( - no_media=True, option=1 - ) + mock_instance.ingest_sample_file.assert_called_once_with(no_media=True, option=1) def test_update_files(runner, mock_r2r_execution_wrapper): @@ -254,8 +245,7 @@ def test_docker_down_command(runner): result = runner.invoke(cli, ["docker-down"]) assert result.exit_code == 0 assert ( - "Docker Compose setup has been successfully brought down." - in result.output + "Docker Compose setup has been successfully brought down." in result.output ) mock_bring_down.assert_called_once() mock_remove_network.assert_called_once() diff --git a/tests/test_client.py b/tests/test_client.py index 7751e6cf2..90f172690 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -17,7 +17,7 @@ from fastapi.testclient import TestClient # TODO: need to import this from the package, not from the local directory -from r2r_python_sdk.sdk.client import R2RClient +from sdk.client import R2RClient oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") @@ -26,15 +26,15 @@ def create_user(email: str, password: str): return UserResponse( id=uuid.UUID("12345678-1234-5678-1234-567812345678"), email=email, - hashed_password="hashed_" + password, + hashed_password=f"hashed_{password}", is_active=True, is_superuser=False, is_verified=False, name="Test User", bio="Test Bio", profile_picture="http://example.com/pic.jpg", - created_at=datetime.utcnow(), - updated_at=datetime.utcnow(), + created_at=datetime.now(datetime.UTC), + updated_at=datetime.now(datetime.UTC), ) @@ -83,9 +83,7 @@ def auth_wrapper(token: str = Depends(oauth2_scheme)): @pytest.fixture(scope="function") def mock_db(): db = MagicMock() - db.relational.get_user_by_email.return_value = ( - None # Simulate empty database - ) + db.relational.get_user_by_email.return_value = None # Simulate empty database db.relational.create_user.side_effect = create_user db.relational.get_user_by_id.return_value = create_user( @@ -107,8 +105,8 @@ def update_user(user): title=f"Document {i}", type="txt", group_ids=[uuid.uuid4()], - created_at=datetime.utcnow(), - updated_at=datetime.utcnow(), + created_at=datetime.now(datetime.UTC), + updated_at=datetime.now(datetime.UTC), version="1", metadata={}, size_in_bytes=1000, @@ -297,9 +295,7 @@ async def test_password_reset_flow(r2r_client, mock_db): r2r_client.register(**user_data) # Request password reset - reset_response = r2r_client.request_password_reset( - "reset_pass@example.com" - ) + reset_response = r2r_client.request_password_reset("reset_pass@example.com") print("reset_response = ", reset_response) assert "message" in reset_response["results"] @@ -308,9 +304,7 @@ async def test_password_reset_flow(r2r_client, mock_db): confirm_response = r2r_client.confirm_password_reset( mock_reset_token, "new_password" ) - assert ( - confirm_response["results"]["message"] == "Password reset successfully" - ) + assert confirm_response["results"]["message"] == "Password reset successfully" # Try logging in with new password login_response = r2r_client.login( diff --git a/tests/test_kg.py b/tests/test_kg.py index ae4289657..7f8c4885c 100644 --- a/tests/test_kg.py +++ b/tests/test_kg.py @@ -6,15 +6,17 @@ from core.base import DocumentFragment, KGExtraction, Entity, Triple, Community from uuid import uuid4 + @pytest.fixture def kg_extraction_pipe(): return KGTriplesExtractionPipe( kg_provider=MagicMock(), llm_provider=MagicMock(), prompt_provider=MagicMock(), - chunking_provider=MagicMock() + chunking_provider=MagicMock(), ) + @pytest.fixture def document_fragment(): return DocumentFragment( @@ -24,18 +26,28 @@ def document_fragment(): user_id=uuid4(), group_ids=[uuid4()], data="Test data", - metadata={} + metadata={}, ) + + @pytest.mark.asyncio async def test_extract_kg_success(kg_extraction_pipe, document_fragment): - kg_extraction_pipe.llm_provider.aget_completion = AsyncMock(return_value=MagicMock( - choices=[MagicMock(message=MagicMock(content=( - '("entity"$$$$Entity1$$$$Category1$$$$Description1)' - '("relationship"$$$$Entity1$$$$Entity2$$$$Predicate$$$$Description$$$$0.8)' - )))] - )) + kg_extraction_pipe.llm_provider.aget_completion = AsyncMock( + return_value=MagicMock( + choices=[ + MagicMock( + message=MagicMock( + content=( + '("entity"$$$$Entity1$$$$Category1$$$$Description1)' + '("relationship"$$$$Entity1$$$$Entity2$$$$Predicate$$$$Description$$$$0.8)' + ) + ) + ) + ] + ) + ) result = await kg_extraction_pipe.extract_kg(document_fragment) - + assert isinstance(result, KGExtraction) assert len(result.entities) == 1 assert len(result.triples) == 1 @@ -43,103 +55,156 @@ async def test_extract_kg_success(kg_extraction_pipe, document_fragment): assert result.triples[0].subject == "Entity1" assert result.triples[0].object == "Entity2" + @pytest.mark.asyncio async def test_run_logic(kg_extraction_pipe, document_fragment): async def mock_input_generator(): for _ in range(2): yield document_fragment - + input_mock = MagicMock() input_mock.message = mock_input_generator() - - kg_extraction_pipe.extract_kg = AsyncMock(return_value=KGExtraction( - entities=[Entity(name="TestEntity", category="TestCategory", description="TestDescription")], - triples=[Triple(subject="TestSubject", predicate="TestPredicate", object="TestObject")] - )) - - results = [result async for result in kg_extraction_pipe._run_logic(input_mock, MagicMock(), "run_id")] - + + kg_extraction_pipe.extract_kg = AsyncMock( + return_value=KGExtraction( + entities=[ + Entity( + name="TestEntity", + category="TestCategory", + description="TestDescription", + ) + ], + triples=[ + Triple( + subject="TestSubject", + predicate="TestPredicate", + object="TestObject", + ) + ], + ) + ) + + results = [ + result + async for result in kg_extraction_pipe._run_logic( + input_mock, MagicMock(), "run_id" + ) + ] + assert len(results) == 2 for result in results: assert isinstance(result, KGExtraction) assert len(result.entities) == 1 assert len(result.triples) == 1 + @pytest.fixture def mock_kg_provider(mocker): provider = mocker.Mock() provider.get_all_entities.return_value = [ - Entity(name=f"Entity{i}", category=f"Category{i%2+1}", description=f"Description{i}") + Entity( + name=f"Entity{i}", + category=f"Category{i%2+1}", + description=f"Description{i}", + ) for i in range(1, 4) ] provider.get_entities.return_value = [ - Entity(name=f"Entity{i}", category=f"Category{i%2+1}", description=f"Description{i}") + Entity( + name=f"Entity{i}", + category=f"Category{i%2+1}", + description=f"Description{i}", + ) for i in range(1, 4) ] provider.get_triples.return_value = [ - Triple(subject=f"Entity{i}", predicate=f"Predicate{i%2+1}", object=f"Entity{i+1}") + Triple( + subject=f"Entity{i}", + predicate=f"Predicate{i%2+1}", + object=f"Entity{i+1}", + ) for i in range(1, 4) ] provider.get_communities.return_value = [ - Community(id=f"Community{i}", level=f"Level{i%2+1}", short_id=f"Short{i}", title=f"Title{i}", entity_ids=[f"Entity{i}"], relationship_ids=[f"Relationship{i}"]) + Community( + id=f"Community{i}", + level=f"Level{i%2+1}", + short_id=f"Short{i}", + title=f"Title{i}", + entity_ids=[f"Entity{i}"], + relationship_ids=[f"Relationship{i}"], + ) for i in range(1, 4) ] return provider + @pytest.fixture def mock_embedding_provider(mocker): provider = mocker.Mock() provider.get_embeddings.return_value = [ - [0.1*i, 0.2*i, 0.3*i] for i in range(1, 4) + [0.1 * i, 0.2 * i, 0.3 * i] for i in range(1, 4) ] provider.async_get_embedding = AsyncMock(return_value=[0.1, 0.2, 0.3]) return provider + @pytest.fixture def mock_completion_provider(mocker): provider = mocker.Mock() - + async def mock_aget_completion(*args, **kwargs): return mocker.Mock( - choices=[mocker.Mock(message=mocker.Mock(content="Cluster summary"))] + choices=[ + mocker.Mock(message=mocker.Mock(content="Cluster summary")) + ] ) - + provider.aget_completion = mock_aget_completion return provider + @pytest.fixture def mock_prompt_provider(mocker): provider = mocker.Mock() provider.get_message_payload.return_value = mocker.Mock( task_prompt_name="graphrag_community_reports", - task_inputs={"input_text": "Test input text"} + task_inputs={"input_text": "Test input text"}, ) provider._get_message_payload.return_value = { "task_prompt_name": "graphrag_community_reports", - "task_inputs": {"input_text": "Test input text"} + "task_inputs": {"input_text": "Test input text"}, } return provider + @pytest.fixture -def kg_clustering_pipe(mocker, mock_kg_provider, mock_embedding_provider, mock_completion_provider, mock_prompt_provider): +def kg_clustering_pipe( + mocker, + mock_kg_provider, + mock_embedding_provider, + mock_completion_provider, + mock_prompt_provider, +): return KGClusteringPipe( kg_provider=mock_kg_provider, embedding_provider=mock_embedding_provider, llm_provider=mock_completion_provider, prompt_provider=mock_prompt_provider, - n_clusters=2 + n_clusters=2, ) + @pytest.mark.asyncio async def test_cluster_kg(kg_clustering_pipe): triples = [ Triple(subject="Entity1", predicate="relatedTo", object="Entity2"), Triple(subject="Entity2", predicate="relatedTo", object="Entity3"), - Triple(subject="Entity3", predicate="relatedTo", object="Entity1") + Triple(subject="Entity3", predicate="relatedTo", object="Entity1"), ] result = [] @@ -147,5 +212,5 @@ async def test_cluster_kg(kg_clustering_pipe): result.append(community) assert len(result) == 1 - assert result[0]['id'] == '0_0' - assert result[0]['title'] == '_' \ No newline at end of file + assert result[0]["id"] == "0_0" + assert result[0]["title"] == "_" From 30f524a9d34cc86cbf87d5a7c988ad5569968104 Mon Sep 17 00:00:00 2001 From: Nolan Tremelling <34580718+NolanTrem@users.noreply.github.com> Date: Tue, 20 Aug 2024 17:25:42 -0700 Subject: [PATCH 23/74] Rm files readded by git (#904) --- py/core/main/execution.py | 479 -------------------------------------- py/poetry.lock | 46 +--- py/pyproject.toml | 4 +- pyproject.toml | 2 +- 4 files changed, 12 insertions(+), 519 deletions(-) delete mode 100644 py/core/main/execution.py diff --git a/py/core/main/execution.py b/py/core/main/execution.py deleted file mode 100644 index b6bd5c0fd..000000000 --- a/py/core/main/execution.py +++ /dev/null @@ -1,479 +0,0 @@ -import ast -import asyncio -import json -import os -import threading -import time -from typing import Any, Dict, Optional, Union -from uuid import UUID - -import click -from core.base import ( - AnalysisTypes, - GenerationConfig, - KGSearchSettings, - LogFilterCriteria, - VectorSearchSettings, -) -from fastapi import UploadFile - -from .assembly.builder import R2RBuilder -from .assembly.config import R2RConfig -from .r2r import R2R - - -class R2RExecutionWrapper: - """A demo class for the R2R library.""" - - def __init__( - self, - config_path: Optional[str] = None, - config_name: Optional[str] = "default", - client_mode: bool = True, - base_url="http://localhost:8000", - ): - if config_path and config_name: - raise Exception("Cannot specify both config_path and config_name") - - # Handle fire CLI - if isinstance(client_mode, str): - client_mode = client_mode.lower() == "true" - self.client_mode = client_mode - self.base_url = base_url - - if self.client_mode: - from sdk.client import R2RClient - - self.client = R2RClient(base_url) - self.app = None - else: - config = ( - R2RConfig.from_toml(config_path) - if config_path - else R2RConfig.from_toml( - R2RBuilder.CONFIG_OPTIONS[config_name or "default"] - ) - ) - - self.client = None - self.app = R2R(config=config) - - def serve(self, host: str = "0.0.0.0", port: int = 8000): - if not self.client_mode: - self.app.serve(host, port) - else: - raise ValueError( - "Serve method is only available when `client_mode=False`." - ) - - def _parse_metadata_string(metadata_string: str) -> list[dict]: - """ - Convert a string representation of metadata into a list of dictionaries. - - The input string can be in one of two formats: - 1. JSON array of objects: '[{"key": "value"}, {"key2": "value2"}]' - 2. Python-like list of dictionaries: "[{'key': 'value'}, {'key2': 'value2'}]" - - Args: - metadata_string (str): The string representation of metadata. - - Returns: - list[dict]: A list of dictionaries representing the metadata. - - Raises: - ValueError: If the string cannot be parsed into a list of dictionaries. - """ - if not metadata_string: - return [] - - try: - # First, try to parse as JSON - return json.loads(metadata_string) - except json.JSONDecodeError as e: - try: - # If JSON parsing fails, try to evaluate as a Python literal - result = ast.literal_eval(metadata_string) - if not isinstance(result, list) or not all( - isinstance(item, dict) for item in result - ): - raise ValueError( - "The string does not represent a list of dictionaries" - ) from e - return result - except (ValueError, SyntaxError) as exc: - raise ValueError( - "Unable to parse the metadata string. " - "Please ensure it's a valid JSON array or Python list of dictionaries." - ) from exc - - def ingest_files( - self, - file_paths: list[str], - metadatas: Optional[list[dict]] = None, - document_ids: Optional[list[Union[UUID, str]]] = None, - versions: Optional[list[str]] = None, - ): - if isinstance(file_paths, str): - file_paths = list(file_paths.split(",")) - if isinstance(metadatas, str): - metadatas = self._parse_metadata_string(metadatas) - if isinstance(document_ids, str): - document_ids = list(document_ids.split(",")) - if isinstance(versions, str): - versions = list(versions.split(",")) - - all_file_paths = [] - for path in file_paths: - if os.path.isdir(path): - for root, _, files in os.walk(path): - all_file_paths.extend( - os.path.join(root, file) for file in files - ) - else: - all_file_paths.append(path) - - files = [ - UploadFile( - filename=os.path.basename(file_path), - file=open(file_path, "rb"), - ) - for file_path in all_file_paths - ] - - for file in files: - file.file.seek(0, 2) - file.size = file.file.tell() - file.file.seek(0) - - try: - spinner_chars = "|/-\\" - stop_spinner = False - - def spinner(): - i = 0 - while not stop_spinner: - click.echo( - f"\rIngesting files {spinner_chars[i % len(spinner_chars)]}", - nl=False, - ) - time.sleep(0.1) - i += 1 - - spinner_thread = threading.Thread(target=spinner) - spinner_thread.start() - - try: - if self.client_mode: - results = self.client.ingest_files( - file_paths=all_file_paths, - document_ids=document_ids, - metadatas=metadatas, - versions=versions, - ) - results["results"] - else: - results = self.app.ingest_files( - files=files, - document_ids=document_ids, - metadatas=metadatas, - versions=versions, - ) - finally: - stop_spinner = True - spinner_thread.join() - click.echo("\rIngestion complete! ") - - return results - finally: - for file in files: - file.file.close() - - def update_files( - self, - file_paths: list[str], - document_ids: list[str], - metadatas: Optional[list[dict]] = None, - ): - if isinstance(file_paths, str): - file_paths = list(file_paths.split(",")) - if isinstance(metadatas, str): - metadatas = self._parse_metadata_string(metadatas) - if isinstance(document_ids, str): - document_ids = list(document_ids.split(",")) - - if self.client_mode: - return self.client.update_files( - file_paths=file_paths, - document_ids=document_ids, - metadatas=metadatas, - )["results"] - - files = [ - UploadFile( - filename=file_path, - file=open(file_path, "rb"), - ) - for file_path in file_paths - ] - return self.app.update_files( - files=files, document_ids=document_ids, metadatas=metadatas - ) - - def search( - self, - query: str, - use_vector_search: bool = True, - filters: Optional[dict[str, str]] = None, - search_limit: int = 10, - use_hybrid_search: bool = False, - use_kg_search: bool = False, - kg_search_generation_config: Optional[dict] = None, - kg_search_type: str = "global", - kg_search_level: Optional[str] = None, - entity_types: list = [], - relationships: list = [], - ): - if self.client_mode: - return self.client.search( - query, - VectorSearchSettings( - use_vector_search=use_vector_search, - filters=filters or {}, - search_limit=search_limit, - use_hybrid_search=use_hybrid_search, - ), - KGSearchSettings( - use_kg_search=use_kg_search, - kg_search_type=kg_search_type, - kg_search_level=kg_search_level, - entity_types=entity_types, - relationships=relationships, - kg_search_generation_config=GenerationConfig( - **(kg_search_generation_config or {}) - ), - ), - )["results"] - else: - return self.app.search( - query, - VectorSearchSettings( - use_vector_search=use_vector_search, - filters=filters or {}, - search_limit=search_limit, - use_hybrid_search=use_hybrid_search, - ), - KGSearchSettings( - use_kg_search=use_kg_search, - kg_search_generation_config=GenerationConfig( - **(kg_search_generation_config or {}) - ), - kg_search_type=kg_search_type, - kg_search_level=kg_search_level, - entity_types=entity_types, - relationships=relationships, - ), - ) - - def rag( - self, - query: str, - use_vector_search: bool = True, - filters: Optional[dict[str, str]] = None, - search_limit: int = 10, - use_hybrid_search: bool = False, - use_kg_search: bool = False, - kg_search_generation_config: Optional[dict] = None, - stream: bool = False, - rag_generation_config: Optional[dict] = None, - kg_search_type: str = "global", - kg_search_level: Optional[str] = None, - ): - if self.client_mode: - response = self.client.rag( - query, - vector_search_settings=VectorSearchSettings( - use_vector_search=use_vector_search, - filters=filters or {}, - search_limit=search_limit, - use_hybrid_search=use_hybrid_search, - ), - kg_search_settings=KGSearchSettings( - use_kg_search=use_kg_search, - kg_search_generation_config=GenerationConfig( - **(kg_search_generation_config or {}) - ), - kg_search_type=kg_search_type, - kg_search_level=kg_search_level, - ), - rag_generation_config=GenerationConfig( - **(rag_generation_config or {}) - ), - ) - - if not stream: - response = response["results"] - return response - else: - return response - else: - response = self.app.rag( - query, - vector_search_settings=VectorSearchSettings( - use_vector_search=use_vector_search, - filters=filters or {}, - search_limit=search_limit, - use_hybrid_search=use_hybrid_search, - ), - kg_search_settings=KGSearchSettings( - use_kg_search=use_kg_search, - kg_search_generation_config=GenerationConfig( - **(kg_search_generation_config or {}) - ), - ), - rag_generation_config=GenerationConfig( - **(rag_generation_config or {}) - ), - ) - if not stream: - return response - else: - - async def async_generator(): - async for chunk in response: - yield chunk - - def sync_generator(): - try: - loop = asyncio.get_event_loop() - async_gen = async_generator() - while True: - try: - yield loop.run_until_complete( - async_gen.__anext__() - ) - except StopAsyncIteration: - break - except Exception: - pass - - return sync_generator() - - def documents_overview( - self, - document_ids: Optional[list[str]] = None, - ): - if self.client_mode: - return self.client.documents_overview(document_ids)["results"] - else: - return self.app.documents_overview(document_ids) - - def enrich_graph(self): - if self.client_mode: - return self.client.enrich_graph() - else: - return self.app.enrich_graph() - - def delete( - self, - filters: Optional[dict[str, str]] = None, - ): - if self.client_mode: - return self.client.delete(filters)["results"] - else: - return self.app.delete(filters) - - def logs( - self, - run_type_filter: Optional[str] = None, - max_runs: int = 100, - ): - if self.client_mode: - return self.client.logs(run_type_filter, max_runs)["results"] - else: - return self.app.logs(run_type_filter, max_runs) - - def document_chunks(self, document_id: str): - doc_uuid = UUID(document_id) - if self.client_mode: - return self.client.document_chunks(doc_uuid)["results"] - else: - return self.app.document_chunks(doc_uuid) - - def app_settings(self): - if self.client_mode: - return self.client.app_settings() - else: - return self.app.app_settings() - - def users_overview(self, user_ids: Optional[list[UUID]] = None): - if self.client_mode: - return self.client.users_overview(user_ids)["results"] - else: - return self.app.users_overview(user_ids) - - def analytics( - self, - filters: Optional[Dict[str, Any]] = None, - analysis_types: Optional[Dict[str, Any]] = None, - ): - if self.client_mode: - return self.client.analytics( - filter_criteria=filters, - analysis_types=analysis_types, - )["results"] - - filter_criteria = LogFilterCriteria(filters=filters) - analysis_types_obj = AnalysisTypes(analysis_types=analysis_types) - return self.app.analytics( - filter_criteria=filter_criteria, analysis_types=analysis_types_obj - ) - - def ingest_sample_file(self, no_media: bool = True, option: int = 0): - from core.examples.scripts.sample_data_ingestor import ( - SampleDataIngestor, - ) - - """Ingest the first sample file into R2R.""" - sample_ingestor = SampleDataIngestor(self) - return sample_ingestor.ingest_sample_file( - no_media=no_media, option=option - ) - - def ingest_sample_files(self, no_media: bool = True): - from core.examples.scripts.sample_data_ingestor import ( - SampleDataIngestor, - ) - - """Ingest the first sample file into R2R.""" - sample_ingestor = SampleDataIngestor(self) - return sample_ingestor.ingest_sample_files(no_media=no_media) - - def inspect_knowledge_graph( - self, limit: int = 100, print_descriptions: bool = False - ) -> str: - if self.client_mode: - return self.client.inspect_knowledge_graph( - limit, print_descriptions - )["results"] - else: - return self.engine.inspect_knowledge_graph( - limit, print_descriptions - ) - - def health(self) -> str: - if self.client_mode: - return self.client.health() - - def get_app(self): - if not self.client_mode: - return self.app.app.app - else: - raise Exception( - "`get_app` method is only available when running with `client_mode=False`." - ) - - -if __name__ == "__main__": - import fire - - fire.Fire(R2RExecutionWrapper) diff --git a/py/poetry.lock b/py/poetry.lock index d6b949067..e365e7793 100644 --- a/py/poetry.lock +++ b/py/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. [[package]] name = "aiohappyeyeballs" @@ -929,20 +929,6 @@ docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1 testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8.0.1)", "pytest (>=7.4.3)", "pytest-asyncio (>=0.21)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)", "virtualenv (>=20.26.2)"] typing = ["typing-extensions (>=4.8)"] -[[package]] -name = "fire" -version = "0.5.0" -description = "A library for automatically generating command line interfaces." -optional = true -python-versions = "*" -files = [ - {file = "fire-0.5.0.tar.gz", hash = "sha256:a6b0d49e98c8963910021f92bba66f65ab440da2982b78eb1bbf95a0a34aacc6"}, -] - -[package.dependencies] -six = "*" -termcolor = "*" - [[package]] name = "flake8" version = "6.1.0" @@ -2569,13 +2555,13 @@ httpx = ">=0.27.0,<0.28.0" [[package]] name = "openai" -version = "1.41.1" +version = "1.42.0" description = "The official Python library for the openai API" optional = false python-versions = ">=3.7.1" files = [ - {file = "openai-1.41.1-py3-none-any.whl", hash = "sha256:56fb04105263f79559aff3ceea2e1dd16f8c5385e8238cb66cf0e6888fa8bfcf"}, - {file = "openai-1.41.1.tar.gz", hash = "sha256:e38e376efd91e0d4db071e2a6517b6b4cac1c2a6fd63efdc5ec6be10c5967c1b"}, + {file = "openai-1.42.0-py3-none-any.whl", hash = "sha256:dc91e0307033a4f94931e5d03cc3b29b9717014ad5e73f9f2051b6cb5eda4d80"}, + {file = "openai-1.42.0.tar.gz", hash = "sha256:c9d31853b4e0bc2dc8bd08003b462a006035655a701471695d0bfdc08529cde3"}, ] [package.dependencies] @@ -3974,13 +3960,13 @@ stats = ["scipy (>=1.7)", "statsmodels (>=0.12)"] [[package]] name = "setuptools" -version = "73.0.0" +version = "73.0.1" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-73.0.0-py3-none-any.whl", hash = "sha256:f2bfcce7ae1784d90b04c57c2802e8649e1976530bb25dc72c2b078d3ecf4864"}, - {file = "setuptools-73.0.0.tar.gz", hash = "sha256:3c08705fadfc8c7c445cf4d98078f0fafb9225775b2b4e8447e40348f82597c0"}, + {file = "setuptools-73.0.1-py3-none-any.whl", hash = "sha256:b208925fcb9f7af924ed2dc04708ea89791e24bde0d3020b27df0e116088b34e"}, + {file = "setuptools-73.0.1.tar.gz", hash = "sha256:d59a3e788ab7e012ab2c4baed1b376da6366883ee20d7a5fc426816e3d7b1193"}, ] [package.extras] @@ -4196,20 +4182,6 @@ build = ["cython (>=0.29.33)"] develop = ["colorama", "cython (>=0.29.33)", "cython (>=3.0.10,<4)", "flake8", "isort", "joblib", "matplotlib (>=3)", "pytest (>=7.3.0,<8)", "pytest-cov", "pytest-randomly", "pytest-xdist", "pywinpty", "setuptools-scm[toml] (>=8.0,<9.0)"] docs = ["ipykernel", "jupyter-client", "matplotlib", "nbconvert", "nbformat", "numpydoc", "pandas-datareader", "sphinx"] -[[package]] -name = "termcolor" -version = "2.4.0" -description = "ANSI color formatting for output in terminal" -optional = true -python-versions = ">=3.8" -files = [ - {file = "termcolor-2.4.0-py3-none-any.whl", hash = "sha256:9297c0df9c99445c2412e832e882a7884038a25617c60cea2ad69488d4040d63"}, - {file = "termcolor-2.4.0.tar.gz", hash = "sha256:aab9e56047c8ac41ed798fa36d892a37aca6b3e9159f3e0c24bc64a9b3ac7b7a"}, -] - -[package.extras] -tests = ["pytest", "pytest-cov"] - [[package]] name = "threadpoolctl" version = "3.5.0" @@ -4779,10 +4751,10 @@ doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linke test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy", "pytest-ruff (>=0.2.1)"] [extras] -core = ["aiosqlite", "asyncpg", "bcrypt", "beautifulsoup4", "deepdiff", "fire", "fsspec", "graspologic", "gunicorn", "litellm", "markdown", "neo4j", "ollama", "openai", "openpyxl", "passlib", "poppler-utils", "posthog", "psutil", "pydantic", "pyjwt", "pypdf", "python-docx", "python-multipart", "python-pptx", "pyyaml", "redis", "requests", "sqlalchemy", "toml", "types-requests", "uvicorn", "vecs"] +core = ["aiosqlite", "asyncpg", "bcrypt", "beautifulsoup4", "deepdiff", "fsspec", "graspologic", "gunicorn", "litellm", "markdown", "neo4j", "ollama", "openai", "openpyxl", "passlib", "poppler-utils", "posthog", "psutil", "pydantic", "pyjwt", "pypdf", "python-docx", "python-multipart", "python-pptx", "pyyaml", "redis", "requests", "sqlalchemy", "toml", "types-requests", "uvicorn", "vecs"] core-ingest-movies = ["moviepy", "opencv-python"] [metadata] lock-version = "2.0" python-versions = ">=3.9,<3.13" -content-hash = "34b93bcd771abd4c1eb4f3ffb79f36a716835e721e46cd0767007201abf6d806" +content-hash = "e7200bc7f06b1a2b7e36a8f0a449b324848a490371aeb72f375034724b84eab0" diff --git a/py/pyproject.toml b/py/pyproject.toml index eb04f31d0..953c8bcfc 100644 --- a/py/pyproject.toml +++ b/py/pyproject.toml @@ -30,7 +30,6 @@ openai = { version = "^1.11.1" } pydantic = { extras = ["email"], version = "^2.8.2", optional = true } python-multipart = { version = "^0.0.9", optional = true } -fire = { version = "^0.5.0", optional = true } gunicorn = { version = "^21.2.0", optional = true } requests = { version = "^2.31.0", optional = true } types-requests = { version = "^2.31.0", optional = true } @@ -62,10 +61,11 @@ poppler-utils = { version = "^0.1.0", optional = true } psutil = { version = "^6.0.0", optional = true } deepdiff = { version = "^7.0.1", optional = true } graspologic = { version = "^3.4.1", optional = true } +click = "^8.1.7" [tool.poetry.extras] core = [ - "pydantic", "python-multipart", "fire", "gunicorn", "requests", "types-requests", + "pydantic", "python-multipart", "gunicorn", "requests", "types-requests", "uvicorn", "aiosqlite", "asyncpg", "redis", "beautifulsoup4", "openpyxl", "markdown", "pypdf", "python-pptx", "python-docx", "vecs", "litellm", "openai", "fsspec", "posthog", "sqlalchemy", "ollama", "neo4j", "passlib", "bcrypt", diff --git a/pyproject.toml b/pyproject.toml index bf751095e..0c2f96ae1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -87,7 +87,7 @@ pytest-cov = "^5.0.0" colorama = "^0.4.6" [tool.poetry.scripts] -r2r = "core.cli.cli:main" +r2r = "cli.cli:main" [tool.black] line-length = 79 From a2267bc1912dc1b67d67d4acdb536b26f7c81b4b Mon Sep 17 00:00:00 2001 From: Nolan Tremelling <34580718+NolanTrem@users.noreply.github.com> Date: Tue, 20 Aug 2024 17:48:28 -0700 Subject: [PATCH 24/74] Remove Execution Wrapper (#905) * Rm files readded by git * Fix merge botch --- .pre-commit-config.yaml | 2 +- py/cli/commands/ingestion.py | 28 +++-- py/cli/commands/retrieval.py | 28 +++-- py/core/base/providers/kg.py | 8 +- py/core/configs/unstructured.toml | 2 +- py/core/main/app_entry.py | 5 +- py/core/main/services/retrieval_service.py | 29 +++-- py/poetry.lock | 6 +- py/pyproject.toml | 2 +- py/sdk/client.py | 8 +- py/sdk/ingestion.py | 8 +- py/sdk/management.py | 40 +++++-- pyproject.toml | 127 --------------------- 13 files changed, 122 insertions(+), 171 deletions(-) delete mode 100644 pyproject.toml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5961fe9e2..1a086bbdc 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -19,7 +19,7 @@ repos: - id: black name: black - entry: bash -c 'cd py && poetry run black $(git diff --cached --name-only --diff-filter=ACM | grep ".py$" | xargs -I {} echo ../{})' + entry: bash -c 'cd py && poetry run black .' language: system types: [python] pass_filenames: false diff --git a/py/cli/commands/ingestion.py b/py/cli/commands/ingestion.py index 3e84f54e6..0666ee869 100644 --- a/py/cli/commands/ingestion.py +++ b/py/cli/commands/ingestion.py @@ -11,9 +11,15 @@ @cli.command() -@click.argument("file_paths", nargs=-1, required=True, type=click.Path(exists=True)) -@click.option("--document-ids", multiple=True, help="Document IDs for ingestion") -@click.option("--metadatas", type=JSON, help="Metadatas for ingestion as a JSON string") +@click.argument( + "file_paths", nargs=-1, required=True, type=click.Path(exists=True) +) +@click.option( + "--document-ids", multiple=True, help="Document IDs for ingestion" +) +@click.option( + "--metadatas", type=JSON, help="Metadatas for ingestion as a JSON string" +) @click.option( "--versions", multiple=True, @@ -27,18 +33,24 @@ def ingest_files(client, file_paths, document_ids, metadatas, versions): document_ids = list(document_ids) if document_ids else None versions = list(versions) if versions else None - response = client.ingest_files(file_paths, metadatas, document_ids, versions) + response = client.ingest_files( + file_paths, metadatas, document_ids, versions + ) click.echo(json.dumps(response, indent=2)) @cli.command() -@click.argument("file-paths", nargs=-1, required=True, type=click.Path(exists=True)) +@click.argument( + "file-paths", nargs=-1, required=True, type=click.Path(exists=True) +) @click.option( "--document-ids", required=True, help="Document IDs to update (comma-separated)", ) -@click.option("--metadatas", type=JSON, help="Metadatas for updating as a JSON string") +@click.option( + "--metadatas", type=JSON, help="Metadatas for updating as a JSON string" +) @click.pass_obj def update_files(client, file_paths, document_ids, metadatas): """Update existing files in R2R.""" @@ -77,7 +89,9 @@ def ingest_files_from_urls(client, urls): try: response = client.ingest_files([temp_file_path]) - click.echo(f"File '{filename}' ingested successfully. Response: {response}") + click.echo( + f"File '{filename}' ingested successfully. Response: {response}" + ) ingested_files.append(filename) finally: os.unlink(temp_file_path) diff --git a/py/cli/commands/retrieval.py b/py/cli/commands/retrieval.py index b7ff0cd07..e2e0d5782 100644 --- a/py/cli/commands/retrieval.py +++ b/py/cli/commands/retrieval.py @@ -5,7 +5,9 @@ @cli.command() -@click.option("--query", prompt="Enter your search query", help="The search query") +@click.option( + "--query", prompt="Enter your search query", help="The search query" +) # VectorSearchSettings @click.option( "--use-vector-search", @@ -18,13 +20,17 @@ type=JSON, help="Filters to apply to the vector search as a JSON", ) -@click.option("--search-limit", default=None, help="Number of search results to return") +@click.option( + "--search-limit", default=None, help="Number of search results to return" +) @click.option("--do-hybrid-search", is_flag=True, help="Perform hybrid search") @click.option( "--selected-group-ids", type=JSON, help="Group IDs to search for as a JSON" ) # KGSearchSettings -@click.option("--use-kg-search", is_flag=True, help="Use knowledge graph search") +@click.option( + "--use-kg-search", is_flag=True, help="Use knowledge graph search" +) @click.option("--kg-search-type", default=None, help="Local or Global") @click.option("--kg-search-level", default=None, help="Level of KG search") @click.option( @@ -32,7 +38,9 @@ type=JSON, help="KG search generation config", ) -@click.option("--entity-types", type=JSON, help="Entity types to search for as a JSON") +@click.option( + "--entity-types", type=JSON, help="Entity types to search for as a JSON" +) @click.option( "--relationships", type=JSON, help="Relationships to search for as a JSON" ) @@ -111,13 +119,17 @@ def search(client, query, **kwargs): "--use-vector-search", is_flag=True, default=True, help="Use vector search" ) @click.option("--filters", type=JSON, help="Search filters as JSON") -@click.option("--search-limit", default=10, help="Number of search results to return") +@click.option( + "--search-limit", default=10, help="Number of search results to return" +) @click.option("--do-hybrid-search", is_flag=True, help="Perform hybrid search") @click.option( "--selected-group-ids", type=JSON, help="Group IDs to search for as a JSON" ) # KG Search Settings -@click.option("--use-kg-search", is_flag=True, help="Use knowledge graph search") +@click.option( + "--use-kg-search", is_flag=True, help="Use knowledge graph search" +) @click.option("--kg-search-type", default="global", help="Local or Global") @click.option( "--kg-search-level", @@ -125,7 +137,9 @@ def search(client, query, **kwargs): help="Level of cluster to use for Global KG search", ) @click.option("--kg-search-model", default=None, help="Model for KG agent") -@click.option("--entity-types", type=JSON, help="Entity types to search for as a JSON") +@click.option( + "--entity-types", type=JSON, help="Entity types to search for as a JSON" +) @click.option( "--relationships", type=JSON, help="Relationships to search for as a JSON" ) diff --git a/py/core/base/providers/kg.py b/py/core/base/providers/kg.py index 9f34b8af0..6259fd829 100644 --- a/py/core/base/providers/kg.py +++ b/py/core/base/providers/kg.py @@ -37,7 +37,9 @@ class KGProvider(ABC): def __init__(self, config: KGConfig) -> None: if not isinstance(config, KGConfig): - raise ValueError("KGProvider must be initialized with a `KGConfig`.") + raise ValueError( + "KGProvider must be initialized with a `KGConfig`." + ) logger.info(f"Initializing KG provider with config: {config}") self.config = config self.validate_config() @@ -116,7 +118,9 @@ def structured_query( param_map = {} @abstractmethod - def vector_query(self, query, **kwargs: Any) -> Tuple[list[Entity], list[float]]: + def vector_query( + self, query, **kwargs: Any + ) -> Tuple[list[Entity], list[float]]: """Abstract method to query the graph store with a vector store query.""" # TODO - Type this method. diff --git a/py/core/configs/unstructured.toml b/py/core/configs/unstructured.toml index 8c2a00237..a8786d13a 100644 --- a/py/core/configs/unstructured.toml +++ b/py/core/configs/unstructured.toml @@ -5,4 +5,4 @@ provider = "unstructured_api" provider = "unstructured" method = "recursive" chunk_size = 512 -chunk_overlap = 50 \ No newline at end of file +chunk_overlap = 50 diff --git a/py/core/main/app_entry.py b/py/core/main/app_entry.py index 3f487ddbd..d61e15fbe 100644 --- a/py/core/main/app_entry.py +++ b/py/core/main/app_entry.py @@ -38,7 +38,10 @@ def r2r_app( raise ValueError(f"Invalid config name: {config_name}") config = R2RConfig.from_toml(R2RBuilder.CONFIG_OPTIONS[config_name]) - if config.embedding.provider == "openai" and "OPENAI_API_KEY" not in os.environ: + if ( + config.embedding.provider == "openai" + and "OPENAI_API_KEY" not in os.environ + ): raise ValueError( "Must set OPENAI_API_KEY in order to initialize OpenAIEmbeddingProvider." ) diff --git a/py/core/main/services/retrieval_service.py b/py/core/main/services/retrieval_service.py index f52a85766..d9e72bc8a 100644 --- a/py/core/main/services/retrieval_service.py +++ b/py/core/main/services/retrieval_service.py @@ -61,7 +61,10 @@ async def search( async with manage_run(self.run_manager, "search_app") as run_id: t0 = time.time() - if kg_search_settings.use_kg_search and self.config.kg.provider is None: + if ( + kg_search_settings.use_kg_search + and self.config.kg.provider is None + ): raise R2RException( status_code=400, message="Knowledge Graph search is not enabled in the configuration.", @@ -164,9 +167,13 @@ async def rag( ) if len(results) == 0: - raise R2RException(status_code=404, message="No results found") + raise R2RException( + status_code=404, message="No results found" + ) if len(results) > 1: - logger.warning(f"Multiple results found for query: {query}") + logger.warning( + f"Multiple results found for query: {query}" + ) completion_record.search_results = ( results[0].search_results @@ -174,7 +181,9 @@ async def rag( else None ) completion_record.llm_response = ( - results[0].completion if hasattr(results[0], "completion") else None + results[0].completion + if hasattr(results[0], "completion") + else None ) completion_record.completion_end_time = datetime.now() @@ -210,7 +219,9 @@ async def stream_rag_response( ): async def stream_response(): async with manage_run(self.run_manager, "arag"): - async for chunk in await self.pipelines.streaming_rag_pipeline.run( + async for ( + chunk + ) in await self.pipelines.streaming_rag_pipeline.run( input=to_async_generator([query]), run_manager=self.run_manager, vector_search_settings=vector_search_settings, @@ -260,7 +271,9 @@ async def agent( async def stream_response(): async with manage_run(self.run_manager, "arag_agent"): - async for chunk in self.agents.streaming_rag_agent.arun( + async for ( + chunk + ) in self.agents.streaming_rag_agent.arun( messages=messages, system_instruction=task_prompt_override, vector_search_settings=vector_search_settings, @@ -300,4 +313,6 @@ async def stream_response(): status_code=502, message="Ollama server not reachable or returned an invalid response", ) - raise R2RException(status_code=500, message="Internal Server Error") + raise R2RException( + status_code=500, message="Internal Server Error" + ) diff --git a/py/poetry.lock b/py/poetry.lock index e365e7793..2914428a1 100644 --- a/py/poetry.lock +++ b/py/poetry.lock @@ -2596,11 +2596,11 @@ files = [ [package.dependencies] numpy = [ {version = ">=1.21.0", markers = "python_version == \"3.9\" and platform_system == \"Darwin\" and platform_machine == \"arm64\""}, - {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, - {version = ">=1.23.5", markers = "python_version >= \"3.11\" and python_version < \"3.12\""}, {version = ">=1.21.4", markers = "python_version >= \"3.10\" and platform_system == \"Darwin\" and python_version < \"3.11\""}, {version = ">=1.21.2", markers = "platform_system != \"Darwin\" and python_version >= \"3.10\" and python_version < \"3.11\""}, {version = ">=1.19.3", markers = "platform_system == \"Linux\" and platform_machine == \"aarch64\" and python_version >= \"3.8\" and python_version < \"3.10\" or python_version > \"3.9\" and python_version < \"3.10\" or python_version >= \"3.9\" and platform_system != \"Darwin\" and python_version < \"3.10\" or python_version >= \"3.9\" and platform_machine != \"arm64\" and python_version < \"3.10\""}, + {version = ">=1.23.5", markers = "python_version >= \"3.11\" and python_version < \"3.12\""}, + {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, ] [[package]] @@ -2683,8 +2683,8 @@ files = [ [package.dependencies] numpy = [ {version = ">=1.22.4", markers = "python_version < \"3.11\""}, - {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, {version = ">=1.23.2", markers = "python_version == \"3.11\""}, + {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, ] python-dateutil = ">=2.8.2" pytz = ">=2020.1" diff --git a/py/pyproject.toml b/py/pyproject.toml index 953c8bcfc..0e1733aa3 100644 --- a/py/pyproject.toml +++ b/py/pyproject.toml @@ -24,10 +24,10 @@ python = ">=3.9,<3.13" httpx = "^0.27.0" nest-asyncio = "^1.6.0" fastapi = "^0.109.2" +click = "^8.1.7" # Core dependencies (optional) openai = { version = "^1.11.1" } - pydantic = { extras = ["email"], version = "^2.8.2", optional = true } python-multipart = { version = "^0.0.9", optional = true } gunicorn = { version = "^21.2.0", optional = true } diff --git a/py/sdk/client.py b/py/sdk/client.py index 60b34cf22..57b065806 100644 --- a/py/sdk/client.py +++ b/py/sdk/client.py @@ -105,7 +105,9 @@ def __init__( self._retrieval, self._server, ]: - for name, method in inspect.getmembers(group, predicate=inspect.isfunction): + for name, method in inspect.getmembers( + group, predicate=inspect.isfunction + ): if not name.startswith("_"): self._methods[name] = method @@ -181,7 +183,9 @@ async def __aexit__(self, exc_type, exc_val, exc_tb): def __getattr__(self, name): if name in self._methods: - return lambda *args, **kwargs: self._methods[name](self, *args, **kwargs) + return lambda *args, **kwargs: self._methods[name]( + self, *args, **kwargs + ) raise AttributeError(f"'R2RClient' object has no attribute '{name}'") def __dir__(self): diff --git a/py/sdk/ingestion.py b/py/sdk/ingestion.py index ed15a3147..e8206ef28 100644 --- a/py/sdk/ingestion.py +++ b/py/sdk/ingestion.py @@ -34,7 +34,9 @@ async def ingest_files( for path in file_paths: if os.path.isdir(path): for root, _, files in os.walk(path): - all_file_paths.extend(os.path.join(root, file) for file in files) + all_file_paths.extend( + os.path.join(root, file) for file in files + ) else: all_file_paths.append(path) @@ -94,7 +96,9 @@ async def update_files( dict: Update results containing processed, failed, and skipped documents. """ if len(file_paths) != len(document_ids): - raise ValueError("Number of file paths must match number of document IDs.") + raise ValueError( + "Number of file paths must match number of document IDs." + ) with ExitStack() as stack: files = [ diff --git a/py/sdk/management.py b/py/sdk/management.py index e39247ec3..9d4486154 100644 --- a/py/sdk/management.py +++ b/py/sdk/management.py @@ -86,7 +86,9 @@ async def score_completion( dict: The response from the server. """ data = {"message_id": message_id, "score": score} - return await client._make_request("POST", "score_completion", json=data) + return await client._make_request( + "POST", "score_completion", json=data + ) @staticmethod async def users_overview( @@ -105,7 +107,9 @@ async def users_overview( params = {} if user_ids is not None: params["user_ids"] = [str(uid) for uid in user_ids] - return await client._make_request("GET", "users_overview", params=params) + return await client._make_request( + "GET", "users_overview", params=params + ) @staticmethod async def delete( @@ -145,7 +149,9 @@ async def documents_overview( if document_ids: params["document_ids"] = document_ids - return await client._make_request("GET", "documents_overview", params=params) + return await client._make_request( + "GET", "documents_overview", params=params + ) @staticmethod async def document_chunks( @@ -161,7 +167,9 @@ async def document_chunks( Returns: dict: The chunks for the document. """ - return await client._make_request("GET", f"document_chunks/{document_id}") + return await client._make_request( + "GET", f"document_chunks/{document_id}" + ) @staticmethod async def inspect_knowledge_graph( @@ -209,7 +217,9 @@ async def groups_overview( params["limit"] = limit if offset: params["offset"] = offset - return await client._make_request("GET", "groups_overview", params=params) + return await client._make_request( + "GET", "groups_overview", params=params + ) @staticmethod async def create_group( @@ -334,7 +344,9 @@ async def add_user_to_group( "user_id": user_id, "group_id": group_id, } - return await client._make_request("POST", "add_user_to_group", json=data) + return await client._make_request( + "POST", "add_user_to_group", json=data + ) @staticmethod async def remove_user_from_group( @@ -356,7 +368,9 @@ async def remove_user_from_group( "user_id": user_id, "group_id": group_id, } - return await client._make_request("POST", "remove_user_from_group", json=data) + return await client._make_request( + "POST", "remove_user_from_group", json=data + ) @staticmethod async def get_users_in_group( @@ -399,7 +413,9 @@ async def get_groups_for_user( Returns: dict: The list of groups that the user is a member of. """ - return await client._make_request("GET", f"get_groups_for_user/{user_id}") + return await client._make_request( + "GET", f"get_groups_for_user/{user_id}" + ) @staticmethod async def assign_document_to_group( @@ -421,7 +437,9 @@ async def assign_document_to_group( "document_id": document_id, "group_id": group_id, } - return await client._make_request("POST", "assign_document_to_group", json=data) + return await client._make_request( + "POST", "assign_document_to_group", json=data + ) # TODO: Verify that this method is implemented, also, should be a PUT request @staticmethod @@ -462,7 +480,9 @@ async def get_document_groups( Returns: dict: The list of groups that the document is assigned to. """ - return await client._make_request("GET", f"get_document_groups/{document_id}") + return await client._make_request( + "GET", f"get_document_groups/{document_id}" + ) @staticmethod async def get_documents_in_group( diff --git a/pyproject.toml b/pyproject.toml deleted file mode 100644 index 0c2f96ae1..000000000 --- a/pyproject.toml +++ /dev/null @@ -1,127 +0,0 @@ -[build-system] -requires = ["poetry-core", "setuptools", "wheel"] -build-backend = "poetry.core.masonry.api" - -[tool.poetry] -name = "r2r" -version = "0.3.0" -description = "SciPhi R2R" -authors = ["Owen Colegrove "] -license = "MIT" -readme = "README.md" -include = ["r2r.toml", "compose.yaml", "compose.neo4j.yaml", "compose.ollama.yaml", "compose.postgres.yaml", "pyproject.toml"] -packages = [ - { include = "core", from = "py" }, - { include = "sdk", from = "py" }, -] - -[tool.poetry.dependencies] -# Python Versions -python = ">=3.9,<3.13" - -httpx = "^0.27.0" -nest-asyncio = "^1.6.0" -fastapi = "^0.109.2" - -# Core dependencies (optional) -pydantic = { extras = ["email"], version = "^2.8.2", optional = true } -python-multipart = { version = "^0.0.9", optional = true } -fire = { version = "^0.5.0", optional = true } -gunicorn = { version = "^21.2.0", optional = true } -requests = { version = "^2.31.0", optional = true } -types-requests = { version = "^2.31.0", optional = true } -uvicorn = { version = "^0.27.0.post1", optional = true } -aiosqlite = { version = "^0.20.0", optional = true } -asyncpg = { version = "^0.29.0", optional = true } -redis = { version = "^5.0.4", optional = true } -beautifulsoup4 = { version = "^4.12.3", optional = true } -openpyxl = { version = "^3.1.2", optional = true } -markdown = { version = "^3.6", optional = true } -pypdf = { version = "^4.2.0", optional = true } -python-pptx = { version = "^1.0.1", optional = true } -python-docx = { version = "^1.1.0", optional = true } -opencv-python = { version = "^4.10.0.82", optional = true } -moviepy = { version = "^1.0.3", optional = true } -vecs = { version = "^0.4.0", optional = true } -litellm = { version = "^1.42.3", optional = true } -openai = { version = "^1.11.1", optional = true } -fsspec = { version = "^2024.6.0", optional = true } -posthog = { version = "^3.5.0", optional = true } -sqlalchemy = { version = "^2.0.30", optional = true } -ollama = { version = "^0.3.1", optional = true } -neo4j = { version = "^5.21.0", optional = true } -passlib = { version = "^1.7.4", optional = true } -bcrypt = { version = "^4.1.3", optional = true } -pyjwt = { version = "^2.8.0", optional = true } -toml = { version = "^0.10.2", optional = true } -pyyaml = { version = "^6.0.1", optional = true } -poppler-utils = { version = "^0.1.0", optional = true } -psutil = { version = "^6.0.0", optional = true } -deepdiff = { version = "^7.0.1", optional = true } -graspologic = { version = "^3.4.1", optional = true } - -[tool.poetry.extras] -core = [ - "pydantic", "python-multipart", "fire", "gunicorn", "requests", "types-requests", - "uvicorn", "aiosqlite", "asyncpg", "redis", "beautifulsoup4", "openpyxl", - "markdown", "pypdf", "python-pptx", "python-docx", "vecs", "litellm", "openai", - "fsspec", "posthog", "sqlalchemy", "ollama", "neo4j", "passlib", "bcrypt", - "pyjwt", "toml", "pyyaml", "poppler-utils", "psutil", "deepdiff", -] -ingest-movies = ["opencv-python", "moviepy"] -kgs = ["graspologic"] -all = ["core", "ingest-movies"] - -[tool.poetry.group.dev.dependencies] -black = "^24.3.0" -codecov = "^2.1.13" -flake8 = "6.1.0" -isort = "5.12.0" -mypy = "^1.5.1" -pre-commit = "^2.9" -pytest = "^8.2.0" -pytest-asyncio = "^0.23.6" -pytest-dependency = "^0.6.0" -pytest-mock = "^3.14.0" -pytest-cov = "^5.0.0" -colorama = "^0.4.6" - -[tool.poetry.scripts] -r2r = "cli.cli:main" - -[tool.black] -line-length = 79 -target-version = ['py39'] -include = '\.pyi?$' -extend-exclude = ''' -/( - # directories - \.eggs - | \.git - | \.hg - | \.mypy_cache - | \.tox - | \.venv - | build - | dist -)/ -''' - -[tool.mypy] -ignore_missing_imports = true -exclude = 'playground/.*|deprecated/.*|dump/.*|docs/source|vecs/*' - -[[tool.mypy.overrides]] -module = "yaml" -ignore_missing_imports = true - -[tool.pytest.ini_options] -asyncio_mode = "auto" -addopts = "--cov=r2r --cov-report=term-missing --cov-report=xml" -testpaths = [ - "tests", -] -filterwarnings = [ - "ignore::DeprecationWarning", - "ignore::pytest.PytestUnraisableExceptionWarning", -] From 8f09101610da544dc8efb0a1600c3855c84896b6 Mon Sep 17 00:00:00 2001 From: emrgnt-cmplxty <68796651+emrgnt-cmplxty@users.noreply.github.com> Date: Tue, 20 Aug 2024 18:09:07 -0700 Subject: [PATCH 25/74] Feature/fix auth revive tests rebased (#906) * adding the client touch ups * fix auth, revive tests * add back tests * uncomment run auth workflow * decruft * refresh test kg --- go/sdk/pkg/sdk/ingestion.go | 4 +- js/sdk/src/r2rClient.ts | 12 +- py/core/base/api/models/__init__.py | 9 +- .../base/api/models/management/responses.py | 3 +- .../base/api/models/restructure/responses.py | 4 +- py/core/base/providers/auth.py | 2 +- py/core/examples/scripts/run_auth_workflow.py | 8 +- py/core/main/api/__init__.py | 2 +- py/core/main/api/routes/ingestion/base.py | 182 ++------- .../ingestion/ingestion_router_openapi.yml | 4 +- py/core/main/api/routes/management/base.py | 34 +- py/core/main/assembly/factory.py | 9 +- py/core/main/services/ingestion_service.py | 1 + py/core/pipelines/ingestion_pipeline.py | 4 +- py/core/providers/database/user.py | 4 +- py/poetry.lock | 34 +- py/pyproject.toml | 9 +- py/sdk/auth.py | 16 +- py/sdk/client.py | 14 +- py/sdk/ingestion.py | 41 +- py/sdk/management.py | 8 +- py/sdk/retrieval.py | 48 ++- {tests => py/tests}/__init__.py | 0 .../tests}/docker_tests/dockerTest.bash | 0 .../test_document_management.json | 0 .../test_group_management.json | 0 .../expected_outputs/test_observability.json | 0 .../expected_outputs/test_retrieval.json | 0 .../test_user_management.json | 0 {tests => py/tests}/regression/runner.py | 24 +- .../tests}/regression/test_cases/base.py | 44 +- .../test_cases/test_document_management.py | 0 .../test_cases/test_group_management.py | 0 .../test_cases/test_observability.py | 0 .../regression/test_cases/test_retrieval.py | 0 .../test_cases/test_user_management.py | 0 .../test_data/admin_document_group1.txt | 0 .../test_data/admin_document_user1.txt | 0 .../regression/test_data/test_document.txt | 0 .../regression/test_data/user1_document.txt | 0 .../test_data/user1_document_group.txt | 0 .../regression/test_data/user2_document.txt | 0 {tests => py/tests}/test_abstractions.py | 0 {tests => py/tests}/test_auth.py | 0 {tests => py/tests}/test_cli.py | 32 +- py/tests/test_client.py | 377 ++++++++++++++++++ {tests => py/tests}/test_config.py | 0 {tests => py/tests}/test_database.py | 34 +- {tests => py/tests}/test_embedding.py | 0 {tests => py/tests}/test_end_to_end.py | 0 {tests => py/tests}/test_groups.py | 0 {tests => py/tests}/test_groups_client.py | 3 +- {tests => py/tests}/test_ingestion_service.py | 0 {tests => py/tests}/test_kg.py | 2 +- {tests => py/tests}/test_llms.py | 0 {tests => py/tests}/test_logging.py | 0 {tests => py/tests}/test_parser.py | 0 {tests => py/tests}/test_pipeline.py | 0 {tests => py/tests}/test_vector_db.py | 125 +++--- 59 files changed, 729 insertions(+), 364 deletions(-) rename {tests => py/tests}/__init__.py (100%) rename {tests => py/tests}/docker_tests/dockerTest.bash (100%) rename {tests => py/tests}/regression/expected_outputs/test_document_management.json (100%) rename {tests => py/tests}/regression/expected_outputs/test_group_management.json (100%) rename {tests => py/tests}/regression/expected_outputs/test_observability.json (100%) rename {tests => py/tests}/regression/expected_outputs/test_retrieval.json (100%) rename {tests => py/tests}/regression/expected_outputs/test_user_management.json (100%) rename {tests => py/tests}/regression/runner.py (86%) rename {tests => py/tests}/regression/test_cases/base.py (89%) rename {tests => py/tests}/regression/test_cases/test_document_management.py (100%) rename {tests => py/tests}/regression/test_cases/test_group_management.py (100%) rename {tests => py/tests}/regression/test_cases/test_observability.py (100%) rename {tests => py/tests}/regression/test_cases/test_retrieval.py (100%) rename {tests => py/tests}/regression/test_cases/test_user_management.py (100%) rename {tests => py/tests}/regression/test_data/admin_document_group1.txt (100%) rename {tests => py/tests}/regression/test_data/admin_document_user1.txt (100%) rename {tests => py/tests}/regression/test_data/test_document.txt (100%) rename {tests => py/tests}/regression/test_data/user1_document.txt (100%) rename {tests => py/tests}/regression/test_data/user1_document_group.txt (100%) rename {tests => py/tests}/regression/test_data/user2_document.txt (100%) rename {tests => py/tests}/test_abstractions.py (100%) rename {tests => py/tests}/test_auth.py (100%) rename {tests => py/tests}/test_cli.py (93%) create mode 100644 py/tests/test_client.py rename {tests => py/tests}/test_config.py (100%) rename {tests => py/tests}/test_database.py (82%) rename {tests => py/tests}/test_embedding.py (100%) rename {tests => py/tests}/test_end_to_end.py (100%) rename {tests => py/tests}/test_groups.py (100%) rename {tests => py/tests}/test_groups_client.py (99%) rename {tests => py/tests}/test_ingestion_service.py (100%) rename {tests => py/tests}/test_kg.py (99%) rename {tests => py/tests}/test_llms.py (100%) rename {tests => py/tests}/test_logging.py (100%) rename {tests => py/tests}/test_parser.py (100%) rename {tests => py/tests}/test_pipeline.py (100%) rename {tests => py/tests}/test_vector_db.py (70%) diff --git a/go/sdk/pkg/sdk/ingestion.go b/go/sdk/pkg/sdk/ingestion.go index d6a77ad38..0f4f9bc62 100644 --- a/go/sdk/pkg/sdk/ingestion.go +++ b/go/sdk/pkg/sdk/ingestion.go @@ -84,7 +84,7 @@ func (i *Ingestion) IngestFiles( if err != nil { return nil, fmt.Errorf("error marshaling chunking config: %w", err) } - writer.WriteField("chunking_config_override", string(chunkingConfigJSON)) + writer.WriteField("chunking_settings", string(chunkingConfigJSON)) } err := writer.Close() @@ -167,7 +167,7 @@ func (i *Ingestion) UpdateFiles( if err != nil { return nil, fmt.Errorf("error marshaling chunking config: %w", err) } - writer.WriteField("chunking_config_override", string(chunkingConfigJSON)) + writer.WriteField("chunking_settings", string(chunkingConfigJSON)) } err = writer.Close() diff --git a/js/sdk/src/r2rClient.ts b/js/sdk/src/r2rClient.ts index b1703e069..3b3396a58 100644 --- a/js/sdk/src/r2rClient.ts +++ b/js/sdk/src/r2rClient.ts @@ -403,7 +403,7 @@ export class r2rClient { document_ids?: string[]; user_ids?: (string | null)[]; versions?: string[]; - chunking_config_override?: Record; + chunking_settings?: Record; skip_document_info?: boolean; } = {}, ): Promise { @@ -468,8 +468,8 @@ export class r2rClient { : undefined, user_ids: options.user_ids ? JSON.stringify(options.user_ids) : undefined, versions: options.versions ? JSON.stringify(options.versions) : undefined, - chunking_config_override: options.chunking_config_override - ? JSON.stringify(options.chunking_config_override) + chunking_settings: options.chunking_settings + ? JSON.stringify(options.chunking_settings) : undefined, skip_document_info: options.skip_document_info !== undefined @@ -511,7 +511,7 @@ export class r2rClient { options: { document_ids: string[]; metadatas?: Record[]; - chunking_config_override?: Record; + chunking_settings?: Record; }, ): Promise { this._ensureAuthenticated(); @@ -549,8 +549,8 @@ export class r2rClient { metadatas: options.metadatas ? JSON.stringify(options.metadatas) : undefined, - chunking_config_override: options.chunking_config_override - ? JSON.stringify(options.chunking_config_override) + chunking_settings: options.chunking_settings + ? JSON.stringify(options.chunking_settings) : undefined, }; diff --git a/py/core/base/api/models/__init__.py b/py/core/base/api/models/__init__.py index e83f16244..1bbf8549c 100644 --- a/py/core/base/api/models/__init__.py +++ b/py/core/base/api/models/__init__.py @@ -33,6 +33,10 @@ WrappedServerStatsResponse, WrappedUserOverviewResponse, ) +from .restructure.responses import ( + KGEnrichementResponse, + WrappedKGEnrichementResponse, +) from .retrieval.responses import ( RAGAgentResponse, RAGResponse, @@ -42,11 +46,6 @@ WrappedSearchResponse, ) -from .restructure.responses import ( - KGEnrichementResponse, - WrappedKGEnrichementResponse, -) - __all__ = [ # Auth Responses "GenericMessageResponse", diff --git a/py/core/base/api/models/management/responses.py b/py/core/base/api/models/management/responses.py index 22c7037ba..64636c6ee 100644 --- a/py/core/base/api/models/management/responses.py +++ b/py/core/base/api/models/management/responses.py @@ -32,7 +32,7 @@ class ServerStats(BaseModel): class AnalyticsResponse(BaseModel): - analytics_data: Any + analytics_data: Optional[dict] = None filtered_logs: Dict[str, Any] @@ -61,6 +61,7 @@ class DocumentOverviewResponse(BaseModel): updated_at: datetime status: str version: str + metadata: Dict[str, Any] class DocumentChunkResponse(BaseModel): diff --git a/py/core/base/api/models/restructure/responses.py b/py/core/base/api/models/restructure/responses.py index 7f57c6f98..e9e62e85e 100644 --- a/py/core/base/api/models/restructure/responses.py +++ b/py/core/base/api/models/restructure/responses.py @@ -1,9 +1,9 @@ +from datetime import datetime from typing import Any, Dict, List, Optional from uuid import UUID -from pydantic import BaseModel -from datetime import datetime from core.base.api.models.base import ResultsWrapper +from pydantic import BaseModel class KGEnrichementResponse(BaseModel): diff --git a/py/core/base/providers/auth.py b/py/core/base/providers/auth.py index 88a86f103..f979f38ba 100644 --- a/py/core/base/providers/auth.py +++ b/py/core/base/providers/auth.py @@ -91,7 +91,7 @@ def login(self, email: str, password: str) -> Dict[str, Token]: @abstractmethod def refresh_access_token( - self, user_email: str, refresh_access_token: str + self, user_email: str, refresh_token: str ) -> Dict[str, str]: pass diff --git a/py/core/examples/scripts/run_auth_workflow.py b/py/core/examples/scripts/run_auth_workflow.py index db24394ec..ad4837fc6 100644 --- a/py/core/examples/scripts/run_auth_workflow.py +++ b/py/core/examples/scripts/run_auth_workflow.py @@ -1,5 +1,5 @@ # TODO: need to import this from the package, not from the local directory -from r2r_python_sdk.sdk.client import R2RClient +from r2r import R2RClient if __name__ == "__main__": client = R2RClient( @@ -7,7 +7,7 @@ ) # Replace with your R2R deployment URL # Register a new user - user_result = client.register("user1@test.com", "password123") + user_result = client.register("user11123@test.com", "password123") print(user_result) # # Uncomment when running with authentication @@ -16,7 +16,7 @@ # print(verify_result) # Login immediately (assuming email verification is disabled) - login_result = client.login("user1@test.com", "password123") + login_result = client.login("user11123@test.com", "password123") print(login_result) # Refresh access token @@ -51,7 +51,7 @@ print(logout_result) # {'results': {'message': 'Logged out successfully'}} - # Login as admin + # # Login as admin login_result = client.login("admin@example.com", "change_me_immediately") # Now you can access superuser features, for example: diff --git a/py/core/main/api/__init__.py b/py/core/main/api/__init__.py index 1ca250e35..573280998 100644 --- a/py/core/main/api/__init__.py +++ b/py/core/main/api/__init__.py @@ -1,8 +1,8 @@ from .routes.auth.base import AuthRouter from .routes.base_router import BaseRouter from .routes.ingestion.base import IngestionRouter -from .routes.restructure.base import RestructureRouter from .routes.management.base import ManagementRouter +from .routes.restructure.base import RestructureRouter from .routes.retrieval.base import RetrievalRouter __all__ = [ diff --git a/py/core/main/api/routes/ingestion/base.py b/py/core/main/api/routes/ingestion/base.py index 8eba7ef91..5c973b18f 100644 --- a/py/core/main/api/routes/ingestion/base.py +++ b/py/core/main/api/routes/ingestion/base.py @@ -9,6 +9,7 @@ from core.base.api.models.ingestion.responses import WrappedIngestionResponse from core.base.utils import generate_user_document_id from fastapi import Depends, File, Form, UploadFile +from pydantic import Json from ....assembly.factory import R2RProviderFactory from ....engine import R2REngine @@ -46,21 +47,19 @@ async def ingest_files_app( files: List[UploadFile] = File( ..., description=ingest_files_descriptions.get("files") ), - document_ids: Optional[list[str]] = Form( + document_ids: Optional[Json[list[UUID]]] = Form( None, description=ingest_files_descriptions.get("document_ids"), ), - versions: Optional[list[str]] = Form( + versions: Optional[Json[list[str]]] = Form( None, description=ingest_files_descriptions.get("versions") ), - metadatas: Optional[list[dict]] = Form( + metadatas: Optional[Json[list[dict]]] = Form( None, description=ingest_files_descriptions.get("metadatas") ), - chunking_config_override: Optional[ChunkingConfig] = Form( + chunking_settings: Optional[ChunkingConfig] = Form( None, - description=ingest_files_descriptions.get( - "chunking_config_override" - ), + description=ingest_files_descriptions.get("chunking_settings"), ), auth_user=Depends(self.engine.providers.auth.auth_wrapper), ) -> WrappedIngestionResponse: @@ -71,19 +70,12 @@ async def ingest_files_app( A valid user authentication token is required to access this endpoint, as regular users can only ingest files for their own access. More expansive group permissioning is under development. """ - try: - parsed_data = self.parse_ingest_files_form_data( - metadatas, document_ids, versions, chunking_config_override - ) - except R2RException as e: - raise e - chunking_provider = None - if chunking_config_override: - chunking_config_override.validate() + if chunking_settings: + chunking_settings.validate() chunking_provider = ( R2RProviderFactory.create_chunking_provider( - chunking_config_override + chunking_settings ) ) else: @@ -111,9 +103,9 @@ async def ingest_files_app( ingestion_result = await self.engine.aingest_files( files=files, - metadatas=parsed_data["metadatas"], - document_ids=parsed_data["document_ids"], - versions=parsed_data["versions"], + metadatas=metadatas, + document_ids=document_ids, + versions=versions, user=auth_user, chunking_provider=chunking_provider, ) @@ -146,17 +138,16 @@ async def update_files_app( files: List[UploadFile] = File( ..., description=update_files_descriptions.get("files") ), - document_ids: Optional[list[str]] = Form( - None, description=update_files_descriptions.get("document_ids") + document_ids: Optional[Json[list[UUID]]] = Form( + None, + description=ingest_files_descriptions.get("document_ids"), ), - metadatas: Optional[list[dict]] = Form( - None, description=update_files_descriptions.get("metadatas") + metadatas: Optional[Json[list[dict]]] = Form( + None, description=ingest_files_descriptions.get("metadatas") ), - chunking_config_override: Optional[str] = Form( + chunking_settings: Optional[ChunkingConfig] = Form( None, - description=update_files_descriptions.get( - "chunking_config_override" - ), + description=ingest_files_descriptions.get("chunking_settings"), ), auth_user=Depends(self.engine.providers.auth.auth_wrapper), ) -> WrappedIngestionResponse: @@ -171,143 +162,18 @@ async def update_files_app( A valid user authentication token is required to access this endpoint, as regular users can only update their own files. More expansive group permissioning is under development. """ - try: - parsed_data = self.parse_update_files_form_data( - metadatas, - document_ids, - chunking_config_override, - [file.filename for file in files], - auth_user.id, - ) - except R2RException as e: - raise e - chunking_provider = None - if chunking_config_override: - config = ChunkingConfig(**chunking_config_override) + if chunking_settings: + config = ChunkingConfig(**chunking_settings) chunking_provider = ( R2RProviderFactory.create_chunking_provider(config) ) + print("input metadatas = ", metadatas) return await self.engine.aupdate_files( files=files, - metadatas=parsed_data["metadatas"], - document_ids=parsed_data["document_ids"], + metadatas=metadatas, + document_ids=document_ids, chunking_provider=chunking_provider, user=auth_user, ) - - @staticmethod - def parse_ingest_files_form_data( - metadatas: Optional[str], - document_ids: Optional[str], - versions: Optional[str], - chunking_config_override: Optional[str], - ) -> dict: - try: - parsed_metadatas = ( - json.loads(metadatas) - if metadatas and metadatas != "null" - else None - ) - if parsed_metadatas is not None and not isinstance( - parsed_metadatas, list - ): - raise ValueError("metadatas must be a list of dictionaries") - - parsed_document_ids = ( - json.loads(document_ids) - if document_ids and document_ids != "null" - else None - ) - if parsed_document_ids is not None: - parsed_document_ids = [ - UUID(doc_id) for doc_id in parsed_document_ids - ] - - parsed_versions = ( - json.loads(versions) - if versions and versions != "null" - else None - ) - - parsed_chunking_config = ( - json.loads(chunking_config_override) - if chunking_config_override - and chunking_config_override != "null" - else None - ) - - return { - "metadatas": parsed_metadatas, - "document_ids": parsed_document_ids, - "versions": parsed_versions, - "chunking_config_override": parsed_chunking_config, - } - except json.JSONDecodeError as e: - raise R2RException( - status_code=400, message=f"Invalid JSON in form data: {e}" - ) from e - except ValueError as e: - raise R2RException(status_code=400, message=str(e)) from e - except Exception as e: - raise R2RException( - status_code=400, message=f"Error processing form data: {e}" - ) from e - - @staticmethod - def parse_update_files_form_data( - metadatas: Optional[list[dict]], - document_ids: Optional[list[str]], - chunking_config_override: Optional[str], - filenames: list[str], - user_id: str, - ): - try: - parsed_metadatas = ( - json.loads(metadatas) - if metadatas and metadatas != "null" - else None - ) - if parsed_metadatas is not None and not isinstance( - parsed_metadatas, list - ): - raise ValueError("metadatas must be a list of dictionaries") - - parsed_document_ids = ( - json.loads(document_ids) - if document_ids and document_ids != "null" - else None - ) - if parsed_document_ids is not None: - parsed_document_ids = [ - UUID(doc_id) for doc_id in parsed_document_ids - ] - else: - parsed_document_ids = [ - generate_user_document_id(filename, UUID(user_id)) - for filename in filenames - ] - - parsed_chunking_config = ( - json.loads(chunking_config_override) - if chunking_config_override - and chunking_config_override != "null" - else None - ) - - return { - "metadatas": parsed_metadatas, - "document_ids": parsed_document_ids, - "chunking_config_override": parsed_chunking_config, - } - except json.JSONDecodeError as e: - raise R2RException( - status_code=400, message=f"Invalid JSON in form data: {e}" - ) from e - except ValueError as e: - raise R2RException(status_code=400, message=str(e)) from e - except Exception as e: - raise R2RException( - status_code=400, message=f"Error processing form data: {e}" - ) from e diff --git a/py/core/main/api/routes/ingestion/ingestion_router_openapi.yml b/py/core/main/api/routes/ingestion/ingestion_router_openapi.yml index 31e81c784..7f751ff3c 100644 --- a/py/core/main/api/routes/ingestion/ingestion_router_openapi.yml +++ b/py/core/main/api/routes/ingestion/ingestion_router_openapi.yml @@ -30,7 +30,7 @@ ingest_files: metadatas: "An optional list of JSON metadata to affix to each file" document_ids: "An optional list of document ids for each file. If not provided, the system will generate a unique document id via the `generate_user_document_id` method." versions: "An optional list of versions for each file. If not provided, the system will default to the tag `v1`." - chunking_config_override: "An optional dictionary to override the default chunking configuration for the ingestion process. If not provided, the system will use the default server-side chunking configuration." + chunking_settings: "An optional dictionary to override the default chunking configuration for the ingestion process. If not provided, the system will use the default server-side chunking configuration." update_files: openapi_extra: @@ -58,4 +58,4 @@ update_files: files: "The list of paths of input files to update in the system." document_ids: "An optional list of document ids for each file. If not provided, the system will attempt to generate the corresponding unique from the `generate_user_document_id` method." metadatas: "An optional list of JSON metadata to affix to each file" - chunking_config_override: "JSON string for chunking configuration override" + chunking_settings: "JSON string for chunking configuration override" diff --git a/py/core/main/api/routes/management/base.py b/py/core/main/api/routes/management/base.py index bf5aa7973..542224b66 100644 --- a/py/core/main/api/routes/management/base.py +++ b/py/core/main/api/routes/management/base.py @@ -22,7 +22,9 @@ WrappedServerStatsResponse, WrappedUserOverviewResponse, ) +from core.base.logging import AnalysisTypes, LogFilterCriteria from fastapi import Body, Depends, Path, Query +from pydantic import Json from ....engine import R2REngine from ..base_router import BaseRouter @@ -86,8 +88,8 @@ async def update_prompt_app( @self.router.get("/analytics") @self.base_endpoint async def get_analytics_app( - filter_criteria: Optional[str] = Query("{}"), - analysis_types: Optional[str] = Query("{}"), + filter_criteria: Optional[Json[dict]] = Query({}), + analysis_types: Optional[Json[dict]] = Query({}), auth_user=Depends(self.engine.providers.auth.auth_wrapper), ) -> WrappedAnalyticsResponse: if not auth_user.is_superuser: @@ -96,18 +98,11 @@ async def get_analytics_app( ) try: - # Parse the query parameters - filter_criteria_dict = ( - json.loads(filter_criteria) if filter_criteria else {} - ) - analysis_types_dict = ( - json.loads(analysis_types) if analysis_types else {} - ) - - return await self.engine.aanalytics( - filter_criteria=filter_criteria_dict, - analysis_types=analysis_types_dict, + result = await self.engine.aanalytics( + filter_criteria=LogFilterCriteria(**filter_criteria), + analysis_types=AnalysisTypes(**analysis_types), ) + return result except json.JSONDecodeError as e: raise R2RException( f"Invalid JSON in query parameters: {str(e)}", 400 @@ -162,7 +157,7 @@ async def score_completion( @self.router.get("/users_overview") @self.base_endpoint async def users_overview_app( - user_ids: list[str] = Query([]), + user_ids: Optional[list[str]] = Query([]), auth_user=Depends(self.engine.providers.auth.auth_wrapper), ) -> WrappedUserOverviewResponse: if not auth_user.is_superuser: @@ -171,7 +166,9 @@ async def users_overview_app( 403, ) - user_uuids = [UUID(user_id) for user_id in user_ids] + user_uuids = ( + [UUID(user_id) for user_id in user_ids] if user_ids else None + ) return await self.engine.ausers_overview(user_ids=user_uuids) @@ -196,16 +193,17 @@ async def documents_overview_app( document_uuids = [ UUID(document_id) for document_id in document_ids ] - return await self.engine.adocuments_overview( + result = await self.engine.adocuments_overview( user_ids=request_user_ids, group_ids=auth_user.group_ids, document_ids=document_uuids, ) + return result - @self.router.get("/document_chunks") + @self.router.get("/document_chunks/{document_id}") @self.base_endpoint async def document_chunks_app( - document_id: str = Query(...), + document_id: str = Path(...), auth_user=Depends(self.engine.providers.auth.auth_wrapper), ) -> WrappedDocumentChunkResponse: document_uuid = UUID(document_id) diff --git a/py/core/main/assembly/factory.py b/py/core/main/assembly/factory.py index fa3296163..7c45864a4 100644 --- a/py/core/main/assembly/factory.py +++ b/py/core/main/assembly/factory.py @@ -246,7 +246,7 @@ def create_providers( auth_provider_override: Optional[AuthProvider] = None, database_provider_override: Optional[DatabaseProvider] = None, parsing_provider_override: Optional[ParsingProvider] = None, - chunking_config_override: Optional[ChunkingProvider] = None, + chunking_settings: Optional[ChunkingProvider] = None, *args, **kwargs, ) -> R2RProviders: @@ -291,11 +291,8 @@ def create_providers( self.config.parsing, *args, **kwargs ) ) - chunking_provider = ( - chunking_config_override - or self.create_chunking_provider( - self.config.chunking, *args, **kwargs - ) + chunking_provider = chunking_settings or self.create_chunking_provider( + self.config.chunking, *args, **kwargs ) return R2RProviders( diff --git a/py/core/main/services/ingestion_service.py b/py/core/main/services/ingestion_service.py index 85d64b747..5327720f5 100644 --- a/py/core/main/services/ingestion_service.py +++ b/py/core/main/services/ingestion_service.py @@ -171,6 +171,7 @@ async def update_files( document = self._file_to_document( file, user, doc_id, updated_metadata ) + print("document = ", document) documents.append(document) ingestion_results = await self.ingest_documents( diff --git a/py/core/pipelines/ingestion_pipeline.py b/py/core/pipelines/ingestion_pipeline.py index 006ca309c..2f4f4ef7d 100644 --- a/py/core/pipelines/ingestion_pipeline.py +++ b/py/core/pipelines/ingestion_pipeline.py @@ -32,7 +32,7 @@ async def run( state: Optional[AsyncState] = None, stream: bool = False, run_manager: Optional[RunManager] = None, - chunking_config_override: Optional[ChunkingProvider] = None, + chunking_settings: Optional[ChunkingProvider] = None, user: Optional[UserResponse] = None, *args: Any, **kwargs: Any, @@ -74,7 +74,7 @@ async def process_documents(): ), state, run_manager, - chunking_config_override=chunking_config_override, + chunking_settings=chunking_settings, *args, **kwargs, ): diff --git a/py/core/providers/database/user.py b/py/core/providers/database/user.py index 8098d228d..7208b1859 100644 --- a/py/core/providers/database/user.py +++ b/py/core/providers/database/user.py @@ -481,10 +481,10 @@ def get_users_overview( is_verified=row[4], created_at=row[5], updated_at=row[6], - group_ids=row[7], + group_ids=row[7] or [], num_files=row[8], total_size_in_bytes=row[9], - document_ids=row[10], + document_ids=row[10] or [], ) for row in results ] diff --git a/py/poetry.lock b/py/poetry.lock index 2914428a1..c350d9ac9 100644 --- a/py/poetry.lock +++ b/py/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. [[package]] name = "aiohappyeyeballs" @@ -929,6 +929,20 @@ docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1 testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8.0.1)", "pytest (>=7.4.3)", "pytest-asyncio (>=0.21)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)", "virtualenv (>=20.26.2)"] typing = ["typing-extensions (>=4.8)"] +[[package]] +name = "fire" +version = "0.5.0" +description = "A library for automatically generating command line interfaces." +optional = true +python-versions = "*" +files = [ + {file = "fire-0.5.0.tar.gz", hash = "sha256:a6b0d49e98c8963910021f92bba66f65ab440da2982b78eb1bbf95a0a34aacc6"}, +] + +[package.dependencies] +six = "*" +termcolor = "*" + [[package]] name = "flake8" version = "6.1.0" @@ -4182,6 +4196,20 @@ build = ["cython (>=0.29.33)"] develop = ["colorama", "cython (>=0.29.33)", "cython (>=3.0.10,<4)", "flake8", "isort", "joblib", "matplotlib (>=3)", "pytest (>=7.3.0,<8)", "pytest-cov", "pytest-randomly", "pytest-xdist", "pywinpty", "setuptools-scm[toml] (>=8.0,<9.0)"] docs = ["ipykernel", "jupyter-client", "matplotlib", "nbconvert", "nbformat", "numpydoc", "pandas-datareader", "sphinx"] +[[package]] +name = "termcolor" +version = "2.4.0" +description = "ANSI color formatting for output in terminal" +optional = true +python-versions = ">=3.8" +files = [ + {file = "termcolor-2.4.0-py3-none-any.whl", hash = "sha256:9297c0df9c99445c2412e832e882a7884038a25617c60cea2ad69488d4040d63"}, + {file = "termcolor-2.4.0.tar.gz", hash = "sha256:aab9e56047c8ac41ed798fa36d892a37aca6b3e9159f3e0c24bc64a9b3ac7b7a"}, +] + +[package.extras] +tests = ["pytest", "pytest-cov"] + [[package]] name = "threadpoolctl" version = "3.5.0" @@ -4751,10 +4779,10 @@ doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linke test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy", "pytest-ruff (>=0.2.1)"] [extras] -core = ["aiosqlite", "asyncpg", "bcrypt", "beautifulsoup4", "deepdiff", "fsspec", "graspologic", "gunicorn", "litellm", "markdown", "neo4j", "ollama", "openai", "openpyxl", "passlib", "poppler-utils", "posthog", "psutil", "pydantic", "pyjwt", "pypdf", "python-docx", "python-multipart", "python-pptx", "pyyaml", "redis", "requests", "sqlalchemy", "toml", "types-requests", "uvicorn", "vecs"] +core = ["aiosqlite", "asyncpg", "bcrypt", "beautifulsoup4", "deepdiff", "fire", "fsspec", "graspologic", "gunicorn", "litellm", "markdown", "neo4j", "ollama", "openai", "openpyxl", "passlib", "poppler-utils", "posthog", "psutil", "pydantic", "pyjwt", "pypdf", "python-docx", "python-multipart", "python-pptx", "pyyaml", "redis", "requests", "sqlalchemy", "toml", "types-requests", "uvicorn", "vecs"] core-ingest-movies = ["moviepy", "opencv-python"] [metadata] lock-version = "2.0" python-versions = ">=3.9,<3.13" -content-hash = "e7200bc7f06b1a2b7e36a8f0a449b324848a490371aeb72f375034724b84eab0" +content-hash = "34b93bcd771abd4c1eb4f3ffb79f36a716835e721e46cd0767007201abf6d806" diff --git a/py/pyproject.toml b/py/pyproject.toml index 0e1733aa3..f96330fbf 100644 --- a/py/pyproject.toml +++ b/py/pyproject.toml @@ -12,7 +12,6 @@ license = "MIT" include = ["r2r.toml", "compose.yaml", "compose.neo4j.yaml", "compose.ollama.yaml", "compose.postgres.yaml", "pyproject.toml"] packages = [ { include = "r2r", from = "." }, - { include = "cli", from = "." }, { include = "core", from = "." }, { include = "sdk", from = "." }, ] @@ -24,12 +23,13 @@ python = ">=3.9,<3.13" httpx = "^0.27.0" nest-asyncio = "^1.6.0" fastapi = "^0.109.2" -click = "^8.1.7" # Core dependencies (optional) openai = { version = "^1.11.1" } + pydantic = { extras = ["email"], version = "^2.8.2", optional = true } python-multipart = { version = "^0.0.9", optional = true } +fire = { version = "^0.5.0", optional = true } gunicorn = { version = "^21.2.0", optional = true } requests = { version = "^2.31.0", optional = true } types-requests = { version = "^2.31.0", optional = true } @@ -61,11 +61,10 @@ poppler-utils = { version = "^0.1.0", optional = true } psutil = { version = "^6.0.0", optional = true } deepdiff = { version = "^7.0.1", optional = true } graspologic = { version = "^3.4.1", optional = true } -click = "^8.1.7" [tool.poetry.extras] core = [ - "pydantic", "python-multipart", "gunicorn", "requests", "types-requests", + "pydantic", "python-multipart", "fire", "gunicorn", "requests", "types-requests", "uvicorn", "aiosqlite", "asyncpg", "redis", "beautifulsoup4", "openpyxl", "markdown", "pypdf", "python-pptx", "python-docx", "vecs", "litellm", "openai", "fsspec", "posthog", "sqlalchemy", "ollama", "neo4j", "passlib", "bcrypt", @@ -88,7 +87,7 @@ pytest-cov = "^5.0.0" colorama = "^0.4.6" [tool.poetry.scripts] -r2r = "cli.cli:main" +r2r = "core.cli.cli:main" [tool.black] line-length = 79 diff --git a/py/sdk/auth.py b/py/sdk/auth.py index 578bea36b..e71f7bbe2 100644 --- a/py/sdk/auth.py +++ b/py/sdk/auth.py @@ -31,7 +31,7 @@ async def verify_email(client, verification_code: str) -> dict: return await client._make_request( "POST", "verify_email", - json={"verification_code": verification_code}, + json=verification_code, ) @staticmethod @@ -102,6 +102,7 @@ async def update_user( "profile_picture": profile_picture, } data = {k: v for k, v in data.items() if v is not None} + print("data = ", data) return await client._make_request("PUT", "user", json=data) @staticmethod @@ -112,9 +113,8 @@ async def refresh_access_token(client) -> dict[str, Token]: Returns: dict[str, Token]: The access and refresh tokens from the server. """ - data = {"refresh_token": client._refresh_token} response = await client._make_request( - "POST", "refresh_access_token", json=data + "POST", "refresh_access_token", json=client._refresh_token ) client.access_token = response["results"]["access_token"]["token"] client._refresh_token = response["results"]["refresh_token"]["token"] @@ -152,7 +152,7 @@ async def request_password_reset(client, email: str) -> dict: dict: The response from the server. """ return await client._make_request( - "POST", "request_password_reset", json={"email": email} + "POST", "request_password_reset", json=email ) @staticmethod @@ -173,9 +173,7 @@ async def confirm_password_reset( return await client._make_request("POST", "reset_password", json=data) @staticmethod - async def delete_user( - client, user_id: str, password: Optional[str] = None - ) -> dict: + async def delete_user(client, user_id: str, password: str = None) -> dict: """ Deletes the user with the given user ID. @@ -186,9 +184,7 @@ async def delete_user( Returns: dict: The response from the server. """ - data = {"user_id": user_id} - if password: - data["password"] = password + data = {"user_id": user_id, "password": password} response = await client._make_request("DELETE", "user", json=data) client.access_token = None client._refresh_token = None diff --git a/py/sdk/client.py b/py/sdk/client.py index 57b065806..8de4ac637 100644 --- a/py/sdk/client.py +++ b/py/sdk/client.py @@ -120,10 +120,18 @@ async def _make_request(self, method, endpoint, **kwargs): "verify_email", ]: headers.update(self._get_auth_header()) - params = kwargs.pop("params", {}) - params = {**params, **EMPTY_ARGS} + if ( + kwargs.get("params", None) == {} + or kwargs.get("params", None) == None + ): + if "params" in kwargs: + kwargs.pop("params") if isinstance(self.client, TestClient): + # Weird mocking fix... + params = kwargs.pop("params", {}) + params = {**params, **EMPTY_ARGS} + response = getattr(self.client, method.lower())( url, headers=headers, params=params, **kwargs ) @@ -131,7 +139,7 @@ async def _make_request(self, method, endpoint, **kwargs): else: try: response = await self.client.request( - method, url, headers=headers, params=params, **kwargs + method, url, headers=headers, **kwargs ) await handle_request_error_async(response) return response.json() if response.content else None diff --git a/py/sdk/ingestion.py b/py/sdk/ingestion.py index e8206ef28..1a7abefde 100644 --- a/py/sdk/ingestion.py +++ b/py/sdk/ingestion.py @@ -2,6 +2,7 @@ import os from contextlib import ExitStack from typing import Optional, Union +from uuid import UUID from .models import ChunkingConfig @@ -12,10 +13,10 @@ class IngestionMethods: async def ingest_files( client, file_paths: list[str], + document_ids: Optional[list[Union[str, UUID]]] = None, metadatas: Optional[list[dict]] = None, - document_ids: Optional[list[str]] = None, versions: Optional[list[str]] = None, - chunking_config_override: Optional[Union[dict, ChunkingConfig]] = None, + chunking_settings: Optional[Union[dict, ChunkingConfig]] = None, ) -> dict: """ Ingest files into your R2R deployment @@ -25,7 +26,7 @@ async def ingest_files( metadatas (Optional[List[dict]]): List of metadata dictionaries for each file. document_ids (Optional[List[str]]): List of document IDs. versions (Optional[List[str]]): List of version strings for each file. - chunking_config_override (Optional[Union[dict, ChunkingConfig]]): Custom chunking configuration. + chunking_settings (Optional[Union[dict, ChunkingConfig]]): Custom chunking configuration. Returns: dict: Ingestion results containing processed, failed, and skipped documents. @@ -61,13 +62,13 @@ async def ingest_files( else None ), "versions": json.dumps(versions) if versions else None, - "chunking_config_override": ( + "chunking_settings": ( json.dumps( - chunking_config_override.model_dump() - if isinstance(chunking_config_override, ChunkingConfig) - else chunking_config_override + chunking_settings.model_dump() + if isinstance(chunking_settings, ChunkingConfig) + else chunking_settings ) - if chunking_config_override + if chunking_settings else None ), } @@ -79,9 +80,9 @@ async def ingest_files( async def update_files( client, file_paths: list[str], - document_ids: list[str], + document_ids: Optional[list[str]], metadatas: Optional[list[dict]] = None, - chunking_config_override: Optional[Union[dict, ChunkingConfig]] = None, + chunking_settings: Optional[Union[dict, ChunkingConfig]] = None, ) -> dict: """ Update existing files in your R2R deployment. @@ -90,7 +91,7 @@ async def update_files( file_paths (List[str]): List of file paths to update. document_ids (List[str]): List of document IDs to update. metadatas (Optional[List[dict]]): List of updated metadata dictionaries for each file. - chunking_config_override (Optional[Union[dict, ChunkingConfig]]): Custom chunking configuration. + chunking_settings (Optional[Union[dict, ChunkingConfig]]): Custom chunking configuration. Returns: dict: Update results containing processed, failed, and skipped documents. @@ -113,16 +114,16 @@ async def update_files( for file in file_paths ] - data = { - "document_ids": document_ids, - } + data = {} + if document_ids: + data["document_ids"] = json.dumps(document_ids) if metadatas: - data["metadatas"] = metadatas - if chunking_config_override: - data["chunking_config_override"] = ( - chunking_config_override.model_dump() - if isinstance(chunking_config_override, ChunkingConfig) - else chunking_config_override + data["metadatas"] = json.dumps(metadatas) + if chunking_settings: + data["chunking_settings"] = ( + chunking_settings.model_dump() + if isinstance(chunking_settings, ChunkingConfig) + else chunking_settings ) return await client._make_request( diff --git a/py/sdk/management.py b/py/sdk/management.py index 9d4486154..3abff1b00 100644 --- a/py/sdk/management.py +++ b/py/sdk/management.py @@ -1,5 +1,6 @@ import json from typing import Optional, Union +from uuid import UUID class ManagementMethods: @@ -114,7 +115,7 @@ async def users_overview( @staticmethod async def delete( client, - filters: dict[str, str], + filters: dict, ) -> dict: """ Delete data from the database given a set of filters. @@ -134,7 +135,7 @@ async def delete( @staticmethod async def documents_overview( client, - document_ids: Optional[list[str]] = None, + document_ids: Optional[list[Union[UUID, str]]] = None, ) -> dict: """ Get an overview of documents in the R2R deployment. @@ -146,6 +147,9 @@ async def documents_overview( dict: The overview of documents in the system. """ params = {} + document_ids = ( + [str(doc_id) for doc_id in document_ids] if document_ids else None + ) if document_ids: params["document_ids"] = document_ids diff --git a/py/sdk/retrieval.py b/py/sdk/retrieval.py index 5e446e3e9..b64cf6d39 100644 --- a/py/sdk/retrieval.py +++ b/py/sdk/retrieval.py @@ -33,15 +33,11 @@ async def search( Returns: SearchResponse: The search response. """ - if isinstance(vector_search_settings, dict): - vector_search_settings = VectorSearchSettings( - **vector_search_settings - ) - if isinstance(kg_search_settings, dict): - kg_search_settings = KGSearchSettings(**kg_search_settings) - if not isinstance(vector_search_settings, dict): + if vector_search_settings and not isinstance( + vector_search_settings, dict + ): vector_search_settings = vector_search_settings.model_dump() - if not isinstance(kg_search_settings, dict): + if kg_search_settings and not isinstance(kg_search_settings, dict): kg_search_settings = kg_search_settings.model_dump() data = { @@ -55,7 +51,7 @@ async def search( async def rag( client, query: str, - rag_generation_config: Union[dict, GenerationConfig], + rag_generation_config: Optional[Union[dict, GenerationConfig]] = None, vector_search_settings: Optional[ Union[dict, VectorSearchSettings] ] = None, @@ -68,18 +64,22 @@ async def rag( Args: query (str): The query to search for. - rag_generation_config (Union[dict, GenerationConfig]): RAG generation configuration. + rag_generation_config (Optional[Union[dict, GenerationConfig]]): RAG generation configuration. vector_search_settings (Optional[Union[dict, VectorSearchSettings]]): Vector search settings. kg_search_settings (Optional[Union[dict, KGSearchSettings]]): KG search settings. Returns: Union[RAGResponse, AsyncGenerator[RAGResponse, None]]: The RAG response """ - if not isinstance(rag_generation_config, dict): + if rag_generation_config and not isinstance( + rag_generation_config, dict + ): rag_generation_config = rag_generation_config.model_dump() - if not isinstance(vector_search_settings, dict): + if vector_search_settings and not isinstance( + vector_search_settings, dict + ): vector_search_settings = vector_search_settings.model_dump() - if not isinstance(kg_search_settings, dict): + if kg_search_settings and not isinstance(kg_search_settings, dict): kg_search_settings = kg_search_settings.model_dump() data = { @@ -89,7 +89,9 @@ async def rag( "kg_search_settings": kg_search_settings, } - if rag_generation_config.get("stream", False): + if rag_generation_config and rag_generation_config.get( + "stream", False + ): return client._make_streaming_request("POST", "rag", json=data) else: return await client._make_request("POST", "rag", json=data) @@ -98,7 +100,7 @@ async def rag( async def agent( client, messages: list[Union[dict, Message]], - rag_generation_config: Union[dict, GenerationConfig], + rag_generation_config: Optional[Union[dict, GenerationConfig]], vector_search_settings: Optional[ Union[dict, VectorSearchSettings] ] = None, @@ -113,7 +115,7 @@ async def agent( Args: messages (List[Union[dict, Message]]): The messages to send to the agent. - rag_generation_config (Union[dict, GenerationConfig]): RAG generation configuration. + rag_generation_config (Optional[Union[dict, GenerationConfig]]): RAG generation configuration. vector_search_settings (Optional[Union[dict, VectorSearchSettings]]): Vector search settings. kg_search_settings (Optional[Union[dict, KGSearchSettings]]): KG search settings. task_prompt_override (Optional[str]): Task prompt override. @@ -122,11 +124,15 @@ async def agent( Returns: Union[List[Message], AsyncGenerator[Message, None]]: The agent response. """ - if not isinstance(rag_generation_config, dict): + if rag_generation_config and not isinstance( + rag_generation_config, dict + ): rag_generation_config = rag_generation_config.model_dump() - if not isinstance(vector_search_settings, dict): + if vector_search_settings and not isinstance( + vector_search_settings, dict + ): vector_search_settings = vector_search_settings.model_dump() - if not isinstance(kg_search_settings, dict): + if kg_search_settings and not isinstance(kg_search_settings, dict): kg_search_settings = kg_search_settings.model_dump() messages = [ @@ -143,7 +149,9 @@ async def agent( "include_title_if_available": include_title_if_available, } - if rag_generation_config.get("stream", False): + if rag_generation_config and rag_generation_config.get( + "stream", False + ): return client._make_streaming_request("POST", "agent", json=data) else: return await client._make_request("POST", "agent", json=data) diff --git a/tests/__init__.py b/py/tests/__init__.py similarity index 100% rename from tests/__init__.py rename to py/tests/__init__.py diff --git a/tests/docker_tests/dockerTest.bash b/py/tests/docker_tests/dockerTest.bash similarity index 100% rename from tests/docker_tests/dockerTest.bash rename to py/tests/docker_tests/dockerTest.bash diff --git a/tests/regression/expected_outputs/test_document_management.json b/py/tests/regression/expected_outputs/test_document_management.json similarity index 100% rename from tests/regression/expected_outputs/test_document_management.json rename to py/tests/regression/expected_outputs/test_document_management.json diff --git a/tests/regression/expected_outputs/test_group_management.json b/py/tests/regression/expected_outputs/test_group_management.json similarity index 100% rename from tests/regression/expected_outputs/test_group_management.json rename to py/tests/regression/expected_outputs/test_group_management.json diff --git a/tests/regression/expected_outputs/test_observability.json b/py/tests/regression/expected_outputs/test_observability.json similarity index 100% rename from tests/regression/expected_outputs/test_observability.json rename to py/tests/regression/expected_outputs/test_observability.json diff --git a/tests/regression/expected_outputs/test_retrieval.json b/py/tests/regression/expected_outputs/test_retrieval.json similarity index 100% rename from tests/regression/expected_outputs/test_retrieval.json rename to py/tests/regression/expected_outputs/test_retrieval.json diff --git a/tests/regression/expected_outputs/test_user_management.json b/py/tests/regression/expected_outputs/test_user_management.json similarity index 100% rename from tests/regression/expected_outputs/test_user_management.json rename to py/tests/regression/expected_outputs/test_user_management.json diff --git a/tests/regression/runner.py b/py/tests/regression/runner.py similarity index 86% rename from tests/regression/runner.py rename to py/tests/regression/runner.py index 52d19942b..c62784ae2 100644 --- a/tests/regression/runner.py +++ b/py/tests/regression/runner.py @@ -6,7 +6,7 @@ from colorama import Fore, Style, init # TODO: need to import this from the package, not from the local directory -from sdk.client import R2RClient +from r2r import R2RClient from test_cases.base import BaseTest, RegressionTest @@ -32,7 +32,11 @@ def __init__( if not check_only: self.outputs_dir = os.path.join( os.path.dirname(__file__), - ("expected_outputs" if self.update_expected else "observed_outputs"), + ( + "expected_outputs" + if self.update_expected + else "observed_outputs" + ), ) os.makedirs(self.outputs_dir, exist_ok=True) @@ -67,12 +71,20 @@ def compare_all(self) -> bool: observed_outputs_dir = os.path.join( os.path.dirname(__file__), "observed_outputs" ) - print(f"\n{Fore.CYAN}Comparing results for test suites:{Style.RESET_ALL}") + print( + f"\n{Fore.CYAN}Comparing results for test suites:{Style.RESET_ALL}" + ) for test in self.tests: - if test.compare_outputs(observed_outputs_dir, expected_outputs_dir): - print(f"{Fore.GREEN}{test.__class__.__name__} ✓{Style.RESET_ALL}") + if test.compare_outputs( + observed_outputs_dir, expected_outputs_dir + ): + print( + f"{Fore.GREEN}{test.__class__.__name__} ✓{Style.RESET_ALL}" + ) else: - print(f"{Fore.RED}{test.__class__.__name__} ✗{Style.RESET_ALL}") + print( + f"{Fore.RED}{test.__class__.__name__} ✗{Style.RESET_ALL}" + ) all_passed = False return all_passed diff --git a/tests/regression/test_cases/base.py b/py/tests/regression/test_cases/base.py similarity index 89% rename from tests/regression/test_cases/base.py rename to py/tests/regression/test_cases/base.py index f2241416d..48120f59a 100644 --- a/tests/regression/test_cases/base.py +++ b/py/tests/regression/test_cases/base.py @@ -3,11 +3,11 @@ import re from typing import Any, Callable, Dict, Optional -from colorama import Fore, Style +from colorama import Fore, Style, init from deepdiff import DeepDiff # TODO: need to import this from the package, not from the local directory -from sdk.client import R2RClient +from r2r import R2RClient def _to_snake_case(name: str) -> str: @@ -47,7 +47,9 @@ def _save_expected_output(self, output: Dict[str, Any]): with open(self.expected_output_file, "w") as f: json.dump(output, f, indent=2) - def _compare_output(self, actual: Dict[str, Any], expected: Dict[str, Any]) -> bool: + def _compare_output( + self, actual: Dict[str, Any], expected: Dict[str, Any] + ) -> bool: diff = self._custom_diff(expected, actual) if diff: print(f"\nTest {self.name} failed. Differences found:") @@ -65,7 +67,9 @@ def _custom_diff( if "completion" in expected_results and "completion" in actual_results: # Custom comparison for content field - expected_completion = self._get_completion_content(expected_results) + expected_completion = self._get_completion_content( + expected_results + ) actual_completion = self._get_completion_content(actual_results) if ( expected_completion @@ -88,7 +92,9 @@ def _custom_diff( exclude_paths=self.exclude_paths, ) if deep_diff: - diff["other_differences"] = self._serialize_deep_diff(deep_diff) + diff["other_differences"] = self._serialize_deep_diff( + deep_diff + ) # Print the specific fields that are different for change_type, changes in deep_diff.items(): if change_type == "values_changed": @@ -98,9 +104,13 @@ def _custom_diff( print(f" Actual: {change['new_value']}") except Exception as e: - diff["deepdiff_error"] = f"Error in DeepDiff comparison: {str(e)}" + diff["deepdiff_error"] = ( + f"Error in DeepDiff comparison: {str(e)}" + ) return diff - elif "completion" in expected_results or "completion" in actual_results: + elif ( + "completion" in expected_results or "completion" in actual_results + ): diff["content_mismatch"] = { "expected_results": expected_results, "actual_results": actual_results, @@ -115,7 +125,9 @@ def _custom_diff( ) if deep_diff: - diff["other_differences"] = self._serialize_deep_diff(deep_diff) + diff["other_differences"] = self._serialize_deep_diff( + deep_diff + ) # Print the specific fields that are different for change_type, changes in deep_diff.items(): if change_type == "values_changed": @@ -158,7 +170,9 @@ def _fuzzy_content_match( expected_words = set(re.findall(r"\w+", expected.lower())) actual_words = set(re.findall(r"\w+", actual.lower())) common_words = expected_words.intersection(actual_words) - similarity = len(common_words) / max(len(expected_words), len(actual_words)) + similarity = len(common_words) / max( + len(expected_words), len(actual_words) + ) return similarity >= threshold @@ -219,9 +233,13 @@ def compare_outputs( observed_outputs.get(snake_case_name, {}), expected_outputs.get(snake_case_name, {}), ): - print(f"{Fore.GREEN} Test {snake_case_name} passed ✓{Style.RESET_ALL}") + print( + f"{Fore.GREEN} Test {snake_case_name} passed ✓{Style.RESET_ALL}" + ) else: - print(f"{Fore.RED} Test {snake_case_name} failed ✗{Style.RESET_ALL}") + print( + f"{Fore.RED} Test {snake_case_name} failed ✗{Style.RESET_ALL}" + ) all_passed = False return all_passed @@ -247,7 +265,9 @@ def set_exclude_paths(self, test_name: str, exclude_paths: list[str] = []): self.exclude_paths_map[_to_snake_case(test_name)] = exclude_paths def get_test_cases(self) -> Dict[str, callable]: - raise NotImplementedError("Subclasses must implement get_test_cases method") + raise NotImplementedError( + "Subclasses must implement get_test_cases method" + ) def _load_expected_outputs(self) -> Dict[str, Any]: with open(self.expected_outputs_file, "r") as f: diff --git a/tests/regression/test_cases/test_document_management.py b/py/tests/regression/test_cases/test_document_management.py similarity index 100% rename from tests/regression/test_cases/test_document_management.py rename to py/tests/regression/test_cases/test_document_management.py diff --git a/tests/regression/test_cases/test_group_management.py b/py/tests/regression/test_cases/test_group_management.py similarity index 100% rename from tests/regression/test_cases/test_group_management.py rename to py/tests/regression/test_cases/test_group_management.py diff --git a/tests/regression/test_cases/test_observability.py b/py/tests/regression/test_cases/test_observability.py similarity index 100% rename from tests/regression/test_cases/test_observability.py rename to py/tests/regression/test_cases/test_observability.py diff --git a/tests/regression/test_cases/test_retrieval.py b/py/tests/regression/test_cases/test_retrieval.py similarity index 100% rename from tests/regression/test_cases/test_retrieval.py rename to py/tests/regression/test_cases/test_retrieval.py diff --git a/tests/regression/test_cases/test_user_management.py b/py/tests/regression/test_cases/test_user_management.py similarity index 100% rename from tests/regression/test_cases/test_user_management.py rename to py/tests/regression/test_cases/test_user_management.py diff --git a/tests/regression/test_data/admin_document_group1.txt b/py/tests/regression/test_data/admin_document_group1.txt similarity index 100% rename from tests/regression/test_data/admin_document_group1.txt rename to py/tests/regression/test_data/admin_document_group1.txt diff --git a/tests/regression/test_data/admin_document_user1.txt b/py/tests/regression/test_data/admin_document_user1.txt similarity index 100% rename from tests/regression/test_data/admin_document_user1.txt rename to py/tests/regression/test_data/admin_document_user1.txt diff --git a/tests/regression/test_data/test_document.txt b/py/tests/regression/test_data/test_document.txt similarity index 100% rename from tests/regression/test_data/test_document.txt rename to py/tests/regression/test_data/test_document.txt diff --git a/tests/regression/test_data/user1_document.txt b/py/tests/regression/test_data/user1_document.txt similarity index 100% rename from tests/regression/test_data/user1_document.txt rename to py/tests/regression/test_data/user1_document.txt diff --git a/tests/regression/test_data/user1_document_group.txt b/py/tests/regression/test_data/user1_document_group.txt similarity index 100% rename from tests/regression/test_data/user1_document_group.txt rename to py/tests/regression/test_data/user1_document_group.txt diff --git a/tests/regression/test_data/user2_document.txt b/py/tests/regression/test_data/user2_document.txt similarity index 100% rename from tests/regression/test_data/user2_document.txt rename to py/tests/regression/test_data/user2_document.txt diff --git a/tests/test_abstractions.py b/py/tests/test_abstractions.py similarity index 100% rename from tests/test_abstractions.py rename to py/tests/test_abstractions.py diff --git a/tests/test_auth.py b/py/tests/test_auth.py similarity index 100% rename from tests/test_auth.py rename to py/tests/test_auth.py diff --git a/tests/test_cli.py b/py/tests/test_cli.py similarity index 93% rename from tests/test_cli.py rename to py/tests/test_cli.py index 2c63a1193..724403b66 100644 --- a/tests/test_cli.py +++ b/py/tests/test_cli.py @@ -2,9 +2,9 @@ import click import pytest +from click.testing import CliRunner from cli.cli import cli from cli.utils.param_types import JSON -from click.testing import CliRunner @pytest.fixture @@ -14,9 +14,9 @@ def runner(): @pytest.fixture def mock_r2r_execution_wrapper(): - with patch("r2r.cli.command_group.R2RExecutionWrapper") as mock: - yield mock - + # with patch("cli.command_group.R2RExecutionWrapper") as mock: + # yield mock + pass def test_cli_group(runner): result = runner.invoke(cli, ["--help"]) @@ -28,7 +28,10 @@ def test_generate_private_key(runner): result = runner.invoke(cli, ["generate-private-key"]) assert result.exit_code == 0 assert "Generated Private Key:" in result.output - assert "Keep this key secure and use it as your R2R_SECRET_KEY." in result.output + assert ( + "Keep this key secure and use it as your R2R_SECRET_KEY." + in result.output + ) def test_delete_command(runner, mock_r2r_execution_wrapper): @@ -38,7 +41,9 @@ def test_delete_command(runner, mock_r2r_execution_wrapper): result = runner.invoke(cli, ["delete", "--filter", "key1:eq:value1"]) assert result.exit_code == 0 assert "Deleted successfully" in result.output - mock_instance.delete.assert_called_once_with(filters={"key1": {"$eq": "value1"}}) + mock_instance.delete.assert_called_once_with( + filters={"key1": {"$eq": "value1"}} + ) def test_multiple_deletes(runner, mock_r2r_execution_wrapper): @@ -119,11 +124,15 @@ def test_ingest_sample_file(runner, mock_r2r_execution_wrapper): mock_instance = mock_r2r_execution_wrapper.return_value mock_instance.ingest_sample_file.return_value = "Sample file ingested" - result = runner.invoke(cli, ["ingest-sample-file", "--no-media", "--option", "1"]) + result = runner.invoke( + cli, ["ingest-sample-file", "--no-media", "--option", "1"] + ) print(f"Output: {result.output}") assert result.exit_code == 0 assert "Sample file ingested" in result.output - mock_instance.ingest_sample_file.assert_called_once_with(no_media=True, option=1) + mock_instance.ingest_sample_file.assert_called_once_with( + no_media=True, option=1 + ) def test_update_files(runner, mock_r2r_execution_wrapper): @@ -234,10 +243,10 @@ def test_json_param_type(): def test_docker_down_command(runner): with ( patch( - "r2r.cli.commands.server_operations.bring_down_docker_compose" + "cli.commands.server_operations.bring_down_docker_compose" ) as mock_bring_down, patch( - "r2r.cli.commands.server_operations.remove_r2r_network" + "cli.commands.server_operations.remove_r2r_network" ) as mock_remove_network, ): @@ -245,7 +254,8 @@ def test_docker_down_command(runner): result = runner.invoke(cli, ["docker-down"]) assert result.exit_code == 0 assert ( - "Docker Compose setup has been successfully brought down." in result.output + "Docker Compose setup has been successfully brought down." + in result.output ) mock_bring_down.assert_called_once() mock_remove_network.assert_called_once() diff --git a/py/tests/test_client.py b/py/tests/test_client.py new file mode 100644 index 000000000..ff983cc9a --- /dev/null +++ b/py/tests/test_client.py @@ -0,0 +1,377 @@ +import uuid +from datetime import datetime +from unittest.mock import MagicMock + +import pytest +from core import ( + DocumentInfo, + R2RApp, + R2RBuilder, + R2REngine, + R2RException, + Token, + UserResponse, +) +from fastapi import Body, Depends +from fastapi.security import OAuth2PasswordBearer +from fastapi.testclient import TestClient + +# TODO: need to import this from the package, not from the local directory +from r2r import R2RClient + +oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") + + +def create_user(email: str, password: str): + return UserResponse( + id=uuid.UUID("12345678-1234-5678-1234-567812345678"), + email=email, + hashed_password="hashed_" + password, + is_active=True, + is_superuser=False, + is_verified=False, + name="Test User", + bio="Test Bio", + profile_picture="http://example.com/pic.jpg", + created_at=datetime.utcnow(), + updated_at=datetime.utcnow(), + ) + + +@pytest.fixture(scope="function") +def mock_auth_wrapper(): + def auth_wrapper(token: str = Depends(oauth2_scheme)): + return UserResponse( + id=uuid.UUID("12345678-1234-5678-1234-567812345678"), + email="test@example.com", + is_active=True, + hashed_password="xxx", + is_superuser=False, + ) + + return auth_wrapper + + +@pytest.fixture(scope="function") +def mock_auth_wrapper(): + def auth_wrapper(token: str = Depends(oauth2_scheme)): + return UserResponse( + id=uuid.UUID("12345678-1234-5678-1234-567812345678"), + email="test@example.com", + is_active=True, + hashed_password="xxx", + is_superuser=True, + ) + + return auth_wrapper + + +@pytest.fixture(scope="function") +def mock_super_auth_wrapper(): + def auth_wrapper(token: str = Depends(oauth2_scheme)): + return UserResponse( + id=uuid.UUID("12345678-1234-5678-1234-567812345678"), + email="test@example.com", + is_active=True, + hashed_password="xxx", + is_superuser=True, + ) + + return auth_wrapper + + +@pytest.fixture(scope="function") +def mock_db(): + db = MagicMock() + db.relational.get_user_by_email.return_value = ( + None # Simulate empty database + ) + + db.relational.create_user.side_effect = create_user + db.relational.get_user_by_id.return_value = create_user( + email="test@example.com", password="password" + ) + + def update_user(user): + updated_user = create_user(email=user.email, password="password") + updated_user.name = user.name + updated_user.bio = user.bio + updated_user.profile_picture = user.profile_picture + return updated_user + + db.relational.update_user.side_effect = update_user + db.relational.get_documents_in_group.return_value = [ + DocumentInfo( + user_id=uuid.uuid4(), + id=uuid.uuid4(), + title=f"Document {i}", + type="txt", + group_ids=[uuid.uuid4()], + created_at=datetime.utcnow(), + updated_at=datetime.utcnow(), + version="1", + metadata={}, + size_in_bytes=1000, + ) + for i in range(100) + ] + + return db + + +async def mock_asearch(*args, **kwargs): + return { + "vector_search_results": [ + { + "fragment_id": "c68dc72e-fc23-5452-8f49-d7bd46088a96", + "extraction_id": "3f3d47f3-8baf-58eb-8bc2-0171fb1c6e09", + "document_id": "3e157b3a-8469-51db-90d9-52e7d896b49b", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "score": 0.23943702876567796, + "text": "Alternate Base Rate means, for any day, a rate per annum equal to the greatest of (i) the Prime Rate in effect on such day, (ii) the Federal Funds Effective Rate in effect on such day \nplus \u00bd of 1% and (iii) the sum of (a) the Adjusted LIBO Rate that would be payable onsuch day for a Eurodollar Borrowing with a one-month interest period", + "metadata": { + "title": "uber_2021.pdf", + "associatedQuery": "What is the capital of France?", + }, + }, + { + "fragment_id": "f0b40c99-e200-507b-a4b9-e931e0b5f321", + "extraction_id": "0348ae71-bccb-58d1-8b5f-36810e46245a", + "document_id": "3e157b3a-8469-51db-90d9-52e7d896b49b", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "score": 0.22033508121967305, + "text": "s, could also restrict our future access to the capital markets.ITEM 1B. UNRESOLVED STAFF\n COMMENTSNot applicable.\nITEM 2. PROPERTIES\nAs\n of December 31, 2021, we leased and owned office facilities around the world totaling 10.6 million square feet, including 2.6 million square feet for ourcorporate headquarte\nrs in the San Francisco Bay Area, California.We", + "metadata": { + "title": "uber_2021.pdf", + "associatedQuery": "What is the capital of France?", + }, + }, + { + "fragment_id": "967c4291-0629-55b6-9323-e2291de8730d", + "extraction_id": "7595cdf2-d1b0-5f13-b853-8ce6857ca5f5", + "document_id": "3e157b3a-8469-51db-90d9-52e7d896b49b", + "user_id": "2acb499e-8428-543b-bd85-0d9098718220", + "group_ids": [], + "score": 0.21763332188129403, + "text": "RFR means, for any RFR Loan denominated in (a) British Pounds, SONIA and (b) Swiss Francs, SARON. \nRFR Borrowing means, as to any Borrowing, the RFR Loans comprising such Borrowing. \nRFR Business Day means, for any Loan denominated in (a) British Pounds, any day except for (i) a Saturday, (ii) a Sunday or (iii) a day on which banks are closed for general business in London and (b) Swiss Francs, any day except for (i) a Saturday, (ii) a Sunday or", + "metadata": { + "title": "uber_2021.pdf", + "associatedQuery": "What is the capital of France?", + }, + }, + ] + } + + +@pytest.fixture(scope="function") +def app_client(mock_db, mock_auth_wrapper): + config = R2RBuilder._get_config("auth") + providers = MagicMock() + providers.auth.login.return_value = { + "access_token": Token(token="access_token", token_type="access"), + "refresh_token": Token(token="refresh_token", token_type="refresh"), + } + providers.auth.auth_wrapper = mock_auth_wrapper + providers.auth.register.side_effect = mock_db.relational.create_user + providers.auth.verify_email.return_value = { + "message": "Email verified successfully" + } + providers.auth.change_password.return_value = { + "message": "Password changed successfully" + } + providers.auth.request_password_reset.return_value = { + "message": "If the email exists, a reset link has been sent" + } + providers.auth.confirm_password_reset.return_value = { + "message": "Password reset successfully" + } + providers.auth.logout.return_value = {"message": "Logged out successfully"} + + providers.database = mock_db + pipelines = MagicMock() + agents = MagicMock() + engine = R2REngine( + config=config, + providers=providers, + pipelines=pipelines, + agents=agents, + ) + engine.asearch = mock_asearch + app = R2RApp(engine) + return TestClient(app.app) + + +@pytest.fixture(scope="function") +def r2r_client(app_client): + return R2RClient(base_url="http://testserver", custom_client=app_client) + + +def test_health_check(r2r_client): + response = r2r_client.health() + assert response["results"] == {"response": "ok"} + + +def test_register_user(r2r_client, mock_db): + user_data = {"email": "test@example.com", "password": "testpassword"} + response = r2r_client.register(**user_data) + assert "results" in response + assert response["results"]["email"] == user_data["email"] + assert "id" in response["results"] + assert "hashed_password" in response["results"] + mock_db.relational.create_user.assert_called_once() + + +def test_login_user(r2r_client, mock_db): + user_data = {"email": "login_test@example.com", "password": "testpassword"} + mock_db.relational.get_user_by_email.return_value = None + response = r2r_client.register(**user_data) + + mock_db.relational.get_user_by_email.return_value = UserResponse( + id=uuid.UUID("12345678-1234-5678-1234-567812345678"), + email=user_data["email"], + hashed_password="hashed_" + user_data["password"], + is_active=True, + is_superuser=False, + verification_code_expiry=None, + ) + response = r2r_client.login(**user_data) + assert "results" in response + assert "access_token" in response["results"] + assert "refresh_token" in response["results"] + + +def test_authenticated_search(r2r_client, mock_db): + # Register and login + user_data = { + "email": "search_test@example.com", + "password": "testpassword", + } + r2r_client.register(**user_data) + login_response = r2r_client.login(**user_data) + + # Perform search + search_query = "test query" + search_response = r2r_client.search(search_query) + results = search_response["results"] + assert "vector_search_results" in results + assert len(results["vector_search_results"]) > 0 + assert ( + results["vector_search_results"][0]["fragment_id"] + == "c68dc72e-fc23-5452-8f49-d7bd46088a96" + ) + assert ( + results["vector_search_results"][0]["text"] + == "Alternate Base Rate means, for any day, a rate per annum equal to the greatest of (i) the Prime Rate in effect on such day, (ii) the Federal Funds Effective Rate in effect on such day \nplus \u00bd of 1% and (iii) the sum of (a) the Adjusted LIBO Rate that would be payable onsuch day for a Eurodollar Borrowing with a one-month interest period" + ) + assert results["vector_search_results"][0]["score"] == 0.23943702876567796 + + +@pytest.mark.asyncio +async def test_change_password(r2r_client, mock_db): + # Register and login + user_data = { + "email": "change_pass@example.com", + "password": "old_password", + } + r2r_client.register(**user_data) + r2r_client.login(**user_data) + + # Change password + response = r2r_client.change_password("old_password", "new_password") + print("response = ", response) + assert response["results"]["message"] == "Password changed successfully" + + # Try logging in with new password + login_response = r2r_client.login( + email="change_pass@example.com", password="new_password" + ) + assert "access_token" in login_response["results"] + + +@pytest.mark.asyncio +async def test_password_reset_flow(r2r_client, mock_db): + # Register a user + user_data = {"email": "reset_pass@example.com", "password": "old_password"} + r2r_client.register(**user_data) + + # Request password reset + reset_response = r2r_client.request_password_reset( + "reset_pass@example.com" + ) + print("reset_response = ", reset_response) + assert "message" in reset_response["results"] + + # Confirm password reset (we'll need to mock the reset token) + mock_reset_token = "mock_reset_token" + confirm_response = r2r_client.confirm_password_reset( + mock_reset_token, "new_password" + ) + assert ( + confirm_response["results"]["message"] == "Password reset successfully" + ) + + # Try logging in with new password + login_response = r2r_client.login( + email="reset_pass@example.com", password="new_password" + ) + assert "access_token" in login_response["results"] + + +@pytest.mark.asyncio +async def test_logout(r2r_client, mock_db): + # Register and login + user_data = {"email": "logout@example.com", "password": "password123"} + r2r_client.register(**user_data) + r2r_client.login(**user_data) + + # Logout + logout_response = r2r_client.logout() + assert logout_response["results"]["message"] == "Logged out successfully" + + # Ensure client's tokens are cleared + assert r2r_client.access_token is None + assert r2r_client._refresh_token is None + + +@pytest.mark.asyncio +async def test_user_profile(r2r_client, mock_db): + # Register and login + user_data = {"email": "profile@example.com", "password": "password123"} + r2r_client.register(**user_data) + r2r_client.login(**user_data) + + # Get user profile + # mock_db.relational.get_user_by_id.return_value = create_user( + # UserCreate(email="profile@example.com", password="password") + # ) + # profile = r2r_client.user() + + # assert profile["results"]["email"] == "profile@example.com" + + # Update user profile + updated_profile = r2r_client.update_user(name="John Doe", bio="Test bio") + assert updated_profile["results"]["name"] == "John Doe" + assert updated_profile["results"]["bio"] == "Test bio" + + +@pytest.mark.asyncio +async def test_get_documents_in_group(r2r_client, mock_db): + # Register and login as a superuser + user_data = {"email": "superuser@example.com", "password": "password123"} + r2r_client.register(**user_data) + + # Set the mock user as a superuser + # mock_db.relational.get_user_by_email.return_value.is_superuser = True + + r2r_client.login(**user_data) + + # Get documents in group + group_id = uuid.uuid4() + response = r2r_client.get_documents_in_group(group_id) + + assert "results" in response + assert len(response["results"]) == 100 # Default limit + assert response["results"][0]["title"] == "Document 0" + assert response["results"][0]["type"] == "txt" diff --git a/tests/test_config.py b/py/tests/test_config.py similarity index 100% rename from tests/test_config.py rename to py/tests/test_config.py diff --git a/tests/test_database.py b/py/tests/test_database.py similarity index 82% rename from tests/test_database.py rename to py/tests/test_database.py index 8999c52b0..81681b1ba 100644 --- a/tests/test_database.py +++ b/py/tests/test_database.py @@ -7,6 +7,7 @@ DatabaseProvider, Vector, VectorEntry, + VectorSearchSettings, generate_id_from_label, ) from core.providers import PostgresDBProvider @@ -66,7 +67,10 @@ def test_db_initialization(request, db_fixture): def test_db_copy_and_search(request, db_fixture): db = request.getfixturevalue(db_fixture) db.vector.upsert(sample_entries[0]) - results = db.vector.search(query_vector=sample_entries[0].vector.data) + results = db.vector.semantic_search( + query_vector=sample_entries[0].vector.data, + search_settings=VectorSearchSettings(), + ) assert len(results) == 1 assert results[0].fragment_id == sample_entries[0].fragment_id assert results[0].score == pytest.approx(1.0, rel=1e-3) @@ -76,7 +80,10 @@ def test_db_copy_and_search(request, db_fixture): def test_db_upsert_and_search(request, db_fixture): db = request.getfixturevalue(db_fixture) db.vector.upsert(sample_entries[0]) - results = db.vector.search(query_vector=sample_entries[0].vector.data) + results = db.vector.semantic_search( + query_vector=sample_entries[0].vector.data, + search_settings=VectorSearchSettings(), + ) assert len(results) == 1 assert results[0].fragment_id == sample_entries[0].fragment_id assert results[0].score == pytest.approx(1.0, rel=1e-3) @@ -87,7 +94,9 @@ def test_imperfect_match(request, db_fixture): db = request.getfixturevalue(db_fixture) db.vector.upsert(sample_entries[0]) query_vector = [val + 0.1 for val in sample_entries[0].vector.data] - results = db.vector.search(query_vector=query_vector) + results = db.vector.semantic_search( + query_vector=query_vector, search_settings=VectorSearchSettings() + ) assert len(results) == 1 assert results[0].fragment_id == sample_entries[0].fragment_id assert results[0].score < 1.0 @@ -100,7 +109,10 @@ def test_bulk_insert_and_search(request, db_fixture): db.vector.upsert(entry) query_vector = sample_entries[0].vector.data - results = db.vector.search(query_vector=query_vector, limit=5) + results = db.vector.semantic_search( + query_vector=query_vector, + search_settings=VectorSearchSettings(search_limit=5), + ) assert len(results) == 5 assert results[0].fragment_id == sample_entries[0].fragment_id assert results[0].score == pytest.approx(1.0, rel=1e-3) @@ -114,8 +126,9 @@ def test_search_with_filters(request, db_fixture): filtered_id = sample_entries[0].metadata["key"] query_vector = sample_entries[0].vector.data - results = db.vector.search( - query_vector=query_vector, filters={"key": filtered_id} + results = db.vector.semantic_search( + query_vector=query_vector, + search_settings=VectorSearchSettings(filters={"key": filtered_id}), ) assert len(results) == 1 assert results[0].fragment_id == sample_entries[0].fragment_id @@ -131,7 +144,10 @@ def test_delete(request, db_fixture): key_to_delete = sample_entries[0].metadata["key"] db.vector.delete(filters={"key": {"$eq": key_to_delete}}) - results = db.vector.search(query_vector=sample_entries[0].vector.data) + results = db.vector.semantic_search( + query_vector=sample_entries[0].vector.data, + search_settings=VectorSearchSettings(), + ) assert all(result.metadata["key"] != key_to_delete for result in results) @@ -151,7 +167,9 @@ def test_upsert(request, db_fixture): ) db.vector.upsert(modified_entry) - results = db.vector.search(query_vector=[0.5, 0.5, 0.5]) + results = db.vector.semantic_search( + query_vector=[0.5, 0.5, 0.5], search_settings=VectorSearchSettings() + ) assert len(results) == 1 assert results[0].fragment_id == sample_entries[0].fragment_id assert results[0].metadata["key"] == "new_value" diff --git a/tests/test_embedding.py b/py/tests/test_embedding.py similarity index 100% rename from tests/test_embedding.py rename to py/tests/test_embedding.py diff --git a/tests/test_end_to_end.py b/py/tests/test_end_to_end.py similarity index 100% rename from tests/test_end_to_end.py rename to py/tests/test_end_to_end.py diff --git a/tests/test_groups.py b/py/tests/test_groups.py similarity index 100% rename from tests/test_groups.py rename to py/tests/test_groups.py diff --git a/tests/test_groups_client.py b/py/tests/test_groups_client.py similarity index 99% rename from tests/test_groups_client.py rename to py/tests/test_groups_client.py index de1a81fa4..dfc691af5 100644 --- a/tests/test_groups_client.py +++ b/py/tests/test_groups_client.py @@ -3,11 +3,12 @@ from unittest.mock import MagicMock import pytest -from core import R2RApp, R2RBuilder, R2RClient, R2REngine, Token, UserResponse +from core import R2RApp, R2RBuilder, R2REngine, Token, UserResponse from core.base import GroupResponse from fastapi import Depends from fastapi.security import OAuth2PasswordBearer from fastapi.testclient import TestClient +from r2r import R2RClient oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") diff --git a/tests/test_ingestion_service.py b/py/tests/test_ingestion_service.py similarity index 100% rename from tests/test_ingestion_service.py rename to py/tests/test_ingestion_service.py diff --git a/tests/test_kg.py b/py/tests/test_kg.py similarity index 99% rename from tests/test_kg.py rename to py/tests/test_kg.py index 7f8c4885c..f1d93c03c 100644 --- a/tests/test_kg.py +++ b/py/tests/test_kg.py @@ -213,4 +213,4 @@ async def test_cluster_kg(kg_clustering_pipe): assert len(result) == 1 assert result[0]["id"] == "0_0" - assert result[0]["title"] == "_" + assert result[0]["title"] == "_" \ No newline at end of file diff --git a/tests/test_llms.py b/py/tests/test_llms.py similarity index 100% rename from tests/test_llms.py rename to py/tests/test_llms.py diff --git a/tests/test_logging.py b/py/tests/test_logging.py similarity index 100% rename from tests/test_logging.py rename to py/tests/test_logging.py diff --git a/tests/test_parser.py b/py/tests/test_parser.py similarity index 100% rename from tests/test_parser.py rename to py/tests/test_parser.py diff --git a/tests/test_pipeline.py b/py/tests/test_pipeline.py similarity index 100% rename from tests/test_pipeline.py rename to py/tests/test_pipeline.py diff --git a/tests/test_vector_db.py b/py/tests/test_vector_db.py similarity index 70% rename from tests/test_vector_db.py rename to py/tests/test_vector_db.py index d4d1b0459..342940a6e 100644 --- a/tests/test_vector_db.py +++ b/py/tests/test_vector_db.py @@ -2,7 +2,7 @@ from uuid import UUID, uuid4 import pytest -from core.base import DatabaseConfig, Vector, VectorEntry +from core.base import DatabaseConfig, Vector, VectorEntry, VectorSearchSettings from core.providers import PostgresDBProvider @@ -89,10 +89,11 @@ def sample_entries(vector_db): def test_search_equality_filter(vector_db, sample_entries): query_vector = Vector([0.2, 0.3, 0.4]) - results = vector_db.search( + results = vector_db.semantic_search( query_vector.data, - limit=10, - filters={"category": {"$eq": "fruit"}}, + VectorSearchSettings( + search_limit=10, filters={"category": {"$eq": "fruit"}} + ), ) assert len(results) == 3 assert all(r.metadata["category"] == "fruit" for r in results) @@ -100,10 +101,11 @@ def test_search_equality_filter(vector_db, sample_entries): def test_search_not_equal_filter(vector_db, sample_entries): query_vector = Vector([0.2, 0.3, 0.4]) - results = vector_db.search( + results = vector_db.semantic_search( query_vector.data, - limit=10, - filters={"category": {"$ne": "fruit"}}, + VectorSearchSettings( + search_limit=10, filters={"category": {"$ne": "fruit"}} + ), ) assert len(results) == 1 assert results[0].metadata["category"] == "vegetable" @@ -111,10 +113,9 @@ def test_search_not_equal_filter(vector_db, sample_entries): def test_search_greater_than_filter(vector_db, sample_entries): query_vector = Vector([0.2, 0.3, 0.4]) - results = vector_db.search( + results = vector_db.semantic_search( query_vector.data, - limit=10, - filters={"price": {"$gt": 1.0}}, + VectorSearchSettings(search_limit=10, filters={"price": {"$gt": 1.0}}), ) assert len(results) == 1 assert results[0].text == "Durian" @@ -122,10 +123,11 @@ def test_search_greater_than_filter(vector_db, sample_entries): def test_search_less_than_or_equal_filter(vector_db, sample_entries): query_vector = Vector([0.2, 0.3, 0.4]) - results = vector_db.search( + results = vector_db.semantic_search( query_vector.data, - limit=10, - filters={"price": {"$lte": 1.0}}, + VectorSearchSettings( + search_limit=10, filters={"price": {"$lte": 1.0}} + ), ) assert len(results) == 3 assert all(r.metadata["price"] <= 1.0 for r in results) @@ -133,10 +135,11 @@ def test_search_less_than_or_equal_filter(vector_db, sample_entries): def test_search_in_filter(vector_db, sample_entries): query_vector = Vector([0.2, 0.3, 0.4]) - results = vector_db.search( + results = vector_db.semantic_search( query_vector.data, - limit=10, - filters={"color": {"$in": ["red", "yellow"]}}, + VectorSearchSettings( + search_limit=10, filters={"color": {"$in": ["red", "yellow"]}} + ), ) assert len(results) == 2 assert all(r.metadata["color"] in ["red", "yellow"] for r in results) @@ -144,16 +147,18 @@ def test_search_in_filter(vector_db, sample_entries): def test_search_complex_and_filter(vector_db, sample_entries): query_vector = Vector([0.2, 0.3, 0.4]) - results = vector_db.search( + results = vector_db.semantic_search( query_vector.data, - limit=10, - filters={ - "$and": [ - {"category": {"$eq": "fruit"}}, - {"price": {"$lt": 2.0}}, - {"color": {"$ne": "yellow"}}, - ] - }, + VectorSearchSettings( + search_limit=10, + filters={ + "$and": [ + {"category": {"$eq": "fruit"}}, + {"price": {"$lt": 2.0}}, + {"color": {"$ne": "yellow"}}, + ] + }, + ), ) assert len(results) == 1 assert results[0].text == "Apple" @@ -161,15 +166,17 @@ def test_search_complex_and_filter(vector_db, sample_entries): def test_search_complex_or_filter(vector_db, sample_entries): query_vector = Vector([0.2, 0.3, 0.4]) - results = vector_db.search( + results = vector_db.semantic_search( query_vector.data, - limit=10, - filters={ - "$or": [ - {"category": {"$eq": "vegetable"}}, - {"price": {"$gte": 5.0}}, - ] - }, + VectorSearchSettings( + search_limit=10, + filters={ + "$or": [ + {"category": {"$eq": "vegetable"}}, + {"price": {"$gte": 5.0}}, + ] + }, + ), ) assert len(results) == 2 assert any(r.metadata["category"] == "vegetable" for r in results) @@ -178,20 +185,22 @@ def test_search_complex_or_filter(vector_db, sample_entries): def test_search_nested_and_or_filters(vector_db, sample_entries): query_vector = Vector([0.2, 0.3, 0.4]) - results = vector_db.search( + results = vector_db.semantic_search( query_vector.data, - limit=10, - filters={ - "$and": [ - {"category": {"$eq": "fruit"}}, - { - "$or": [ - {"color": {"$in": ["red", "yellow"]}}, - {"price": {"$gt": 2.0}}, - ] - }, - ] - }, + VectorSearchSettings( + search_limit=10, + filters={ + "$and": [ + {"category": {"$eq": "fruit"}}, + { + "$or": [ + {"color": {"$in": ["red", "yellow"]}}, + {"price": {"$gt": 2.0}}, + ] + }, + ] + }, + ), ) assert len(results) == 3 assert all(r.metadata["category"] == "fruit" for r in results) @@ -204,7 +213,9 @@ def test_search_nested_and_or_filters(vector_db, sample_entries): def test_delete_equality(vector_db, sample_entries): deleted_ids = vector_db.delete({"category": {"$eq": "vegetable"}}) assert len(deleted_ids) == 1 - remaining = vector_db.search(Vector([0.2, 0.3, 0.4]).data, limit=10) + remaining = vector_db.semantic_search( + Vector([0.2, 0.3, 0.4]).data, VectorSearchSettings(search_limit=10) + ) assert len(remaining) == 3 assert all(r.metadata["category"] == "fruit" for r in remaining) @@ -212,7 +223,9 @@ def test_delete_equality(vector_db, sample_entries): def test_delete_greater_than(vector_db, sample_entries): deleted_ids = vector_db.delete({"price": {"$gt": 1.0}}) assert len(deleted_ids) == 1 - remaining = vector_db.search(Vector([0.2, 0.3, 0.4]).data, limit=10) + remaining = vector_db.semantic_search( + Vector([0.2, 0.3, 0.4]).data, VectorSearchSettings(search_limit=10) + ) assert len(remaining) == 3 assert all(r.metadata["price"] <= 1.0 for r in remaining) @@ -220,7 +233,9 @@ def test_delete_greater_than(vector_db, sample_entries): def test_delete_in(vector_db, sample_entries): deleted_ids = vector_db.delete({"color": {"$in": ["red", "yellow"]}}) assert len(deleted_ids) == 2 - remaining = vector_db.search(Vector([0.2, 0.3, 0.4]).data, limit=10) + remaining = vector_db.semantic_search( + Vector([0.2, 0.3, 0.4]).data, VectorSearchSettings(search_limit=10) + ) assert len(remaining) == 2 assert all(r.metadata["color"] not in ["red", "yellow"] for r in remaining) @@ -235,7 +250,9 @@ def test_delete_complex_and(vector_db, sample_entries): } ) assert len(deleted_ids) == 1 - remaining = vector_db.search(Vector([0.2, 0.3, 0.4]).data, limit=10) + remaining = vector_db.semantic_search( + Vector([0.2, 0.3, 0.4]).data, VectorSearchSettings(search_limit=10) + ) assert len(remaining) == 3 assert not any( r.metadata["category"] == "fruit" and r.metadata["price"] < 1.0 @@ -253,7 +270,9 @@ def test_delete_complex_or(vector_db, sample_entries): } ) assert len(deleted_ids) == 2 - remaining = vector_db.search(Vector([0.2, 0.3, 0.4]).data, limit=10) + remaining = vector_db.semantic_search( + Vector([0.2, 0.3, 0.4]).data, VectorSearchSettings(search_limit=10) + ) assert len(remaining) == 2 assert all( r.metadata["category"] != "vegetable" and r.metadata["price"] < 5.0 @@ -276,6 +295,8 @@ def test_delete_nested_and_or(vector_db, sample_entries): } ) assert len(deleted_ids) == 3 - remaining = vector_db.search(Vector([0.2, 0.3, 0.4]).data, limit=10) + remaining = vector_db.semantic_search( + Vector([0.2, 0.3, 0.4]).data, VectorSearchSettings(search_limit=10) + ) assert len(remaining) == 1 assert remaining[0].metadata["category"] == "vegetable" From 66e3c1e6abe17712c7ef44ebac4abcb61a98c80d Mon Sep 17 00:00:00 2001 From: emrgnt-cmplxty <68796651+emrgnt-cmplxty@users.noreply.github.com> Date: Tue, 20 Aug 2024 18:13:58 -0700 Subject: [PATCH 26/74] fixup toml (#908) --- py/pyproject.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/py/pyproject.toml b/py/pyproject.toml index f96330fbf..e0900d5ea 100644 --- a/py/pyproject.toml +++ b/py/pyproject.toml @@ -13,6 +13,7 @@ include = ["r2r.toml", "compose.yaml", "compose.neo4j.yaml", "compose.ollama.yam packages = [ { include = "r2r", from = "." }, { include = "core", from = "." }, + { include = "cli", from = "." }, { include = "sdk", from = "." }, ] @@ -87,7 +88,7 @@ pytest-cov = "^5.0.0" colorama = "^0.4.6" [tool.poetry.scripts] -r2r = "core.cli.cli:main" +r2r = "cli.cli:main" [tool.black] line-length = 79 From 2bc77c2606cb19a602d7839aa3ade1306cdb3708 Mon Sep 17 00:00:00 2001 From: emrgnt-cmplxty <68796651+emrgnt-cmplxty@users.noreply.github.com> Date: Tue, 20 Aug 2024 18:44:02 -0700 Subject: [PATCH 27/74] Feature/fix ingestion update (#909) * fixup toml * fix update --- go/cli/rag_operations.go | 8 +++--- go/sdk/pkg/sdk/retrieval.go | 2 +- js/sdk/README.md | 2 +- js/sdk/src/models.tsx | 2 +- py/cli/commands/retrieval.py | 8 +++--- py/core/examples/hello_r2r.py | 30 ++++++++++------------ py/core/main/api/routes/ingestion/base.py | 1 - py/core/main/services/ingestion_service.py | 19 ++++++++------ py/sdk/ingestion.py | 28 +++++++++++++++++--- py/sdk/models.py | 2 +- py/tests/test_cli.py | 1 + py/tests/test_kg.py | 2 +- 12 files changed, 64 insertions(+), 41 deletions(-) diff --git a/go/cli/rag_operations.go b/go/cli/rag_operations.go index dee23cd65..3c81d5721 100644 --- a/go/cli/rag_operations.go +++ b/go/cli/rag_operations.go @@ -48,7 +48,7 @@ var ragCmd = &cobra.Command{ json.Unmarshal([]byte(filtersStr), &filters) } searchLimit, _ := cmd.Flags().GetInt("search-limit") - doHybridSearch, _ := cmd.Flags().GetBool("do-hybrid-search") + doHybridSearch, _ := cmd.Flags().GetBool("use-hybrid-search") useKgSearch, _ := cmd.Flags().GetBool("use-kg-search") kgSearchModel, _ := cmd.Flags().GetString("kg-search-model") stream, _ := cmd.Flags().GetBool("stream") @@ -108,7 +108,7 @@ var searchCmd = &cobra.Command{ json.Unmarshal([]byte(filtersStr), &filters) } searchLimit, _ := cmd.Flags().GetInt("search-limit") - doHybridSearch, _ := cmd.Flags().GetBool("do-hybrid-search") + doHybridSearch, _ := cmd.Flags().GetBool("use-hybrid-search") useKgSearch, _ := cmd.Flags().GetBool("use-kg-search") kgSearchModel, _ := cmd.Flags().GetString("kg-search-model") kgSearchType, _ := cmd.Flags().GetString("kg-search-type") @@ -161,7 +161,7 @@ func init() { ragCmd.Flags().Bool("use-vector-search", true, "Use vector search") ragCmd.Flags().String("filters", "", "Search filters as JSON") ragCmd.Flags().Int("search-limit", 10, "Number of search results to return") - ragCmd.Flags().Bool("do-hybrid-search", false, "Perform hybrid search") + ragCmd.Flags().Bool("use-hybrid-search", false, "Perform hybrid search") ragCmd.Flags().Bool("use-kg-search", false, "Use knowledge graph search") ragCmd.Flags().String("kg-search-model", "", "Model for KG agent") ragCmd.Flags().Bool("stream", false, "Stream the RAG response") @@ -173,7 +173,7 @@ func init() { searchCmd.Flags().Bool("use-vector-search", true, "Use vector search") searchCmd.Flags().String("filters", "", "Search filters as JSON") searchCmd.Flags().Int("search-limit", 10, "Number of search results to return") - searchCmd.Flags().Bool("do-hybrid-search", false, "Perform hybrid search") + searchCmd.Flags().Bool("use-hybrid-search", false, "Perform hybrid search") searchCmd.Flags().Bool("use-kg-search", false, "Use knowledge graph search") searchCmd.Flags().String("kg-search-model", "", "Model for KG agent") searchCmd.Flags().String("kg-search-type", "global", "Local or Global") diff --git a/go/sdk/pkg/sdk/retrieval.go b/go/sdk/pkg/sdk/retrieval.go index 6e90a6533..4e6203730 100644 --- a/go/sdk/pkg/sdk/retrieval.go +++ b/go/sdk/pkg/sdk/retrieval.go @@ -39,7 +39,7 @@ type VectorSearchSettings struct { UseVectorSearch bool `json:"use_vector_search"` Filters map[string]interface{} `json:"filters"` SearchLimit int `json:"search_limit"` - DoHybridSearch bool `json:"do_hybrid_search"` + DoHybridSearch bool `json:"use_hybrid_search"` SelectedGroupIDs []string `json:"selected_group_ids"` } diff --git a/js/sdk/README.md b/js/sdk/README.md index 4cf1966fd..ba9c34d27 100644 --- a/js/sdk/README.md +++ b/js/sdk/README.md @@ -95,7 +95,7 @@ const ragResult = await client.rag({ use_vector_search: true, search_filters: {}, search_limit: 10, - do_hybrid_search: false, + use_hybrid_search: false, use_kg_search: false, kg_generation_config: {}, rag_generation_config: { diff --git a/js/sdk/src/models.tsx b/js/sdk/src/models.tsx index ac800d737..eee1eb834 100644 --- a/js/sdk/src/models.tsx +++ b/js/sdk/src/models.tsx @@ -37,7 +37,7 @@ export interface VectorSearchSettings { use_vector_search?: boolean; filters?: Record; search_limit?: number; - do_hybrid_search?: boolean; + use_hybrid_search?: boolean; } export interface KGSearchSettings { diff --git a/py/cli/commands/retrieval.py b/py/cli/commands/retrieval.py index e2e0d5782..11662c417 100644 --- a/py/cli/commands/retrieval.py +++ b/py/cli/commands/retrieval.py @@ -23,7 +23,7 @@ @click.option( "--search-limit", default=None, help="Number of search results to return" ) -@click.option("--do-hybrid-search", is_flag=True, help="Perform hybrid search") +@click.option("--use-hybrid-search", is_flag=True, help="Perform hybrid search") @click.option( "--selected-group-ids", type=JSON, help="Group IDs to search for as a JSON" ) @@ -64,7 +64,7 @@ def search(client, query, **kwargs): "use_vector_search", "filters", "search_limit", - "do_hybrid_search", + "use_hybrid_search", "selected_group_ids", ] and v is not None @@ -122,7 +122,7 @@ def search(client, query, **kwargs): @click.option( "--search-limit", default=10, help="Number of search results to return" ) -@click.option("--do-hybrid-search", is_flag=True, help="Perform hybrid search") +@click.option("--use-hybrid-search", is_flag=True, help="Perform hybrid search") @click.option( "--selected-group-ids", type=JSON, help="Group IDs to search for as a JSON" ) @@ -169,7 +169,7 @@ def rag(client, query, **kwargs): "use_vector_search", "filters", "search_limit", - "do_hybrid_search", + "use_hybrid_search", "selected_group_ids", ] and v is not None diff --git a/py/core/examples/hello_r2r.py b/py/core/examples/hello_r2r.py index c114d2774..22f3ed402 100644 --- a/py/core/examples/hello_r2r.py +++ b/py/core/examples/hello_r2r.py @@ -1,25 +1,23 @@ -from core import R2R, Document, GenerationConfig +from r2r import R2RClient -app = R2R() # You may pass a custom configuration to `R2R` with config=... +client = R2RClient("http://localhost:8000") -app.ingest_documents( - [ - Document( - type="txt", - data="John is a person that works at Google.", - metadata={}, - ) - ] -) +with open("test.txt", "w") as file: + file.write("John is a person that works at Google.") + +client.ingest_files(file_paths=["test.txt"]) -rag_results = app.rag( - "Who is john", GenerationConfig(model="gpt-3.5-turbo", temperature=0.0) +# Call RAG directly on an R2R object +rag_response = client.rag( + query="Who is john", + rag_generation_config={"model": "gpt-3.5-turbo", "temperature": 0.0}, ) -print(f"Search Results:\n{rag_results.search_results}") -print(f"Completion:\n{rag_results.completion}") +results = rag_response['results'] +print(f"Search Results:\n{results['search_results']}") +print(f"Completion:\n{results['completion']}") # RAG Results: # Search Results: # AggregateSearchResult(vector_search_results=[VectorSearchResult(id=2d71e689-0a0e-5491-a50b-4ecb9494c832, score=0.6848798582029441, metadata={'text': 'John is a person that works at Google.', 'version': 'v0', 'chunk_order': 0, 'document_id': 'ed76b6ee-dd80-5172-9263-919d493b439a', 'extraction_id': '1ba494d7-cb2f-5f0e-9f64-76c31da11381', 'associatedQuery': 'Who is john'})], kg_search_results=None) # Completion: -# ChatCompletion(id='chatcmpl-9g0HnjGjyWDLADe7E2EvLWa35cMkB', choices=[Choice(finish_reason='stop', index=0, logprobs=None, message=ChatCompletionMessage(content='John is a person that works at Google [1].', role='agent', function_call=None, tool_calls=None))], created=1719797903, model='gpt-3.5-turbo-0125', object='chat.completion', service_tier=None, system_fingerprint=None, usage=CompletionUsage(completion_tokens=11, prompt_tokens=145, total_tokens=156)) +# ChatCompletion(id='chatcmpl-9g0HnjGjyWDLADe7E2EvLWa35cMkB', choices=[Choice(finish_reason='stop', index=0, logprobs=None, message=ChatCompletionMessage(content='John is a person that works at Google [1].', role='assistant', function_call=None, tool_calls=None))], created=1719797903, model='gpt-3.5-turbo-0125', object='chat.completion', service_tier=None, system_fingerprint=None, usage=CompletionUsage(completion_tokens=11, prompt_tokens=145, total_tokens=156)) \ No newline at end of file diff --git a/py/core/main/api/routes/ingestion/base.py b/py/core/main/api/routes/ingestion/base.py index 5c973b18f..a7263cbb2 100644 --- a/py/core/main/api/routes/ingestion/base.py +++ b/py/core/main/api/routes/ingestion/base.py @@ -168,7 +168,6 @@ async def update_files_app( chunking_provider = ( R2RProviderFactory.create_chunking_provider(config) ) - print("input metadatas = ", metadatas) return await self.engine.aupdate_files( files=files, diff --git a/py/core/main/services/ingestion_service.py b/py/core/main/services/ingestion_service.py index 5327720f5..1b9201229 100644 --- a/py/core/main/services/ingestion_service.py +++ b/py/core/main/services/ingestion_service.py @@ -104,7 +104,7 @@ async def update_files( self, files: list[UploadFile], user: UserResponse, - document_ids: list[UUID], + document_ids: Optional[list[UUID]], metadatas: Optional[list[dict]] = None, chunking_provider: Optional[ChunkingProvider] = None, *args: Any, @@ -120,12 +120,16 @@ async def update_files( message="Database provider is not available for updating documents.", ) try: - if len(document_ids) != len(files): - raise R2RException( - status_code=400, - message="Number of ids does not match number of files.", - ) - + if document_ids: + if len(document_ids) != len(files): + raise R2RException( + status_code=400, + message="Number of ids does not match number of files.", + ) + else: + document_ids = [generate_user_document_id(file.filename, user.id) for file in files] + print('user_id = ', user.id) + print('document_ids = ', document_ids) # Only superusers can modify arbitrary document ids, which this gate guarantees in conjuction with the check that follows documents_overview = ( ( @@ -171,7 +175,6 @@ async def update_files( document = self._file_to_document( file, user, doc_id, updated_metadata ) - print("document = ", document) documents.append(document) ingestion_results = await self.ingest_documents( diff --git a/py/sdk/ingestion.py b/py/sdk/ingestion.py index 1a7abefde..cea3f56c6 100644 --- a/py/sdk/ingestion.py +++ b/py/sdk/ingestion.py @@ -23,14 +23,31 @@ async def ingest_files( Args: file_paths (List[str]): List of file paths to ingest. - metadatas (Optional[List[dict]]): List of metadata dictionaries for each file. document_ids (Optional[List[str]]): List of document IDs. + metadatas (Optional[List[dict]]): List of metadata dictionaries for each file. versions (Optional[List[str]]): List of version strings for each file. chunking_settings (Optional[Union[dict, ChunkingConfig]]): Custom chunking configuration. Returns: dict: Ingestion results containing processed, failed, and skipped documents. """ + if document_ids is not None and len(file_paths) != len(document_ids): + raise ValueError( + "Number of file paths must match number of document IDs." + ) + if metadatas is not None and len(file_paths) != len(metadatas): + raise ValueError( + "Number of metadatas must match number of document IDs." + ) + if versions is not None and len(file_paths) != len(versions): + raise ValueError( + "Number of versions must match number of document IDs." + ) + if chunking_settings is not None and chunking_settings is not ChunkingConfig: + # check if the provided dict maps to a ChunkingConfig + ChunkingConfig(**chunking_settings) + + all_file_paths = [] for path in file_paths: if os.path.isdir(path): @@ -80,7 +97,7 @@ async def ingest_files( async def update_files( client, file_paths: list[str], - document_ids: Optional[list[str]], + document_ids: Optional[list[str]] = None, metadatas: Optional[list[dict]] = None, chunking_settings: Optional[Union[dict, ChunkingConfig]] = None, ) -> dict: @@ -96,10 +113,15 @@ async def update_files( Returns: dict: Update results containing processed, failed, and skipped documents. """ - if len(file_paths) != len(document_ids): + if document_ids is not None and len(file_paths) != len(document_ids): + raise ValueError( + "Number of file paths must match number of document IDs." + ) + if metadatas is not None and len(file_paths) != len(metadatas): raise ValueError( "Number of file paths must match number of document IDs." ) + with ExitStack() as stack: files = [ diff --git a/py/sdk/models.py b/py/sdk/models.py index d6fbd2598..96cd0a457 100644 --- a/py/sdk/models.py +++ b/py/sdk/models.py @@ -219,7 +219,7 @@ class VectorSearchSettings(BaseModel): ge=1, le=100, ) - do_hybrid_search: bool = Field( + use_hybrid_search: bool = Field( default=False, description="Whether to perform a hybrid search (combining vector and keyword search)", ) diff --git a/py/tests/test_cli.py b/py/tests/test_cli.py index 724403b66..0205effb2 100644 --- a/py/tests/test_cli.py +++ b/py/tests/test_cli.py @@ -18,6 +18,7 @@ def mock_r2r_execution_wrapper(): # yield mock pass + def test_cli_group(runner): result = runner.invoke(cli, ["--help"]) assert result.exit_code == 0 diff --git a/py/tests/test_kg.py b/py/tests/test_kg.py index f1d93c03c..7f8c4885c 100644 --- a/py/tests/test_kg.py +++ b/py/tests/test_kg.py @@ -213,4 +213,4 @@ async def test_cluster_kg(kg_clustering_pipe): assert len(result) == 1 assert result[0]["id"] == "0_0" - assert result[0]["title"] == "_" \ No newline at end of file + assert result[0]["title"] == "_" From d638ca90214b38c76a8963e53da9aba5a8b8d41c Mon Sep 17 00:00:00 2001 From: Nolan Tremelling <34580718+NolanTrem@users.noreply.github.com> Date: Wed, 21 Aug 2024 10:27:26 -0700 Subject: [PATCH 28/74] Fix CLI Tests (#912) Fix CLI tests --- py/cli/commands/retrieval.py | 8 +- py/cli/utils/param_types.py | 2 + py/core/examples/hello_r2r.py | 4 +- py/core/main/services/ingestion_service.py | 9 +- py/sdk/ingestion.py | 7 +- py/tests/cli/__init__.py | 0 py/tests/cli/commands/__init__.py | 0 py/tests/cli/commands/test_auth.py | 32 ++ py/tests/cli/commands/test_ingestion.py | 174 +++++++++++ py/tests/cli/commands/test_management.py | 208 +++++++++++++ py/tests/cli/commands/test_restructure.py | 55 ++++ py/tests/cli/test_cli.py | 48 +++ py/tests/cli/test_command_group.py | 27 ++ py/tests/cli/utils/test_docker_utils.py | 83 ++++++ py/tests/cli/utils/test_param_types.py | 68 +++++ py/tests/cli/utils/test_timer.py | 77 +++++ py/tests/test_cli.py | 330 --------------------- py/tests/test_kg.py | 9 +- 18 files changed, 797 insertions(+), 344 deletions(-) create mode 100644 py/tests/cli/__init__.py create mode 100644 py/tests/cli/commands/__init__.py create mode 100644 py/tests/cli/commands/test_auth.py create mode 100644 py/tests/cli/commands/test_ingestion.py create mode 100644 py/tests/cli/commands/test_management.py create mode 100644 py/tests/cli/commands/test_restructure.py create mode 100644 py/tests/cli/test_cli.py create mode 100644 py/tests/cli/test_command_group.py create mode 100644 py/tests/cli/utils/test_docker_utils.py create mode 100644 py/tests/cli/utils/test_param_types.py create mode 100644 py/tests/cli/utils/test_timer.py delete mode 100644 py/tests/test_cli.py diff --git a/py/cli/commands/retrieval.py b/py/cli/commands/retrieval.py index 11662c417..c1897ff73 100644 --- a/py/cli/commands/retrieval.py +++ b/py/cli/commands/retrieval.py @@ -23,7 +23,9 @@ @click.option( "--search-limit", default=None, help="Number of search results to return" ) -@click.option("--use-hybrid-search", is_flag=True, help="Perform hybrid search") +@click.option( + "--use-hybrid-search", is_flag=True, help="Perform hybrid search" +) @click.option( "--selected-group-ids", type=JSON, help="Group IDs to search for as a JSON" ) @@ -122,7 +124,9 @@ def search(client, query, **kwargs): @click.option( "--search-limit", default=10, help="Number of search results to return" ) -@click.option("--use-hybrid-search", is_flag=True, help="Perform hybrid search") +@click.option( + "--use-hybrid-search", is_flag=True, help="Perform hybrid search" +) @click.option( "--selected-group-ids", type=JSON, help="Group IDs to search for as a JSON" ) diff --git a/py/cli/utils/param_types.py b/py/cli/utils/param_types.py index 3bf626d6d..9a29881ee 100644 --- a/py/cli/utils/param_types.py +++ b/py/cli/utils/param_types.py @@ -8,6 +8,8 @@ class JsonParamType(click.ParamType): name = "json" def convert(self, value, param, ctx) -> Dict[str, Any]: + if value is None: + return None if isinstance(value, dict): return value try: diff --git a/py/core/examples/hello_r2r.py b/py/core/examples/hello_r2r.py index 22f3ed402..260c36e2c 100644 --- a/py/core/examples/hello_r2r.py +++ b/py/core/examples/hello_r2r.py @@ -12,7 +12,7 @@ query="Who is john", rag_generation_config={"model": "gpt-3.5-turbo", "temperature": 0.0}, ) -results = rag_response['results'] +results = rag_response["results"] print(f"Search Results:\n{results['search_results']}") print(f"Completion:\n{results['completion']}") @@ -20,4 +20,4 @@ # Search Results: # AggregateSearchResult(vector_search_results=[VectorSearchResult(id=2d71e689-0a0e-5491-a50b-4ecb9494c832, score=0.6848798582029441, metadata={'text': 'John is a person that works at Google.', 'version': 'v0', 'chunk_order': 0, 'document_id': 'ed76b6ee-dd80-5172-9263-919d493b439a', 'extraction_id': '1ba494d7-cb2f-5f0e-9f64-76c31da11381', 'associatedQuery': 'Who is john'})], kg_search_results=None) # Completion: -# ChatCompletion(id='chatcmpl-9g0HnjGjyWDLADe7E2EvLWa35cMkB', choices=[Choice(finish_reason='stop', index=0, logprobs=None, message=ChatCompletionMessage(content='John is a person that works at Google [1].', role='assistant', function_call=None, tool_calls=None))], created=1719797903, model='gpt-3.5-turbo-0125', object='chat.completion', service_tier=None, system_fingerprint=None, usage=CompletionUsage(completion_tokens=11, prompt_tokens=145, total_tokens=156)) \ No newline at end of file +# ChatCompletion(id='chatcmpl-9g0HnjGjyWDLADe7E2EvLWa35cMkB', choices=[Choice(finish_reason='stop', index=0, logprobs=None, message=ChatCompletionMessage(content='John is a person that works at Google [1].', role='assistant', function_call=None, tool_calls=None))], created=1719797903, model='gpt-3.5-turbo-0125', object='chat.completion', service_tier=None, system_fingerprint=None, usage=CompletionUsage(completion_tokens=11, prompt_tokens=145, total_tokens=156)) diff --git a/py/core/main/services/ingestion_service.py b/py/core/main/services/ingestion_service.py index 1b9201229..fc9cbf445 100644 --- a/py/core/main/services/ingestion_service.py +++ b/py/core/main/services/ingestion_service.py @@ -127,9 +127,12 @@ async def update_files( message="Number of ids does not match number of files.", ) else: - document_ids = [generate_user_document_id(file.filename, user.id) for file in files] - print('user_id = ', user.id) - print('document_ids = ', document_ids) + document_ids = [ + generate_user_document_id(file.filename, user.id) + for file in files + ] + print("user_id = ", user.id) + print("document_ids = ", document_ids) # Only superusers can modify arbitrary document ids, which this gate guarantees in conjuction with the check that follows documents_overview = ( ( diff --git a/py/sdk/ingestion.py b/py/sdk/ingestion.py index cea3f56c6..edacb807c 100644 --- a/py/sdk/ingestion.py +++ b/py/sdk/ingestion.py @@ -43,10 +43,12 @@ async def ingest_files( raise ValueError( "Number of versions must match number of document IDs." ) - if chunking_settings is not None and chunking_settings is not ChunkingConfig: + if ( + chunking_settings is not None + and chunking_settings is not ChunkingConfig + ): # check if the provided dict maps to a ChunkingConfig ChunkingConfig(**chunking_settings) - all_file_paths = [] for path in file_paths: @@ -121,7 +123,6 @@ async def update_files( raise ValueError( "Number of file paths must match number of document IDs." ) - with ExitStack() as stack: files = [ diff --git a/py/tests/cli/__init__.py b/py/tests/cli/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/py/tests/cli/commands/__init__.py b/py/tests/cli/commands/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/py/tests/cli/commands/test_auth.py b/py/tests/cli/commands/test_auth.py new file mode 100644 index 000000000..b1670c214 --- /dev/null +++ b/py/tests/cli/commands/test_auth.py @@ -0,0 +1,32 @@ +import pytest +from cli.commands.auth import generate_private_key +from click.testing import CliRunner + + +@pytest.fixture +def runner(): + return CliRunner() + + +def test_generate_private_key(runner): + result = runner.invoke(generate_private_key) + assert result.exit_code == 0 + assert "Generated Private Key:" in result.output + assert ( + "Keep this key secure and use it as your R2R_SECRET_KEY." + in result.output + ) + + +def test_generate_private_key_output_format(runner): + result = runner.invoke(generate_private_key) + key_line = [ + line + for line in result.output.split("\n") + if "Generated Private Key:" in line + ][0] + key = key_line.split(":")[1].strip() + assert len(key) > 32 # The key should be reasonably long + assert ( + key.isalnum() or "-" in key or "_" in key + ) # The key should be URL-safe diff --git a/py/tests/cli/commands/test_ingestion.py b/py/tests/cli/commands/test_ingestion.py new file mode 100644 index 000000000..28c26a3dc --- /dev/null +++ b/py/tests/cli/commands/test_ingestion.py @@ -0,0 +1,174 @@ +import tempfile +from unittest.mock import MagicMock, patch + +import click +import pytest +from cli.cli import cli +from click.testing import CliRunner + + +@pytest.fixture +def runner(): + return CliRunner() + + +@pytest.fixture +def mock_client(): + return MagicMock() + + +@pytest.fixture +def temp_file(): + with tempfile.NamedTemporaryFile(mode="w", delete=False) as f: + f.write("Test content") + f.flush() + yield f.name + + +@pytest.fixture(autouse=True) +def mock_cli_obj(mock_client): + with patch( + "cli.commands.ingestion.click.get_current_context" + ) as mock_context: + mock_context.return_value.obj = mock_client + yield + + +@pytest.fixture(autouse=True) +def mock_r2r_client(): + with patch( + "cli.command_group.R2RClient", new=MagicMock() + ) as MockR2RClient: + mock_client = MockR2RClient.return_value + mock_client.ingest_files.return_value = {"status": "success"} + mock_client.update_files.return_value = {"status": "updated"} + + original_callback = cli.callback + + def new_callback(*args, **kwargs): + ctx = click.get_current_context() + ctx.obj = mock_client + return original_callback(*args, **kwargs) + + cli.callback = new_callback + + yield mock_client + + cli.callback = original_callback + + +def test_ingest_files(runner, mock_r2r_client, temp_file): + result = runner.invoke(cli, ["ingest-files", temp_file]) + assert result.exit_code == 0 + assert '"status": "success"' in result.output + mock_r2r_client.ingest_files.assert_called_once_with( + [temp_file], None, None, None + ) + + +def test_ingest_files_with_options(runner, mock_r2r_client, temp_file): + result = runner.invoke( + cli, + [ + "ingest-files", + temp_file, + "--document-ids", + "doc1", + "--metadatas", + '{"key": "value"}', + "--versions", + "v1", + ], + ) + assert result.exit_code == 0 + assert '"status": "success"' in result.output + assert mock_r2r_client.ingest_files.called, "ingest_files was not called" + mock_r2r_client.ingest_files.assert_called_once_with( + [temp_file], {"key": "value"}, ["doc1"], ["v1"] + ) + + +def test_update_files(runner, mock_r2r_client, temp_file): + result = runner.invoke( + cli, + [ + "update-files", + temp_file, + "--document-ids", + "doc1", + "--metadatas", + '{"key": "new_value"}', + ], + ) + assert result.exit_code == 0 + assert '"status": "updated"' in result.output + assert mock_r2r_client.update_files.called, "update_files was not called" + mock_r2r_client.update_files.assert_called_once_with( + [temp_file], ["doc1"], [{"key": "new_value"}] + ) + + +@patch("cli.commands.ingestion.ingest_files_from_urls") +def test_ingest_sample_file(mock_ingest, runner, mock_r2r_client): + mock_ingest.return_value = ["aristotle.txt"] + result = runner.invoke(cli, ["ingest-sample-file"]) + assert result.exit_code == 0 + assert "Sample file ingestion completed" in result.output + assert "aristotle.txt" in result.output + mock_ingest.assert_called_once() + + +@patch("cli.commands.ingestion.ingest_files_from_urls") +def test_ingest_sample_files(mock_ingest, runner, mock_r2r_client): + mock_ingest.return_value = ["aristotle.txt", "got.txt"] + result = runner.invoke(cli, ["ingest-sample-files"]) + assert result.exit_code == 0 + assert "Sample files ingestion completed" in result.output + assert "aristotle.txt" in result.output + assert "got.txt" in result.output + mock_ingest.assert_called_once() + + +@patch("cli.commands.ingestion.requests.get") +@patch("cli.commands.ingestion.tempfile.NamedTemporaryFile") +def test_ingest_files_from_urls(mock_temp_file, mock_get, mock_r2r_client): + mock_get.return_value.text = "File content" + mock_temp_file.return_value.__enter__.return_value.name = "/tmp/test_file" + mock_r2r_client.ingest_files.return_value = {"status": "success"} + + with patch("cli.commands.ingestion.os.unlink") as mock_unlink: + from cli.commands.ingestion import ingest_files_from_urls + + result = ingest_files_from_urls( + mock_r2r_client, ["http://example.com/file.txt"] + ) + + assert result == ["file.txt"] + mock_r2r_client.ingest_files.assert_called_once_with(["/tmp/test_file"]) + mock_unlink.assert_called_once_with("/tmp/test_file") + + +def test_ingest_files_with_invalid_file(runner, mock_r2r_client): + result = runner.invoke(cli, ["ingest-files", "nonexistent_file.txt"]) + assert result.exit_code != 0 + assert "Error" in result.output + assert not mock_r2r_client.ingest_files.called + + +def test_update_files_with_invalid_metadata( + runner, mock_r2r_client, temp_file +): + result = runner.invoke( + cli, + [ + "update-files", + temp_file, + "--document-ids", + "doc1", + "--metadatas", + "invalid_json", + ], + ) + assert result.exit_code != 0 + assert "Error" in result.output + assert not mock_r2r_client.update_files.called diff --git a/py/tests/cli/commands/test_management.py b/py/tests/cli/commands/test_management.py new file mode 100644 index 000000000..fe1854590 --- /dev/null +++ b/py/tests/cli/commands/test_management.py @@ -0,0 +1,208 @@ +import json +from unittest.mock import MagicMock, patch + +import click +import pytest +from cli.cli import cli +from click.testing import CliRunner + + +@pytest.fixture +def runner(): + return CliRunner() + + +@pytest.fixture(autouse=True) +def mock_r2r_client(): + with patch( + "cli.command_group.R2RClient", new=MagicMock() + ) as MockR2RClient: + mock_client = MockR2RClient.return_value + mock_client.analytics.return_value = { + "status": "success", + "result": "analytics data", + } + mock_client.app_settings.return_value = { + "setting1": "value1", + "setting2": "value2", + } + mock_client.users_overview.return_value = [ + {"id": "user1", "name": "John"}, + {"id": "user2", "name": "Jane"}, + ] + mock_client.delete.return_value = {"deleted": 2} + mock_client.documents_overview.return_value = { + "results": [ + {"id": "doc1", "title": "Document 1"}, + {"id": "doc2", "title": "Document 2"}, + ] + } + mock_client.document_chunks.return_value = [ + {"id": "chunk1", "content": "Content 1"}, + {"id": "chunk2", "content": "Content 2"}, + ] + mock_client.inspect_knowledge_graph.return_value = { + "nodes": 100, + "edges": 500, + } + + original_callback = cli.callback + + def new_callback(*args, **kwargs): + ctx = click.get_current_context() + ctx.obj = mock_client + return original_callback(*args, **kwargs) + + cli.callback = new_callback + + yield mock_client + + cli.callback = original_callback + + +def test_analytics(runner, mock_r2r_client): + filters = {"date": "2023-01-01"} + analysis_types = {"type": "user_activity"} + + result = runner.invoke( + cli, + [ + "analytics", + "--filters", + json.dumps(filters), + "--analysis-types", + json.dumps(analysis_types), + ], + ) + + assert result.exit_code == 0 + assert "success" in result.output + mock_r2r_client.analytics.assert_called_once_with(filters, analysis_types) + + +def test_analytics_invalid_json(runner, mock_r2r_client): + result = runner.invoke( + cli, + [ + "analytics", + "--filters", + "invalid_json", + "--analysis-types", + '{"type": "user_activity"}', + ], + ) + + assert result.exit_code == 2 + assert "Invalid value for '--filters'" in result.output + + +def test_app_settings(runner, mock_r2r_client): + result = runner.invoke(cli, ["app-settings"]) + + assert result.exit_code == 0 + assert "setting1" in result.output + assert "value2" in result.output + mock_r2r_client.app_settings.assert_called_once() + + +def test_users_overview(runner, mock_r2r_client): + result = runner.invoke(cli, ["users-overview", "--user-ids", "user1"]) + + print(f"Exit code: {result.exit_code}") + print(f"Output: {result.output}") + + assert result.exit_code == 0 + assert "user1" in result.output + mock_r2r_client.users_overview.assert_called_once_with(["user1"]) + + +def test_users_overview_no_ids(runner, mock_r2r_client): + result = runner.invoke(cli, ["users-overview"]) + + assert result.exit_code == 0 + assert "user1" in result.output + assert "Jane" in result.output + mock_r2r_client.users_overview.assert_called_once_with(None) + + +def test_delete(runner, mock_r2r_client): + result = runner.invoke( + cli, ["delete", "-f", "date:gt:2023-01-01", "-f", "status:eq:inactive"] + ) + + assert result.exit_code == 0 + assert "deleted" in result.output + expected_filters = { + "date": {"$gt": "2023-01-01"}, + "status": {"$eq": "inactive"}, + } + mock_r2r_client.delete.assert_called_once_with(filters=expected_filters) + + +def test_delete_invalid_filter(runner, mock_r2r_client): + result = runner.invoke(cli, ["delete", "-f", "invalid_filter"]) + + assert result.exit_code != 0 + + +def test_documents_overview_without_document_id(runner, mock_r2r_client): + result = runner.invoke( + cli, + [ + "documents-overview", + ], + ) + + assert result.exit_code == 0 + mock_r2r_client.documents_overview.assert_called_once() + + +def test_documents_overview_with_document_id(runner, mock_r2r_client): + result = runner.invoke( + cli, ["documents-overview", "--document-ids", "doc1"] + ) + + print(f"Exit code: {result.exit_code}") + print(f"Output: {result.output}") + + assert result.exit_code == 0 + assert "doc1" in result.output + mock_r2r_client.documents_overview.assert_called_once_with(["doc1"]) + + +def test_document_chunks(runner, mock_r2r_client): + result = runner.invoke(cli, ["document-chunks", "--document-id", "doc1"]) + + assert result.exit_code == 0 + assert "chunk1" in result.output + assert "Content 2" in result.output + mock_r2r_client.document_chunks.assert_called_once_with("doc1") + + +def test_document_chunks_no_id(runner, mock_r2r_client): + result = runner.invoke(cli, ["document-chunks"]) + + print(f"Exit code: {result.exit_code}") + print(f"Output: {result.output}") + + assert result.exit_code == 0 + mock_r2r_client.document_chunks.assert_called_once_with(None) + assert "chunk1" in result.output + + +def test_inspect_knowledge_graph(runner, mock_r2r_client): + result = runner.invoke(cli, ["inspect-knowledge-graph", "--limit", "100"]) + + assert result.exit_code == 0 + assert "nodes" in result.output + assert "500" in result.output + mock_r2r_client.inspect_knowledge_graph.assert_called_once_with("100") + + +def test_inspect_knowledge_graph_no_limit(runner, mock_r2r_client): + result = runner.invoke(cli, ["inspect-knowledge-graph"]) + + assert result.exit_code == 0 + assert "nodes" in result.output + assert "500" in result.output + mock_r2r_client.inspect_knowledge_graph.assert_called_once_with(None) diff --git a/py/tests/cli/commands/test_restructure.py b/py/tests/cli/commands/test_restructure.py new file mode 100644 index 000000000..fb5967e9e --- /dev/null +++ b/py/tests/cli/commands/test_restructure.py @@ -0,0 +1,55 @@ +import json +from unittest.mock import MagicMock, patch + +import click +import pytest +from cli.cli import cli +from click.testing import CliRunner + + +@pytest.fixture +def runner(): + return CliRunner() + + +@pytest.fixture +def mock_client(): + return MagicMock() + + +@pytest.fixture(autouse=True) +def mock_cli_obj(mock_client): + with patch( + "cli.commands.restructure.click.get_current_context" + ) as mock_context: + mock_context.return_value.obj = mock_client + yield + + +@pytest.fixture(autouse=True) +def mock_r2r_client(): + with patch( + "cli.command_group.R2RClient", new=MagicMock() + ) as MockR2RClient: + mock_client = MockR2RClient.return_value + + original_callback = cli.callback + + def new_callback(*args, **kwargs): + ctx = click.get_current_context() + ctx.obj = mock_client + return original_callback(*args, **kwargs) + + cli.callback = new_callback + + yield mock_client + + cli.callback = original_callback + + +def test_enrich_graph(runner, mock_r2r_client): + result = runner.invoke(cli, ["enrich-graph"]) + + assert result.exit_code == 0 + assert "Time taken" in result.output + mock_r2r_client.restructure.assert_called_once() diff --git a/py/tests/cli/test_cli.py b/py/tests/cli/test_cli.py new file mode 100644 index 000000000..8605a5d23 --- /dev/null +++ b/py/tests/cli/test_cli.py @@ -0,0 +1,48 @@ +import pytest +from cli.cli import cli, main +from click.testing import CliRunner + + +@pytest.fixture +def runner(): + return CliRunner() + + +def test_cli_group_exists(): + assert callable(cli) + assert cli.name == "cli" + + +def test_main_function(runner): + result = runner.invoke(cli, ["--help"]) + assert result.exit_code == 0 + assert "Usage: cli [OPTIONS] COMMAND [ARGS]..." in result.output + + +def test_commands_added(): + commands = [ + "generate-private-key", + "ingest-files", + "update-files", + "ingest-sample-file", + "ingest-sample-files", + "analytics", + "app-settings", + "users-overview", + "documents-overview", + "document-chunks", + "inspect-knowledge-graph", + "enrich-graph", + "search", + "rag", + "health", + "server-stats", + "logs", + "docker-down", + "generate-report", + "serve", + "update", + "version", + ] + for command in commands: + assert command in cli.commands diff --git a/py/tests/cli/test_command_group.py b/py/tests/cli/test_command_group.py new file mode 100644 index 000000000..bb4e113da --- /dev/null +++ b/py/tests/cli/test_command_group.py @@ -0,0 +1,27 @@ +import pytest +from cli.command_group import cli +from click.testing import CliRunner + + +@pytest.fixture +def runner(): + return CliRunner() + + +def test_cli_group_options(): + assert "config_path" in [param.name for param in cli.params] + assert "config_name" in [param.name for param in cli.params] + assert "base_url" in [param.name for param in cli.params] + + +def test_cli_group_help(runner): + result = runner.invoke(cli, ["--help"]) + assert result.exit_code == 0 + assert "R2R CLI for all core operations." in result.output + + +def test_base_url_option(runner): + result = runner.invoke( + cli, ["--base-url", "http://example.com", "generate-private-key"] + ) + assert result.exit_code == 0 diff --git a/py/tests/cli/utils/test_docker_utils.py b/py/tests/cli/utils/test_docker_utils.py new file mode 100644 index 000000000..abc4e7408 --- /dev/null +++ b/py/tests/cli/utils/test_docker_utils.py @@ -0,0 +1,83 @@ +import os +import socket +from unittest.mock import MagicMock, patch + +import pytest +from cli.utils.docker_utils import ( + bring_down_docker_compose, + build_docker_command, + check_llm_reqs, + check_set_docker_env_vars, + check_subnet_conflict, + find_available_port, + remove_r2r_network, +) +from click.testing import CliRunner + + +@pytest.fixture +def runner(): + return CliRunner() + + +def test_bring_down_docker_compose(runner): + with patch("os.system") as mock_system: + mock_system.return_value = 0 + result = bring_down_docker_compose("test_project", True, True) + assert result == 0 + mock_system.assert_called_once() + + +@patch("subprocess.check_output") +@patch("os.system") +def test_remove_r2r_network(mock_system, mock_check_output): + mock_check_output.return_value = b"r2r_test_network\nother_network" + mock_system.return_value = 0 + remove_r2r_network() + mock_system.assert_called_once_with("docker network rm r2r_test_network") + + +@pytest.mark.parametrize( + "llm_provider,model_provider,env_vars,expected_exit", + [ + ("openai", "openai", {"OPENAI_API_KEY": "test"}, False), + ("openai", "openai", {}, True), + ], +) +def test_check_llm_reqs(llm_provider, model_provider, env_vars, expected_exit): + with patch.dict(os.environ, env_vars, clear=True): + with patch("click.confirm", return_value=False): + with ( + pytest.raises(SystemExit) + if expected_exit + else patch("sys.exit") + ) as mock_exit: + check_llm_reqs(llm_provider, model_provider) + if expected_exit: + mock_exit.assert_called_once_with(1) + + +def test_build_docker_command(): + compose_files = { + "base": "base.yaml", + "neo4j": "neo4j.yaml", + "ollama": "ollama.yaml", + "postgres": "postgres.yaml", + } + command = build_docker_command( + compose_files, + "localhost", + 8000, + False, + False, + False, + "test_project", + None, + "test_image", + ) + assert ( + "docker compose -f base.yaml -f neo4j.yaml -f ollama.yaml -f postgres.yaml" + in command + ) + assert "--project-name test_project" in command + assert "up -d" in command diff --git a/py/tests/cli/utils/test_param_types.py b/py/tests/cli/utils/test_param_types.py new file mode 100644 index 000000000..71c6368e7 --- /dev/null +++ b/py/tests/cli/utils/test_param_types.py @@ -0,0 +1,68 @@ +from unittest.mock import MagicMock + +import click +import pytest +from cli.utils.param_types import JSON, JsonParamType + + +def test_json_param_type_convert_valid_json(): + json_type = JsonParamType() + result = json_type.convert('{"key": "value"}', None, None) + assert result == {"key": "value"} + + +def test_json_param_type_convert_invalid_json(): + json_type = JsonParamType() + with pytest.raises(click.BadParameter) as excinfo: + json_type.convert("{invalid json}", None, None) + assert "is not a valid JSON string" in str(excinfo.value) + + +def test_json_param_type_convert_dict(): + json_type = JsonParamType() + input_dict = {"key": "value"} + result = json_type.convert(input_dict, None, None) + assert result == input_dict + + +def test_json_param_type_name(): + json_type = JsonParamType() + assert json_type.name == "json" + + +def test_json_global_instance(): + assert isinstance(JSON, JsonParamType) + + +def test_json_param_type_convert_with_context(): + json_type = JsonParamType() + mock_ctx = MagicMock() + mock_param = MagicMock() + result = json_type.convert('{"key": "value"}', mock_param, mock_ctx) + assert result == {"key": "value"} + + +def test_json_param_type_convert_empty_string(): + json_type = JsonParamType() + with pytest.raises(click.BadParameter) as excinfo: + json_type.convert("", None, None) + assert "is not a valid JSON string" in str(excinfo.value) + + +def test_json_param_type_convert_none(): + json_type = JsonParamType() + result = json_type.convert(None, None, None) + assert result is None + + +def test_json_param_type_convert_complex_json(): + json_type = JsonParamType() + complex_json = ( + '{"key1": "value1", "key2": [1, 2, 3], "key3": {"nested": true}}' + ) + result = json_type.convert(complex_json, None, None) + assert result == { + "key1": "value1", + "key2": [1, 2, 3], + "key3": {"nested": True}, + } diff --git a/py/tests/cli/utils/test_timer.py b/py/tests/cli/utils/test_timer.py new file mode 100644 index 000000000..109bc3e02 --- /dev/null +++ b/py/tests/cli/utils/test_timer.py @@ -0,0 +1,77 @@ +import time +from unittest.mock import patch + +import pytest +from cli.utils.timer import timer + + +def test_timer_measures_time(): + with patch("time.time") as mock_time: + mock_time.side_effect = [0, 0.1] + + @timer() + def dummy_function(): + time.sleep(0.1) + + with patch("click.echo") as mock_echo: + dummy_function() + mock_echo.assert_called_once_with("Time taken: 0.10 seconds") + + +def test_timer_handles_exceptions(): + @timer() + def error_function(): + raise ValueError("Test exception") + + with patch("time.time") as mock_time: + mock_time.side_effect = [0, 0.1] + + with pytest.raises(ValueError, match="Test exception"): + error_function() + + +def test_timer_nested(): + with patch("time.time") as mock_time: + mock_time.side_effect = [0, 0.1, 0.2, 0.3] + + @timer() + def outer_function(): + time.sleep(0.1) + + @timer() + def inner_function(): + time.sleep(0.1) + + inner_function() + + with patch("click.echo") as mock_echo: + outer_function() + assert mock_echo.call_count == 2 + mock_echo.assert_any_call("Time taken: 0.10 seconds") + mock_echo.assert_any_call("Time taken: 0.30 seconds") + + +def test_timer_zero_duration(): + with patch("time.time") as mock_time: + mock_time.side_effect = [0, 0] + + @timer() + def quick_function(): + pass + + with patch("click.echo") as mock_echo: + quick_function() + mock_echo.assert_called_once_with("Time taken: 0.00 seconds") + + +def test_timer_as_context_manager(): + with patch("time.time") as mock_time: + mock_time.side_effect = [0, 0.1] + + def function_with_context(): + with timer(): + time.sleep(0.1) + + with patch("click.echo") as mock_echo: + function_with_context() + mock_echo.assert_called_once_with("Time taken: 0.10 seconds") diff --git a/py/tests/test_cli.py b/py/tests/test_cli.py deleted file mode 100644 index 0205effb2..000000000 --- a/py/tests/test_cli.py +++ /dev/null @@ -1,330 +0,0 @@ -from unittest.mock import patch - -import click -import pytest -from click.testing import CliRunner -from cli.cli import cli -from cli.utils.param_types import JSON - - -@pytest.fixture -def runner(): - return CliRunner() - - -@pytest.fixture -def mock_r2r_execution_wrapper(): - # with patch("cli.command_group.R2RExecutionWrapper") as mock: - # yield mock - pass - - -def test_cli_group(runner): - result = runner.invoke(cli, ["--help"]) - assert result.exit_code == 0 - assert "R2R CLI for all core operations." in result.output - - -def test_generate_private_key(runner): - result = runner.invoke(cli, ["generate-private-key"]) - assert result.exit_code == 0 - assert "Generated Private Key:" in result.output - assert ( - "Keep this key secure and use it as your R2R_SECRET_KEY." - in result.output - ) - - -def test_delete_command(runner, mock_r2r_execution_wrapper): - mock_instance = mock_r2r_execution_wrapper.return_value - mock_instance.delete.return_value = "Deleted successfully" - - result = runner.invoke(cli, ["delete", "--filter", "key1:eq:value1"]) - assert result.exit_code == 0 - assert "Deleted successfully" in result.output - mock_instance.delete.assert_called_once_with( - filters={"key1": {"$eq": "value1"}} - ) - - -def test_multiple_deletes(runner, mock_r2r_execution_wrapper): - mock_instance = mock_r2r_execution_wrapper.return_value - mock_instance.delete.return_value = "Deleted successfully" - - result = runner.invoke( - cli, - ["delete", "--filter", "key1:eq:value1", "--filter", "key2:eq:value2"], - ) - assert result.exit_code == 0 - assert "Deleted successfully" in result.output - mock_instance.delete.assert_called_once_with( - filters={"key1": {"$eq": "value1"}, "key2": {"$eq": "value2"}} - ) - - -def test_documents_overview(runner, mock_r2r_execution_wrapper): - mock_instance = mock_r2r_execution_wrapper.return_value - mock_instance.documents_overview.return_value = [ - "Document 1", - "Document 2", - ] - - result = runner.invoke( - cli, - [ - "documents-overview", - "--document-ids", - "id1", - "--document-ids", - "id2", - ], - ) - assert result.exit_code == 0 - assert "Document 1" in result.output - assert "Document 2" in result.output - mock_instance.documents_overview.assert_called_once_with(["id1", "id2"]) - - -def test_document_chunks(runner, mock_r2r_execution_wrapper): - mock_instance = mock_r2r_execution_wrapper.return_value - mock_instance.document_chunks.return_value = ["Chunk 1", "Chunk 2"] - - result = runner.invoke(cli, ["document-chunks", "doc_id"]) - assert result.exit_code == 0 - assert "Chunk 1" in result.output - assert "Chunk 2" in result.output - mock_instance.document_chunks.assert_called_once_with("doc_id") - - -def test_ingest_files(runner, mock_r2r_execution_wrapper): - mock_instance = mock_r2r_execution_wrapper.return_value - mock_instance.ingest_files.return_value = "Files ingested successfully" - - result = runner.invoke( - cli, - [ - "ingest-files", - "--file-paths", - "file1.txt", - "--file-paths", - "file2.txt", - "--document-ids", - "id1", - "--document-ids", - "id2", - ], - ) - assert result.exit_code == 0 - assert "Files ingested successfully" in result.output - mock_instance.ingest_files.assert_called_once_with( - ["file1.txt", "file2.txt"], ["id1", "id2"], None, None - ) - - -def test_ingest_sample_file(runner, mock_r2r_execution_wrapper): - mock_instance = mock_r2r_execution_wrapper.return_value - mock_instance.ingest_sample_file.return_value = "Sample file ingested" - - result = runner.invoke( - cli, ["ingest-sample-file", "--no-media", "--option", "1"] - ) - print(f"Output: {result.output}") - assert result.exit_code == 0 - assert "Sample file ingested" in result.output - mock_instance.ingest_sample_file.assert_called_once_with( - no_media=True, option=1 - ) - - -def test_update_files(runner, mock_r2r_execution_wrapper): - mock_instance = mock_r2r_execution_wrapper.return_value - mock_instance.update_files.return_value = "Files updated successfully" - - result = runner.invoke( - cli, - [ - "update-files", - "file1.txt", - "--document-ids", - "id1", - "--metadatas", - '{"key": "value"}', - ], - ) - assert result.exit_code == 0 - assert "Files updated successfully" in result.output - mock_instance.update_files.assert_called_once_with( - ["file1.txt"], ["id1"], ['{"key": "value"}'] - ) - - -def test_analytics(runner, mock_r2r_execution_wrapper): - mock_instance = mock_r2r_execution_wrapper.return_value - mock_instance.analytics.return_value = {"data": "analytics data"} - - result = runner.invoke( - cli, - [ - "analytics", - "--filters", - '{"date": "2023-01-01"}', - "--analysis-types", - '{"type": "usage"}', - ], - ) - assert result.exit_code == 0 - assert "{'data': 'analytics data'}" in result.output - mock_instance.analytics.assert_called_once_with( - {"date": "2023-01-01"}, {"type": "usage"} - ) - - -def test_app_settings(runner, mock_r2r_execution_wrapper): - mock_instance = mock_r2r_execution_wrapper.return_value - mock_instance.app_settings.return_value = {"setting1": "value1"} - - result = runner.invoke(cli, ["app-settings"]) - assert result.exit_code == 0 - assert "{'setting1': 'value1'}" in result.output - mock_instance.app_settings.assert_called_once() - - -def test_logs(runner, mock_r2r_execution_wrapper): - mock_instance = mock_r2r_execution_wrapper.return_value - mock_instance.logs.return_value = [ - { - "run_id": "test-run-id", - "run_type": "test", - "timestamp": "2024-08-05T20:00:00", - "user_id": "test-user-id", - "entries": [{"key": "test-key", "value": "test-value"}], - } - ] - - result = runner.invoke(cli, ["logs", "--run-type-filter", "error"]) - assert result.exit_code == 0 - assert "Run ID: test-run-id" in result.output - assert "Run Type: test" in result.output - assert "Timestamp: 2024-08-05T20:00:00" in result.output - assert "User ID: test-user-id" in result.output - assert "Entries:" in result.output - assert " - test-key: test-value" in result.output - assert "Total runs: 1" in result.output - - -def test_users_overview(runner, mock_r2r_execution_wrapper): - mock_instance = mock_r2r_execution_wrapper.return_value - mock_instance.users_overview.return_value = ["User 1", "User 2"] - - result = runner.invoke( - cli, - [ - "users-overview", - "--user-ids", - "123e4567-e89b-12d3-a456-426614174000", - ], - ) - assert result.exit_code == 0 - assert "User 1" in result.output - assert "User 2" in result.output - mock_instance.users_overview.assert_called_once() - - -def test_json_param_type(): - result = JSON.convert('{"key": "value"}', param=None, ctx=None) - assert result == {"key": "value"} - - with pytest.raises(click.BadParameter): - JSON.convert("invalid json", param=None, ctx=None) - - result = JSON.convert({"key": "value"}, param=None, ctx=None) - assert result == {"key": "value"} - - -def test_docker_down_command(runner): - with ( - patch( - "cli.commands.server_operations.bring_down_docker_compose" - ) as mock_bring_down, - patch( - "cli.commands.server_operations.remove_r2r_network" - ) as mock_remove_network, - ): - - mock_bring_down.return_value = 0 - result = runner.invoke(cli, ["docker-down"]) - assert result.exit_code == 0 - assert ( - "Docker Compose setup has been successfully brought down." - in result.output - ) - mock_bring_down.assert_called_once() - mock_remove_network.assert_called_once() - - # legacy code - # mock_bring_down.return_value = 1 - # result = runner.invoke(cli, ["docker-down"]) - # assert result.exit_code == 0 - # assert ( - # "An error occurred while bringing down the Docker Compose setup." - # in result.output - # ) - # mock_remove_network.assert_called_once() - - -def test_generate_report_command(): - runner = CliRunner() - with ( - patch("subprocess.check_output") as mock_check_output, - patch("platform.system") as mock_system, - patch("platform.release") as mock_release, - patch("platform.version") as mock_version, - patch("platform.machine") as mock_machine, - patch("platform.processor") as mock_processor, - ): - - mock_check_output.side_effect = [ - "container1\tname1\tUp 2 hours\n", - "network1\tnetwork_name1\n", - "172.17.0.0/16\n", - ] - mock_system.return_value = "Linux" - mock_release.return_value = "5.4.0" - mock_version.return_value = "#1 SMP Thu Jun 18 12:34:56 UTC 2020" - mock_machine.return_value = "x86_64" - mock_processor.return_value = "x86_64" - - result = runner.invoke(cli, ["generate-report"]) - assert result.exit_code == 0 - assert "System Report:" in result.output - assert "r2r_version" in result.output - assert "docker_ps" in result.output - assert "docker_subnets" in result.output - assert "os_info" in result.output - - -def test_health_command(runner, mock_r2r_execution_wrapper): - mock_instance = mock_r2r_execution_wrapper.return_value - mock_instance.health.return_value = "Server is healthy" - - result = runner.invoke(cli, ["health"]) - assert result.exit_code == 0 - assert "Server is healthy" in result.output - mock_instance.health.assert_called_once() - - -def test_update_command(runner): - with patch("subprocess.run") as mock_run: - mock_run.return_value.stdout = "Successfully updated R2R" - result = runner.invoke(cli, ["update"]) - assert result.exit_code == 0 - assert "Successfully updated R2R" in result.output - assert "R2R has been successfully updated." in result.output - - -def test_version_command(runner): - with patch("importlib.metadata.version") as mock_version: - mock_version.return_value = "1.0.0" - result = runner.invoke(cli, ["version"]) - assert result.exit_code == 0 - assert "1.0.0" in result.output diff --git a/py/tests/test_kg.py b/py/tests/test_kg.py index 7f8c4885c..1236c492c 100644 --- a/py/tests/test_kg.py +++ b/py/tests/test_kg.py @@ -1,11 +1,12 @@ -import pytest import asyncio from unittest.mock import AsyncMock, MagicMock -from core.pipes.kg.extraction import KGTriplesExtractionPipe -from core.pipes.kg.clustering import KGClusteringPipe -from core.base import DocumentFragment, KGExtraction, Entity, Triple, Community from uuid import uuid4 +import pytest +from core.base import Community, DocumentFragment, Entity, KGExtraction, Triple +from core.pipes.kg.clustering import KGClusteringPipe +from core.pipes.kg.extraction import KGTriplesExtractionPipe + @pytest.fixture def kg_extraction_pipe(): From 4ea5b59ec0276d24ff27be8f6f82d6e9aaf3f570 Mon Sep 17 00:00:00 2001 From: Shreyas Pimpalgaonkar Date: Wed, 21 Aug 2024 14:47:19 -0400 Subject: [PATCH 29/74] Shreyas/kg runtime cfg (#913) add kg runtime config --- py/cli/commands/restructure.py | 2 +- py/core/base/__init__.py | 2 ++ py/core/base/abstractions/__init__.py | 3 ++ py/core/base/abstractions/restructure.py | 23 +++++++++++++ py/core/base/providers/kg.py | 4 ++- py/core/configs/neo4j_kg.toml | 20 ++++++++---- py/core/main/api/routes/restructure/base.py | 9 ++++-- py/core/main/assembly/builder.py | 1 + py/core/main/services/restructure_service.py | 5 ++- py/core/pipes/kg/clustering.py | 32 +++++++++---------- py/core/pipes/kg/extraction.py | 2 +- py/core/providers/chunking/r2r_chunking.py | 7 ++-- .../providers/parsing/unstructured_parsing.py | 19 ++++++----- py/sdk/models.py | 27 ++++++++++++++++ py/sdk/restructure.py | 17 +++++++--- 15 files changed, 130 insertions(+), 43 deletions(-) create mode 100644 py/core/base/abstractions/restructure.py diff --git a/py/cli/commands/restructure.py b/py/cli/commands/restructure.py index 451c95c3b..770678a9a 100644 --- a/py/cli/commands/restructure.py +++ b/py/cli/commands/restructure.py @@ -13,6 +13,6 @@ def enrich_graph(client): Perform graph enrichment over the entire graph. """ with timer(): - response = client.restructure() + response = client.enrich_graph() click.echo(response) diff --git a/py/core/base/__init__.py b/py/core/base/__init__.py index 09f9e00e3..5fdb09128 100644 --- a/py/core/base/__init__.py +++ b/py/core/base/__init__.py @@ -47,6 +47,8 @@ "KGSearchSettings", "VectorSearchResult", "VectorSearchSettings", + # Restructure abstractions + "KGEnrichmentSettings", # User abstractions "Token", "TokenData", diff --git a/py/core/base/abstractions/__init__.py b/py/core/base/abstractions/__init__.py index 1245a7e4c..74d043a72 100644 --- a/py/core/base/abstractions/__init__.py +++ b/py/core/base/abstractions/__init__.py @@ -35,6 +35,7 @@ VectorSearchResult, VectorSearchSettings, ) +from .restructure import KGEnrichmentSettings from .user import Token, TokenData, UserStats from .vector import Vector, VectorEntry, VectorType @@ -81,6 +82,8 @@ "KGSearchSettings", "VectorSearchResult", "VectorSearchSettings", + # Restructure abstractions + "KGEnrichmentSettings", # User abstractions "Token", "TokenData", diff --git a/py/core/base/abstractions/restructure.py b/py/core/base/abstractions/restructure.py new file mode 100644 index 000000000..3d1dd9b01 --- /dev/null +++ b/py/core/base/abstractions/restructure.py @@ -0,0 +1,23 @@ +from typing import Optional + +from pydantic import BaseModel, Field + +from .llm import GenerationConfig + + +class KGEnrichmentSettings(BaseModel): + """Settings for knowledge graph enrichment.""" + + max_knowledge_triples: int = Field( + default=100, + description="The maximum number of knowledge triples to extract from each chunk.", + ) + + generation_config: GenerationConfig = Field( + default_factory=GenerationConfig, + description="Configuration for text generation during graph enrichment.", + ) + leiden_params: dict = Field( + default_factory=dict, + description="Parameters for the Leiden algorithm.", + ) diff --git a/py/core/base/providers/kg.py b/py/core/base/providers/kg.py index 6259fd829..310c37b92 100644 --- a/py/core/base/providers/kg.py +++ b/py/core/base/providers/kg.py @@ -7,6 +7,7 @@ from ...base.utils.base_utils import RelationshipType from ..abstractions.graph import Entity, KGExtraction, Triple from ..abstractions.llm import GenerationConfig +from ..abstractions.restructure import KGEnrichmentSettings from .base import ProviderConfig logger = logging.getLogger(__name__) @@ -20,8 +21,9 @@ class KGConfig(ProviderConfig): kg_extraction_prompt: Optional[str] = "few_shot_ner_kg_extraction" kg_search_prompt: Optional[str] = "kg_search" kg_extraction_config: Optional[GenerationConfig] = None + kg_search_config: Optional[GenerationConfig] = None kg_store_path: Optional[str] = None - max_knowledge_triples: Optional[int] = 100 + kg_enrichment_settings: Optional[KGEnrichmentSettings] = KGEnrichmentSettings() def validate(self) -> None: if self.provider not in self.supported_providers: diff --git a/py/core/configs/neo4j_kg.toml b/py/core/configs/neo4j_kg.toml index ae78dfe12..ad43a10f9 100644 --- a/py/core/configs/neo4j_kg.toml +++ b/py/core/configs/neo4j_kg.toml @@ -27,12 +27,20 @@ kg_extraction_prompt = "graphrag_triplet_extraction_zero_shot" [kg.kg_extraction_config] - model = "gpt-4o-mini" - temperature = 1 - top_p = 1 - max_tokens_to_sample = 1_024 - stream = false - add_generation_kwargs = { } + model = "gpt-4o-mini" + temperature = 0.1 + top_p = 1 + max_tokens_to_sample = 1_024 + stream = false + add_generation_kwargs = { } + + [kg.kg_search_config] + model = "gpt-4o-mini" + temperature = 0.1 + top_p = 1 + max_tokens_to_sample = 1_024 + stream = false + add_generation_kwargs = { } [database] provider = "postgres" diff --git a/py/core/main/api/routes/restructure/base.py b/py/core/main/api/routes/restructure/base.py index abf44fc66..de8b00c36 100644 --- a/py/core/main/api/routes/restructure/base.py +++ b/py/core/main/api/routes/restructure/base.py @@ -1,7 +1,8 @@ +from core.base import KGEnrichmentSettings from core.main.api.routes.base_router import BaseRouter from core.main.engine import R2REngine -from fastapi import Depends - +from typing import Union +from fastapi import Body, Depends class RestructureRouter(BaseRouter): def __init__(self, engine: R2REngine): @@ -12,6 +13,10 @@ def setup_routes(self): @self.router.post("/enrich_graph") @self.base_endpoint async def enrich_graph( + KGEnrichmentSettings: Union[dict, KGEnrichmentSettings] = Body( + ..., + description="Settings for knowledge graph enrichment", + ), auth_user=( Depends(self.engine.providers.auth.auth_wrapper) if self.engine.providers.auth diff --git a/py/core/main/assembly/builder.py b/py/core/main/assembly/builder.py index c7ef206b3..be8d95a22 100644 --- a/py/core/main/assembly/builder.py +++ b/py/core/main/assembly/builder.py @@ -63,6 +63,7 @@ def __init__( self.provider_factory_override: Optional[Type[R2RProviderFactory]] = ( None ) + self.pipe_factory_override: Optional[R2RPipeFactory] = None self.pipeline_factory_override: Optional[R2RPipelineFactory] = None diff --git a/py/core/main/services/restructure_service.py b/py/core/main/services/restructure_service.py index e85d0a7bd..aff7f4a72 100644 --- a/py/core/main/services/restructure_service.py +++ b/py/core/main/services/restructure_service.py @@ -2,6 +2,7 @@ from typing import Any, Dict, List from core.base import R2RException, RunLoggingSingleton, RunManager +from core.base.abstractions import KGEnrichmentSettings from ..abstractions import R2RAgents, R2RPipelines, R2RProviders from ..assembly.config import R2RConfig @@ -30,7 +31,9 @@ def __init__( logging_connection, ) - async def enrich_graph(self) -> Dict[str, Any]: + async def enrich_graph( + self, enrich_graph_settings: KGEnrichmentSettings = KGEnrichmentSettings() + ) -> Dict[str, Any]: """ Perform graph enrichment. diff --git a/py/core/pipes/kg/clustering.py b/py/core/pipes/kg/clustering.py index ed31eb3fd..b80014006 100644 --- a/py/core/pipes/kg/clustering.py +++ b/py/core/pipes/kg/clustering.py @@ -22,6 +22,7 @@ PromptProvider, RunLoggingSingleton, Triple, + KGEnrichmentSettings, ) logger = logging.getLogger(__name__) @@ -38,9 +39,6 @@ def __init__( llm_provider: CompletionProvider, prompt_provider: PromptProvider, embedding_provider: EmbeddingProvider, - cluster_batch_size: int = 100, - max_cluster_size: int = 10, - use_lcc: bool = True, pipe_logger: Optional[RunLoggingSingleton] = None, type: PipeType = PipeType.OTHER, config: Optional[AsyncPipe.PipeConfig] = None, @@ -57,23 +55,20 @@ def __init__( ) self.kg_provider = kg_provider self.llm_provider = llm_provider - self.cluster_batch_size = cluster_batch_size - self.max_cluster_size = max_cluster_size - self.use_lcc = use_lcc self.prompt_provider = prompt_provider self.embedding_provider = embedding_provider def _compute_leiden_communities( self, graph: nx.Graph, - seed: int = 0xDEADBEEF, + settings: KGEnrichmentSettings, ) -> dict[int, dict[str, int]]: """Compute Leiden communities.""" try: from graspologic.partition import hierarchical_leiden community_mapping = hierarchical_leiden( - graph, max_cluster_size=self.max_cluster_size, random_seed=seed + graph, **settings.leiden_params ) results: dict[int, dict[str, int]] = {} for partition in community_mapping: @@ -84,7 +79,9 @@ def _compute_leiden_communities( except ImportError as e: raise ImportError("Please install the graspologic package.") from e - async def cluster_kg(self, triples: list[Triple]) -> list[Community]: + async def cluster_kg( + self, triples: list[Triple], settings: KGEnrichmentSettings = KGEnrichmentSettings() + ) -> list[Community]: """ Clusters the knowledge graph triples into communities using hierarchical Leiden algorithm. """ @@ -100,7 +97,9 @@ async def cluster_kg(self, triples: list[Triple]) -> list[Community]: id=f"{triple.subject}->{triple.predicate}->{triple.object}", ) - hierarchical_communities = self._compute_leiden_communities(G) + hierarchical_communities = self._compute_leiden_communities( + G, settings=settings + ) community_details = {} @@ -172,9 +171,7 @@ async def process_community(community_key, community): "input_text": input_text, }, ), - generation_config=GenerationConfig( - model="gpt-4o-mini", - ), + generation_config=settings.generation_config, ) description = description.choices[0].message.content @@ -202,8 +199,11 @@ async def process_community(community_key, community): ) ) - for completed_task in asyncio.as_completed(tasks): - yield await completed_task + total_tasks = len(tasks) + for i, completed_task in enumerate(asyncio.as_completed(tasks), 1): + result = await completed_task + logger.info(f"Progress: {i}/{total_tasks} communities completed ({i/total_tasks*100:.2f}%)") + yield result async def _run_logic( self, @@ -230,5 +230,5 @@ async def _run_logic( triples = self.kg_provider.get_triples() - async for community in self.cluster_kg(triples): + async for community in self.cluster_kg(triples, self.kg_provider.config.kg_enrichment_settings): yield community diff --git a/py/core/pipes/kg/extraction.py b/py/core/pipes/kg/extraction.py index 9edd708b0..896ed44e0 100644 --- a/py/core/pipes/kg/extraction.py +++ b/py/core/pipes/kg/extraction.py @@ -88,7 +88,7 @@ async def extract_kg( task_inputs = {"input": fragment.data} task_inputs["max_knowledge_triples"] = ( - self.kg_provider.config.max_knowledge_triples + self.kg_provider.config.kg_enrichment_settings.max_knowledge_triples ) messages = self.prompt_provider._get_message_payload( diff --git a/py/core/providers/chunking/r2r_chunking.py b/py/core/providers/chunking/r2r_chunking.py index fac009ffe..dd900a1f1 100644 --- a/py/core/providers/chunking/r2r_chunking.py +++ b/py/core/providers/chunking/r2r_chunking.py @@ -22,6 +22,9 @@ def __init__(self, config: ChunkingConfig): ) def _initialize_text_splitter(self) -> TextSplitter: + logger.info( + f"Initializing text splitter with method: {self.config.method}" + ) # Debug log if self.config.method == Method.RECURSIVE: return RecursiveCharacterTextSplitter( chunk_size=self.config.chunk_size, @@ -29,10 +32,10 @@ def _initialize_text_splitter(self) -> TextSplitter: ) elif self.config.method == Method.BASIC: # Implement basic method - raise NotImplementedError("Basic method not implemented yet") + pass elif self.config.method == Method.BY_TITLE: # Implement by_title method - raise NotImplementedError("By_title method not implemented yet") + pass else: raise ValueError(f"Unsupported method type: {self.config.method}") diff --git a/py/core/providers/parsing/unstructured_parsing.py b/py/core/providers/parsing/unstructured_parsing.py index 3fe073a52..a32cf1e9e 100644 --- a/py/core/providers/parsing/unstructured_parsing.py +++ b/py/core/providers/parsing/unstructured_parsing.py @@ -17,14 +17,6 @@ class UnstructuredParsingProvider(ParsingProvider): def __init__(self, use_api, config): - try: - from unstructured.partition.auto import partition - - self.partition = partition - except ImportError as e: - raise ImportError( - "Please install the unstructured package to use the unstructured parsing provider." - ) from e if config.excluded_parsers: logger.warning( "Excluded parsers are not supported by the unstructured parsing provider." @@ -57,6 +49,17 @@ def __init__(self, use_api, config): self.operations = operations self.dict_to_elements = dict_to_elements + else: + try: + from unstructured.partition.auto import partition + + self.partition = partition + + except ImportError: + raise ImportError( + "Please install the unstructured package to use the unstructured parsing provider." + ) + super().__init__(config) async def parse( diff --git a/py/sdk/models.py b/py/sdk/models.py index 96cd0a457..3986a816e 100644 --- a/py/sdk/models.py +++ b/py/sdk/models.py @@ -88,6 +88,17 @@ class KGSearchSettings(BaseModel): } +class KGEnrichmentSettings(BaseModel): + leiden_params: dict = Field( + default_factory=dict, + description="Parameters for the Leiden algorithm.", + ) + generation_config: GenerationConfig = Field( + default_factory=GenerationConfig, + description="Configuration for text generation during graph enrichment.", + ) + + class ProviderConfig(BaseModel, ABC): """A base provider configuration class""" @@ -237,7 +248,23 @@ def model_dump(self, *args, **kwargs): str(uuid) for uuid in dump["selected_group_ids"] ] return dump + +class KGEnrichmentSettings(BaseModel): + max_knowledge_triples: int = Field( + default=100, + description="The maximum number of knowledge triples to extract from each chunk.", + ) + generation_config: GenerationConfig = Field( + default_factory=GenerationConfig, + description="The generation configuration for the KG enrichment.", + ) + leiden_params: dict = Field( + default_factory=dict, + description="The parameters for the Leiden algorithm.", + ) +class KGEnrichementResponse(BaseModel): + enriched_content: Dict[str, Any] class UserResponse(BaseModel): id: UUID diff --git a/py/sdk/restructure.py b/py/sdk/restructure.py index 156fba98d..10acb1876 100644 --- a/py/sdk/restructure.py +++ b/py/sdk/restructure.py @@ -1,16 +1,23 @@ -from typing import Any, Dict, List, Optional +from typing import Any, Dict, List, Optional, Union from core.base import Document -from core.base.api.models import KGEnrichementResponse - +from .models import KGEnrichmentSettings, KGEnrichementResponse class RestructureMethods: @staticmethod - async def enrich_graph(client) -> KGEnrichementResponse: + async def enrich_graph( + client, KGEnrichmentSettings: KGEnrichmentSettings = KGEnrichmentSettings() + ) -> KGEnrichementResponse: """ Perform graph enrichment over the entire graph. Returns: KGEnrichementResponse: Results of the graph enrichment process. """ - return await client._make_request("POST", "enrich_graph") + if not isinstance(KGEnrichmentSettings, dict): + KGEnrichmentSettings = KGEnrichmentSettings.model_dump() + + data = { + "KGEnrichmentSettings": KGEnrichmentSettings, + } + return await client._make_request("POST", "enrich_graph", json=data) From 3c7d1cfe98358841753e9902cbf4c524d4616217 Mon Sep 17 00:00:00 2001 From: Shreyas Pimpalgaonkar Date: Wed, 21 Aug 2024 14:58:12 -0400 Subject: [PATCH 30/74] rename kgenrichmentresponse (#914) --- py/core/base/api/models/__init__.py | 8 ++++---- py/core/base/api/models/restructure/responses.py | 4 ++-- py/sdk/models.py | 13 +------------ py/sdk/restructure.py | 6 +++--- 4 files changed, 10 insertions(+), 21 deletions(-) diff --git a/py/core/base/api/models/__init__.py b/py/core/base/api/models/__init__.py index 1bbf8549c..c5506d172 100644 --- a/py/core/base/api/models/__init__.py +++ b/py/core/base/api/models/__init__.py @@ -34,8 +34,8 @@ WrappedUserOverviewResponse, ) from .restructure.responses import ( - KGEnrichementResponse, - WrappedKGEnrichementResponse, + KGEnrichmentResponse, + WrappedKGEnrichmentResponse, ) from .retrieval.responses import ( RAGAgentResponse, @@ -57,8 +57,8 @@ "IngestionResponse", "WrappedIngestionResponse", # Restructure Responses - "KGEnrichementResponse", - "WrappedKGEnrichementResponse", + "KGEnrichmentResponse", + "WrappedKGEnrichmentResponse", # Management Responses "PromptResponse", "ServerStats", diff --git a/py/core/base/api/models/restructure/responses.py b/py/core/base/api/models/restructure/responses.py index e9e62e85e..ed35bd437 100644 --- a/py/core/base/api/models/restructure/responses.py +++ b/py/core/base/api/models/restructure/responses.py @@ -6,8 +6,8 @@ from pydantic import BaseModel -class KGEnrichementResponse(BaseModel): +class KGEnrichmentResponse(BaseModel): enriched_content: Dict[str, Any] -WrappedKGEnrichementResponse = ResultsWrapper[KGEnrichementResponse] +WrappedKGEnrichmentResponse = ResultsWrapper[KGEnrichmentResponse] diff --git a/py/sdk/models.py b/py/sdk/models.py index 3986a816e..22ded990f 100644 --- a/py/sdk/models.py +++ b/py/sdk/models.py @@ -88,17 +88,6 @@ class KGSearchSettings(BaseModel): } -class KGEnrichmentSettings(BaseModel): - leiden_params: dict = Field( - default_factory=dict, - description="Parameters for the Leiden algorithm.", - ) - generation_config: GenerationConfig = Field( - default_factory=GenerationConfig, - description="Configuration for text generation during graph enrichment.", - ) - - class ProviderConfig(BaseModel, ABC): """A base provider configuration class""" @@ -263,7 +252,7 @@ class KGEnrichmentSettings(BaseModel): description="The parameters for the Leiden algorithm.", ) -class KGEnrichementResponse(BaseModel): +class KGEnrichmentResponse(BaseModel): enriched_content: Dict[str, Any] class UserResponse(BaseModel): diff --git a/py/sdk/restructure.py b/py/sdk/restructure.py index 10acb1876..ca93edc2b 100644 --- a/py/sdk/restructure.py +++ b/py/sdk/restructure.py @@ -1,18 +1,18 @@ from typing import Any, Dict, List, Optional, Union from core.base import Document -from .models import KGEnrichmentSettings, KGEnrichementResponse +from .models import KGEnrichmentSettings, KGEnrichmentResponse class RestructureMethods: @staticmethod async def enrich_graph( client, KGEnrichmentSettings: KGEnrichmentSettings = KGEnrichmentSettings() - ) -> KGEnrichementResponse: + ) -> KGEnrichmentResponse: """ Perform graph enrichment over the entire graph. Returns: - KGEnrichementResponse: Results of the graph enrichment process. + KGEnrichmentResponse: Results of the graph enrichment process. """ if not isinstance(KGEnrichmentSettings, dict): KGEnrichmentSettings = KGEnrichmentSettings.model_dump() From 02664836a58ca3b5c45be0b0bdb4a85a556761e5 Mon Sep 17 00:00:00 2001 From: emrgnt-cmplxty <68796651+emrgnt-cmplxty@users.noreply.github.com> Date: Wed, 21 Aug 2024 13:21:46 -0700 Subject: [PATCH 31/74] Feature/add nltk hybrid expansion rebased (#917) * expand hybrid search with nltk * cleanups * cleanup hybrid search * format * add setup.py * update --- py/cli/commands/ingestion.py | 67 ++-- py/core/base/abstractions/__init__.py | 2 +- py/core/base/providers/kg.py | 4 +- py/core/main/api/routes/ingestion/base.py | 4 +- py/core/main/api/routes/restructure/base.py | 4 +- py/core/main/services/restructure_service.py | 3 +- py/core/pipes/kg/clustering.py | 14 +- py/core/providers/database/vecs/collection.py | 152 +++++-- py/core/providers/database/vector.py | 137 +++---- py/poetry.lock | 49 ++- py/pyproject.toml | 9 +- py/sdk/ingestion.py | 6 +- py/sdk/models.py | 5 +- py/sdk/restructure.py | 7 +- py/setup.py | 17 + .../test_cases/test_document_management.py | 1 - py/tests/test_cli.py | 330 ++++++++++++++++ tests/test_client.py | 371 ------------------ 18 files changed, 660 insertions(+), 522 deletions(-) create mode 100644 py/setup.py create mode 100644 py/tests/test_cli.py delete mode 100644 tests/test_client.py diff --git a/py/cli/commands/ingestion.py b/py/cli/commands/ingestion.py index 0666ee869..403aaa632 100644 --- a/py/cli/commands/ingestion.py +++ b/py/cli/commands/ingestion.py @@ -1,6 +1,7 @@ import json import os import tempfile +import uuid from urllib.parse import urlparse import click @@ -75,28 +76,44 @@ def update_files(client, file_paths, document_ids, metadatas): def ingest_files_from_urls(client, urls): """Download and ingest files from given URLs.""" - ingested_files = [] - for url in urls: - filename = os.path.basename(urlparse(url).path) + files_to_ingest = [] + metadatas = [] + document_ids = [] + temp_files = [] + + try: + for url in urls: + filename = os.path.basename(urlparse(url).path) + is_pdf = filename.lower().endswith(".pdf") + + temp_file = tempfile.NamedTemporaryFile( + mode="wb" if is_pdf else "w+", + delete=False, + suffix=f"_{filename}", + ) + temp_files.append(temp_file) - with tempfile.NamedTemporaryFile( - mode="w+", delete=False, suffix=f"_{filename}" - ) as temp_file: response = requests.get(url) response.raise_for_status() - temp_file.write(response.text) - temp_file_path = temp_file.name + if is_pdf: + temp_file.write(response.content) + else: + temp_file.write(response.text) + temp_file.close() - try: - response = client.ingest_files([temp_file_path]) - click.echo( - f"File '{filename}' ingested successfully. Response: {response}" - ) - ingested_files.append(filename) - finally: - os.unlink(temp_file_path) + files_to_ingest.append(temp_file.name) + metadatas.append({"title": filename}) + document_ids.append(uuid.uuid5(uuid.NAMESPACE_DNS, url)) + + response = client.ingest_files( + files_to_ingest, metadatas=metadatas, document_ids=document_ids + ) - return ingested_files + return response["results"] + finally: + # Clean up temporary files + for temp_file in temp_files: + os.unlink(temp_file.name) @cli.command() @@ -106,10 +123,9 @@ def ingest_sample_file(client): sample_file_url = "https://raw.githubusercontent.com/SciPhi-AI/R2R/main/r2r/examples/data/aristotle.txt" with timer(): - ingested_files = ingest_files_from_urls(client, [sample_file_url]) - + response = ingest_files_from_urls(client, [sample_file_url]) click.echo( - f"Sample file ingestion completed. Ingested files: {', '.join(ingested_files)}" + f"Sample file ingestion completed. Ingest files response:\n\n{response}" ) @@ -120,10 +136,17 @@ def ingest_sample_files(client): urls = [ "https://raw.githubusercontent.com/SciPhi-AI/R2R/main/r2r/examples/data/aristotle.txt", "https://raw.githubusercontent.com/SciPhi-AI/R2R/main/r2r/examples/data/got.txt", + "https://raw.githubusercontent.com/SciPhi-AI/R2R/main/r2r/examples/data/pg_essay_1.html", + "https://raw.githubusercontent.com/SciPhi-AI/R2R/main/r2r/examples/data/pg_essay_2.html", + "https://raw.githubusercontent.com/SciPhi-AI/R2R/main/r2r/examples/data/pg_essay_3.html", + "https://raw.githubusercontent.com/SciPhi-AI/R2R/main/r2r/examples/data/pg_essay_4.html", + "https://raw.githubusercontent.com/SciPhi-AI/R2R/main/r2r/examples/data/pg_essay_5.html", + "https://raw.githubusercontent.com/SciPhi-AI/R2R/main/r2r/examples/data/lyft_2021.pdf", + "https://raw.githubusercontent.com/SciPhi-AI/R2R/main/r2r/examples/data/uber_2021.pdf", ] with timer(): - ingested_files = ingest_files_from_urls(client, urls) + response = ingest_files_from_urls(client, urls) click.echo( - f"Sample files ingestion completed. Ingested files: {', '.join(ingested_files)}" + f"Sample file ingestion completed. Ingest files response:\n\n{response}" ) diff --git a/py/core/base/abstractions/__init__.py b/py/core/base/abstractions/__init__.py index 74d043a72..34f64ad71 100644 --- a/py/core/base/abstractions/__init__.py +++ b/py/core/base/abstractions/__init__.py @@ -28,6 +28,7 @@ RAGCompletion, ) from .prompt import Prompt +from .restructure import KGEnrichmentSettings from .search import ( AggregateSearchResult, KGSearchResult, @@ -35,7 +36,6 @@ VectorSearchResult, VectorSearchSettings, ) -from .restructure import KGEnrichmentSettings from .user import Token, TokenData, UserStats from .vector import Vector, VectorEntry, VectorType diff --git a/py/core/base/providers/kg.py b/py/core/base/providers/kg.py index 310c37b92..4c44a037e 100644 --- a/py/core/base/providers/kg.py +++ b/py/core/base/providers/kg.py @@ -23,7 +23,9 @@ class KGConfig(ProviderConfig): kg_extraction_config: Optional[GenerationConfig] = None kg_search_config: Optional[GenerationConfig] = None kg_store_path: Optional[str] = None - kg_enrichment_settings: Optional[KGEnrichmentSettings] = KGEnrichmentSettings() + kg_enrichment_settings: Optional[KGEnrichmentSettings] = ( + KGEnrichmentSettings() + ) def validate(self) -> None: if self.provider not in self.supported_providers: diff --git a/py/core/main/api/routes/ingestion/base.py b/py/core/main/api/routes/ingestion/base.py index a7263cbb2..5e0998991 100644 --- a/py/core/main/api/routes/ingestion/base.py +++ b/py/core/main/api/routes/ingestion/base.py @@ -57,7 +57,7 @@ async def ingest_files_app( metadatas: Optional[Json[list[dict]]] = Form( None, description=ingest_files_descriptions.get("metadatas") ), - chunking_settings: Optional[ChunkingConfig] = Form( + chunking_settings: Optional[Json[ChunkingConfig]] = Form( None, description=ingest_files_descriptions.get("chunking_settings"), ), @@ -145,7 +145,7 @@ async def update_files_app( metadatas: Optional[Json[list[dict]]] = Form( None, description=ingest_files_descriptions.get("metadatas") ), - chunking_settings: Optional[ChunkingConfig] = Form( + chunking_settings: Optional[Json[ChunkingConfig]] = Form( None, description=ingest_files_descriptions.get("chunking_settings"), ), diff --git a/py/core/main/api/routes/restructure/base.py b/py/core/main/api/routes/restructure/base.py index de8b00c36..fe68c909b 100644 --- a/py/core/main/api/routes/restructure/base.py +++ b/py/core/main/api/routes/restructure/base.py @@ -1,9 +1,11 @@ +from typing import Union + from core.base import KGEnrichmentSettings from core.main.api.routes.base_router import BaseRouter from core.main.engine import R2REngine -from typing import Union from fastapi import Body, Depends + class RestructureRouter(BaseRouter): def __init__(self, engine: R2REngine): super().__init__(engine) diff --git a/py/core/main/services/restructure_service.py b/py/core/main/services/restructure_service.py index aff7f4a72..42bdbcfd1 100644 --- a/py/core/main/services/restructure_service.py +++ b/py/core/main/services/restructure_service.py @@ -32,7 +32,8 @@ def __init__( ) async def enrich_graph( - self, enrich_graph_settings: KGEnrichmentSettings = KGEnrichmentSettings() + self, + enrich_graph_settings: KGEnrichmentSettings = KGEnrichmentSettings(), ) -> Dict[str, Any]: """ Perform graph enrichment. diff --git a/py/core/pipes/kg/clustering.py b/py/core/pipes/kg/clustering.py index b80014006..53f3e4b13 100644 --- a/py/core/pipes/kg/clustering.py +++ b/py/core/pipes/kg/clustering.py @@ -17,12 +17,12 @@ CompletionProvider, EmbeddingProvider, GenerationConfig, + KGEnrichmentSettings, KGProvider, PipeType, PromptProvider, RunLoggingSingleton, Triple, - KGEnrichmentSettings, ) logger = logging.getLogger(__name__) @@ -80,7 +80,9 @@ def _compute_leiden_communities( raise ImportError("Please install the graspologic package.") from e async def cluster_kg( - self, triples: list[Triple], settings: KGEnrichmentSettings = KGEnrichmentSettings() + self, + triples: list[Triple], + settings: KGEnrichmentSettings = KGEnrichmentSettings(), ) -> list[Community]: """ Clusters the knowledge graph triples into communities using hierarchical Leiden algorithm. @@ -202,7 +204,9 @@ async def process_community(community_key, community): total_tasks = len(tasks) for i, completed_task in enumerate(asyncio.as_completed(tasks), 1): result = await completed_task - logger.info(f"Progress: {i}/{total_tasks} communities completed ({i/total_tasks*100:.2f}%)") + logger.info( + f"Progress: {i}/{total_tasks} communities completed ({i/total_tasks*100:.2f}%)" + ) yield result async def _run_logic( @@ -230,5 +234,7 @@ async def _run_logic( triples = self.kg_provider.get_triples() - async for community in self.cluster_kg(triples, self.kg_provider.config.kg_enrichment_settings): + async for community in self.cluster_kg( + triples, self.kg_provider.config.kg_enrichment_settings + ): yield community diff --git a/py/core/providers/database/vecs/collection.py b/py/core/providers/database/vecs/collection.py index e342ad49a..ccae50c00 100644 --- a/py/core/providers/database/vecs/collection.py +++ b/py/core/providers/database/vecs/collection.py @@ -24,10 +24,15 @@ from uuid import UUID, uuid4 import psycopg2 +import sqlalchemy as sa +from core.base import VectorSearchResult from core.base.abstractions import VectorSearchSettings from flupy import flu +from nltk.corpus import wordnet +from nltk.stem import SnowballStemmer from sqlalchemy import ( Column, + Index, MetaData, String, Table, @@ -373,16 +378,6 @@ def _create(self): """ ) ) - - # Create index on fts column - sess.execute( - text( - f""" - CREATE INDEX ix_fts_{unique_string} ON vecs."{self.table.name}" USING GIN (fts); - """ - ) - ) - return self def _drop(self): @@ -425,6 +420,7 @@ def upsert( "vec": record[5], "text": record[6], "metadata": record[7], + "fts": func.to_tsvector(record[6]), } for record in chunk ] @@ -439,6 +435,7 @@ def upsert( vec=stmt.excluded.vec, text=stmt.excluded.text, metadata=stmt.excluded.metadata, + fts=stmt.excluded.fts, ), ) sess.execute(stmt) @@ -647,6 +644,102 @@ def query( return [str(x) for x in sess.scalars(stmt).fetchall()] return sess.execute(stmt).fetchall() or [] + def full_text_search( + self, query_text: str, search_settings: VectorSearchSettings + ) -> List[VectorSearchResult]: + + stemmer = SnowballStemmer("english") + + def expand_query(query: str) -> str: + words = query.split() + expanded_words = set() + for word in words: + stemmed = stemmer.stem(word) + expanded_words.update([word, stemmed]) + for syn in wordnet.synsets(word): + for lemma in syn.lemmas(): + expanded_words.add(lemma.name()) + return " | ".join(expanded_words) + + expanded_query = expand_query(query_text) + ts_query = sa.func.to_tsquery("english", expanded_query) + + phrase_rank = ( + sa.func.ts_rank_cd( + sa.func.to_tsvector("english", self.table.c.text), + sa.func.phraseto_tsquery("english", query_text), + 32, + ) + * 2 + ) # Give higher weight to exact phrases + + partial_match_rank = sa.func.ts_rank_cd( + sa.func.to_tsvector("english", self.table.c.text), + sa.func.to_tsquery( + "english", + " & ".join(f"{word}:*" for word in query_text.split()), + ), + 32, + ) + + combined_rank = ( + phrase_rank + + partial_match_rank + + sa.func.ts_rank_cd( + sa.func.to_tsvector("english", self.table.c.text), ts_query, 32 + ) + * (sa.func.similarity(self.table.c.text, query_text) + 0.1) + ).label("rank") + + stmt = ( + sa.select( + self.table.c.fragment_id, + self.table.c.extraction_id, + self.table.c.document_id, + self.table.c.user_id, + self.table.c.group_ids, + self.table.c.text, + self.table.c.metadata, + combined_rank, + ) + .where( + sa.or_( + self.table.c.fts.op("@@")(ts_query), + sa.func.similarity(self.table.c.text, query_text) > 0.1, + self.table.c.fts.op("@@")( + sa.func.phraseto_tsquery("english", query_text) + ), + self.table.c.fts.op("@@")( + sa.func.to_tsquery( + "english", + " & ".join( + f"{word}:*" for word in query_text.split() + ), + ) + ), + ) + ) + .order_by(sa.desc("rank")) + .limit(search_settings.hybrid_search_settings.full_text_limit) + ) + + with self.client.Session() as sess: + results = sess.execute(stmt).fetchall() + + return [ + VectorSearchResult( + fragment_id=str(r.fragment_id), + extraction_id=str(r.extraction_id), + document_id=str(r.document_id), + user_id=str(r.user_id), + group_ids=r.group_ids, + text=r.text, + score=float(r.rank), + metadata=r.metadata, + ) + for r in results + ] + def build_filters(self, filters: Dict): """ PUBLIC @@ -1028,20 +1121,7 @@ def create_index( def _build_table(name: str, meta: MetaData, dimension: int) -> Table: - """ - PRIVATE - - Builds a SQLAlchemy model underpinning a `vecs.Collection`. - - Args: - name (str): The name of the table. - meta (MetaData): MetaData instance associated with the SQL database. - dimension: The dimension of the vectors in the collection. - - Returns: - Table: The constructed SQL table. - """ - return Table( + table = Table( name, meta, Column("fragment_id", postgresql.UUID, primary_key=True), @@ -1052,20 +1132,28 @@ def _build_table(name: str, meta: MetaData, dimension: int) -> Table: "group_ids", postgresql.ARRAY(postgresql.UUID), server_default="{}" ), Column("vec", Vector(dimension), nullable=False), + Column("text", postgresql.TEXT, nullable=True), Column( - "text", postgresql.TEXT, nullable=True - ), # New standalone text column + "fts", + postgresql.TSVECTOR, + nullable=False, + server_default=text("to_tsvector('english'::regconfig, '')"), + ), Column( "metadata", postgresql.JSONB, server_default=text("'{}'::jsonb"), nullable=False, ), - Column( - "fts", - postgresql.TSVECTOR, - server_default=text("to_tsvector('english', '')"), - nullable=False, - ), # New FTS column extend_existing=True, ) + + # Add GIN index for full-text search and trigram similarity + Index( + f"idx_{name}_fts_trgm", + table.c.fts, + table.c.text, + postgresql_using="gin", + postgresql_ops={"text": "gin_trgm_ops"}, # Remove gin_tsvector_ops + ) + return table diff --git a/py/core/providers/database/vector.py b/py/core/providers/database/vector.py index 0eec9a880..a40da4dca 100644 --- a/py/core/providers/database/vector.py +++ b/py/core/providers/database/vector.py @@ -125,9 +125,18 @@ def __init__(self, config: DatabaseConfig, *args, **kwargs): ) def _initialize_vector_db(self, dimension: int) -> None: + # Create extension for trigram similarity + with self.vx.Session() as sess: + sess.execute(text("CREATE EXTENSION IF NOT EXISTS pg_trgm;")) + sess.execute(text("CREATE EXTENSION IF NOT EXISTS btree_gin;")) + sess.commit() + self.collection = self.vx.get_or_create_collection( name=self.collection_name, dimension=dimension ) + self.collection.create_index(measure="cosine_distance") + self.collection.create_index(measure="l2_distance") + self.collection.create_index(measure="max_inner_product") def upsert(self, entry: VectorEntry) -> None: if self.collection is None: @@ -216,72 +225,69 @@ def full_text_search( raise ValueError( "Please call `initialize_collection` before attempting to run `full_text_search`." ) - from sqlalchemy import func, select - from sqlalchemy.sql.expression import or_ - - full_text_query = ( - select( - self.collection.table.c.fragment_id, - self.collection.table.c.extraction_id, - self.collection.table.c.document_id, - self.collection.table.c.user_id, - self.collection.table.c.group_ids, - self.collection.table.c.text, - self.collection.table.c.metadata, - func.ts_rank_cd( - func.to_tsvector("english", self.collection.table.c.text), - func.websearch_to_tsquery("english", query_text), - 1 | 2 | 4 | 8 | 16 | 32 | 64, - ).label("rank"), - func.ts_headline( - "english", - self.collection.table.c.text, - func.websearch_to_tsquery("english", query_text), - "StartSel = , StopSel = , MaxWords=35, MinWords=15", - ).label("headline"), - ) - .where( - or_( - func.to_tsvector( - "english", self.collection.table.c.text - ).op("@@")( - func.websearch_to_tsquery("english", query_text) - ), - func.similarity(self.collection.table.c.text, query_text) - > 0.3, - ) - ) - .order_by( - func.ts_rank_cd( - func.to_tsvector("english", self.collection.table.c.text), - func.websearch_to_tsquery("english", query_text), - 1 | 2 | 4 | 8 | 16 | 32 | 64, - ).desc() - ) - .limit(search_settings.hybrid_search_settings.full_text_limit) + results = self.collection.full_text_search( + query_text=query_text, search_settings=search_settings ) - - if search_settings.filters: - full_text_query = full_text_query.where( - self.collection.build_filters(search_settings.filters) - ) - - with self.vx.Session() as session: - results = session.execute(full_text_query).fetchall() - - return [ - VectorSearchResult( - fragment_id=result.fragment_id, - extraction_id=result.extraction_id, - document_id=result.document_id, - user_id=result.user_id, - group_ids=result.group_ids, - text=result.text, - score=float(result.rank), - metadata={**result.metadata, "headline": result.headline}, - ) - for result in results - ] + print("results = ", results) + return results + # from sqlalchemy import func, select + # from sqlalchemy.sql.expression import or_ + + # words = query_text.split() + # similarity_threshold = 0.3 # Adjust this value to control fuzziness + + # full_text_query = ( + # select( + # self.collection.table.c.fragment_id, + # self.collection.table.c.extraction_id, + # self.collection.table.c.document_id, + # self.collection.table.c.user_id, + # self.collection.table.c.group_ids, + # self.collection.table.c.text, + # self.collection.table.c.metadata, + # (func.ts_rank( + # func.to_tsvector('english', self.collection.table.c.text), + # func.plainto_tsquery('english', query_text), + # ) + + # func.similarity(self.collection.table.c.text, query_text)).label("rank"), + # func.ts_headline( + # 'english', + # self.collection.table.c.text, + # func.plainto_tsquery('english', query_text), + # "StartSel = , StopSel = , MaxWords=35, MinWords=15" + # ).label("headline"), + # ) + # .where( + # or_( + # func.to_tsvector('english', self.collection.table.c.text).op('@@')( + # func.plainto_tsquery('english', query_text) + # ), + # func.similarity(self.collection.table.c.text, query_text) > similarity_threshold + # ) + # ) + # .order_by(text("rank DESC")) + # .limit(search_settings.hybrid_search_settings.full_text_limit) + # ) + + # print(f"Full-text query: {full_text_query}") + + # with self.vx.Session() as session: + # results = session.execute(full_text_query).fetchall() + # print('results = ', results) + + # return [ + # VectorSearchResult( + # fragment_id=result.fragment_id, + # extraction_id=result.extraction_id, + # document_id=result.document_id, + # user_id=result.user_id, + # group_ids=result.group_ids, + # text=result.text, + # score=float(result.rank), + # metadata={**result.metadata, "headline": result.headline}, + # ) + # for result in results + # ] def hybrid_search( self, @@ -307,7 +313,6 @@ def hybrid_search( query_text, search_settings, ) - semantic_limit = search_settings.search_limit full_text_limit = ( search_settings.hybrid_search_settings.full_text_limit diff --git a/py/poetry.lock b/py/poetry.lock index c350d9ac9..9d2e98341 100644 --- a/py/poetry.lock +++ b/py/poetry.lock @@ -1694,7 +1694,7 @@ files = [ name = "joblib" version = "1.4.2" description = "Lightweight pipelining with Python functions" -optional = true +optional = false python-versions = ">=3.8" files = [ {file = "joblib-1.4.2-py3-none-any.whl", hash = "sha256:06d478d5674cbc267e7496a410ee875abd68e4340feff4490bcb7afb88060ae6"}, @@ -1851,13 +1851,13 @@ files = [ [[package]] name = "litellm" -version = "1.43.19" +version = "1.44.1" description = "Library to easily interface with LLM API providers" optional = true python-versions = "!=2.7.*,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,!=3.7.*,>=3.8" files = [ - {file = "litellm-1.43.19-py3-none-any.whl", hash = "sha256:f66bfe9c8b91577af57a5d1203728abc9b59df38a545148b7e85dec903185c12"}, - {file = "litellm-1.43.19.tar.gz", hash = "sha256:b1f475f98073632f0cea6d814bb10b14b6498e5ff93b91b52dfc00445bf013ab"}, + {file = "litellm-1.44.1-py3-none-any.whl", hash = "sha256:6367cfafbdd5d6a5125cefd21375df89f0b8a0d77044616cd88462be77d05564"}, + {file = "litellm-1.44.1.tar.gz", hash = "sha256:b9013df8b255335a08df1e9e7ac589dab97b7fe8adb0c614e2ef4b65adcc33fb"}, ] [package.dependencies] @@ -2463,6 +2463,31 @@ doc = ["nb2plots (>=0.7)", "nbconvert (<7.9)", "numpydoc (>=1.6)", "pillow (>=9. extra = ["lxml (>=4.6)", "pydot (>=1.4.2)", "pygraphviz (>=1.11)", "sympy (>=1.10)"] test = ["pytest (>=7.2)", "pytest-cov (>=4.0)"] +[[package]] +name = "nltk" +version = "3.9.1" +description = "Natural Language Toolkit" +optional = false +python-versions = ">=3.8" +files = [ + {file = "nltk-3.9.1-py3-none-any.whl", hash = "sha256:4fa26829c5b00715afe3061398a8989dc643b92ce7dd93fb4585a70930d168a1"}, + {file = "nltk-3.9.1.tar.gz", hash = "sha256:87d127bd3de4bd89a4f81265e5fa59cb1b199b27440175370f7417d2bc7ae868"}, +] + +[package.dependencies] +click = "*" +joblib = "*" +regex = ">=2021.8.3" +tqdm = "*" + +[package.extras] +all = ["matplotlib", "numpy", "pyparsing", "python-crfsuite", "requests", "scikit-learn", "scipy", "twython"] +corenlp = ["requests"] +machine-learning = ["numpy", "python-crfsuite", "scikit-learn", "scipy"] +plot = ["matplotlib"] +tgrep = ["pyparsing"] +twitter = ["twython"] + [[package]] name = "nodeenv" version = "1.9.1" @@ -2610,11 +2635,11 @@ files = [ [package.dependencies] numpy = [ {version = ">=1.21.0", markers = "python_version == \"3.9\" and platform_system == \"Darwin\" and platform_machine == \"arm64\""}, + {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, + {version = ">=1.23.5", markers = "python_version >= \"3.11\" and python_version < \"3.12\""}, {version = ">=1.21.4", markers = "python_version >= \"3.10\" and platform_system == \"Darwin\" and python_version < \"3.11\""}, {version = ">=1.21.2", markers = "platform_system != \"Darwin\" and python_version >= \"3.10\" and python_version < \"3.11\""}, {version = ">=1.19.3", markers = "platform_system == \"Linux\" and platform_machine == \"aarch64\" and python_version >= \"3.8\" and python_version < \"3.10\" or python_version > \"3.9\" and python_version < \"3.10\" or python_version >= \"3.9\" and platform_system != \"Darwin\" and python_version < \"3.10\" or python_version >= \"3.9\" and platform_machine != \"arm64\" and python_version < \"3.10\""}, - {version = ">=1.23.5", markers = "python_version >= \"3.11\" and python_version < \"3.12\""}, - {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, ] [[package]] @@ -2697,8 +2722,8 @@ files = [ [package.dependencies] numpy = [ {version = ">=1.22.4", markers = "python_version < \"3.11\""}, - {version = ">=1.23.2", markers = "python_version == \"3.11\""}, {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, + {version = ">=1.23.2", markers = "python_version == \"3.11\""}, ] python-dateutil = ">=2.8.2" pytz = ">=2020.1" @@ -2935,13 +2960,13 @@ dev = ["Click (>=7.0)", "Sphinx (>=2.2.1)"] [[package]] name = "posthog" -version = "3.5.0" +version = "3.5.2" description = "Integrate PostHog into any python application." optional = true python-versions = "*" files = [ - {file = "posthog-3.5.0-py2.py3-none-any.whl", hash = "sha256:3c672be7ba6f95d555ea207d4486c171d06657eb34b3ce25eb043bfe7b6b5b76"}, - {file = "posthog-3.5.0.tar.gz", hash = "sha256:8f7e3b2c6e8714d0c0c542a2109b83a7549f63b7113a133ab2763a89245ef2ef"}, + {file = "posthog-3.5.2-py2.py3-none-any.whl", hash = "sha256:605b3d92369971cc99290b1fcc8534cbddac3726ef7972caa993454a5ecfb644"}, + {file = "posthog-3.5.2.tar.gz", hash = "sha256:a383a80c1f47e0243f5ce359e81e06e2e7b37eb39d1d6f8d01c3e64ed29df2ee"}, ] [package.dependencies] @@ -3647,7 +3672,7 @@ rpds-py = ">=0.7.0" name = "regex" version = "2024.7.24" description = "Alternative regular expression module, to replace re." -optional = true +optional = false python-versions = ">=3.8" files = [ {file = "regex-2024.7.24-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:228b0d3f567fafa0633aee87f08b9276c7062da9616931382993c03808bb68ce"}, @@ -4785,4 +4810,4 @@ core-ingest-movies = ["moviepy", "opencv-python"] [metadata] lock-version = "2.0" python-versions = ">=3.9,<3.13" -content-hash = "34b93bcd771abd4c1eb4f3ffb79f36a716835e721e46cd0767007201abf6d806" +content-hash = "32a72ff508ce34d83088f25d824aabf7134d70c56332bae6bc495b0bcafa84ec" diff --git a/py/pyproject.toml b/py/pyproject.toml index e0900d5ea..1b7816148 100644 --- a/py/pyproject.toml +++ b/py/pyproject.toml @@ -62,6 +62,7 @@ poppler-utils = { version = "^0.1.0", optional = true } psutil = { version = "^6.0.0", optional = true } deepdiff = { version = "^7.0.1", optional = true } graspologic = { version = "^3.4.1", optional = true } +nltk = "^3.9.1" [tool.poetry.extras] core = [ @@ -87,9 +88,6 @@ pytest-mock = "^3.14.0" pytest-cov = "^5.0.0" colorama = "^0.4.6" -[tool.poetry.scripts] -r2r = "cli.cli:main" - [tool.black] line-length = 79 target-version = ['py39'] @@ -116,6 +114,10 @@ exclude = 'playground/.*|deprecated/.*|dump/.*|docs/source|vecs/*' module = "yaml" ignore_missing_imports = true +[tool.poetry.scripts] +r2r = "cli.cli:main" +download-nltk-data = "scripts.download_nltk_data:download_nltk_data" + [tool.pytest.ini_options] asyncio_mode = "auto" addopts = "--cov=r2r --cov-report=term-missing --cov-report=xml" @@ -126,3 +128,4 @@ filterwarnings = [ "ignore::DeprecationWarning", "ignore::pytest.PytestUnraisableExceptionWarning", ] + diff --git a/py/sdk/ingestion.py b/py/sdk/ingestion.py index edacb807c..48037973e 100644 --- a/py/sdk/ingestion.py +++ b/py/sdk/ingestion.py @@ -99,7 +99,7 @@ async def ingest_files( async def update_files( client, file_paths: list[str], - document_ids: Optional[list[str]] = None, + document_ids: Optional[list[Union[str, UUID]]] = None, metadatas: Optional[list[dict]] = None, chunking_settings: Optional[Union[dict, ChunkingConfig]] = None, ) -> dict: @@ -139,7 +139,9 @@ async def update_files( data = {} if document_ids: - data["document_ids"] = json.dumps(document_ids) + data["document_ids"] = json.dumps( + [str(doc_id) for doc_id in document_ids] + ) if metadatas: data["metadatas"] = json.dumps(metadatas) if chunking_settings: diff --git a/py/sdk/models.py b/py/sdk/models.py index 22ded990f..8dd86cf71 100644 --- a/py/sdk/models.py +++ b/py/sdk/models.py @@ -237,7 +237,8 @@ def model_dump(self, *args, **kwargs): str(uuid) for uuid in dump["selected_group_ids"] ] return dump - + + class KGEnrichmentSettings(BaseModel): max_knowledge_triples: int = Field( default=100, @@ -252,9 +253,11 @@ class KGEnrichmentSettings(BaseModel): description="The parameters for the Leiden algorithm.", ) + class KGEnrichmentResponse(BaseModel): enriched_content: Dict[str, Any] + class UserResponse(BaseModel): id: UUID email: str diff --git a/py/sdk/restructure.py b/py/sdk/restructure.py index ca93edc2b..fd3df0ebf 100644 --- a/py/sdk/restructure.py +++ b/py/sdk/restructure.py @@ -1,12 +1,15 @@ from typing import Any, Dict, List, Optional, Union from core.base import Document -from .models import KGEnrichmentSettings, KGEnrichmentResponse + +from .models import KGEnrichmentResponse, KGEnrichmentSettings + class RestructureMethods: @staticmethod async def enrich_graph( - client, KGEnrichmentSettings: KGEnrichmentSettings = KGEnrichmentSettings() + client, + KGEnrichmentSettings: KGEnrichmentSettings = KGEnrichmentSettings(), ) -> KGEnrichmentResponse: """ Perform graph enrichment over the entire graph. diff --git a/py/setup.py b/py/setup.py new file mode 100644 index 000000000..e3ddf044d --- /dev/null +++ b/py/setup.py @@ -0,0 +1,17 @@ +import nltk +from setuptools import setup + +def download_nltk_data(): + nltk.download('wordnet', quiet=True) + +setup( + name='r2r', + version='0.3.0', + setup_requires=['nltk'], + cmdclass={ + 'install': lambda _: download_nltk_data(), + }, +) + +if __name__ == '__main__': + download_nltk_data() diff --git a/py/tests/regression/test_cases/test_document_management.py b/py/tests/regression/test_cases/test_document_management.py index 67fadf64f..bf3a5ff19 100644 --- a/py/tests/regression/test_cases/test_document_management.py +++ b/py/tests/regression/test_cases/test_document_management.py @@ -1,7 +1,6 @@ import os from core import R2RException - from tests.regression.test_cases.base import BaseTest diff --git a/py/tests/test_cli.py b/py/tests/test_cli.py new file mode 100644 index 000000000..cedd40a71 --- /dev/null +++ b/py/tests/test_cli.py @@ -0,0 +1,330 @@ +from unittest.mock import patch + +import click +import pytest +from cli.cli import cli +from cli.utils.param_types import JSON +from click.testing import CliRunner + + +@pytest.fixture +def runner(): + return CliRunner() + + +@pytest.fixture +def mock_r2r_execution_wrapper(): + # with patch("cli.command_group.R2RExecutionWrapper") as mock: + # yield mock + pass + + +def test_cli_group(runner): + result = runner.invoke(cli, ["--help"]) + assert result.exit_code == 0 + assert "R2R CLI for all core operations." in result.output + + +def test_generate_private_key(runner): + result = runner.invoke(cli, ["generate-private-key"]) + assert result.exit_code == 0 + assert "Generated Private Key:" in result.output + assert ( + "Keep this key secure and use it as your R2R_SECRET_KEY." + in result.output + ) + + +def test_delete_command(runner, mock_r2r_execution_wrapper): + mock_instance = mock_r2r_execution_wrapper.return_value + mock_instance.delete.return_value = "Deleted successfully" + + result = runner.invoke(cli, ["delete", "--filter", "key1:eq:value1"]) + assert result.exit_code == 0 + assert "Deleted successfully" in result.output + mock_instance.delete.assert_called_once_with( + filters={"key1": {"$eq": "value1"}} + ) + + +def test_multiple_deletes(runner, mock_r2r_execution_wrapper): + mock_instance = mock_r2r_execution_wrapper.return_value + mock_instance.delete.return_value = "Deleted successfully" + + result = runner.invoke( + cli, + ["delete", "--filter", "key1:eq:value1", "--filter", "key2:eq:value2"], + ) + assert result.exit_code == 0 + assert "Deleted successfully" in result.output + mock_instance.delete.assert_called_once_with( + filters={"key1": {"$eq": "value1"}, "key2": {"$eq": "value2"}} + ) + + +def test_documents_overview(runner, mock_r2r_execution_wrapper): + mock_instance = mock_r2r_execution_wrapper.return_value + mock_instance.documents_overview.return_value = [ + "Document 1", + "Document 2", + ] + + result = runner.invoke( + cli, + [ + "documents-overview", + "--document-ids", + "id1", + "--document-ids", + "id2", + ], + ) + assert result.exit_code == 0 + assert "Document 1" in result.output + assert "Document 2" in result.output + mock_instance.documents_overview.assert_called_once_with(["id1", "id2"]) + + +def test_document_chunks(runner, mock_r2r_execution_wrapper): + mock_instance = mock_r2r_execution_wrapper.return_value + mock_instance.document_chunks.return_value = ["Chunk 1", "Chunk 2"] + + result = runner.invoke(cli, ["document-chunks", "doc_id"]) + assert result.exit_code == 0 + assert "Chunk 1" in result.output + assert "Chunk 2" in result.output + mock_instance.document_chunks.assert_called_once_with("doc_id") + + +def test_ingest_files(runner, mock_r2r_execution_wrapper): + mock_instance = mock_r2r_execution_wrapper.return_value + mock_instance.ingest_files.return_value = "Files ingested successfully" + + result = runner.invoke( + cli, + [ + "ingest-files", + "--file-paths", + "file1.txt", + "--file-paths", + "file2.txt", + "--document-ids", + "id1", + "--document-ids", + "id2", + ], + ) + assert result.exit_code == 0 + assert "Files ingested successfully" in result.output + mock_instance.ingest_files.assert_called_once_with( + ["file1.txt", "file2.txt"], ["id1", "id2"], None, None + ) + + +def test_ingest_sample_file(runner, mock_r2r_execution_wrapper): + mock_instance = mock_r2r_execution_wrapper.return_value + mock_instance.ingest_sample_file.return_value = "Sample file ingested" + + result = runner.invoke( + cli, ["ingest-sample-file", "--no-media", "--option", "1"] + ) + print(f"Output: {result.output}") + assert result.exit_code == 0 + assert "Sample file ingested" in result.output + mock_instance.ingest_sample_file.assert_called_once_with( + no_media=True, option=1 + ) + + +def test_update_files(runner, mock_r2r_execution_wrapper): + mock_instance = mock_r2r_execution_wrapper.return_value + mock_instance.update_files.return_value = "Files updated successfully" + + result = runner.invoke( + cli, + [ + "update-files", + "file1.txt", + "--document-ids", + "id1", + "--metadatas", + '{"key": "value"}', + ], + ) + assert result.exit_code == 0 + assert "Files updated successfully" in result.output + mock_instance.update_files.assert_called_once_with( + ["file1.txt"], ["id1"], ['{"key": "value"}'] + ) + + +def test_analytics(runner, mock_r2r_execution_wrapper): + mock_instance = mock_r2r_execution_wrapper.return_value + mock_instance.analytics.return_value = {"data": "analytics data"} + + result = runner.invoke( + cli, + [ + "analytics", + "--filters", + '{"date": "2023-01-01"}', + "--analysis-types", + '{"type": "usage"}', + ], + ) + assert result.exit_code == 0 + assert "{'data': 'analytics data'}" in result.output + mock_instance.analytics.assert_called_once_with( + {"date": "2023-01-01"}, {"type": "usage"} + ) + + +def test_app_settings(runner, mock_r2r_execution_wrapper): + mock_instance = mock_r2r_execution_wrapper.return_value + mock_instance.app_settings.return_value = {"setting1": "value1"} + + result = runner.invoke(cli, ["app-settings"]) + assert result.exit_code == 0 + assert "{'setting1': 'value1'}" in result.output + mock_instance.app_settings.assert_called_once() + + +def test_logs(runner, mock_r2r_execution_wrapper): + mock_instance = mock_r2r_execution_wrapper.return_value + mock_instance.logs.return_value = [ + { + "run_id": "test-run-id", + "run_type": "test", + "timestamp": "2024-08-05T20:00:00", + "user_id": "test-user-id", + "entries": [{"key": "test-key", "value": "test-value"}], + } + ] + + result = runner.invoke(cli, ["logs", "--run-type-filter", "error"]) + assert result.exit_code == 0 + assert "Run ID: test-run-id" in result.output + assert "Run Type: test" in result.output + assert "Timestamp: 2024-08-05T20:00:00" in result.output + assert "User ID: test-user-id" in result.output + assert "Entries:" in result.output + assert " - test-key: test-value" in result.output + assert "Total runs: 1" in result.output + + +def test_users_overview(runner, mock_r2r_execution_wrapper): + mock_instance = mock_r2r_execution_wrapper.return_value + mock_instance.users_overview.return_value = ["User 1", "User 2"] + + result = runner.invoke( + cli, + [ + "users-overview", + "--user-ids", + "123e4567-e89b-12d3-a456-426614174000", + ], + ) + assert result.exit_code == 0 + assert "User 1" in result.output + assert "User 2" in result.output + mock_instance.users_overview.assert_called_once() + + +def test_json_param_type(): + result = JSON.convert('{"key": "value"}', param=None, ctx=None) + assert result == {"key": "value"} + + with pytest.raises(click.BadParameter): + JSON.convert("invalid json", param=None, ctx=None) + + result = JSON.convert({"key": "value"}, param=None, ctx=None) + assert result == {"key": "value"} + + +def test_docker_down_command(runner): + with ( + patch( + "cli.commands.server_operations.bring_down_docker_compose" + ) as mock_bring_down, + patch( + "cli.commands.server_operations.remove_r2r_network" + ) as mock_remove_network, + ): + + mock_bring_down.return_value = 0 + result = runner.invoke(cli, ["docker-down"]) + assert result.exit_code == 0 + assert ( + "Docker Compose setup has been successfully brought down." + in result.output + ) + mock_bring_down.assert_called_once() + mock_remove_network.assert_called_once() + + # legacy code + # mock_bring_down.return_value = 1 + # result = runner.invoke(cli, ["docker-down"]) + # assert result.exit_code == 0 + # assert ( + # "An error occurred while bringing down the Docker Compose setup." + # in result.output + # ) + # mock_remove_network.assert_called_once() + + +def test_generate_report_command(): + runner = CliRunner() + with ( + patch("subprocess.check_output") as mock_check_output, + patch("platform.system") as mock_system, + patch("platform.release") as mock_release, + patch("platform.version") as mock_version, + patch("platform.machine") as mock_machine, + patch("platform.processor") as mock_processor, + ): + + mock_check_output.side_effect = [ + "container1\tname1\tUp 2 hours\n", + "network1\tnetwork_name1\n", + "172.17.0.0/16\n", + ] + mock_system.return_value = "Linux" + mock_release.return_value = "5.4.0" + mock_version.return_value = "#1 SMP Thu Jun 18 12:34:56 UTC 2020" + mock_machine.return_value = "x86_64" + mock_processor.return_value = "x86_64" + + result = runner.invoke(cli, ["generate-report"]) + assert result.exit_code == 0 + assert "System Report:" in result.output + assert "r2r_version" in result.output + assert "docker_ps" in result.output + assert "docker_subnets" in result.output + assert "os_info" in result.output + + +def test_health_command(runner, mock_r2r_execution_wrapper): + mock_instance = mock_r2r_execution_wrapper.return_value + mock_instance.health.return_value = "Server is healthy" + + result = runner.invoke(cli, ["health"]) + assert result.exit_code == 0 + assert "Server is healthy" in result.output + mock_instance.health.assert_called_once() + + +def test_update_command(runner): + with patch("subprocess.run") as mock_run: + mock_run.return_value.stdout = "Successfully updated R2R" + result = runner.invoke(cli, ["update"]) + assert result.exit_code == 0 + assert "Successfully updated R2R" in result.output + assert "R2R has been successfully updated." in result.output + + +def test_version_command(runner): + with patch("importlib.metadata.version") as mock_version: + mock_version.return_value = "1.0.0" + result = runner.invoke(cli, ["version"]) + assert result.exit_code == 0 + assert "1.0.0" in result.output diff --git a/tests/test_client.py b/tests/test_client.py deleted file mode 100644 index 90f172690..000000000 --- a/tests/test_client.py +++ /dev/null @@ -1,371 +0,0 @@ -import uuid -from datetime import datetime -from unittest.mock import MagicMock - -import pytest -from core import ( - DocumentInfo, - R2RApp, - R2RBuilder, - R2REngine, - R2RException, - Token, - UserResponse, -) -from fastapi import Body, Depends -from fastapi.security import OAuth2PasswordBearer -from fastapi.testclient import TestClient - -# TODO: need to import this from the package, not from the local directory -from sdk.client import R2RClient - -oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") - - -def create_user(email: str, password: str): - return UserResponse( - id=uuid.UUID("12345678-1234-5678-1234-567812345678"), - email=email, - hashed_password=f"hashed_{password}", - is_active=True, - is_superuser=False, - is_verified=False, - name="Test User", - bio="Test Bio", - profile_picture="http://example.com/pic.jpg", - created_at=datetime.now(datetime.UTC), - updated_at=datetime.now(datetime.UTC), - ) - - -@pytest.fixture(scope="function") -def mock_auth_wrapper(): - def auth_wrapper(token: str = Depends(oauth2_scheme)): - return UserResponse( - id=uuid.UUID("12345678-1234-5678-1234-567812345678"), - email="test@example.com", - is_active=True, - hashed_password="xxx", - is_superuser=False, - ) - - return auth_wrapper - - -@pytest.fixture(scope="function") -def mock_auth_wrapper(): - def auth_wrapper(token: str = Depends(oauth2_scheme)): - return UserResponse( - id=uuid.UUID("12345678-1234-5678-1234-567812345678"), - email="test@example.com", - is_active=True, - hashed_password="xxx", - is_superuser=True, - ) - - return auth_wrapper - - -@pytest.fixture(scope="function") -def mock_super_auth_wrapper(): - def auth_wrapper(token: str = Depends(oauth2_scheme)): - return UserResponse( - id=uuid.UUID("12345678-1234-5678-1234-567812345678"), - email="test@example.com", - is_active=True, - hashed_password="xxx", - is_superuser=True, - ) - - return auth_wrapper - - -@pytest.fixture(scope="function") -def mock_db(): - db = MagicMock() - db.relational.get_user_by_email.return_value = None # Simulate empty database - - db.relational.create_user.side_effect = create_user - db.relational.get_user_by_id.return_value = create_user( - email="test@example.com", password="password" - ) - - def update_user(user): - updated_user = create_user(email=user.email, password="password") - updated_user.name = user.name - updated_user.bio = user.bio - updated_user.profile_picture = user.profile_picture - return updated_user - - db.relational.update_user.side_effect = update_user - db.relational.get_documents_in_group.return_value = [ - DocumentInfo( - user_id=uuid.uuid4(), - id=uuid.uuid4(), - title=f"Document {i}", - type="txt", - group_ids=[uuid.uuid4()], - created_at=datetime.now(datetime.UTC), - updated_at=datetime.now(datetime.UTC), - version="1", - metadata={}, - size_in_bytes=1000, - ) - for i in range(100) - ] - - return db - - -async def mock_asearch(*args, **kwargs): - return { - "vector_search_results": [ - { - "fragment_id": "c68dc72e-fc23-5452-8f49-d7bd46088a96", - "extraction_id": "3f3d47f3-8baf-58eb-8bc2-0171fb1c6e09", - "document_id": "3e157b3a-8469-51db-90d9-52e7d896b49b", - "user_id": "2acb499e-8428-543b-bd85-0d9098718220", - "group_ids": [], - "score": 0.23943702876567796, - "text": "Alternate Base Rate means, for any day, a rate per annum equal to the greatest of (i) the Prime Rate in effect on such day, (ii) the Federal Funds Effective Rate in effect on such day \nplus \u00bd of 1% and (iii) the sum of (a) the Adjusted LIBO Rate that would be payable onsuch day for a Eurodollar Borrowing with a one-month interest period", - "metadata": { - "title": "uber_2021.pdf", - "associatedQuery": "What is the capital of France?", - }, - }, - { - "fragment_id": "f0b40c99-e200-507b-a4b9-e931e0b5f321", - "extraction_id": "0348ae71-bccb-58d1-8b5f-36810e46245a", - "document_id": "3e157b3a-8469-51db-90d9-52e7d896b49b", - "user_id": "2acb499e-8428-543b-bd85-0d9098718220", - "group_ids": [], - "score": 0.22033508121967305, - "text": "s, could also restrict our future access to the capital markets.ITEM 1B. UNRESOLVED STAFF\n COMMENTSNot applicable.\nITEM 2. PROPERTIES\nAs\n of December 31, 2021, we leased and owned office facilities around the world totaling 10.6 million square feet, including 2.6 million square feet for ourcorporate headquarte\nrs in the San Francisco Bay Area, California.We", - "metadata": { - "title": "uber_2021.pdf", - "associatedQuery": "What is the capital of France?", - }, - }, - { - "fragment_id": "967c4291-0629-55b6-9323-e2291de8730d", - "extraction_id": "7595cdf2-d1b0-5f13-b853-8ce6857ca5f5", - "document_id": "3e157b3a-8469-51db-90d9-52e7d896b49b", - "user_id": "2acb499e-8428-543b-bd85-0d9098718220", - "group_ids": [], - "score": 0.21763332188129403, - "text": "RFR means, for any RFR Loan denominated in (a) British Pounds, SONIA and (b) Swiss Francs, SARON. \nRFR Borrowing means, as to any Borrowing, the RFR Loans comprising such Borrowing. \nRFR Business Day means, for any Loan denominated in (a) British Pounds, any day except for (i) a Saturday, (ii) a Sunday or (iii) a day on which banks are closed for general business in London and (b) Swiss Francs, any day except for (i) a Saturday, (ii) a Sunday or", - "metadata": { - "title": "uber_2021.pdf", - "associatedQuery": "What is the capital of France?", - }, - }, - ] - } - - -@pytest.fixture(scope="function") -def app_client(mock_db, mock_auth_wrapper): - config = R2RBuilder._get_config("auth") - providers = MagicMock() - providers.auth.login.return_value = { - "access_token": Token(token="access_token", token_type="access"), - "refresh_token": Token(token="refresh_token", token_type="refresh"), - } - providers.auth.auth_wrapper = mock_auth_wrapper - providers.auth.register.side_effect = mock_db.relational.create_user - providers.auth.verify_email.return_value = { - "message": "Email verified successfully" - } - providers.auth.change_password.return_value = { - "message": "Password changed successfully" - } - providers.auth.request_password_reset.return_value = { - "message": "If the email exists, a reset link has been sent" - } - providers.auth.confirm_password_reset.return_value = { - "message": "Password reset successfully" - } - providers.auth.logout.return_value = {"message": "Logged out successfully"} - - providers.database = mock_db - pipelines = MagicMock() - agents = MagicMock() - engine = R2REngine( - config=config, - providers=providers, - pipelines=pipelines, - agents=agents, - ) - engine.asearch = mock_asearch - app = R2RApp(engine) - return TestClient(app.app) - - -@pytest.fixture(scope="function") -def r2r_client(app_client): - return R2RClient(base_url="http://testserver", custom_client=app_client) - - -def test_health_check(r2r_client): - response = r2r_client.health() - assert response["results"] == {"response": "ok"} - - -def test_register_user(r2r_client, mock_db): - user_data = {"email": "test@example.com", "password": "testpassword"} - response = r2r_client.register(**user_data) - assert "results" in response - assert response["results"]["email"] == user_data["email"] - assert "id" in response["results"] - assert "hashed_password" in response["results"] - mock_db.relational.create_user.assert_called_once() - - -def test_login_user(r2r_client, mock_db): - user_data = {"email": "login_test@example.com", "password": "testpassword"} - mock_db.relational.get_user_by_email.return_value = None - response = r2r_client.register(**user_data) - - mock_db.relational.get_user_by_email.return_value = UserResponse( - id=uuid.UUID("12345678-1234-5678-1234-567812345678"), - email=user_data["email"], - hashed_password="hashed_" + user_data["password"], - is_active=True, - is_superuser=False, - verification_code_expiry=None, - ) - response = r2r_client.login(**user_data) - assert "results" in response - assert "access_token" in response["results"] - assert "refresh_token" in response["results"] - - -def test_authenticated_search(r2r_client, mock_db): - # Register and login - user_data = { - "email": "search_test@example.com", - "password": "testpassword", - } - r2r_client.register(**user_data) - login_response = r2r_client.login(**user_data) - - # Perform search - search_query = "test query" - search_response = r2r_client.search(search_query) - results = search_response["results"] - assert "vector_search_results" in results - assert len(results["vector_search_results"]) > 0 - assert ( - results["vector_search_results"][0]["fragment_id"] - == "c68dc72e-fc23-5452-8f49-d7bd46088a96" - ) - assert ( - results["vector_search_results"][0]["text"] - == "Alternate Base Rate means, for any day, a rate per annum equal to the greatest of (i) the Prime Rate in effect on such day, (ii) the Federal Funds Effective Rate in effect on such day \nplus \u00bd of 1% and (iii) the sum of (a) the Adjusted LIBO Rate that would be payable onsuch day for a Eurodollar Borrowing with a one-month interest period" - ) - assert results["vector_search_results"][0]["score"] == 0.23943702876567796 - - -@pytest.mark.asyncio -async def test_change_password(r2r_client, mock_db): - # Register and login - user_data = { - "email": "change_pass@example.com", - "password": "old_password", - } - r2r_client.register(**user_data) - r2r_client.login(**user_data) - - # Change password - response = r2r_client.change_password("old_password", "new_password") - print("response = ", response) - assert response["results"]["message"] == "Password changed successfully" - - # Try logging in with new password - login_response = r2r_client.login( - email="change_pass@example.com", password="new_password" - ) - assert "access_token" in login_response["results"] - - -@pytest.mark.asyncio -async def test_password_reset_flow(r2r_client, mock_db): - # Register a user - user_data = {"email": "reset_pass@example.com", "password": "old_password"} - r2r_client.register(**user_data) - - # Request password reset - reset_response = r2r_client.request_password_reset("reset_pass@example.com") - print("reset_response = ", reset_response) - assert "message" in reset_response["results"] - - # Confirm password reset (we'll need to mock the reset token) - mock_reset_token = "mock_reset_token" - confirm_response = r2r_client.confirm_password_reset( - mock_reset_token, "new_password" - ) - assert confirm_response["results"]["message"] == "Password reset successfully" - - # Try logging in with new password - login_response = r2r_client.login( - email="reset_pass@example.com", password="new_password" - ) - assert "access_token" in login_response["results"] - - -@pytest.mark.asyncio -async def test_logout(r2r_client, mock_db): - # Register and login - user_data = {"email": "logout@example.com", "password": "password123"} - r2r_client.register(**user_data) - r2r_client.login(**user_data) - - # Logout - logout_response = r2r_client.logout() - assert logout_response["results"]["message"] == "Logged out successfully" - - # Ensure client's tokens are cleared - assert r2r_client.access_token is None - assert r2r_client._refresh_token is None - - -@pytest.mark.asyncio -async def test_user_profile(r2r_client, mock_db): - # Register and login - user_data = {"email": "profile@example.com", "password": "password123"} - r2r_client.register(**user_data) - r2r_client.login(**user_data) - - # Get user profile - # mock_db.relational.get_user_by_id.return_value = create_user( - # UserCreate(email="profile@example.com", password="password") - # ) - # profile = r2r_client.user() - - # assert profile["results"]["email"] == "profile@example.com" - - # Update user profile - updated_profile = r2r_client.update_user(name="John Doe", bio="Test bio") - assert updated_profile["results"]["name"] == "John Doe" - assert updated_profile["results"]["bio"] == "Test bio" - - -@pytest.mark.asyncio -async def test_get_documents_in_group(r2r_client, mock_db): - # Register and login as a superuser - user_data = {"email": "superuser@example.com", "password": "password123"} - r2r_client.register(**user_data) - - # Set the mock user as a superuser - # mock_db.relational.get_user_by_email.return_value.is_superuser = True - - r2r_client.login(**user_data) - - # Get documents in group - group_id = uuid.uuid4() - response = r2r_client.get_documents_in_group(group_id) - - assert "results" in response - assert len(response["results"]) == 100 # Default limit - assert response["results"][0]["title"] == "Document 0" - assert response["results"][0]["type"] == "txt" From 46022160acdf70c24ca4f56b0c3a9baebff971c8 Mon Sep 17 00:00:00 2001 From: emrgnt-cmplxty <68796651+emrgnt-cmplxty@users.noreply.github.com> Date: Wed, 21 Aug 2024 13:23:31 -0700 Subject: [PATCH 32/74] add script (#918) --- py/scripts/download_nltk_data.py | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 py/scripts/download_nltk_data.py diff --git a/py/scripts/download_nltk_data.py b/py/scripts/download_nltk_data.py new file mode 100644 index 000000000..c4adbcfc5 --- /dev/null +++ b/py/scripts/download_nltk_data.py @@ -0,0 +1,7 @@ +import nltk + +def download_nltk_data(): + nltk.download('wordnet', quiet=True) + +if __name__ == "__main__": + download_nltk_data() From 19e424b692e8e535795633fe4dea8fe92c549b09 Mon Sep 17 00:00:00 2001 From: Nolan Tremelling <34580718+NolanTrem@users.noreply.github.com> Date: Wed, 21 Aug 2024 14:44:50 -0700 Subject: [PATCH 33/74] Fix bug in document chunks (#921) --- .../r2rClientIntegrationSuperUser.test.ts | 76 +- js/sdk/package-lock.json | 75 +- js/sdk/package.json | 1 + js/sdk/pnpm-lock.yaml | 3056 ++++++----------- js/sdk/src/r2rClient.ts | 15 +- py/cli/commands/management.py | 9 +- py/core/providers/database/vector.py | 22 +- 7 files changed, 1167 insertions(+), 2087 deletions(-) diff --git a/js/sdk/__tests__/r2rClientIntegrationSuperUser.test.ts b/js/sdk/__tests__/r2rClientIntegrationSuperUser.test.ts index 2deed26f1..f192c8de4 100644 --- a/js/sdk/__tests__/r2rClientIntegrationSuperUser.test.ts +++ b/js/sdk/__tests__/r2rClientIntegrationSuperUser.test.ts @@ -3,6 +3,12 @@ const fs = require("fs"); const baseUrl = "http://localhost:8000"; +/** + * raskolnikov.txt should have an id of `f9f61fc8-079c-52d0-910a-c657958e385b` + * karamozov.txt should have an id of `73749580-1ade-50c6-8fbe-a5e9e87783c8` + * myshkin.txt should have an id of `2e05b285-2746-5778-9e4a-e293db92f3be` + */ + describe("r2rClient Integration Tests", () => { let client: r2rClient; @@ -43,17 +49,17 @@ describe("r2rClient Integration Tests", () => { await expect(client.ingestFiles(files)).resolves.not.toThrow(); }); - // test("Update files", async () => { - // const updated_file = [ - // { path: "examples/data/folder/myshkin.txt", name: "super_myshkin.txt" }, - // ]; - // await expect( - // client.updateFiles(updated_file, { - // document_ids: ["2e05b285-2746-5778-9e4a-e293db92f3be"], - // metadatas: [{ title: "updated_karamozov.txt" }], - // }), - // ).resolves.not.toThrow(); - // }); + test("Update files", async () => { + const updated_file = [ + { path: "examples/data/folder/myshkin.txt", name: "super_myshkin.txt" }, + ]; + await expect( + client.updateFiles(updated_file, { + document_ids: ["2e05b285-2746-5778-9e4a-e293db92f3be"], + metadatas: [{ title: "updated_karamozov.txt" }], + }), + ).resolves.not.toThrow(); + }); test("Search documents", async () => { await expect(client.search("test")).resolves.not.toThrow(); @@ -111,6 +117,7 @@ describe("r2rClient Integration Tests", () => { // expect(fullResponse.length).toBeGreaterThan(0); // }, 30000); + // Deletes raskolnikov.txt test("Delete document", async () => { await expect( client.delete({ @@ -124,33 +131,31 @@ describe("r2rClient Integration Tests", () => { // await expect(client.logs()).resolves.not.toThrow(); // }); - // TODO: verfiy that this works, blocked by R2R logging issues - // test("App settings", async () => { - // await expect(client.appSettings()).resolves.not.toThrow(); - // }); + test("App settings", async () => { + await expect(client.appSettings()).resolves.not.toThrow(); + }); - // test("Get analytics", async () => { - // const filterCriteria: Record | string = { - // filters: { - // search_latencies: "search_latency", - // }, - // }; + test("Get analytics", async () => { + const filterCriteria: Record | string = { + filters: { + search_latencies: "search_latency", + }, + }; - // const analysisTypes: Record | string = { - // analysis_types: { - // search_latencies: ["basic_statistics", "search_latency"], - // }, - // }; + const analysisTypes: Record | string = { + analysis_types: { + search_latencies: ["basic_statistics", "search_latency"], + }, + }; - // await expect( - // client.analytics(filterCriteria, analysisTypes), - // ).resolves.not.toThrow(); - // }); + await expect( + client.analytics(filterCriteria, analysisTypes), + ).resolves.not.toThrow(); + }); - // TODO: Fix in R2R, 'PostgresRelationalDBProvider' object has no attribute 'get_users_overview') - // test("Get users overview", async () => { - // await expect(client.usersOverview()).resolves.not.toThrow(); - // }); + test("Get users overview", async () => { + await expect(client.usersOverview()).resolves.not.toThrow(); + }); test("Get documents overview", async () => { await expect(client.documentsOverview()).resolves.not.toThrow(); @@ -163,10 +168,13 @@ describe("r2rClient Integration Tests", () => { }); test("Clean up remaining documents", async () => { + // Deletes karamozov.txt await expect( client.delete({ document_id: "73749580-1ade-50c6-8fbe-a5e9e87783c8" }), ).resolves.toBe(""); + + // Deletes myshkin.txt await expect( client.delete({ document_id: "2e05b285-2746-5778-9e4a-e293db92f3be" }), ).resolves.toBe(""); diff --git a/js/sdk/package-lock.json b/js/sdk/package-lock.json index 8a898fcc0..143b567ea 100644 --- a/js/sdk/package-lock.json +++ b/js/sdk/package-lock.json @@ -6,24 +6,25 @@ "packages": { "": { "name": "r2r-js", - "version": "1.2.9", + "version": "1.2.15", "license": "ISC", "dependencies": { - "axios": "^1.7.2", + "axios": "^1.7.4", "form-data": "^4.0.0", - "posthog-js": "^1.148.0", - "posthog-node": "^4.0.1", + "posthog-js": "^1.155.4", + "posthog-node": "^4.1.0", "uuid": "^10.0.0" }, "devDependencies": { "@types/jest": "^29.5.12", - "@types/node": "^20.14.11", + "@types/mocha": "^10.0.7", + "@types/node": "^20.14.15", "@types/uuid": "^10.0.0", "jest": "^29.7.0", "prettier": "^3.3.3", - "ts-jest": "^29.2.3", + "ts-jest": "^29.2.4", "ts-node": "^10.9.2", - "typescript": "^5.5.3" + "typescript": "^5.5.4" } }, "node_modules/@ampproject/remapping": { @@ -1145,19 +1146,27 @@ "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.12.tgz", "integrity": "sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==", "dev": true, + "license": "MIT", "dependencies": { "expect": "^29.0.0", "pretty-format": "^29.0.0" } }, + "node_modules/@types/mocha": { + "version": "10.0.7", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.7.tgz", + "integrity": "sha512-GN8yJ1mNTcFcah/wKEFIJckJx9iJLoMSzWcfRRuxz/Jk+U6KQNnml+etbtxFK8lPjzOw3zp4Ha/kjSst9fsHYw==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/node": { - "version": "20.14.11", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.11.tgz", - "integrity": "sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==", + "version": "20.16.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.1.tgz", + "integrity": "sha512-zJDo7wEadFtSyNz5QITDfRcrhqDvQI1xQNQ0VoizPjM/dVAODqqIUWbJPkvsxmTI0MYRGRikcdjMPhOssnPejQ==", "dev": true, "license": "MIT", "dependencies": { - "undici-types": "~5.26.4" + "undici-types": "~6.19.2" } }, "node_modules/@types/stack-utils": { @@ -1291,9 +1300,10 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/axios": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz", - "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz", + "integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==", + "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -3330,9 +3340,9 @@ } }, "node_modules/posthog-js": { - "version": "1.148.0", - "resolved": "https://registry.npmjs.org/posthog-js/-/posthog-js-1.148.0.tgz", - "integrity": "sha512-nydf+aret26YViDBwH7DdN/c8dmCzQGNQ1yredeE47UlbpJ3J/iTgskNdmGJIofFcdSagcwAE/FF7s++YfTtvg==", + "version": "1.157.2", + "resolved": "https://registry.npmjs.org/posthog-js/-/posthog-js-1.157.2.tgz", + "integrity": "sha512-ATYKGs+Q51u26nHHhrhWNh1whqFm7j/rwQQYw+y6/YzNmRlo+YsqrGZji9nqXb9/4fo0ModDr+ZmuOI3hKkUXA==", "license": "MIT", "dependencies": { "fflate": "^0.4.8", @@ -3341,11 +3351,12 @@ } }, "node_modules/posthog-node": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/posthog-node/-/posthog-node-4.0.1.tgz", - "integrity": "sha512-rtqm2h22QxLGBrW2bLYzbRhliIrqgZ0k+gF0LkQ1SNdeD06YE5eilV0MxZppFSxC8TfH0+B0cWCuebEnreIDgQ==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/posthog-node/-/posthog-node-4.1.1.tgz", + "integrity": "sha512-hva26cNSz62H76blhWUF8mZmE3Q81KTrkkpHEZlD00qDov/phLQCrKQnxwjiAN3yI9pv/0/uwte6Gluy1xBmUA==", + "license": "MIT", "dependencies": { - "axios": "^1.6.2", + "axios": "^1.7.4", "rusha": "^0.8.14" }, "engines": { @@ -3727,9 +3738,9 @@ } }, "node_modules/ts-jest": { - "version": "29.2.3", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.2.3.tgz", - "integrity": "sha512-yCcfVdiBFngVz9/keHin9EnsrQtQtEu3nRykNy9RVp+FiPFFbPJ3Sg6Qg4+TkmH0vMP5qsTKgXSsk80HRwvdgQ==", + "version": "29.2.4", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.2.4.tgz", + "integrity": "sha512-3d6tgDyhCI29HlpwIq87sNuI+3Q6GLTTCeYRHCs7vDz+/3GCMwEtV9jezLyl4ZtnBgx00I7hm8PCP8cTksMGrw==", "dev": true, "license": "MIT", "dependencies": { @@ -3852,10 +3863,11 @@ } }, "node_modules/typescript": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", - "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", "dev": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -3865,10 +3877,11 @@ } }, "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "dev": true, + "license": "MIT" }, "node_modules/update-browserslist-db": { "version": "1.0.16", diff --git a/js/sdk/package.json b/js/sdk/package.json index 92b490721..91d8ef6fa 100644 --- a/js/sdk/package.json +++ b/js/sdk/package.json @@ -32,6 +32,7 @@ }, "devDependencies": { "@types/jest": "^29.5.12", + "@types/mocha": "^10.0.7", "@types/node": "^20.14.15", "@types/uuid": "^10.0.0", "jest": "^29.7.0", diff --git a/js/sdk/pnpm-lock.yaml b/js/sdk/pnpm-lock.yaml index 9c23c72b6..a61b8a357 100644 --- a/js/sdk/pnpm-lock.yaml +++ b/js/sdk/pnpm-lock.yaml @@ -1,10 +1,11 @@ -lockfileVersion: "9.0" +lockfileVersion: '9.0' settings: autoInstallPeers: true excludeLinksFromLockfile: false importers: + .: dependencies: axios: @@ -23,13 +24,16 @@ importers: specifier: ^10.0.0 version: 10.0.0 devDependencies: - "@types/jest": + '@types/jest': specifier: ^29.5.12 version: 29.5.12 - "@types/node": + '@types/mocha': + specifier: ^10.0.7 + version: 10.0.7 + '@types/node': specifier: ^20.14.15 version: 20.14.15 - "@types/uuid": + '@types/uuid': specifier: ^10.0.0 version: 10.0.0 jest: @@ -49,926 +53,537 @@ importers: version: 5.5.4 packages: - "@ampproject/remapping@2.3.0": - resolution: - { - integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==, - } - engines: { node: ">=6.0.0" } - - "@babel/code-frame@7.24.7": - resolution: - { - integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==, - } - engines: { node: ">=6.9.0" } - - "@babel/compat-data@7.25.2": - resolution: - { - integrity: sha512-bYcppcpKBvX4znYaPEeFau03bp89ShqNMLs+rmdptMw+heSZh9+z84d2YG+K7cYLbWwzdjtDoW/uqZmPjulClQ==, - } - engines: { node: ">=6.9.0" } - - "@babel/core@7.25.2": - resolution: - { - integrity: sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==, - } - engines: { node: ">=6.9.0" } - - "@babel/generator@7.25.0": - resolution: - { - integrity: sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw==, - } - engines: { node: ">=6.9.0" } - - "@babel/helper-compilation-targets@7.25.2": - resolution: - { - integrity: sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==, - } - engines: { node: ">=6.9.0" } - - "@babel/helper-module-imports@7.24.7": - resolution: - { - integrity: sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==, - } - engines: { node: ">=6.9.0" } - - "@babel/helper-module-transforms@7.25.2": - resolution: - { - integrity: sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==, - } - engines: { node: ">=6.9.0" } + + '@ampproject/remapping@2.3.0': + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + + '@babel/code-frame@7.24.7': + resolution: {integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.25.2': + resolution: {integrity: sha512-bYcppcpKBvX4znYaPEeFau03bp89ShqNMLs+rmdptMw+heSZh9+z84d2YG+K7cYLbWwzdjtDoW/uqZmPjulClQ==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.25.2': + resolution: {integrity: sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.25.0': + resolution: {integrity: sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.25.2': + resolution: {integrity: sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.24.7': + resolution: {integrity: sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.25.2': + resolution: {integrity: sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==} + engines: {node: '>=6.9.0'} peerDependencies: - "@babel/core": ^7.0.0 - - "@babel/helper-plugin-utils@7.24.8": - resolution: - { - integrity: sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==, - } - engines: { node: ">=6.9.0" } - - "@babel/helper-simple-access@7.24.7": - resolution: - { - integrity: sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==, - } - engines: { node: ">=6.9.0" } - - "@babel/helper-string-parser@7.24.8": - resolution: - { - integrity: sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==, - } - engines: { node: ">=6.9.0" } - - "@babel/helper-validator-identifier@7.24.7": - resolution: - { - integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==, - } - engines: { node: ">=6.9.0" } - - "@babel/helper-validator-option@7.24.8": - resolution: - { - integrity: sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==, - } - engines: { node: ">=6.9.0" } - - "@babel/helpers@7.25.0": - resolution: - { - integrity: sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw==, - } - engines: { node: ">=6.9.0" } - - "@babel/highlight@7.24.7": - resolution: - { - integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==, - } - engines: { node: ">=6.9.0" } - - "@babel/parser@7.25.3": - resolution: - { - integrity: sha512-iLTJKDbJ4hMvFPgQwwsVoxtHyWpKKPBrxkANrSYewDPaPpT5py5yeVkgPIJ7XYXhndxJpaA3PyALSXQ7u8e/Dw==, - } - engines: { node: ">=6.0.0" } + '@babel/core': ^7.0.0 + + '@babel/helper-plugin-utils@7.24.8': + resolution: {integrity: sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-simple-access@7.24.7': + resolution: {integrity: sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.24.8': + resolution: {integrity: sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.24.7': + resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.24.8': + resolution: {integrity: sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.25.0': + resolution: {integrity: sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw==} + engines: {node: '>=6.9.0'} + + '@babel/highlight@7.24.7': + resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.25.3': + resolution: {integrity: sha512-iLTJKDbJ4hMvFPgQwwsVoxtHyWpKKPBrxkANrSYewDPaPpT5py5yeVkgPIJ7XYXhndxJpaA3PyALSXQ7u8e/Dw==} + engines: {node: '>=6.0.0'} hasBin: true - "@babel/plugin-syntax-async-generators@7.8.4": - resolution: - { - integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==, - } + '@babel/plugin-syntax-async-generators@7.8.4': + resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} peerDependencies: - "@babel/core": ^7.0.0-0 + '@babel/core': ^7.0.0-0 - "@babel/plugin-syntax-bigint@7.8.3": - resolution: - { - integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==, - } + '@babel/plugin-syntax-bigint@7.8.3': + resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} peerDependencies: - "@babel/core": ^7.0.0-0 + '@babel/core': ^7.0.0-0 - "@babel/plugin-syntax-class-properties@7.12.13": - resolution: - { - integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==, - } + '@babel/plugin-syntax-class-properties@7.12.13': + resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} peerDependencies: - "@babel/core": ^7.0.0-0 - - "@babel/plugin-syntax-class-static-block@7.14.5": - resolution: - { - integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==, - } - engines: { node: ">=6.9.0" } + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-class-static-block@7.14.5': + resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} + engines: {node: '>=6.9.0'} peerDependencies: - "@babel/core": ^7.0.0-0 - - "@babel/plugin-syntax-import-attributes@7.24.7": - resolution: - { - integrity: sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==, - } - engines: { node: ">=6.9.0" } + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-attributes@7.24.7': + resolution: {integrity: sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==} + engines: {node: '>=6.9.0'} peerDependencies: - "@babel/core": ^7.0.0-0 + '@babel/core': ^7.0.0-0 - "@babel/plugin-syntax-import-meta@7.10.4": - resolution: - { - integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==, - } + '@babel/plugin-syntax-import-meta@7.10.4': + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} peerDependencies: - "@babel/core": ^7.0.0-0 + '@babel/core': ^7.0.0-0 - "@babel/plugin-syntax-json-strings@7.8.3": - resolution: - { - integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==, - } + '@babel/plugin-syntax-json-strings@7.8.3': + resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} peerDependencies: - "@babel/core": ^7.0.0-0 - - "@babel/plugin-syntax-jsx@7.24.7": - resolution: - { - integrity: sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==, - } - engines: { node: ">=6.9.0" } + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-jsx@7.24.7': + resolution: {integrity: sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==} + engines: {node: '>=6.9.0'} peerDependencies: - "@babel/core": ^7.0.0-0 + '@babel/core': ^7.0.0-0 - "@babel/plugin-syntax-logical-assignment-operators@7.10.4": - resolution: - { - integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==, - } + '@babel/plugin-syntax-logical-assignment-operators@7.10.4': + resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} peerDependencies: - "@babel/core": ^7.0.0-0 + '@babel/core': ^7.0.0-0 - "@babel/plugin-syntax-nullish-coalescing-operator@7.8.3": - resolution: - { - integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==, - } + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3': + resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} peerDependencies: - "@babel/core": ^7.0.0-0 + '@babel/core': ^7.0.0-0 - "@babel/plugin-syntax-numeric-separator@7.10.4": - resolution: - { - integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==, - } + '@babel/plugin-syntax-numeric-separator@7.10.4': + resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} peerDependencies: - "@babel/core": ^7.0.0-0 + '@babel/core': ^7.0.0-0 - "@babel/plugin-syntax-object-rest-spread@7.8.3": - resolution: - { - integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==, - } + '@babel/plugin-syntax-object-rest-spread@7.8.3': + resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} peerDependencies: - "@babel/core": ^7.0.0-0 + '@babel/core': ^7.0.0-0 - "@babel/plugin-syntax-optional-catch-binding@7.8.3": - resolution: - { - integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==, - } + '@babel/plugin-syntax-optional-catch-binding@7.8.3': + resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} peerDependencies: - "@babel/core": ^7.0.0-0 + '@babel/core': ^7.0.0-0 - "@babel/plugin-syntax-optional-chaining@7.8.3": - resolution: - { - integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==, - } + '@babel/plugin-syntax-optional-chaining@7.8.3': + resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} peerDependencies: - "@babel/core": ^7.0.0-0 - - "@babel/plugin-syntax-private-property-in-object@7.14.5": - resolution: - { - integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==, - } - engines: { node: ">=6.9.0" } + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-private-property-in-object@7.14.5': + resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} + engines: {node: '>=6.9.0'} peerDependencies: - "@babel/core": ^7.0.0-0 - - "@babel/plugin-syntax-top-level-await@7.14.5": - resolution: - { - integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==, - } - engines: { node: ">=6.9.0" } + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-top-level-await@7.14.5': + resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} + engines: {node: '>=6.9.0'} peerDependencies: - "@babel/core": ^7.0.0-0 - - "@babel/plugin-syntax-typescript@7.24.7": - resolution: - { - integrity: sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA==, - } - engines: { node: ">=6.9.0" } + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-typescript@7.24.7': + resolution: {integrity: sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA==} + engines: {node: '>=6.9.0'} peerDependencies: - "@babel/core": ^7.0.0-0 - - "@babel/template@7.25.0": - resolution: - { - integrity: sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==, - } - engines: { node: ">=6.9.0" } - - "@babel/traverse@7.25.3": - resolution: - { - integrity: sha512-HefgyP1x754oGCsKmV5reSmtV7IXj/kpaE1XYY+D9G5PvKKoFfSbiS4M77MdjuwlZKDIKFCffq9rPU+H/s3ZdQ==, - } - engines: { node: ">=6.9.0" } - - "@babel/types@7.25.2": - resolution: - { - integrity: sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q==, - } - engines: { node: ">=6.9.0" } - - "@bcoe/v8-coverage@0.2.3": - resolution: - { - integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==, - } - - "@cspotcode/source-map-support@0.8.1": - resolution: - { - integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==, - } - engines: { node: ">=12" } - - "@istanbuljs/load-nyc-config@1.1.0": - resolution: - { - integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==, - } - engines: { node: ">=8" } - - "@istanbuljs/schema@0.1.3": - resolution: - { - integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==, - } - engines: { node: ">=8" } - - "@jest/console@29.7.0": - resolution: - { - integrity: sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - "@jest/core@29.7.0": - resolution: - { - integrity: sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + '@babel/core': ^7.0.0-0 + + '@babel/template@7.25.0': + resolution: {integrity: sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.25.3': + resolution: {integrity: sha512-HefgyP1x754oGCsKmV5reSmtV7IXj/kpaE1XYY+D9G5PvKKoFfSbiS4M77MdjuwlZKDIKFCffq9rPU+H/s3ZdQ==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.25.2': + resolution: {integrity: sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q==} + engines: {node: '>=6.9.0'} + + '@bcoe/v8-coverage@0.2.3': + resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + + '@cspotcode/source-map-support@0.8.1': + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + + '@istanbuljs/load-nyc-config@1.1.0': + resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} + engines: {node: '>=8'} + + '@istanbuljs/schema@0.1.3': + resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} + engines: {node: '>=8'} + + '@jest/console@29.7.0': + resolution: {integrity: sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/core@29.7.0': + resolution: {integrity: sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 peerDependenciesMeta: node-notifier: optional: true - "@jest/environment@29.7.0": - resolution: - { - integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - "@jest/expect-utils@29.7.0": - resolution: - { - integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - "@jest/expect@29.7.0": - resolution: - { - integrity: sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - "@jest/fake-timers@29.7.0": - resolution: - { - integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - "@jest/globals@29.7.0": - resolution: - { - integrity: sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - "@jest/reporters@29.7.0": - resolution: - { - integrity: sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + '@jest/environment@29.7.0': + resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/expect-utils@29.7.0': + resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/expect@29.7.0': + resolution: {integrity: sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/fake-timers@29.7.0': + resolution: {integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/globals@29.7.0': + resolution: {integrity: sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/reporters@29.7.0': + resolution: {integrity: sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 peerDependenciesMeta: node-notifier: optional: true - "@jest/schemas@29.6.3": - resolution: - { - integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - "@jest/source-map@29.6.3": - resolution: - { - integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - "@jest/test-result@29.7.0": - resolution: - { - integrity: sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - "@jest/test-sequencer@29.7.0": - resolution: - { - integrity: sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - "@jest/transform@29.7.0": - resolution: - { - integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - "@jest/types@29.6.3": - resolution: - { - integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - "@jridgewell/gen-mapping@0.3.5": - resolution: - { - integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==, - } - engines: { node: ">=6.0.0" } - - "@jridgewell/resolve-uri@3.1.2": - resolution: - { - integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==, - } - engines: { node: ">=6.0.0" } - - "@jridgewell/set-array@1.2.1": - resolution: - { - integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==, - } - engines: { node: ">=6.0.0" } - - "@jridgewell/sourcemap-codec@1.5.0": - resolution: - { - integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==, - } - - "@jridgewell/trace-mapping@0.3.25": - resolution: - { - integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==, - } - - "@jridgewell/trace-mapping@0.3.9": - resolution: - { - integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==, - } - - "@sinclair/typebox@0.27.8": - resolution: - { - integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==, - } - - "@sinonjs/commons@3.0.1": - resolution: - { - integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==, - } - - "@sinonjs/fake-timers@10.3.0": - resolution: - { - integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==, - } - - "@tsconfig/node10@1.0.11": - resolution: - { - integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==, - } - - "@tsconfig/node12@1.0.11": - resolution: - { - integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==, - } - - "@tsconfig/node14@1.0.3": - resolution: - { - integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==, - } - - "@tsconfig/node16@1.0.4": - resolution: - { - integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==, - } - - "@types/babel__core@7.20.5": - resolution: - { - integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==, - } - - "@types/babel__generator@7.6.8": - resolution: - { - integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==, - } - - "@types/babel__template@7.4.4": - resolution: - { - integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==, - } - - "@types/babel__traverse@7.20.6": - resolution: - { - integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==, - } - - "@types/graceful-fs@4.1.9": - resolution: - { - integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==, - } - - "@types/istanbul-lib-coverage@2.0.6": - resolution: - { - integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==, - } - - "@types/istanbul-lib-report@3.0.3": - resolution: - { - integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==, - } - - "@types/istanbul-reports@3.0.4": - resolution: - { - integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==, - } - - "@types/jest@29.5.12": - resolution: - { - integrity: sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==, - } - - "@types/node@20.14.15": - resolution: - { - integrity: sha512-Fz1xDMCF/B00/tYSVMlmK7hVeLh7jE5f3B7X1/hmV0MJBwE27KlS7EvD/Yp+z1lm8mVhwV5w+n8jOZG8AfTlKw==, - } - - "@types/stack-utils@2.0.3": - resolution: - { - integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==, - } - - "@types/uuid@10.0.0": - resolution: - { - integrity: sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==, - } - - "@types/yargs-parser@21.0.3": - resolution: - { - integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==, - } - - "@types/yargs@17.0.33": - resolution: - { - integrity: sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==, - } + '@jest/schemas@29.6.3': + resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/source-map@29.6.3': + resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/test-result@29.7.0': + resolution: {integrity: sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/test-sequencer@29.7.0': + resolution: {integrity: sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/transform@29.7.0': + resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/types@29.6.3': + resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jridgewell/gen-mapping@0.3.5': + resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} + engines: {node: '>=6.0.0'} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + + '@jridgewell/trace-mapping@0.3.9': + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + + '@sinclair/typebox@0.27.8': + resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + + '@sinonjs/commons@3.0.1': + resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} + + '@sinonjs/fake-timers@10.3.0': + resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} + + '@tsconfig/node10@1.0.11': + resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} + + '@tsconfig/node12@1.0.11': + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + + '@tsconfig/node14@1.0.3': + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + + '@tsconfig/node16@1.0.4': + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + + '@types/babel__core@7.20.5': + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + + '@types/babel__generator@7.6.8': + resolution: {integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==} + + '@types/babel__template@7.4.4': + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + + '@types/babel__traverse@7.20.6': + resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==} + + '@types/graceful-fs@4.1.9': + resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} + + '@types/istanbul-lib-coverage@2.0.6': + resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} + + '@types/istanbul-lib-report@3.0.3': + resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} + + '@types/istanbul-reports@3.0.4': + resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} + + '@types/jest@29.5.12': + resolution: {integrity: sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==} + + '@types/mocha@10.0.7': + resolution: {integrity: sha512-GN8yJ1mNTcFcah/wKEFIJckJx9iJLoMSzWcfRRuxz/Jk+U6KQNnml+etbtxFK8lPjzOw3zp4Ha/kjSst9fsHYw==} + + '@types/node@20.14.15': + resolution: {integrity: sha512-Fz1xDMCF/B00/tYSVMlmK7hVeLh7jE5f3B7X1/hmV0MJBwE27KlS7EvD/Yp+z1lm8mVhwV5w+n8jOZG8AfTlKw==} + + '@types/stack-utils@2.0.3': + resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} + + '@types/uuid@10.0.0': + resolution: {integrity: sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==} + + '@types/yargs-parser@21.0.3': + resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} + + '@types/yargs@17.0.33': + resolution: {integrity: sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==} acorn-walk@8.3.3: - resolution: - { - integrity: sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==, - } - engines: { node: ">=0.4.0" } + resolution: {integrity: sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==} + engines: {node: '>=0.4.0'} acorn@8.12.1: - resolution: - { - integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==, - } - engines: { node: ">=0.4.0" } + resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==} + engines: {node: '>=0.4.0'} hasBin: true ansi-escapes@4.3.2: - resolution: - { - integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} ansi-regex@5.0.1: - resolution: - { - integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} ansi-styles@3.2.1: - resolution: - { - integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==, - } - engines: { node: ">=4" } + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} ansi-styles@4.3.0: - resolution: - { - integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} ansi-styles@5.2.0: - resolution: - { - integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==, - } - engines: { node: ">=10" } + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} anymatch@3.1.3: - resolution: - { - integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==, - } - engines: { node: ">= 8" } + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} arg@4.1.3: - resolution: - { - integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==, - } + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} argparse@1.0.10: - resolution: - { - integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==, - } + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} async@3.2.5: - resolution: - { - integrity: sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==, - } + resolution: {integrity: sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==} asynckit@0.4.0: - resolution: - { - integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==, - } + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} axios@1.7.4: - resolution: - { - integrity: sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==, - } + resolution: {integrity: sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==} babel-jest@29.7.0: - resolution: - { - integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: - "@babel/core": ^7.8.0 + '@babel/core': ^7.8.0 babel-plugin-istanbul@6.1.1: - resolution: - { - integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} + engines: {node: '>=8'} babel-plugin-jest-hoist@29.6.3: - resolution: - { - integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} babel-preset-current-node-syntax@1.1.0: - resolution: - { - integrity: sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==, - } + resolution: {integrity: sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==} peerDependencies: - "@babel/core": ^7.0.0 + '@babel/core': ^7.0.0 babel-preset-jest@29.6.3: - resolution: - { - integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: - "@babel/core": ^7.0.0 + '@babel/core': ^7.0.0 balanced-match@1.0.2: - resolution: - { - integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==, - } + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} brace-expansion@1.1.11: - resolution: - { - integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==, - } + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} brace-expansion@2.0.1: - resolution: - { - integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==, - } + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} braces@3.0.3: - resolution: - { - integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} browserslist@4.23.3: - resolution: - { - integrity: sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==, - } - engines: { node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7 } + resolution: {integrity: sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true bs-logger@0.2.6: - resolution: - { - integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==, - } - engines: { node: ">= 6" } + resolution: {integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==} + engines: {node: '>= 6'} bser@2.1.1: - resolution: - { - integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==, - } + resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} buffer-from@1.1.2: - resolution: - { - integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==, - } + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} callsites@3.1.0: - resolution: - { - integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==, - } - engines: { node: ">=6" } + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} camelcase@5.3.1: - resolution: - { - integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==, - } - engines: { node: ">=6" } + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} camelcase@6.3.0: - resolution: - { - integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==, - } - engines: { node: ">=10" } + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} caniuse-lite@1.0.30001651: - resolution: - { - integrity: sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==, - } + resolution: {integrity: sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==} chalk@2.4.2: - resolution: - { - integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==, - } - engines: { node: ">=4" } + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} chalk@4.1.2: - resolution: - { - integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==, - } - engines: { node: ">=10" } + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} char-regex@1.0.2: - resolution: - { - integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==, - } - engines: { node: ">=10" } + resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} + engines: {node: '>=10'} ci-info@3.9.0: - resolution: - { - integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} + engines: {node: '>=8'} cjs-module-lexer@1.3.1: - resolution: - { - integrity: sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==, - } + resolution: {integrity: sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==} cliui@8.0.1: - resolution: - { - integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==, - } - engines: { node: ">=12" } + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} co@4.6.0: - resolution: - { - integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==, - } - engines: { iojs: ">= 1.0.0", node: ">= 0.12.0" } + resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} + engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} collect-v8-coverage@1.0.2: - resolution: - { - integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==, - } + resolution: {integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==} color-convert@1.9.3: - resolution: - { - integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==, - } + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} color-convert@2.0.1: - resolution: - { - integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==, - } - engines: { node: ">=7.0.0" } + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} color-name@1.1.3: - resolution: - { - integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==, - } + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} color-name@1.1.4: - resolution: - { - integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==, - } + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} combined-stream@1.0.8: - resolution: - { - integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==, - } - engines: { node: ">= 0.8" } + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} concat-map@0.0.1: - resolution: - { - integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==, - } + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} convert-source-map@2.0.0: - resolution: - { - integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==, - } + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} create-jest@29.7.0: - resolution: - { - integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true create-require@1.1.1: - resolution: - { - integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==, - } + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} cross-spawn@7.0.3: - resolution: - { - integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==, - } - engines: { node: ">= 8" } + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} debug@4.3.6: - resolution: - { - integrity: sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==, - } - engines: { node: ">=6.0" } + resolution: {integrity: sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==} + engines: {node: '>=6.0'} peerDependencies: - supports-color: "*" + supports-color: '*' peerDependenciesMeta: supports-color: optional: true dedent@1.5.3: - resolution: - { - integrity: sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==, - } + resolution: {integrity: sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==} peerDependencies: babel-plugin-macros: ^3.1.0 peerDependenciesMeta: @@ -976,427 +591,244 @@ packages: optional: true deepmerge@4.3.1: - resolution: - { - integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==, - } - engines: { node: ">=0.10.0" } + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} delayed-stream@1.0.0: - resolution: - { - integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==, - } - engines: { node: ">=0.4.0" } + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} detect-newline@3.1.0: - resolution: - { - integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} + engines: {node: '>=8'} diff-sequences@29.6.3: - resolution: - { - integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} diff@4.0.2: - resolution: - { - integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==, - } - engines: { node: ">=0.3.1" } + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + engines: {node: '>=0.3.1'} ejs@3.1.10: - resolution: - { - integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==, - } - engines: { node: ">=0.10.0" } + resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==} + engines: {node: '>=0.10.0'} hasBin: true electron-to-chromium@1.5.9: - resolution: - { - integrity: sha512-HfkT8ndXR0SEkU8gBQQM3rz035bpE/hxkZ1YIt4KJPEFES68HfIU6LzKukH0H794Lm83WJtkSAMfEToxCs15VA==, - } + resolution: {integrity: sha512-HfkT8ndXR0SEkU8gBQQM3rz035bpE/hxkZ1YIt4KJPEFES68HfIU6LzKukH0H794Lm83WJtkSAMfEToxCs15VA==} emittery@0.13.1: - resolution: - { - integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==, - } - engines: { node: ">=12" } + resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} + engines: {node: '>=12'} emoji-regex@8.0.0: - resolution: - { - integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==, - } + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} error-ex@1.3.2: - resolution: - { - integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==, - } + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} escalade@3.1.2: - resolution: - { - integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==, - } - engines: { node: ">=6" } + resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} + engines: {node: '>=6'} escape-string-regexp@1.0.5: - resolution: - { - integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==, - } - engines: { node: ">=0.8.0" } + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} escape-string-regexp@2.0.0: - resolution: - { - integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} + engines: {node: '>=8'} esprima@4.0.1: - resolution: - { - integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==, - } - engines: { node: ">=4" } + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} hasBin: true execa@5.1.1: - resolution: - { - integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==, - } - engines: { node: ">=10" } + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} exit@0.1.2: - resolution: - { - integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==, - } - engines: { node: ">= 0.8.0" } + resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} + engines: {node: '>= 0.8.0'} expect@29.7.0: - resolution: - { - integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} fast-json-stable-stringify@2.1.0: - resolution: - { - integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==, - } + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} fb-watchman@2.0.2: - resolution: - { - integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==, - } + resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} fflate@0.4.8: - resolution: - { - integrity: sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA==, - } + resolution: {integrity: sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA==} filelist@1.0.4: - resolution: - { - integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==, - } + resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} fill-range@7.1.1: - resolution: - { - integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} find-up@4.1.0: - resolution: - { - integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} follow-redirects@1.15.6: - resolution: - { - integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==, - } - engines: { node: ">=4.0" } + resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==} + engines: {node: '>=4.0'} peerDependencies: - debug: "*" + debug: '*' peerDependenciesMeta: debug: optional: true form-data@4.0.0: - resolution: - { - integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==, - } - engines: { node: ">= 6" } + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} fs.realpath@1.0.0: - resolution: - { - integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==, - } + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} fsevents@2.3.3: - resolution: - { - integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==, - } - engines: { node: ^8.16.0 || ^10.6.0 || >=11.0.0 } + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] function-bind@1.1.2: - resolution: - { - integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==, - } + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} gensync@1.0.0-beta.2: - resolution: - { - integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==, - } - engines: { node: ">=6.9.0" } + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} get-caller-file@2.0.5: - resolution: - { - integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==, - } - engines: { node: 6.* || 8.* || >= 10.* } + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} get-package-type@0.1.0: - resolution: - { - integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==, - } - engines: { node: ">=8.0.0" } + resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} + engines: {node: '>=8.0.0'} get-stream@6.0.1: - resolution: - { - integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==, - } - engines: { node: ">=10" } + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} glob@7.2.3: - resolution: - { - integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==, - } + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} deprecated: Glob versions prior to v9 are no longer supported globals@11.12.0: - resolution: - { - integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==, - } - engines: { node: ">=4" } + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} graceful-fs@4.2.11: - resolution: - { - integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==, - } + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} has-flag@3.0.0: - resolution: - { - integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==, - } - engines: { node: ">=4" } + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} has-flag@4.0.0: - resolution: - { - integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} hasown@2.0.2: - resolution: - { - integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==, - } - engines: { node: ">= 0.4" } + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} html-escaper@2.0.2: - resolution: - { - integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==, - } + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} human-signals@2.1.0: - resolution: - { - integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==, - } - engines: { node: ">=10.17.0" } + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} import-local@3.2.0: - resolution: - { - integrity: sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==} + engines: {node: '>=8'} hasBin: true imurmurhash@0.1.4: - resolution: - { - integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==, - } - engines: { node: ">=0.8.19" } + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} inflight@1.0.6: - resolution: - { - integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==, - } + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. inherits@2.0.4: - resolution: - { - integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==, - } + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} is-arrayish@0.2.1: - resolution: - { - integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==, - } + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} is-core-module@2.15.0: - resolution: - { - integrity: sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==, - } - engines: { node: ">= 0.4" } + resolution: {integrity: sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==} + engines: {node: '>= 0.4'} is-fullwidth-code-point@3.0.0: - resolution: - { - integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} is-generator-fn@2.1.0: - resolution: - { - integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==, - } - engines: { node: ">=6" } + resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} + engines: {node: '>=6'} is-number@7.0.0: - resolution: - { - integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==, - } - engines: { node: ">=0.12.0" } + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} is-stream@2.0.1: - resolution: - { - integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} isexe@2.0.0: - resolution: - { - integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==, - } + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} istanbul-lib-coverage@3.2.2: - resolution: - { - integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} + engines: {node: '>=8'} istanbul-lib-instrument@5.2.1: - resolution: - { - integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} + engines: {node: '>=8'} istanbul-lib-instrument@6.0.3: - resolution: - { - integrity: sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==, - } - engines: { node: ">=10" } + resolution: {integrity: sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==} + engines: {node: '>=10'} istanbul-lib-report@3.0.1: - resolution: - { - integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==, - } - engines: { node: ">=10" } + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} istanbul-lib-source-maps@4.0.1: - resolution: - { - integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==, - } - engines: { node: ">=10" } + resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} + engines: {node: '>=10'} istanbul-reports@3.1.7: - resolution: - { - integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} + engines: {node: '>=8'} jake@10.9.2: - resolution: - { - integrity: sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==, - } - engines: { node: ">=10" } + resolution: {integrity: sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==} + engines: {node: '>=10'} hasBin: true jest-changed-files@29.7.0: - resolution: - { - integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} jest-circus@29.7.0: - resolution: - { - integrity: sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} jest-cli@29.7.0: - resolution: - { - integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 @@ -1405,178 +837,109 @@ packages: optional: true jest-config@29.7.0: - resolution: - { - integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: - "@types/node": "*" - ts-node: ">=9.0.0" + '@types/node': '*' + ts-node: '>=9.0.0' peerDependenciesMeta: - "@types/node": + '@types/node': optional: true ts-node: optional: true jest-diff@29.7.0: - resolution: - { - integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} jest-docblock@29.7.0: - resolution: - { - integrity: sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} jest-each@29.7.0: - resolution: - { - integrity: sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} jest-environment-node@29.7.0: - resolution: - { - integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} jest-get-type@29.6.3: - resolution: - { - integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} jest-haste-map@29.7.0: - resolution: - { - integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} jest-leak-detector@29.7.0: - resolution: - { - integrity: sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} jest-matcher-utils@29.7.0: - resolution: - { - integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} jest-message-util@29.7.0: - resolution: - { - integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} jest-mock@29.7.0: - resolution: - { - integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} jest-pnp-resolver@1.2.3: - resolution: - { - integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==, - } - engines: { node: ">=6" } + resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==} + engines: {node: '>=6'} peerDependencies: - jest-resolve: "*" + jest-resolve: '*' peerDependenciesMeta: jest-resolve: optional: true jest-regex-util@29.6.3: - resolution: - { - integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} jest-resolve-dependencies@29.7.0: - resolution: - { - integrity: sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} jest-resolve@29.7.0: - resolution: - { - integrity: sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} jest-runner@29.7.0: - resolution: - { - integrity: sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} jest-runtime@29.7.0: - resolution: - { - integrity: sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} jest-snapshot@29.7.0: - resolution: - { - integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} jest-util@29.7.0: - resolution: - { - integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} jest-validate@29.7.0: - resolution: - { - integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} jest-watcher@29.7.0: - resolution: - { - integrity: sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} jest-worker@29.7.0: - resolution: - { - integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} jest@29.7.0: - resolution: - { - integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 @@ -1585,577 +948,328 @@ packages: optional: true js-tokens@4.0.0: - resolution: - { - integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==, - } + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} js-yaml@3.14.1: - resolution: - { - integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==, - } + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} hasBin: true jsesc@2.5.2: - resolution: - { - integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==, - } - engines: { node: ">=4" } + resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} + engines: {node: '>=4'} hasBin: true json-parse-even-better-errors@2.3.1: - resolution: - { - integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==, - } + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} json5@2.2.3: - resolution: - { - integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==, - } - engines: { node: ">=6" } + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} hasBin: true kleur@3.0.3: - resolution: - { - integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==, - } - engines: { node: ">=6" } + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} leven@3.1.0: - resolution: - { - integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==, - } - engines: { node: ">=6" } + resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} + engines: {node: '>=6'} lines-and-columns@1.2.4: - resolution: - { - integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==, - } + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} locate-path@5.0.0: - resolution: - { - integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} lodash.memoize@4.1.2: - resolution: - { - integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==, - } + resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} lru-cache@5.1.1: - resolution: - { - integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==, - } + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} make-dir@4.0.0: - resolution: - { - integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==, - } - engines: { node: ">=10" } + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} make-error@1.3.6: - resolution: - { - integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==, - } + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} makeerror@1.0.12: - resolution: - { - integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==, - } + resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} merge-stream@2.0.0: - resolution: - { - integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==, - } + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} micromatch@4.0.7: - resolution: - { - integrity: sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==, - } - engines: { node: ">=8.6" } + resolution: {integrity: sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==} + engines: {node: '>=8.6'} mime-db@1.52.0: - resolution: - { - integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==, - } - engines: { node: ">= 0.6" } + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} mime-types@2.1.35: - resolution: - { - integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==, - } - engines: { node: ">= 0.6" } + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} mimic-fn@2.1.0: - resolution: - { - integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==, - } - engines: { node: ">=6" } + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} minimatch@3.1.2: - resolution: - { - integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==, - } + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} minimatch@5.1.6: - resolution: - { - integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==, - } - engines: { node: ">=10" } + resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} + engines: {node: '>=10'} ms@2.1.2: - resolution: - { - integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==, - } + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} natural-compare@1.4.0: - resolution: - { - integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==, - } + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} node-int64@0.4.0: - resolution: - { - integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==, - } + resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} node-releases@2.0.18: - resolution: - { - integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==, - } + resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} normalize-path@3.0.0: - resolution: - { - integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==, - } - engines: { node: ">=0.10.0" } + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} npm-run-path@4.0.1: - resolution: - { - integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} once@1.4.0: - resolution: - { - integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==, - } + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} onetime@5.1.2: - resolution: - { - integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==, - } - engines: { node: ">=6" } + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} p-limit@2.3.0: - resolution: - { - integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==, - } - engines: { node: ">=6" } + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} p-limit@3.1.0: - resolution: - { - integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==, - } - engines: { node: ">=10" } + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} p-locate@4.1.0: - resolution: - { - integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} p-try@2.2.0: - resolution: - { - integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==, - } - engines: { node: ">=6" } + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} parse-json@5.2.0: - resolution: - { - integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} path-exists@4.0.0: - resolution: - { - integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} path-is-absolute@1.0.1: - resolution: - { - integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==, - } - engines: { node: ">=0.10.0" } + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} path-key@3.1.1: - resolution: - { - integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} path-parse@1.0.7: - resolution: - { - integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==, - } + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} picocolors@1.0.1: - resolution: - { - integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==, - } + resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} picomatch@2.3.1: - resolution: - { - integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==, - } - engines: { node: ">=8.6" } + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} pirates@4.0.6: - resolution: - { - integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==, - } - engines: { node: ">= 6" } + resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} + engines: {node: '>= 6'} pkg-dir@4.2.0: - resolution: - { - integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} + engines: {node: '>=8'} posthog-js@1.155.4: - resolution: - { - integrity: sha512-suxwAsmZGqMDXJe/RaCKI3PaDEHiuMDDhKcJklgGAg7eDnywieRkr5CoPcOOvnqTDMnuOPETr98jpYBXKUwGFQ==, - } + resolution: {integrity: sha512-suxwAsmZGqMDXJe/RaCKI3PaDEHiuMDDhKcJklgGAg7eDnywieRkr5CoPcOOvnqTDMnuOPETr98jpYBXKUwGFQ==} posthog-node@4.1.0: - resolution: - { - integrity: sha512-Fd+aMWLjUttlPrfOniDWs35v62rOEIqP5GBzUvRswsNY8rr1g1KuDobqaRFGMCNnrtDmhzUN8y7QucrcwMY/+w==, - } - engines: { node: ">=15.0.0" } + resolution: {integrity: sha512-Fd+aMWLjUttlPrfOniDWs35v62rOEIqP5GBzUvRswsNY8rr1g1KuDobqaRFGMCNnrtDmhzUN8y7QucrcwMY/+w==} + engines: {node: '>=15.0.0'} preact@10.23.2: - resolution: - { - integrity: sha512-kKYfePf9rzKnxOAKDpsWhg/ysrHPqT+yQ7UW4JjdnqjFIeNUnNcEJvhuA8fDenxAGWzUqtd51DfVg7xp/8T9NA==, - } + resolution: {integrity: sha512-kKYfePf9rzKnxOAKDpsWhg/ysrHPqT+yQ7UW4JjdnqjFIeNUnNcEJvhuA8fDenxAGWzUqtd51DfVg7xp/8T9NA==} prettier@3.3.3: - resolution: - { - integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==, - } - engines: { node: ">=14" } + resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} + engines: {node: '>=14'} hasBin: true pretty-format@29.7.0: - resolution: - { - integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} prompts@2.4.2: - resolution: - { - integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==, - } - engines: { node: ">= 6" } + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} proxy-from-env@1.1.0: - resolution: - { - integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==, - } + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} pure-rand@6.1.0: - resolution: - { - integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==, - } + resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} react-is@18.3.1: - resolution: - { - integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==, - } + resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} require-directory@2.1.1: - resolution: - { - integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==, - } - engines: { node: ">=0.10.0" } + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} resolve-cwd@3.0.0: - resolution: - { - integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} + engines: {node: '>=8'} resolve-from@5.0.0: - resolution: - { - integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} resolve.exports@2.0.2: - resolution: - { - integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==, - } - engines: { node: ">=10" } + resolution: {integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==} + engines: {node: '>=10'} resolve@1.22.8: - resolution: - { - integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==, - } + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} hasBin: true rusha@0.8.14: - resolution: - { - integrity: sha512-cLgakCUf6PedEu15t8kbsjnwIFFR2D4RfL+W3iWFJ4iac7z4B0ZI8fxy4R3J956kAI68HclCFGL8MPoUVC3qVA==, - } + resolution: {integrity: sha512-cLgakCUf6PedEu15t8kbsjnwIFFR2D4RfL+W3iWFJ4iac7z4B0ZI8fxy4R3J956kAI68HclCFGL8MPoUVC3qVA==} semver@6.3.1: - resolution: - { - integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==, - } + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true semver@7.6.3: - resolution: - { - integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==, - } - engines: { node: ">=10" } + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} + engines: {node: '>=10'} hasBin: true shebang-command@2.0.0: - resolution: - { - integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} shebang-regex@3.0.0: - resolution: - { - integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} signal-exit@3.0.7: - resolution: - { - integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==, - } + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} sisteransi@1.0.5: - resolution: - { - integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==, - } + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} slash@3.0.0: - resolution: - { - integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} source-map-support@0.5.13: - resolution: - { - integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==, - } + resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} source-map@0.6.1: - resolution: - { - integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==, - } - engines: { node: ">=0.10.0" } + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} sprintf-js@1.0.3: - resolution: - { - integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==, - } + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} stack-utils@2.0.6: - resolution: - { - integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==, - } - engines: { node: ">=10" } + resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} + engines: {node: '>=10'} string-length@4.0.2: - resolution: - { - integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==, - } - engines: { node: ">=10" } + resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} + engines: {node: '>=10'} string-width@4.2.3: - resolution: - { - integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} strip-ansi@6.0.1: - resolution: - { - integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} strip-bom@4.0.0: - resolution: - { - integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} + engines: {node: '>=8'} strip-final-newline@2.0.0: - resolution: - { - integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==, - } - engines: { node: ">=6" } + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} strip-json-comments@3.1.1: - resolution: - { - integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} supports-color@5.5.0: - resolution: - { - integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==, - } - engines: { node: ">=4" } + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} supports-color@7.2.0: - resolution: - { - integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} supports-color@8.1.1: - resolution: - { - integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==, - } - engines: { node: ">=10" } + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} supports-preserve-symlinks-flag@1.0.0: - resolution: - { - integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==, - } - engines: { node: ">= 0.4" } + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} test-exclude@6.0.0: - resolution: - { - integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} + engines: {node: '>=8'} tmpl@1.0.5: - resolution: - { - integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==, - } + resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} to-fast-properties@2.0.0: - resolution: - { - integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==, - } - engines: { node: ">=4" } + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} to-regex-range@5.0.1: - resolution: - { - integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==, - } - engines: { node: ">=8.0" } + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} ts-jest@29.2.4: - resolution: - { - integrity: sha512-3d6tgDyhCI29HlpwIq87sNuI+3Q6GLTTCeYRHCs7vDz+/3GCMwEtV9jezLyl4ZtnBgx00I7hm8PCP8cTksMGrw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0 } + resolution: {integrity: sha512-3d6tgDyhCI29HlpwIq87sNuI+3Q6GLTTCeYRHCs7vDz+/3GCMwEtV9jezLyl4ZtnBgx00I7hm8PCP8cTksMGrw==} + engines: {node: ^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: - "@babel/core": ">=7.0.0-beta.0 <8" - "@jest/transform": ^29.0.0 - "@jest/types": ^29.0.0 + '@babel/core': '>=7.0.0-beta.0 <8' + '@jest/transform': ^29.0.0 + '@jest/types': ^29.0.0 babel-jest: ^29.0.0 - esbuild: "*" + esbuild: '*' jest: ^29.0.0 - typescript: ">=4.3 <6" + typescript: '>=4.3 <6' peerDependenciesMeta: - "@babel/core": + '@babel/core': optional: true - "@jest/transform": + '@jest/transform': optional: true - "@jest/types": + '@jest/types': optional: true babel-jest: optional: true @@ -2163,185 +1277,123 @@ packages: optional: true ts-node@10.9.2: - resolution: - { - integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==, - } + resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} hasBin: true peerDependencies: - "@swc/core": ">=1.2.50" - "@swc/wasm": ">=1.2.50" - "@types/node": "*" - typescript: ">=2.7" + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' peerDependenciesMeta: - "@swc/core": + '@swc/core': optional: true - "@swc/wasm": + '@swc/wasm': optional: true type-detect@4.0.8: - resolution: - { - integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==, - } - engines: { node: ">=4" } + resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} + engines: {node: '>=4'} type-fest@0.21.3: - resolution: - { - integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==, - } - engines: { node: ">=10" } + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} typescript@5.5.4: - resolution: - { - integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==, - } - engines: { node: ">=14.17" } + resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==} + engines: {node: '>=14.17'} hasBin: true undici-types@5.26.5: - resolution: - { - integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==, - } + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} update-browserslist-db@1.1.0: - resolution: - { - integrity: sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==, - } + resolution: {integrity: sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==} hasBin: true peerDependencies: - browserslist: ">= 4.21.0" + browserslist: '>= 4.21.0' uuid@10.0.0: - resolution: - { - integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==, - } + resolution: {integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==} hasBin: true v8-compile-cache-lib@3.0.1: - resolution: - { - integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==, - } + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} v8-to-istanbul@9.3.0: - resolution: - { - integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==, - } - engines: { node: ">=10.12.0" } + resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} + engines: {node: '>=10.12.0'} walker@1.0.8: - resolution: - { - integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==, - } + resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} web-vitals@4.2.3: - resolution: - { - integrity: sha512-/CFAm1mNxSmOj6i0Co+iGFJ58OS4NRGVP+AWS/l509uIK5a1bSoIVaHz/ZumpHTfHSZBpgrJ+wjfpAOrTHok5Q==, - } + resolution: {integrity: sha512-/CFAm1mNxSmOj6i0Co+iGFJ58OS4NRGVP+AWS/l509uIK5a1bSoIVaHz/ZumpHTfHSZBpgrJ+wjfpAOrTHok5Q==} which@2.0.2: - resolution: - { - integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==, - } - engines: { node: ">= 8" } + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} hasBin: true wrap-ansi@7.0.0: - resolution: - { - integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==, - } - engines: { node: ">=10" } + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} wrappy@1.0.2: - resolution: - { - integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==, - } + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} write-file-atomic@4.0.2: - resolution: - { - integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==, - } - engines: { node: ^12.13.0 || ^14.15.0 || >=16.0.0 } + resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} y18n@5.0.8: - resolution: - { - integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==, - } - engines: { node: ">=10" } + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} yallist@3.1.1: - resolution: - { - integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==, - } + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} yargs-parser@21.1.1: - resolution: - { - integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==, - } - engines: { node: ">=12" } + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} yargs@17.7.2: - resolution: - { - integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==, - } - engines: { node: ">=12" } + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} yn@3.1.1: - resolution: - { - integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==, - } - engines: { node: ">=6" } + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} yocto-queue@0.1.0: - resolution: - { - integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==, - } - engines: { node: ">=10" } + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} snapshots: - "@ampproject/remapping@2.3.0": + + '@ampproject/remapping@2.3.0': dependencies: - "@jridgewell/gen-mapping": 0.3.5 - "@jridgewell/trace-mapping": 0.3.25 + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 - "@babel/code-frame@7.24.7": + '@babel/code-frame@7.24.7': dependencies: - "@babel/highlight": 7.24.7 + '@babel/highlight': 7.24.7 picocolors: 1.0.1 - "@babel/compat-data@7.25.2": {} + '@babel/compat-data@7.25.2': {} - "@babel/core@7.25.2": + '@babel/core@7.25.2': dependencies: - "@ampproject/remapping": 2.3.0 - "@babel/code-frame": 7.24.7 - "@babel/generator": 7.25.0 - "@babel/helper-compilation-targets": 7.25.2 - "@babel/helper-module-transforms": 7.25.2(@babel/core@7.25.2) - "@babel/helpers": 7.25.0 - "@babel/parser": 7.25.3 - "@babel/template": 7.25.0 - "@babel/traverse": 7.25.3 - "@babel/types": 7.25.2 + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.24.7 + '@babel/generator': 7.25.0 + '@babel/helper-compilation-targets': 7.25.2 + '@babel/helper-module-transforms': 7.25.2(@babel/core@7.25.2) + '@babel/helpers': 7.25.0 + '@babel/parser': 7.25.3 + '@babel/template': 7.25.0 + '@babel/traverse': 7.25.3 + '@babel/types': 7.25.2 convert-source-map: 2.0.0 debug: 4.3.6 gensync: 1.0.0-beta.2 @@ -2350,185 +1402,185 @@ snapshots: transitivePeerDependencies: - supports-color - "@babel/generator@7.25.0": + '@babel/generator@7.25.0': dependencies: - "@babel/types": 7.25.2 - "@jridgewell/gen-mapping": 0.3.5 - "@jridgewell/trace-mapping": 0.3.25 + '@babel/types': 7.25.2 + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 jsesc: 2.5.2 - "@babel/helper-compilation-targets@7.25.2": + '@babel/helper-compilation-targets@7.25.2': dependencies: - "@babel/compat-data": 7.25.2 - "@babel/helper-validator-option": 7.24.8 + '@babel/compat-data': 7.25.2 + '@babel/helper-validator-option': 7.24.8 browserslist: 4.23.3 lru-cache: 5.1.1 semver: 6.3.1 - "@babel/helper-module-imports@7.24.7": + '@babel/helper-module-imports@7.24.7': dependencies: - "@babel/traverse": 7.25.3 - "@babel/types": 7.25.2 + '@babel/traverse': 7.25.3 + '@babel/types': 7.25.2 transitivePeerDependencies: - supports-color - "@babel/helper-module-transforms@7.25.2(@babel/core@7.25.2)": + '@babel/helper-module-transforms@7.25.2(@babel/core@7.25.2)': dependencies: - "@babel/core": 7.25.2 - "@babel/helper-module-imports": 7.24.7 - "@babel/helper-simple-access": 7.24.7 - "@babel/helper-validator-identifier": 7.24.7 - "@babel/traverse": 7.25.3 + '@babel/core': 7.25.2 + '@babel/helper-module-imports': 7.24.7 + '@babel/helper-simple-access': 7.24.7 + '@babel/helper-validator-identifier': 7.24.7 + '@babel/traverse': 7.25.3 transitivePeerDependencies: - supports-color - "@babel/helper-plugin-utils@7.24.8": {} + '@babel/helper-plugin-utils@7.24.8': {} - "@babel/helper-simple-access@7.24.7": + '@babel/helper-simple-access@7.24.7': dependencies: - "@babel/traverse": 7.25.3 - "@babel/types": 7.25.2 + '@babel/traverse': 7.25.3 + '@babel/types': 7.25.2 transitivePeerDependencies: - supports-color - "@babel/helper-string-parser@7.24.8": {} + '@babel/helper-string-parser@7.24.8': {} - "@babel/helper-validator-identifier@7.24.7": {} + '@babel/helper-validator-identifier@7.24.7': {} - "@babel/helper-validator-option@7.24.8": {} + '@babel/helper-validator-option@7.24.8': {} - "@babel/helpers@7.25.0": + '@babel/helpers@7.25.0': dependencies: - "@babel/template": 7.25.0 - "@babel/types": 7.25.2 + '@babel/template': 7.25.0 + '@babel/types': 7.25.2 - "@babel/highlight@7.24.7": + '@babel/highlight@7.24.7': dependencies: - "@babel/helper-validator-identifier": 7.24.7 + '@babel/helper-validator-identifier': 7.24.7 chalk: 2.4.2 js-tokens: 4.0.0 picocolors: 1.0.1 - "@babel/parser@7.25.3": + '@babel/parser@7.25.3': dependencies: - "@babel/types": 7.25.2 + '@babel/types': 7.25.2 - "@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.25.2)": + '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.25.2)': dependencies: - "@babel/core": 7.25.2 - "@babel/helper-plugin-utils": 7.24.8 + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 - "@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.25.2)": + '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.25.2)': dependencies: - "@babel/core": 7.25.2 - "@babel/helper-plugin-utils": 7.24.8 + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 - "@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.25.2)": + '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.25.2)': dependencies: - "@babel/core": 7.25.2 - "@babel/helper-plugin-utils": 7.24.8 + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 - "@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.25.2)": + '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.25.2)': dependencies: - "@babel/core": 7.25.2 - "@babel/helper-plugin-utils": 7.24.8 + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 - "@babel/plugin-syntax-import-attributes@7.24.7(@babel/core@7.25.2)": + '@babel/plugin-syntax-import-attributes@7.24.7(@babel/core@7.25.2)': dependencies: - "@babel/core": 7.25.2 - "@babel/helper-plugin-utils": 7.24.8 + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 - "@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.25.2)": + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.25.2)': dependencies: - "@babel/core": 7.25.2 - "@babel/helper-plugin-utils": 7.24.8 + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 - "@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.25.2)": + '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.25.2)': dependencies: - "@babel/core": 7.25.2 - "@babel/helper-plugin-utils": 7.24.8 + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 - "@babel/plugin-syntax-jsx@7.24.7(@babel/core@7.25.2)": + '@babel/plugin-syntax-jsx@7.24.7(@babel/core@7.25.2)': dependencies: - "@babel/core": 7.25.2 - "@babel/helper-plugin-utils": 7.24.8 + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 - "@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.25.2)": + '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.25.2)': dependencies: - "@babel/core": 7.25.2 - "@babel/helper-plugin-utils": 7.24.8 + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 - "@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.25.2)": + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.25.2)': dependencies: - "@babel/core": 7.25.2 - "@babel/helper-plugin-utils": 7.24.8 + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 - "@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.25.2)": + '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.25.2)': dependencies: - "@babel/core": 7.25.2 - "@babel/helper-plugin-utils": 7.24.8 + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 - "@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.25.2)": + '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.25.2)': dependencies: - "@babel/core": 7.25.2 - "@babel/helper-plugin-utils": 7.24.8 + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 - "@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.25.2)": + '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.25.2)': dependencies: - "@babel/core": 7.25.2 - "@babel/helper-plugin-utils": 7.24.8 + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 - "@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.25.2)": + '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.25.2)': dependencies: - "@babel/core": 7.25.2 - "@babel/helper-plugin-utils": 7.24.8 + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 - "@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.25.2)": + '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.25.2)': dependencies: - "@babel/core": 7.25.2 - "@babel/helper-plugin-utils": 7.24.8 + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 - "@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.25.2)": + '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.25.2)': dependencies: - "@babel/core": 7.25.2 - "@babel/helper-plugin-utils": 7.24.8 + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 - "@babel/plugin-syntax-typescript@7.24.7(@babel/core@7.25.2)": + '@babel/plugin-syntax-typescript@7.24.7(@babel/core@7.25.2)': dependencies: - "@babel/core": 7.25.2 - "@babel/helper-plugin-utils": 7.24.8 + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 - "@babel/template@7.25.0": + '@babel/template@7.25.0': dependencies: - "@babel/code-frame": 7.24.7 - "@babel/parser": 7.25.3 - "@babel/types": 7.25.2 + '@babel/code-frame': 7.24.7 + '@babel/parser': 7.25.3 + '@babel/types': 7.25.2 - "@babel/traverse@7.25.3": + '@babel/traverse@7.25.3': dependencies: - "@babel/code-frame": 7.24.7 - "@babel/generator": 7.25.0 - "@babel/parser": 7.25.3 - "@babel/template": 7.25.0 - "@babel/types": 7.25.2 + '@babel/code-frame': 7.24.7 + '@babel/generator': 7.25.0 + '@babel/parser': 7.25.3 + '@babel/template': 7.25.0 + '@babel/types': 7.25.2 debug: 4.3.6 globals: 11.12.0 transitivePeerDependencies: - supports-color - "@babel/types@7.25.2": + '@babel/types@7.25.2': dependencies: - "@babel/helper-string-parser": 7.24.8 - "@babel/helper-validator-identifier": 7.24.7 + '@babel/helper-string-parser': 7.24.8 + '@babel/helper-validator-identifier': 7.24.7 to-fast-properties: 2.0.0 - "@bcoe/v8-coverage@0.2.3": {} + '@bcoe/v8-coverage@0.2.3': {} - "@cspotcode/source-map-support@0.8.1": + '@cspotcode/source-map-support@0.8.1': dependencies: - "@jridgewell/trace-mapping": 0.3.9 + '@jridgewell/trace-mapping': 0.3.9 - "@istanbuljs/load-nyc-config@1.1.0": + '@istanbuljs/load-nyc-config@1.1.0': dependencies: camelcase: 5.3.1 find-up: 4.1.0 @@ -2536,25 +1588,25 @@ snapshots: js-yaml: 3.14.1 resolve-from: 5.0.0 - "@istanbuljs/schema@0.1.3": {} + '@istanbuljs/schema@0.1.3': {} - "@jest/console@29.7.0": + '@jest/console@29.7.0': dependencies: - "@jest/types": 29.6.3 - "@types/node": 20.14.15 + '@jest/types': 29.6.3 + '@types/node': 20.14.15 chalk: 4.1.2 jest-message-util: 29.7.0 jest-util: 29.7.0 slash: 3.0.0 - "@jest/core@29.7.0(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))": + '@jest/core@29.7.0(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))': dependencies: - "@jest/console": 29.7.0 - "@jest/reporters": 29.7.0 - "@jest/test-result": 29.7.0 - "@jest/transform": 29.7.0 - "@jest/types": 29.6.3 - "@types/node": 20.14.15 + '@jest/console': 29.7.0 + '@jest/reporters': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.14.15 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.9.0 @@ -2582,51 +1634,51 @@ snapshots: - supports-color - ts-node - "@jest/environment@29.7.0": + '@jest/environment@29.7.0': dependencies: - "@jest/fake-timers": 29.7.0 - "@jest/types": 29.6.3 - "@types/node": 20.14.15 + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.14.15 jest-mock: 29.7.0 - "@jest/expect-utils@29.7.0": + '@jest/expect-utils@29.7.0': dependencies: jest-get-type: 29.6.3 - "@jest/expect@29.7.0": + '@jest/expect@29.7.0': dependencies: expect: 29.7.0 jest-snapshot: 29.7.0 transitivePeerDependencies: - supports-color - "@jest/fake-timers@29.7.0": + '@jest/fake-timers@29.7.0': dependencies: - "@jest/types": 29.6.3 - "@sinonjs/fake-timers": 10.3.0 - "@types/node": 20.14.15 + '@jest/types': 29.6.3 + '@sinonjs/fake-timers': 10.3.0 + '@types/node': 20.14.15 jest-message-util: 29.7.0 jest-mock: 29.7.0 jest-util: 29.7.0 - "@jest/globals@29.7.0": + '@jest/globals@29.7.0': dependencies: - "@jest/environment": 29.7.0 - "@jest/expect": 29.7.0 - "@jest/types": 29.6.3 + '@jest/environment': 29.7.0 + '@jest/expect': 29.7.0 + '@jest/types': 29.6.3 jest-mock: 29.7.0 transitivePeerDependencies: - supports-color - "@jest/reporters@29.7.0": + '@jest/reporters@29.7.0': dependencies: - "@bcoe/v8-coverage": 0.2.3 - "@jest/console": 29.7.0 - "@jest/test-result": 29.7.0 - "@jest/transform": 29.7.0 - "@jest/types": 29.6.3 - "@jridgewell/trace-mapping": 0.3.25 - "@types/node": 20.14.15 + '@bcoe/v8-coverage': 0.2.3 + '@jest/console': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@jridgewell/trace-mapping': 0.3.25 + '@types/node': 20.14.15 chalk: 4.1.2 collect-v8-coverage: 1.0.2 exit: 0.1.2 @@ -2647,35 +1699,35 @@ snapshots: transitivePeerDependencies: - supports-color - "@jest/schemas@29.6.3": + '@jest/schemas@29.6.3': dependencies: - "@sinclair/typebox": 0.27.8 + '@sinclair/typebox': 0.27.8 - "@jest/source-map@29.6.3": + '@jest/source-map@29.6.3': dependencies: - "@jridgewell/trace-mapping": 0.3.25 + '@jridgewell/trace-mapping': 0.3.25 callsites: 3.1.0 graceful-fs: 4.2.11 - "@jest/test-result@29.7.0": + '@jest/test-result@29.7.0': dependencies: - "@jest/console": 29.7.0 - "@jest/types": 29.6.3 - "@types/istanbul-lib-coverage": 2.0.6 + '@jest/console': 29.7.0 + '@jest/types': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.6 collect-v8-coverage: 1.0.2 - "@jest/test-sequencer@29.7.0": + '@jest/test-sequencer@29.7.0': dependencies: - "@jest/test-result": 29.7.0 + '@jest/test-result': 29.7.0 graceful-fs: 4.2.11 jest-haste-map: 29.7.0 slash: 3.0.0 - "@jest/transform@29.7.0": + '@jest/transform@29.7.0': dependencies: - "@babel/core": 7.25.2 - "@jest/types": 29.6.3 - "@jridgewell/trace-mapping": 0.3.25 + '@babel/core': 7.25.2 + '@jest/types': 29.6.3 + '@jridgewell/trace-mapping': 0.3.25 babel-plugin-istanbul: 6.1.1 chalk: 4.1.2 convert-source-map: 2.0.0 @@ -2691,108 +1743,110 @@ snapshots: transitivePeerDependencies: - supports-color - "@jest/types@29.6.3": + '@jest/types@29.6.3': dependencies: - "@jest/schemas": 29.6.3 - "@types/istanbul-lib-coverage": 2.0.6 - "@types/istanbul-reports": 3.0.4 - "@types/node": 20.14.15 - "@types/yargs": 17.0.33 + '@jest/schemas': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-reports': 3.0.4 + '@types/node': 20.14.15 + '@types/yargs': 17.0.33 chalk: 4.1.2 - "@jridgewell/gen-mapping@0.3.5": + '@jridgewell/gen-mapping@0.3.5': dependencies: - "@jridgewell/set-array": 1.2.1 - "@jridgewell/sourcemap-codec": 1.5.0 - "@jridgewell/trace-mapping": 0.3.25 + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 - "@jridgewell/resolve-uri@3.1.2": {} + '@jridgewell/resolve-uri@3.1.2': {} - "@jridgewell/set-array@1.2.1": {} + '@jridgewell/set-array@1.2.1': {} - "@jridgewell/sourcemap-codec@1.5.0": {} + '@jridgewell/sourcemap-codec@1.5.0': {} - "@jridgewell/trace-mapping@0.3.25": + '@jridgewell/trace-mapping@0.3.25': dependencies: - "@jridgewell/resolve-uri": 3.1.2 - "@jridgewell/sourcemap-codec": 1.5.0 + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 - "@jridgewell/trace-mapping@0.3.9": + '@jridgewell/trace-mapping@0.3.9': dependencies: - "@jridgewell/resolve-uri": 3.1.2 - "@jridgewell/sourcemap-codec": 1.5.0 + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 - "@sinclair/typebox@0.27.8": {} + '@sinclair/typebox@0.27.8': {} - "@sinonjs/commons@3.0.1": + '@sinonjs/commons@3.0.1': dependencies: type-detect: 4.0.8 - "@sinonjs/fake-timers@10.3.0": + '@sinonjs/fake-timers@10.3.0': dependencies: - "@sinonjs/commons": 3.0.1 + '@sinonjs/commons': 3.0.1 - "@tsconfig/node10@1.0.11": {} + '@tsconfig/node10@1.0.11': {} - "@tsconfig/node12@1.0.11": {} + '@tsconfig/node12@1.0.11': {} - "@tsconfig/node14@1.0.3": {} + '@tsconfig/node14@1.0.3': {} - "@tsconfig/node16@1.0.4": {} + '@tsconfig/node16@1.0.4': {} - "@types/babel__core@7.20.5": + '@types/babel__core@7.20.5': dependencies: - "@babel/parser": 7.25.3 - "@babel/types": 7.25.2 - "@types/babel__generator": 7.6.8 - "@types/babel__template": 7.4.4 - "@types/babel__traverse": 7.20.6 + '@babel/parser': 7.25.3 + '@babel/types': 7.25.2 + '@types/babel__generator': 7.6.8 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.20.6 - "@types/babel__generator@7.6.8": + '@types/babel__generator@7.6.8': dependencies: - "@babel/types": 7.25.2 + '@babel/types': 7.25.2 - "@types/babel__template@7.4.4": + '@types/babel__template@7.4.4': dependencies: - "@babel/parser": 7.25.3 - "@babel/types": 7.25.2 + '@babel/parser': 7.25.3 + '@babel/types': 7.25.2 - "@types/babel__traverse@7.20.6": + '@types/babel__traverse@7.20.6': dependencies: - "@babel/types": 7.25.2 + '@babel/types': 7.25.2 - "@types/graceful-fs@4.1.9": + '@types/graceful-fs@4.1.9': dependencies: - "@types/node": 20.14.15 + '@types/node': 20.14.15 - "@types/istanbul-lib-coverage@2.0.6": {} + '@types/istanbul-lib-coverage@2.0.6': {} - "@types/istanbul-lib-report@3.0.3": + '@types/istanbul-lib-report@3.0.3': dependencies: - "@types/istanbul-lib-coverage": 2.0.6 + '@types/istanbul-lib-coverage': 2.0.6 - "@types/istanbul-reports@3.0.4": + '@types/istanbul-reports@3.0.4': dependencies: - "@types/istanbul-lib-report": 3.0.3 + '@types/istanbul-lib-report': 3.0.3 - "@types/jest@29.5.12": + '@types/jest@29.5.12': dependencies: expect: 29.7.0 pretty-format: 29.7.0 - "@types/node@20.14.15": + '@types/mocha@10.0.7': {} + + '@types/node@20.14.15': dependencies: undici-types: 5.26.5 - "@types/stack-utils@2.0.3": {} + '@types/stack-utils@2.0.3': {} - "@types/uuid@10.0.0": {} + '@types/uuid@10.0.0': {} - "@types/yargs-parser@21.0.3": {} + '@types/yargs-parser@21.0.3': {} - "@types/yargs@17.0.33": + '@types/yargs@17.0.33': dependencies: - "@types/yargs-parser": 21.0.3 + '@types/yargs-parser': 21.0.3 acorn-walk@8.3.3: dependencies: @@ -2841,9 +1895,9 @@ snapshots: babel-jest@29.7.0(@babel/core@7.25.2): dependencies: - "@babel/core": 7.25.2 - "@jest/transform": 29.7.0 - "@types/babel__core": 7.20.5 + '@babel/core': 7.25.2 + '@jest/transform': 29.7.0 + '@types/babel__core': 7.20.5 babel-plugin-istanbul: 6.1.1 babel-preset-jest: 29.6.3(@babel/core@7.25.2) chalk: 4.1.2 @@ -2854,9 +1908,9 @@ snapshots: babel-plugin-istanbul@6.1.1: dependencies: - "@babel/helper-plugin-utils": 7.24.8 - "@istanbuljs/load-nyc-config": 1.1.0 - "@istanbuljs/schema": 0.1.3 + '@babel/helper-plugin-utils': 7.24.8 + '@istanbuljs/load-nyc-config': 1.1.0 + '@istanbuljs/schema': 0.1.3 istanbul-lib-instrument: 5.2.1 test-exclude: 6.0.0 transitivePeerDependencies: @@ -2864,33 +1918,33 @@ snapshots: babel-plugin-jest-hoist@29.6.3: dependencies: - "@babel/template": 7.25.0 - "@babel/types": 7.25.2 - "@types/babel__core": 7.20.5 - "@types/babel__traverse": 7.20.6 + '@babel/template': 7.25.0 + '@babel/types': 7.25.2 + '@types/babel__core': 7.20.5 + '@types/babel__traverse': 7.20.6 babel-preset-current-node-syntax@1.1.0(@babel/core@7.25.2): dependencies: - "@babel/core": 7.25.2 - "@babel/plugin-syntax-async-generators": 7.8.4(@babel/core@7.25.2) - "@babel/plugin-syntax-bigint": 7.8.3(@babel/core@7.25.2) - "@babel/plugin-syntax-class-properties": 7.12.13(@babel/core@7.25.2) - "@babel/plugin-syntax-class-static-block": 7.14.5(@babel/core@7.25.2) - "@babel/plugin-syntax-import-attributes": 7.24.7(@babel/core@7.25.2) - "@babel/plugin-syntax-import-meta": 7.10.4(@babel/core@7.25.2) - "@babel/plugin-syntax-json-strings": 7.8.3(@babel/core@7.25.2) - "@babel/plugin-syntax-logical-assignment-operators": 7.10.4(@babel/core@7.25.2) - "@babel/plugin-syntax-nullish-coalescing-operator": 7.8.3(@babel/core@7.25.2) - "@babel/plugin-syntax-numeric-separator": 7.10.4(@babel/core@7.25.2) - "@babel/plugin-syntax-object-rest-spread": 7.8.3(@babel/core@7.25.2) - "@babel/plugin-syntax-optional-catch-binding": 7.8.3(@babel/core@7.25.2) - "@babel/plugin-syntax-optional-chaining": 7.8.3(@babel/core@7.25.2) - "@babel/plugin-syntax-private-property-in-object": 7.14.5(@babel/core@7.25.2) - "@babel/plugin-syntax-top-level-await": 7.14.5(@babel/core@7.25.2) + '@babel/core': 7.25.2 + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.25.2) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.25.2) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.25.2) + '@babel/plugin-syntax-import-attributes': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.25.2) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.25.2) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.25.2) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.25.2) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.25.2) babel-preset-jest@29.6.3(@babel/core@7.25.2): dependencies: - "@babel/core": 7.25.2 + '@babel/core': 7.25.2 babel-plugin-jest-hoist: 29.6.3 babel-preset-current-node-syntax: 1.1.0(@babel/core@7.25.2) @@ -2983,7 +2037,7 @@ snapshots: create-jest@29.7.0(@types/node@20.14.15)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)): dependencies: - "@jest/types": 29.6.3 + '@jest/types': 29.6.3 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 @@ -2991,7 +2045,7 @@ snapshots: jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: - - "@types/node" + - '@types/node' - babel-plugin-macros - supports-color - ts-node @@ -3058,7 +2112,7 @@ snapshots: expect@29.7.0: dependencies: - "@jest/expect-utils": 29.7.0 + '@jest/expect-utils': 29.7.0 jest-get-type: 29.6.3 jest-matcher-utils: 29.7.0 jest-message-util: 29.7.0 @@ -3167,9 +2221,9 @@ snapshots: istanbul-lib-instrument@5.2.1: dependencies: - "@babel/core": 7.25.2 - "@babel/parser": 7.25.3 - "@istanbuljs/schema": 0.1.3 + '@babel/core': 7.25.2 + '@babel/parser': 7.25.3 + '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 semver: 6.3.1 transitivePeerDependencies: @@ -3177,9 +2231,9 @@ snapshots: istanbul-lib-instrument@6.0.3: dependencies: - "@babel/core": 7.25.2 - "@babel/parser": 7.25.3 - "@istanbuljs/schema": 0.1.3 + '@babel/core': 7.25.2 + '@babel/parser': 7.25.3 + '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 semver: 7.6.3 transitivePeerDependencies: @@ -3219,11 +2273,11 @@ snapshots: jest-circus@29.7.0: dependencies: - "@jest/environment": 29.7.0 - "@jest/expect": 29.7.0 - "@jest/test-result": 29.7.0 - "@jest/types": 29.6.3 - "@types/node": 20.14.15 + '@jest/environment': 29.7.0 + '@jest/expect': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.14.15 chalk: 4.1.2 co: 4.6.0 dedent: 1.5.3 @@ -3245,9 +2299,9 @@ snapshots: jest-cli@29.7.0(@types/node@20.14.15)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)): dependencies: - "@jest/core": 29.7.0(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)) - "@jest/test-result": 29.7.0 - "@jest/types": 29.6.3 + '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)) + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 chalk: 4.1.2 create-jest: 29.7.0(@types/node@20.14.15)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)) exit: 0.1.2 @@ -3257,16 +2311,16 @@ snapshots: jest-validate: 29.7.0 yargs: 17.7.2 transitivePeerDependencies: - - "@types/node" + - '@types/node' - babel-plugin-macros - supports-color - ts-node jest-config@29.7.0(@types/node@20.14.15)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)): dependencies: - "@babel/core": 7.25.2 - "@jest/test-sequencer": 29.7.0 - "@jest/types": 29.6.3 + '@babel/core': 7.25.2 + '@jest/test-sequencer': 29.7.0 + '@jest/types': 29.6.3 babel-jest: 29.7.0(@babel/core@7.25.2) chalk: 4.1.2 ci-info: 3.9.0 @@ -3287,7 +2341,7 @@ snapshots: slash: 3.0.0 strip-json-comments: 3.1.1 optionalDependencies: - "@types/node": 20.14.15 + '@types/node': 20.14.15 ts-node: 10.9.2(@types/node@20.14.15)(typescript@5.5.4) transitivePeerDependencies: - babel-plugin-macros @@ -3306,7 +2360,7 @@ snapshots: jest-each@29.7.0: dependencies: - "@jest/types": 29.6.3 + '@jest/types': 29.6.3 chalk: 4.1.2 jest-get-type: 29.6.3 jest-util: 29.7.0 @@ -3314,10 +2368,10 @@ snapshots: jest-environment-node@29.7.0: dependencies: - "@jest/environment": 29.7.0 - "@jest/fake-timers": 29.7.0 - "@jest/types": 29.6.3 - "@types/node": 20.14.15 + '@jest/environment': 29.7.0 + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.14.15 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -3325,9 +2379,9 @@ snapshots: jest-haste-map@29.7.0: dependencies: - "@jest/types": 29.6.3 - "@types/graceful-fs": 4.1.9 - "@types/node": 20.14.15 + '@jest/types': 29.6.3 + '@types/graceful-fs': 4.1.9 + '@types/node': 20.14.15 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 @@ -3353,9 +2407,9 @@ snapshots: jest-message-util@29.7.0: dependencies: - "@babel/code-frame": 7.24.7 - "@jest/types": 29.6.3 - "@types/stack-utils": 2.0.3 + '@babel/code-frame': 7.24.7 + '@jest/types': 29.6.3 + '@types/stack-utils': 2.0.3 chalk: 4.1.2 graceful-fs: 4.2.11 micromatch: 4.0.7 @@ -3365,8 +2419,8 @@ snapshots: jest-mock@29.7.0: dependencies: - "@jest/types": 29.6.3 - "@types/node": 20.14.15 + '@jest/types': 29.6.3 + '@types/node': 20.14.15 jest-util: 29.7.0 jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): @@ -3396,12 +2450,12 @@ snapshots: jest-runner@29.7.0: dependencies: - "@jest/console": 29.7.0 - "@jest/environment": 29.7.0 - "@jest/test-result": 29.7.0 - "@jest/transform": 29.7.0 - "@jest/types": 29.6.3 - "@types/node": 20.14.15 + '@jest/console': 29.7.0 + '@jest/environment': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.14.15 chalk: 4.1.2 emittery: 0.13.1 graceful-fs: 4.2.11 @@ -3422,14 +2476,14 @@ snapshots: jest-runtime@29.7.0: dependencies: - "@jest/environment": 29.7.0 - "@jest/fake-timers": 29.7.0 - "@jest/globals": 29.7.0 - "@jest/source-map": 29.6.3 - "@jest/test-result": 29.7.0 - "@jest/transform": 29.7.0 - "@jest/types": 29.6.3 - "@types/node": 20.14.15 + '@jest/environment': 29.7.0 + '@jest/fake-timers': 29.7.0 + '@jest/globals': 29.7.0 + '@jest/source-map': 29.6.3 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.14.15 chalk: 4.1.2 cjs-module-lexer: 1.3.1 collect-v8-coverage: 1.0.2 @@ -3449,14 +2503,14 @@ snapshots: jest-snapshot@29.7.0: dependencies: - "@babel/core": 7.25.2 - "@babel/generator": 7.25.0 - "@babel/plugin-syntax-jsx": 7.24.7(@babel/core@7.25.2) - "@babel/plugin-syntax-typescript": 7.24.7(@babel/core@7.25.2) - "@babel/types": 7.25.2 - "@jest/expect-utils": 29.7.0 - "@jest/transform": 29.7.0 - "@jest/types": 29.6.3 + '@babel/core': 7.25.2 + '@babel/generator': 7.25.0 + '@babel/plugin-syntax-jsx': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-syntax-typescript': 7.24.7(@babel/core@7.25.2) + '@babel/types': 7.25.2 + '@jest/expect-utils': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 babel-preset-current-node-syntax: 1.1.0(@babel/core@7.25.2) chalk: 4.1.2 expect: 29.7.0 @@ -3474,8 +2528,8 @@ snapshots: jest-util@29.7.0: dependencies: - "@jest/types": 29.6.3 - "@types/node": 20.14.15 + '@jest/types': 29.6.3 + '@types/node': 20.14.15 chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 @@ -3483,7 +2537,7 @@ snapshots: jest-validate@29.7.0: dependencies: - "@jest/types": 29.6.3 + '@jest/types': 29.6.3 camelcase: 6.3.0 chalk: 4.1.2 jest-get-type: 29.6.3 @@ -3492,9 +2546,9 @@ snapshots: jest-watcher@29.7.0: dependencies: - "@jest/test-result": 29.7.0 - "@jest/types": 29.6.3 - "@types/node": 20.14.15 + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.14.15 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 @@ -3503,19 +2557,19 @@ snapshots: jest-worker@29.7.0: dependencies: - "@types/node": 20.14.15 + '@types/node': 20.14.15 jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 jest@29.7.0(@types/node@20.14.15)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)): dependencies: - "@jest/core": 29.7.0(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)) - "@jest/types": 29.6.3 + '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)) + '@jest/types': 29.6.3 import-local: 3.2.0 jest-cli: 29.7.0(@types/node@20.14.15)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)) transitivePeerDependencies: - - "@types/node" + - '@types/node' - babel-plugin-macros - supports-color - ts-node @@ -3620,7 +2674,7 @@ snapshots: parse-json@5.2.0: dependencies: - "@babel/code-frame": 7.24.7 + '@babel/code-frame': 7.24.7 error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 @@ -3662,7 +2716,7 @@ snapshots: pretty-format@29.7.0: dependencies: - "@jest/schemas": 29.6.3 + '@jest/schemas': 29.6.3 ansi-styles: 5.2.0 react-is: 18.3.1 @@ -3761,7 +2815,7 @@ snapshots: test-exclude@6.0.0: dependencies: - "@istanbuljs/schema": 0.1.3 + '@istanbuljs/schema': 0.1.3 glob: 7.2.3 minimatch: 3.1.2 @@ -3787,19 +2841,19 @@ snapshots: typescript: 5.5.4 yargs-parser: 21.1.1 optionalDependencies: - "@babel/core": 7.25.2 - "@jest/transform": 29.7.0 - "@jest/types": 29.6.3 + '@babel/core': 7.25.2 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 babel-jest: 29.7.0(@babel/core@7.25.2) ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4): dependencies: - "@cspotcode/source-map-support": 0.8.1 - "@tsconfig/node10": 1.0.11 - "@tsconfig/node12": 1.0.11 - "@tsconfig/node14": 1.0.3 - "@tsconfig/node16": 1.0.4 - "@types/node": 20.14.15 + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.11 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 20.14.15 acorn: 8.12.1 acorn-walk: 8.3.3 arg: 4.1.3 @@ -3830,8 +2884,8 @@ snapshots: v8-to-istanbul@9.3.0: dependencies: - "@jridgewell/trace-mapping": 0.3.25 - "@types/istanbul-lib-coverage": 2.0.6 + '@jridgewell/trace-mapping': 0.3.25 + '@types/istanbul-lib-coverage': 2.0.6 convert-source-map: 2.0.0 walker@1.0.8: diff --git a/js/sdk/src/r2rClient.ts b/js/sdk/src/r2rClient.ts index 3b3396a58..61ec76d5c 100644 --- a/js/sdk/src/r2rClient.ts +++ b/js/sdk/src/r2rClient.ts @@ -756,11 +756,14 @@ export class r2rClient { async documentsOverview(document_ids?: string[]): Promise { this._ensureAuthenticated(); - return this._makeRequest("GET", "documents_overview", { - params: { - document_ids: document_ids ? JSON.stringify(document_ids) : undefined, - }, - }); + let params: Record = {}; + if (document_ids) { + params = { + document_ids: JSON.stringify(document_ids), + }; + } + + return this._makeRequest("GET", "documents_overview", params); } /** @@ -774,7 +777,7 @@ export class r2rClient { return this._makeRequest( "GET", - `document_chunks?document_id=${document_id}`, + `document_chunks/${document_id}`, { headers: { "Content-Type": "application/json", diff --git a/py/cli/commands/management.py b/py/cli/commands/management.py index 79eab188e..52ffc6742 100644 --- a/py/cli/commands/management.py +++ b/py/cli/commands/management.py @@ -93,8 +93,13 @@ def document_chunks(client, document_id): with timer(): response = client.document_chunks(document_id) - for chunk in response: - click.echo(chunk) + chunks = response.get("results", []) + click.echo(f"\nNumber of chunks: {len(chunks)}") + for index, chunk in enumerate(chunks, 1): + click.echo(f"\nChunk {index}:") + click.echo(f"Fragment ID: {chunk['fragment_id']}") + click.echo(f"Text: {chunk['text'][:100]}...") + click.echo(f"Metadata: {chunk['metadata']}") @cli.command() diff --git a/py/core/providers/database/vector.py b/py/core/providers/database/vector.py index a40da4dca..f26f017a0 100644 --- a/py/core/providers/database/vector.py +++ b/py/core/providers/database/vector.py @@ -1,7 +1,5 @@ -import json import logging import os -import time from typing import Any, Optional from core.base import ( @@ -9,10 +7,9 @@ VectorDBProvider, VectorEntry, VectorSearchResult, - generate_id_from_label, ) from core.base.abstractions import VectorSearchSettings -from sqlalchemy import exc, text +from sqlalchemy import text from sqlalchemy.engine.url import make_url from .vecs import Client, Collection, create_client @@ -41,11 +38,9 @@ def __init__(self, config: DatabaseConfig, *args, **kwargs): ) # Check if a complete Postgres URI is provided - postgres_uri = self.config.extra_fields.get( + if postgres_uri := self.config.extra_fields.get( "postgres_uri" - ) or os.getenv("POSTGRES_URI") - - if postgres_uri: + ) or os.getenv("POSTGRES_URI"): # Log loudly that Postgres URI is being used logger.warning("=" * 50) logger.warning( @@ -66,7 +61,7 @@ def __init__(self, config: DatabaseConfig, *args, **kwargs): sanitized_uri = parsed_uri.set(password="*****") logger.info(f"Connecting using URI: {sanitized_uri}") except Exception as e: - raise ValueError(f"Invalid Postgres URI provided: {e}") + raise ValueError(f"Invalid Postgres URI provided: {e}") from e else: # Fall back to existing logic for individual connection parameters user = self.config.extra_fields.get("user", None) or os.getenv( @@ -108,7 +103,7 @@ def __init__(self, config: DatabaseConfig, *args, **kwargs): except Exception as e: raise ValueError( f"Error {e} occurred while attempting to connect to the pgvector provider with {DB_CONNECTION}." - ) + ) from e self.collection_name = self.config.extra_fields.get( "vecs_collection" @@ -325,13 +320,14 @@ def hybrid_search( ) rrf_k = search_settings.hybrid_search_settings.rrf_k # Combine results using RRF - combined_results = {} - for rank, result in enumerate(semantic_results, 1): - combined_results[result.fragment_id] = { + combined_results = { + result.fragment_id: { "semantic_rank": rank, "full_text_rank": full_text_limit, "data": result, } + for rank, result in enumerate(semantic_results, 1) + } for rank, result in enumerate(full_text_results, 1): if result.fragment_id in combined_results: From 2906dcd0d00fdc6da3eec2ac125746436612f7ab Mon Sep 17 00:00:00 2001 From: Nolan Tremelling <34580718+NolanTrem@users.noreply.github.com> Date: Wed, 21 Aug 2024 16:05:31 -0700 Subject: [PATCH 34/74] Fix bug in update files (#923) --- go/README.md | 0 js/README.md | 0 py/README.md | 0 py/core/main/services/ingestion_service.py | 11 +++++------ py/scripts/download_nltk_data.py | 4 +++- py/setup.py | 14 ++++++++------ 6 files changed, 16 insertions(+), 13 deletions(-) create mode 100644 go/README.md create mode 100644 js/README.md create mode 100644 py/README.md diff --git a/go/README.md b/go/README.md new file mode 100644 index 000000000..e69de29bb diff --git a/js/README.md b/js/README.md new file mode 100644 index 000000000..e69de29bb diff --git a/py/README.md b/py/README.md new file mode 100644 index 000000000..e69de29bb diff --git a/py/core/main/services/ingestion_service.py b/py/core/main/services/ingestion_service.py index fc9cbf445..c035e2933 100644 --- a/py/core/main/services/ingestion_service.py +++ b/py/core/main/services/ingestion_service.py @@ -131,8 +131,6 @@ async def update_files( generate_user_document_id(file.filename, user.id) for file in files ] - print("user_id = ", user.id) - print("document_ids = ", document_ids) # Only superusers can modify arbitrary document ids, which this gate guarantees in conjuction with the check that follows documents_overview = ( ( @@ -193,7 +191,10 @@ async def update_files( [doc_info.version for doc_info in documents_overview], ): self.providers.database.vector.delete( - filters={"document_id": {"$eq": doc_id}} + filters={ + "document_id": {"$eq": doc_id}, + "version": {"$eq": old_version}, + } ) self.providers.database.relational.delete_from_documents_overview( doc_id, old_version @@ -415,7 +416,7 @@ async def _process_ingestion_results( # TODO - modify ingestion service so that at end we write out number # of vectors produced or the error message to document info # THEN, return updated document infos here - results = { + return { "processed_documents": [ document for document in document_infos @@ -427,5 +428,3 @@ async def _process_ingestion_results( ], "skipped_documents": skipped_ids, } - - return results diff --git a/py/scripts/download_nltk_data.py b/py/scripts/download_nltk_data.py index c4adbcfc5..f0ed4d6a5 100644 --- a/py/scripts/download_nltk_data.py +++ b/py/scripts/download_nltk_data.py @@ -1,7 +1,9 @@ import nltk + def download_nltk_data(): - nltk.download('wordnet', quiet=True) + nltk.download("wordnet", quiet=True) + if __name__ == "__main__": download_nltk_data() diff --git a/py/setup.py b/py/setup.py index e3ddf044d..a4878cf6c 100644 --- a/py/setup.py +++ b/py/setup.py @@ -1,17 +1,19 @@ import nltk from setuptools import setup + def download_nltk_data(): - nltk.download('wordnet', quiet=True) + nltk.download("wordnet", quiet=True) + setup( - name='r2r', - version='0.3.0', - setup_requires=['nltk'], + name="r2r", + version="0.3.0", + setup_requires=["nltk"], cmdclass={ - 'install': lambda _: download_nltk_data(), + "install": lambda _: download_nltk_data(), }, ) -if __name__ == '__main__': +if __name__ == "__main__": download_nltk_data() From 4cce933159b314532f45d4b0fd8d25f7bcefa3fa Mon Sep 17 00:00:00 2001 From: Shreyas Pimpalgaonkar Date: Wed, 21 Aug 2024 19:28:05 -0400 Subject: [PATCH 35/74] Shreyas/unstructured (#922) * fix dockerfiles * adding config * fix paths * mv unstructured dep to docker * clean * Update docker_utils.py * Update unstructured_parsing.py * Update r2r_chunking.py * Update app_entry.py --- Dockerfile | 19 ++- Dockerfile.unstructured | 28 ++-- py/cli/utils/docker_utils.py | 7 +- py/core/main/app_entry.py | 3 - py/core/main/assembly/factory.py | 1 - py/core/providers/chunking/r2r_chunking.py | 6 +- .../providers/parsing/unstructured_parsing.py | 16 ++- py/poetry.lock | 124 +++++++++++++++++- py/pyproject.toml | 2 +- 9 files changed, 166 insertions(+), 40 deletions(-) diff --git a/Dockerfile b/Dockerfile index a42c9444a..0ea128c9f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,18 +3,21 @@ FROM python:3.10-slim AS builder # Install system dependencies RUN apt-get update && apt-get install -y --no-install-recommends \ gcc g++ musl-dev curl libffi-dev gfortran libopenblas-dev \ - && apt-get clean && rm -rf /var/lib/apt/lists/* + && apt-get clean && rm -rf /var/lib/apt/lists/* \ + && curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y + +ENV PATH="/root/.cargo/bin:${PATH}" WORKDIR /app RUN pip install --no-cache-dir poetry # Copy the dependencies files -COPY pyproject.toml poetry.lock* ./ +COPY py/pyproject.toml py/poetry.lock* ./ # Install the dependencies, including gunicorn and uvicorn RUN poetry config virtualenvs.create false \ - && poetry install --no-dev --no-root \ + && poetry install --extras "core" --no-dev --no-root \ && pip install --no-cache-dir gunicorn uvicorn # Create the final image @@ -25,16 +28,18 @@ RUN apt-get update \ && apt-get install -y --no-install-recommends curl \ && apt-get clean && rm -rf /var/lib/apt/lists/* -WORKDIR /app +WORKDIR /app/py # Copy the installed packages from the builder COPY --from=builder /usr/local/lib/python3.10/site-packages /usr/local/lib/python3.10/site-packages COPY --from=builder /usr/local/bin /usr/local/bin # Copy the application and config -COPY r2r /app/r2r +COPY py/core /app/py/core COPY r2r.toml /app/r2r.toml -COPY pyproject.toml /app/pyproject.toml +COPY py/pyproject.toml /app/py/pyproject.toml + +ENV PYTHONPATH="${PYTHONPATH}:/app/py" # Expose the port ARG PORT=8000 @@ -43,4 +48,4 @@ ENV PORT=$PORT HOST=$HOST EXPOSE $PORT # Run the application -CMD ["sh", "-c", "uvicorn r2r.main.app_entry:app --host $HOST --port $PORT"] +CMD ["sh", "-c", "uvicorn core.main.app_entry:app --host $HOST --port $PORT"] diff --git a/Dockerfile.unstructured b/Dockerfile.unstructured index 82e5ee9d4..989fa42d1 100644 --- a/Dockerfile.unstructured +++ b/Dockerfile.unstructured @@ -1,4 +1,3 @@ -# Start with your existing base image FROM python:3.10-slim AS builder # Install system dependencies (including those needed for Unstructured and OpenCV) @@ -7,41 +6,47 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ tesseract-ocr libtesseract-dev libleptonica-dev pkg-config \ poppler-utils libmagic1 \ libgl1-mesa-glx libglib2.0-0 \ - && apt-get clean && rm -rf /var/lib/apt/lists/* + && apt-get clean && rm -rf /var/lib/apt/lists/* \ + && curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y + +ENV PATH="/root/.cargo/bin:${PATH}" WORKDIR /app RUN pip install --no-cache-dir poetry # Copy the dependencies files -COPY pyproject.toml poetry.lock* ./ +COPY py/pyproject.toml py/poetry.lock* ./ # Install the dependencies, including gunicorn, uvicorn, and unstructured RUN poetry config virtualenvs.create false \ + && poetry install --extras "core" --no-dev --no-root \ && poetry add "unstructured[all-docs]" \ - && poetry install --no-dev --no-root \ + && poetry add "unstructured_client" \ && pip install --no-cache-dir gunicorn uvicorn # Create the final image FROM python:3.10-slim -# Install runtime dependencies +# Install runtime dependencies RUN apt-get update \ && apt-get install -y --no-install-recommends \ curl tesseract-ocr poppler-utils libmagic1 \ libgl1-mesa-glx libglib2.0-0 \ && apt-get clean && rm -rf /var/lib/apt/lists/* -WORKDIR /app +WORKDIR /app/py # Copy the installed packages from the builder COPY --from=builder /usr/local/lib/python3.10/site-packages /usr/local/lib/python3.10/site-packages COPY --from=builder /usr/local/bin /usr/local/bin # Copy the application and config -COPY r2r /app/r2r +COPY py/core /app/py/core COPY r2r.toml /app/r2r.toml -COPY pyproject.toml /app/pyproject.toml +COPY py/pyproject.toml /app/py/pyproject.toml + +ENV PYTHONPATH="${PYTHONPATH}:/app/py" # Download NLTK packages and initialize models RUN python3 -m nltk.downloader punkt averaged_perceptron_tagger \ @@ -51,7 +56,10 @@ RUN python3 -m nltk.downloader punkt averaged_perceptron_tagger \ ENV TESSDATA_PREFIX=/usr/share/tesseract-ocr/4.00/tessdata # Expose the port -EXPOSE 8000 +ARG PORT=8000 +ARG HOST=0.0.0.0 +ENV PORT=$PORT HOST=$HOST +EXPOSE $PORT # Run the application -CMD ["uvicorn", "r2r.main.app_entry:app", "--host", "0.0.0.0", "--port", "8000"] +CMD ["sh", "-c", "uvicorn core.main.app_entry:app --host $HOST --port $PORT"] diff --git a/py/cli/utils/docker_utils.py b/py/cli/utils/docker_utils.py index a4352c83e..571ee1ea8 100644 --- a/py/cli/utils/docker_utils.py +++ b/py/cli/utils/docker_utils.py @@ -111,8 +111,13 @@ def run_docker_serve( if config_path: config = R2RConfig.from_toml(config_path) else: + if hasattr(client, "config_name"): + config_name = client.config_name + else: + config_name = "default" + config = R2RConfig.from_toml( - R2RBuilder.CONFIG_OPTIONS[client.config_name or "default"] + R2RBuilder.CONFIG_OPTIONS[config_name] ) completion_provider = config.completion.provider diff --git a/py/core/main/app_entry.py b/py/core/main/app_entry.py index d61e15fbe..d81d29c6a 100644 --- a/py/core/main/app_entry.py +++ b/py/core/main/app_entry.py @@ -58,7 +58,6 @@ def r2r_app( config_path = os.getenv("CONFIG_PATH", None) if not config_path and not config_name: config_name = "default" -client_mode = os.getenv("CLIENT_MODE", "false").lower() == "true" base_url = os.getenv("BASE_URL") host = os.getenv("HOST", "0.0.0.0") port = int(os.getenv("PORT", "8000")) @@ -66,14 +65,12 @@ def r2r_app( logger.info(f"Environment CONFIG_NAME: {config_name}") logger.info(f"Environment CONFIG_PATH: {config_path}") -logger.info(f"Environment CLIENT_MODE: {client_mode}") logger.info(f"Environment BASE_URL: {base_url}") logger.info(f"Environment PIPELINE_TYPE: {pipeline_type}") app = r2r_app( config_name=config_name, config_path=config_path, - client_mode=client_mode, base_url=base_url, pipeline_type=PipelineType(pipeline_type), ) diff --git a/py/core/main/assembly/factory.py b/py/core/main/assembly/factory.py index 7c45864a4..120920412 100644 --- a/py/core/main/assembly/factory.py +++ b/py/core/main/assembly/factory.py @@ -215,7 +215,6 @@ def create_prompt_provider( prompt_provider = None if prompt_config.provider == "r2r": from core.providers import R2RPromptProvider - prompt_provider = R2RPromptProvider(prompt_config) else: raise ValueError( diff --git a/py/core/providers/chunking/r2r_chunking.py b/py/core/providers/chunking/r2r_chunking.py index dd900a1f1..165145fb8 100644 --- a/py/core/providers/chunking/r2r_chunking.py +++ b/py/core/providers/chunking/r2r_chunking.py @@ -31,11 +31,9 @@ def _initialize_text_splitter(self) -> TextSplitter: chunk_overlap=self.config.chunk_overlap, ) elif self.config.method == Method.BASIC: - # Implement basic method - pass + raise NotImplementedError("Basic chunking method not implemented. Please use Recursive.") elif self.config.method == Method.BY_TITLE: - # Implement by_title method - pass + raise NotImplementedError("By title method not implemented") else: raise ValueError(f"Unsupported method type: {self.config.method}") diff --git a/py/core/providers/parsing/unstructured_parsing.py b/py/core/providers/parsing/unstructured_parsing.py index a32cf1e9e..26e2933ab 100644 --- a/py/core/providers/parsing/unstructured_parsing.py +++ b/py/core/providers/parsing/unstructured_parsing.py @@ -24,10 +24,15 @@ def __init__(self, use_api, config): self.use_api = use_api if self.use_api: - from unstructured.staging.base import dict_to_elements - from unstructured_client import UnstructuredClient - from unstructured_client.models import operations, shared - from unstructured_client.models.errors import SDKError + try: + from unstructured_client import UnstructuredClient + from unstructured_client.models import operations, shared + from unstructured_client.models.errors import SDKError + + except ImportError: + raise ImportError( + "Please install the unstructured package to use the unstructured parsing provider." + ) try: self.unstructured_api_auth = os.environ["UNSTRUCTURED_API_KEY"] @@ -47,7 +52,6 @@ def __init__(self, use_api, config): ) self.shared = shared self.operations = operations - self.dict_to_elements = dict_to_elements else: try: @@ -87,7 +91,7 @@ async def parse( ) ) elements = self.client.general.partition(req) - elements = [element for element in elements.elements] + elements = list(elements.elements) else: logger.info( diff --git a/py/poetry.lock b/py/poetry.lock index 9d2e98341..bfbcfa739 100644 --- a/py/poetry.lock +++ b/py/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. [[package]] name = "aiohappyeyeballs" @@ -766,6 +766,21 @@ files = [ docs = ["ipython", "matplotlib", "numpydoc", "sphinx"] tests = ["pytest", "pytest-cov", "pytest-xdist"] +[[package]] +name = "dataclasses-json" +version = "0.6.7" +description = "Easily serialize dataclasses to and from JSON." +optional = true +python-versions = "<4.0,>=3.7" +files = [ + {file = "dataclasses_json-0.6.7-py3-none-any.whl", hash = "sha256:0dbf33f26c8d5305befd61b39d2b3414e8a407bedc2834dea9b8d642666fb40a"}, + {file = "dataclasses_json-0.6.7.tar.gz", hash = "sha256:b6b3e528266ea45b9535223bc53ca645f5208833c29229e847b3f26a1cc55fc0"}, +] + +[package.dependencies] +marshmallow = ">=3.18.0,<4.0.0" +typing-inspect = ">=0.4.0,<1" + [[package]] name = "decorator" version = "4.4.2" @@ -1701,6 +1716,17 @@ files = [ {file = "joblib-1.4.2.tar.gz", hash = "sha256:2382c5816b2636fbd20a09e0f4e9dad4736765fdfb7dca582943b9c1366b3f0e"}, ] +[[package]] +name = "jsonpath-python" +version = "1.0.6" +description = "A more powerful JSONPath implementation in modern python" +optional = true +python-versions = ">=3.6" +files = [ + {file = "jsonpath-python-1.0.6.tar.gz", hash = "sha256:dd5be4a72d8a2995c3f583cf82bf3cd1a9544cfdabf2d22595b67aff07349666"}, + {file = "jsonpath_python-1.0.6-py3-none-any.whl", hash = "sha256:1e3b78df579f5efc23565293612decee04214609208a2335884b3ee3f786b575"}, +] + [[package]] name = "jsonschema" version = "4.23.0" @@ -2148,6 +2174,25 @@ files = [ {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, ] +[[package]] +name = "marshmallow" +version = "3.22.0" +description = "A lightweight library for converting complex datatypes to and from native Python datatypes." +optional = true +python-versions = ">=3.8" +files = [ + {file = "marshmallow-3.22.0-py3-none-any.whl", hash = "sha256:71a2dce49ef901c3f97ed296ae5051135fd3febd2bf43afe0ae9a82143a494d9"}, + {file = "marshmallow-3.22.0.tar.gz", hash = "sha256:4972f529104a220bb8637d595aa4c9762afbe7f7a77d82dc58c1615d70c5823e"}, +] + +[package.dependencies] +packaging = ">=17.0" + +[package.extras] +dev = ["marshmallow[tests]", "pre-commit (>=3.5,<4.0)", "tox"] +docs = ["alabaster (==1.0.0)", "autodocsumm (==0.2.13)", "sphinx (==8.0.2)", "sphinx-issues (==4.1.0)", "sphinx-version-warning (==1.1.2)"] +tests = ["pytest", "pytz", "simplejson"] + [[package]] name = "matplotlib" version = "3.9.2" @@ -3548,18 +3593,19 @@ dev = ["atomicwrites (==1.4.1)", "attrs (==23.2.0)", "coverage (==7.4.1)", "hatc [[package]] name = "python-pptx" -version = "0.6.23" -description = "Generate and manipulate Open XML PowerPoint (.pptx) files" +version = "1.0.2" +description = "Create, read, and update PowerPoint 2007+ (.pptx) files." optional = true -python-versions = "*" +python-versions = ">=3.8" files = [ - {file = "python-pptx-0.6.23.tar.gz", hash = "sha256:587497ff28e779ab18dbb074f6d4052893c85dedc95ed75df319364f331fedee"}, - {file = "python_pptx-0.6.23-py3-none-any.whl", hash = "sha256:dd0527194627a2b7cc05f3ba23ecaa2d9a0d5ac9b6193a28ed1b7a716f4217d4"}, + {file = "python_pptx-1.0.2-py3-none-any.whl", hash = "sha256:160838e0b8565a8b1f67947675886e9fea18aa5e795db7ae531606d68e785cba"}, + {file = "python_pptx-1.0.2.tar.gz", hash = "sha256:479a8af0eaf0f0d76b6f00b0887732874ad2e3188230315290cd1f9dd9cc7095"}, ] [package.dependencies] lxml = ">=3.1.0" Pillow = ">=3.3.2" +typing-extensions = ">=4.9.0" XlsxWriter = ">=0.5.7" [[package]] @@ -3777,6 +3823,20 @@ urllib3 = ">=1.21.1,<3" socks = ["PySocks (>=1.5.6,!=1.5.7)"] use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] +[[package]] +name = "requests-toolbelt" +version = "1.0.0" +description = "A utility belt for advanced users of python-requests" +optional = true +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6"}, + {file = "requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06"}, +] + +[package.dependencies] +requests = ">=2.0.1,<3.0.0" + [[package]] name = "rpds-py" version = "0.20.0" @@ -4482,6 +4542,21 @@ files = [ {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, ] +[[package]] +name = "typing-inspect" +version = "0.9.0" +description = "Runtime inspection utilities for typing module." +optional = true +python-versions = "*" +files = [ + {file = "typing_inspect-0.9.0-py3-none-any.whl", hash = "sha256:9ee6fc59062311ef8547596ab6b955e1b8aa46242d854bfc78f4f6b0eff35f9f"}, + {file = "typing_inspect-0.9.0.tar.gz", hash = "sha256:b23fc42ff6f6ef6954e4852c1fb512cdd18dbea03134f91f856a95ccc9461f78"}, +] + +[package.dependencies] +mypy-extensions = ">=0.3.0" +typing-extensions = ">=3.7.4" + [[package]] name = "tzdata" version = "2024.1" @@ -4517,6 +4592,41 @@ parametric-umap = ["tensorflow (>=2.1)"] plot = ["bokeh", "colorcet", "datashader", "holoviews", "matplotlib", "pandas", "scikit-image", "seaborn"] tbb = ["tbb (>=2019.0)"] +[[package]] +name = "unstructured-client" +version = "0.25.5" +description = "Python Client SDK for Unstructured API" +optional = true +python-versions = ">=3.8" +files = [ + {file = "unstructured-client-0.25.5.tar.gz", hash = "sha256:adb97ea56ce65f8b277d5b05f093e9d13a3320ac8dea7265ffa71f5e13ed5f84"}, + {file = "unstructured_client-0.25.5-py3-none-any.whl", hash = "sha256:23537fee984e43d06a75f986a73e420a9659cc92010afb8324fbf67c85962eaf"}, +] + +[package.dependencies] +certifi = ">=2023.7.22" +charset-normalizer = ">=3.2.0" +dataclasses-json = ">=0.6.4" +deepdiff = ">=6.0" +httpx = ">=0.27.0" +idna = ">=3.4" +jsonpath-python = ">=1.0.6" +marshmallow = ">=3.19.0" +mypy-extensions = ">=1.0.0" +nest-asyncio = ">=1.6.0" +packaging = ">=23.1" +pypdf = ">=4.0" +python-dateutil = ">=2.8.2" +requests = ">=2.31.0" +requests-toolbelt = ">=1.0.0" +six = ">=1.16.0" +typing-extensions = ">=4.7.1" +typing-inspect = ">=0.9.0" +urllib3 = ">=1.26.18" + +[package.extras] +dev = ["pylint (==3.1.0)"] + [[package]] name = "urllib3" version = "2.2.2" @@ -4804,7 +4914,7 @@ doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linke test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy", "pytest-ruff (>=0.2.1)"] [extras] -core = ["aiosqlite", "asyncpg", "bcrypt", "beautifulsoup4", "deepdiff", "fire", "fsspec", "graspologic", "gunicorn", "litellm", "markdown", "neo4j", "ollama", "openai", "openpyxl", "passlib", "poppler-utils", "posthog", "psutil", "pydantic", "pyjwt", "pypdf", "python-docx", "python-multipart", "python-pptx", "pyyaml", "redis", "requests", "sqlalchemy", "toml", "types-requests", "uvicorn", "vecs"] +core = ["aiosqlite", "asyncpg", "bcrypt", "beautifulsoup4", "deepdiff", "fire", "fsspec", "graspologic", "gunicorn", "litellm", "markdown", "neo4j", "ollama", "openai", "openpyxl", "passlib", "poppler-utils", "posthog", "psutil", "pydantic", "pyjwt", "pypdf", "python-docx", "python-multipart", "python-pptx", "pyyaml", "redis", "requests", "sqlalchemy", "toml", "types-requests", "unstructured_client", "uvicorn", "vecs"] core-ingest-movies = ["moviepy", "opencv-python"] [metadata] diff --git a/py/pyproject.toml b/py/pyproject.toml index 1b7816148..03881ebf6 100644 --- a/py/pyproject.toml +++ b/py/pyproject.toml @@ -42,7 +42,7 @@ beautifulsoup4 = { version = "^4.12.3", optional = true } openpyxl = { version = "^3.1.2", optional = true } markdown = { version = "^3.6", optional = true } pypdf = { version = "^4.2.0", optional = true } -python-pptx = { version = "^0.6.23", optional = true } +python-pptx = { version = "^1.0.1", optional = true } python-docx = { version = "^1.1.0", optional = true } opencv-python = { version = "^4.10.0.82", optional = true } moviepy = { version = "^1.0.3", optional = true } From 0b1c9fa813c1689f2041417b09bde7f75aa4b062 Mon Sep 17 00:00:00 2001 From: emrgnt-cmplxty <68796651+emrgnt-cmplxty@users.noreply.github.com> Date: Wed, 21 Aug 2024 21:44:28 -0700 Subject: [PATCH 36/74] Feature/repair logging (#925) * fixing logs * fix --- py/core/base/logging/base.py | 1 + py/core/main/api/routes/auth/base.py | 6 +++--- py/core/main/api/routes/ingestion/base.py | 6 +++--- py/core/main/api/routes/management/base.py | 6 +++--- py/core/main/api/routes/restructure/base.py | 6 +++--- py/core/main/api/routes/retrieval/base.py | 4 ++-- py/core/main/services/management_service.py | 10 ++++------ py/core/pipes/ingestion/vector_storage_pipe.py | 7 ------- py/tests/test_config.py | 2 -- r2r.toml | 5 +---- 10 files changed, 20 insertions(+), 33 deletions(-) diff --git a/py/core/base/logging/base.py b/py/core/base/logging/base.py index fed478cb2..3a947478d 100644 --- a/py/core/base/logging/base.py +++ b/py/core/base/logging/base.py @@ -9,3 +9,4 @@ class RunType(str, Enum): INGESTION = "INGESTION" AUTH = "AUTH" UNSPECIFIED = "UNSPECIFIED" + RESTRUCTURE = "RESTRUCTURE" diff --git a/py/core/main/api/routes/auth/base.py b/py/core/main/api/routes/auth/base.py index 3e840fd2a..245341348 100644 --- a/py/core/main/api/routes/auth/base.py +++ b/py/core/main/api/routes/auth/base.py @@ -11,7 +11,7 @@ from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm from pydantic import EmailStr -from ..base_router import BaseRouter +from ..base_router import BaseRouter, RunType if TYPE_CHECKING: from ....engine import R2REngine @@ -20,8 +20,8 @@ class AuthRouter(BaseRouter): - def __init__(self, engine: "R2REngine"): - super().__init__(engine) + def __init__(self, engine: "R2REngine", run_type: RunType = RunType.INGESTION): + super().__init__(engine, run_type) self.setup_routes() def setup_routes(self): diff --git a/py/core/main/api/routes/ingestion/base.py b/py/core/main/api/routes/ingestion/base.py index 5e0998991..bc5b334e1 100644 --- a/py/core/main/api/routes/ingestion/base.py +++ b/py/core/main/api/routes/ingestion/base.py @@ -13,14 +13,14 @@ from ....assembly.factory import R2RProviderFactory from ....engine import R2REngine -from ..base_router import BaseRouter +from ..base_router import BaseRouter, RunType logger = logging.getLogger(__name__) class IngestionRouter(BaseRouter): - def __init__(self, engine: R2REngine): - super().__init__(engine) + def __init__(self, engine: R2REngine, run_type: RunType = RunType.INGESTION): + super().__init__(engine, run_type) self.openapi_extras = self.load_openapi_extras() self.setup_routes() diff --git a/py/core/main/api/routes/management/base.py b/py/core/main/api/routes/management/base.py index 542224b66..00c89a31a 100644 --- a/py/core/main/api/routes/management/base.py +++ b/py/core/main/api/routes/management/base.py @@ -27,12 +27,12 @@ from pydantic import Json from ....engine import R2REngine -from ..base_router import BaseRouter +from ..base_router import BaseRouter, RunType class ManagementRouter(BaseRouter): - def __init__(self, engine: R2REngine): - super().__init__(engine) + def __init__(self, engine: R2REngine, run_type: RunType = RunType.MANAGEMENT): + super().__init__(engine, run_type) self.start_time = datetime.now(timezone.utc) self.setup_routes() diff --git a/py/core/main/api/routes/restructure/base.py b/py/core/main/api/routes/restructure/base.py index fe68c909b..7e8ca627b 100644 --- a/py/core/main/api/routes/restructure/base.py +++ b/py/core/main/api/routes/restructure/base.py @@ -1,14 +1,14 @@ from typing import Union from core.base import KGEnrichmentSettings -from core.main.api.routes.base_router import BaseRouter +from core.main.api.routes.base_router import BaseRouter, RunType from core.main.engine import R2REngine from fastapi import Body, Depends class RestructureRouter(BaseRouter): - def __init__(self, engine: R2REngine): - super().__init__(engine) + def __init__(self, engine: R2REngine, run_type: RunType = RunType.RESTRUCTURE): + super().__init__(engine, run_type) self.setup_routes() def setup_routes(self): diff --git a/py/core/main/api/routes/retrieval/base.py b/py/core/main/api/routes/retrieval/base.py index ab45eda1b..d562b2b61 100644 --- a/py/core/main/api/routes/retrieval/base.py +++ b/py/core/main/api/routes/retrieval/base.py @@ -23,8 +23,8 @@ class RetrievalRouter(BaseRouter): - def __init__(self, engine: R2REngine): - super().__init__(engine) + def __init__(self, engine: R2REngine, run_type: RunType = RunType.RETRIEVAL): + super().__init__(engine, run_type) self.openapi_extras = self.load_openapi_extras() self.setup_routes() diff --git a/py/core/main/services/management_service.py b/py/core/main/services/management_service.py index b8b499e2f..43657bfc4 100644 --- a/py/core/main/services/management_service.py +++ b/py/core/main/services/management_service.py @@ -64,7 +64,7 @@ async def alogs( for run in run_info: run_logs = [ - log for log in logs if log["run_id"] == str(run.run_id) + log for log in logs if log["run_id"] == run.run_id ] entries = [ { @@ -73,12 +73,10 @@ async def alogs( "timestamp": log["timestamp"], } for log in run_logs - ][ - ::-1 - ] # Reverse order so that earliest logged values appear first. + ][::-1] # Reverse order so that earliest logged values appear first. log_entry = { - "run_id": run.run_id, + "run_id": str(run.run_id), "run_type": run.run_type, "entries": entries, } @@ -87,7 +85,7 @@ async def alogs( log_entry["timestamp"] = run.timestamp.isoformat() if hasattr(run, "user_id") and run.user_id is not None: - log_entry["user_id"] = run.user_id + log_entry["user_id"] = str(run.user_id) aggregated_logs.append(log_entry) diff --git a/py/core/pipes/ingestion/vector_storage_pipe.py b/py/core/pipes/ingestion/vector_storage_pipe.py index ccb1e71bf..995f8f859 100644 --- a/py/core/pipes/ingestion/vector_storage_pipe.py +++ b/py/core/pipes/ingestion/vector_storage_pipe.py @@ -74,11 +74,8 @@ async def _run_logic( ]: vector_batch = [] document_counts = {} - connection_attempts = 0 - last_vector_received = None async for msg in input.message: - last_vector_received = asyncio.get_event_loop().time() if isinstance(msg, R2RDocumentProcessingError): yield (msg.document_id, msg) continue @@ -89,7 +86,6 @@ async def _run_logic( ) if len(vector_batch) >= self.storage_batch_size: - connection_attempts += 1 try: await self.store(vector_batch) except Exception as e: @@ -97,14 +93,11 @@ async def _run_logic( vector_batch.clear() if vector_batch: - connection_attempts += 1 try: await self.store(vector_batch) except Exception as e: logger.error(f"Failed to store final vector batch: {e}") - logger.info(f"Total connection attempts: {connection_attempts}") - for document_id, count in document_counts.items(): yield ( document_id, diff --git a/py/tests/test_config.py b/py/tests/test_config.py index e8e07273f..a84df71cb 100644 --- a/py/tests/test_config.py +++ b/py/tests/test_config.py @@ -72,7 +72,6 @@ def mock_file(): "rerank_model": "None", "concurrent_request_limit": 256, }, - "eval": {"provider": "None"}, "ingestion": { "excluded_parsers": ["mp4"], "override_parsers": [ @@ -143,7 +142,6 @@ def test_r2r_config_deserialization(mock_file, mock_redis_client): "concurrent_request_limit": 256, }, "kg": {"provider": "None"}, - "eval": {"provider": "None"}, "parsing": {"provider": "r2r"}, "chunking": {"provider": "r2r"}, "completion": {"provider": "litellm"}, diff --git a/r2r.toml b/r2r.toml index 9af14549b..7bd15e132 100644 --- a/r2r.toml +++ b/r2r.toml @@ -40,9 +40,6 @@ add_title_as_prefix = false rerank_model = "None" concurrent_request_limit = 256 -[eval] -provider = "None" - [kg] provider = "None" @@ -60,4 +57,4 @@ provider = "r2r" [agent] system_instruction_name = "rag_agent" -tool_names = ["search"] +tool_names = ["search"] \ No newline at end of file From dfe98f53f2d760a88c516609b66a60a1be9b986b Mon Sep 17 00:00:00 2001 From: emrgnt-cmplxty <68796651+emrgnt-cmplxty@users.noreply.github.com> Date: Thu, 22 Aug 2024 09:11:00 -0700 Subject: [PATCH 37/74] rm double logging (#929) --- py/core/pipelines/ingestion_pipeline.py | 159 ++++++++++++------------ 1 file changed, 79 insertions(+), 80 deletions(-) diff --git a/py/core/pipelines/ingestion_pipeline.py b/py/core/pipelines/ingestion_pipeline.py index 2f4f4ef7d..3de2d095b 100644 --- a/py/core/pipelines/ingestion_pipeline.py +++ b/py/core/pipelines/ingestion_pipeline.py @@ -38,96 +38,95 @@ async def run( **kwargs: Any, ) -> None: self.state = state or AsyncState() - async with manage_run(run_manager): - if self.parsing_pipe is None: - raise ValueError( - "parsing_pipe must be set before running the ingestion pipeline" - ) - if self.chunking_pipe is None: - raise ValueError( - "chunking_pipe must be set before running the ingestion pipeline" - ) - if self.embedding_pipeline is None and self.kg_pipeline is None: - raise ValueError( - "At least one of embedding_pipeline or kg_pipeline must be set before running the ingestion pipeline" - ) - - # Use queues to pass data between pipes and duplicate for each pipeline - parsing_to_chunking_queue = Queue() - embedding_queue = Queue() - kg_queue = Queue() + if self.parsing_pipe is None: + raise ValueError( + "parsing_pipe must be set before running the ingestion pipeline" + ) + if self.chunking_pipe is None: + raise ValueError( + "chunking_pipe must be set before running the ingestion pipeline" + ) + if self.embedding_pipeline is None and self.kg_pipeline is None: + raise ValueError( + "At least one of embedding_pipeline or kg_pipeline must be set before running the ingestion pipeline" + ) - async def process_documents(): - async for parsed_doc in await self.parsing_pipe.run( - self.parsing_pipe.Input(message=input), + # Use queues to pass data between pipes and duplicate for each pipeline + parsing_to_chunking_queue = Queue() + embedding_queue = Queue() + kg_queue = Queue() + + async def process_documents(): + async for parsed_doc in await self.parsing_pipe.run( + self.parsing_pipe.Input(message=input), + state, + run_manager, + *args, + **kwargs, + ): + await parsing_to_chunking_queue.put(parsed_doc) + await parsing_to_chunking_queue.put(None) + + async for chunked_doc in await self.chunking_pipe.run( + self.chunking_pipe.Input( + message=dequeue_requests(parsing_to_chunking_queue) + ), + state, + run_manager, + chunking_settings=chunking_settings, + *args, + **kwargs, + ): + if self.embedding_pipeline: + await embedding_queue.put(chunked_doc) + if self.kg_pipeline: + await kg_queue.put(chunked_doc) + await embedding_queue.put(None) + await kg_queue.put(None) + + # Start the document processing + process_task = asyncio.create_task(process_documents()) + + # Start the embedding and KG pipelines in parallel + tasks = [] + if self.embedding_pipeline: + embedding_task = asyncio.create_task( + self.embedding_pipeline.run( + dequeue_requests(embedding_queue), state, + stream, run_manager, *args, **kwargs, - ): - await parsing_to_chunking_queue.put(parsed_doc) - await parsing_to_chunking_queue.put(None) - - async for chunked_doc in await self.chunking_pipe.run( - self.chunking_pipe.Input( - message=dequeue_requests(parsing_to_chunking_queue) - ), + ) + ) + tasks.append(embedding_task) + + if self.kg_pipeline: + kg_task = asyncio.create_task( + self.kg_pipeline.run( + dequeue_requests(kg_queue), state, + stream, run_manager, - chunking_settings=chunking_settings, *args, **kwargs, - ): - if self.embedding_pipeline: - await embedding_queue.put(chunked_doc) - if self.kg_pipeline: - await kg_queue.put(chunked_doc) - await embedding_queue.put(None) - await kg_queue.put(None) - - # Start the document processing - process_task = asyncio.create_task(process_documents()) - - # Start the embedding and KG pipelines in parallel - tasks = [] - if self.embedding_pipeline: - embedding_task = asyncio.create_task( - self.embedding_pipeline.run( - dequeue_requests(embedding_queue), - state, - stream, - run_manager, - *args, - **kwargs, - ) ) - tasks.append(embedding_task) - - if self.kg_pipeline: - kg_task = asyncio.create_task( - self.kg_pipeline.run( - dequeue_requests(kg_queue), - state, - stream, - run_manager, - *args, - **kwargs, - ) - ) - tasks.append(kg_task) - - # Wait for all tasks to complete - await process_task - results = await asyncio.gather(*tasks) - - return { - "embedding_pipeline_output": ( - results[0] if self.embedding_pipeline else None - ), - "kg_pipeline_output": ( - results[-1] if self.kg_pipeline else None - ), - } + ) + tasks.append(kg_task) + + # Wait for all tasks to complete + await process_task + results = await asyncio.gather(*tasks) + + return { + "embedding_pipeline_output": ( + results[0] if self.embedding_pipeline else None + ), + "kg_pipeline_output": ( + results[-1] if self.kg_pipeline else None + ), + } def add_pipe( self, From 9c3c200ed8e684b37f05d2ad3966c73e8f5bfcd6 Mon Sep 17 00:00:00 2001 From: Nolan Tremelling <34580718+NolanTrem@users.noreply.github.com> Date: Thu, 22 Aug 2024 09:40:47 -0700 Subject: [PATCH 38/74] Configs (#926) * Fix config logic * Update config * Clean up cli entry point --- compose.yaml | 1 - py/cli/command_group.py | 25 ++------------------- py/cli/commands/server.py | 12 ++++++++-- py/cli/utils/docker_utils.py | 26 +++++++++++++--------- py/core/main/app_entry.py | 4 ---- py/core/main/assembly/builder.py | 15 +++++++++---- py/core/main/assembly/factory.py | 1 + py/core/main/r2r.py | 13 +++-------- py/core/providers/chunking/r2r_chunking.py | 4 +++- 9 files changed, 45 insertions(+), 56 deletions(-) diff --git a/compose.yaml b/compose.yaml index 9d1364984..b4a4e7c46 100644 --- a/compose.yaml +++ b/compose.yaml @@ -32,7 +32,6 @@ services: - PYTHONUNBUFFERED=1 - PORT=${PORT:-8000} - HOST=${HOST:-0.0.0.0} - - BASE_URL=${BASE_URL:-http://localhost} # R2R - CONFIG_NAME=${CONFIG_NAME:-} diff --git a/py/cli/command_group.py b/py/cli/command_group.py index 0291bc874..bcc4e30ed 100644 --- a/py/cli/command_group.py +++ b/py/cli/command_group.py @@ -1,31 +1,10 @@ -import os - import click from sdk.client import R2RClient -# TODO: refactor this to remove config path and config name @click.group() -@click.option( - "--config-path", default=None, help="Path to the configuration file" -) -@click.option( - "--config-name", default=None, help="Name of the configuration to use" -) -@click.option( - "--base-url", - default="http://localhost:8000", - help="Base URL for client mode", -) @click.pass_context -def cli(ctx, config_path, config_name, base_url): +def cli(ctx): """R2R CLI for all core operations.""" - if config_path and config_name: - raise click.UsageError( - "Cannot specify both config_path and config_name" - ) - - if config_path: - config_path = os.path.abspath(config_path) - ctx.obj = R2RClient(base_url) + ctx.obj = R2RClient() diff --git a/py/cli/commands/server.py b/py/cli/commands/server.py index f0d948505..c71c003e6 100644 --- a/py/cli/commands/server.py +++ b/py/cli/commands/server.py @@ -182,7 +182,14 @@ def generate_report(): ) @click.option("--project-name", default="r2r", help="Project name for Docker") @click.option("--image", help="Docker image to use") -@click.option("--config-path", help="Path to the configuration file") +@click.option( + "--config-name", default=None, help="Name of the R2R configuration to use" +) +@click.option( + "--config-path", + default=None, + help="Path to a custom R2R configuration file", +) @click.pass_obj def serve( client, @@ -194,6 +201,7 @@ def serve( exclude_postgres, project_name, image, + config_name, config_path, ): """Start the R2R server.""" @@ -239,7 +247,7 @@ def serve( click.echo(f"Opening browser to {url}") webbrowser.open(url) else: - run_local_serve(client, host, port) + run_local_serve(host, port, config_name, config_path) @cli.command() diff --git a/py/cli/utils/docker_utils.py b/py/cli/utils/docker_utils.py index 571ee1ea8..16e47a0a8 100644 --- a/py/cli/utils/docker_utils.py +++ b/py/cli/utils/docker_utils.py @@ -73,8 +73,11 @@ def remove_r2r_network(): def run_local_serve( - obj: R2RClient, host: str, port: int, config_path: Optional[str] = None -): + host: str, + port: int, + config_name: Optional[str] = None, + config_path: Optional[str] = None, +) -> None: try: from r2r import R2R except ImportError: @@ -83,14 +86,17 @@ def run_local_serve( ) sys.exit(1) - r2r_instance = R2R() - llm_provider = r2r_instance.config.completion.provider - llm_model = r2r_instance.config.completion.generation_config.model - model_provider = llm_model.split("/")[0] + r2r_instance = R2R(config_name=config_name, config_path=config_path) + + if config_name or config_path: + completion_config = r2r_instance.config.completion + llm_provider = completion_config.provider + llm_model = completion_config.generation_config.model + model_provider = llm_model.split("/")[0] + check_llm_reqs(llm_provider, model_provider, include_ollama=True) available_port = find_available_port(port) - check_llm_reqs(llm_provider, model_provider, include_ollama=True) r2r_instance.serve(host, available_port) @@ -115,10 +121,8 @@ def run_docker_serve( config_name = client.config_name else: config_name = "default" - - config = R2RConfig.from_toml( - R2RBuilder.CONFIG_OPTIONS[config_name] - ) + + config = R2RConfig.from_toml(R2RBuilder.CONFIG_OPTIONS[config_name]) completion_provider = config.completion.provider completion_model = config.completion.generation_config.model diff --git a/py/core/main/app_entry.py b/py/core/main/app_entry.py index d81d29c6a..c9261327c 100644 --- a/py/core/main/app_entry.py +++ b/py/core/main/app_entry.py @@ -22,7 +22,6 @@ class PipelineType(Enum): def r2r_app( config_name: Optional[str] = "default", config_path: Optional[str] = None, - base_url: Optional[str] = None, pipeline_type: PipelineType = PipelineType.QNA, ) -> FastAPI: if pipeline_type != PipelineType.QNA: @@ -58,19 +57,16 @@ def r2r_app( config_path = os.getenv("CONFIG_PATH", None) if not config_path and not config_name: config_name = "default" -base_url = os.getenv("BASE_URL") host = os.getenv("HOST", "0.0.0.0") port = int(os.getenv("PORT", "8000")) pipeline_type = os.getenv("PIPELINE_TYPE", "qna") logger.info(f"Environment CONFIG_NAME: {config_name}") logger.info(f"Environment CONFIG_PATH: {config_path}") -logger.info(f"Environment BASE_URL: {base_url}") logger.info(f"Environment PIPELINE_TYPE: {pipeline_type}") app = r2r_app( config_name=config_name, config_path=config_path, - base_url=base_url, pipeline_type=PipelineType(pipeline_type), ) diff --git a/py/core/main/assembly/builder.py b/py/core/main/assembly/builder.py index be8d95a22..191180e53 100644 --- a/py/core/main/assembly/builder.py +++ b/py/core/main/assembly/builder.py @@ -44,7 +44,9 @@ class R2RBuilder: CONFIG_OPTIONS["default"] = None @staticmethod - def _get_config(config_name): + def _get_config(config_name, config_path=None): + if config_path: + return R2RConfig.from_toml(config_path) if config_name is None: return R2RConfig.from_toml() if config_name in R2RBuilder.CONFIG_OPTIONS: @@ -55,10 +57,15 @@ def __init__( self, config: Optional[R2RConfig] = None, config_name: Optional[str] = None, + config_path: Optional[str] = None, ): - if config and config_name: - raise ValueError("Cannot specify both config and config_name") - self.config = config or R2RBuilder._get_config(config_name) + if sum(x is not None for x in [config, config_name, config_path]) > 1: + raise ValueError( + "Specify only one of config, config_name, or config_path" + ) + self.config = config or R2RBuilder._get_config( + config_name, config_path + ) self.r2r_app_override: Optional[Type[R2REngine]] = None self.provider_factory_override: Optional[Type[R2RProviderFactory]] = ( None diff --git a/py/core/main/assembly/factory.py b/py/core/main/assembly/factory.py index 120920412..7c45864a4 100644 --- a/py/core/main/assembly/factory.py +++ b/py/core/main/assembly/factory.py @@ -215,6 +215,7 @@ def create_prompt_provider( prompt_provider = None if prompt_config.provider == "r2r": from core.providers import R2RPromptProvider + prompt_provider = R2RPromptProvider(prompt_config) else: raise ValueError( diff --git a/py/core/main/r2r.py b/py/core/main/r2r.py index 12229f0eb..54db472e3 100644 --- a/py/core/main/r2r.py +++ b/py/core/main/r2r.py @@ -32,6 +32,7 @@ def __init__( app: Optional[R2RApp] = None, config: Optional[R2RConfig] = None, config_name: Optional[str] = None, + config_path: Optional[str] = None, *args, **kwargs, ): @@ -40,25 +41,17 @@ def __init__( if engine and app: self.engine = engine self.app = app - elif (config or config_name) or ( - config is None and config_name is None - ): + else: from .assembly.builder import R2RBuilder - # Handle the case where 'config_name' is None and 'config' is None - if not config and not config_name: - config_name = "default" builder = R2RBuilder( config=config, config_name=config_name, + config_path=config_path, ) built = builder.build() self.engine = built.engine self.app = built.app - else: - raise ValueError( - "Must provide either 'engine' and 'app', or 'config'/'config_name' to build the R2R object." - ) def __getattr__(self, name): # Check if the attribute name is 'app' and return it directly diff --git a/py/core/providers/chunking/r2r_chunking.py b/py/core/providers/chunking/r2r_chunking.py index 165145fb8..9b0223bec 100644 --- a/py/core/providers/chunking/r2r_chunking.py +++ b/py/core/providers/chunking/r2r_chunking.py @@ -31,7 +31,9 @@ def _initialize_text_splitter(self) -> TextSplitter: chunk_overlap=self.config.chunk_overlap, ) elif self.config.method == Method.BASIC: - raise NotImplementedError("Basic chunking method not implemented. Please use Recursive.") + raise NotImplementedError( + "Basic chunking method not implemented. Please use Recursive." + ) elif self.config.method == Method.BY_TITLE: raise NotImplementedError("By title method not implemented") else: From b6d33e0ee3fccc01bb0c1a9aa77ab4bb6276b460 Mon Sep 17 00:00:00 2001 From: Nolan Tremelling <34580718+NolanTrem@users.noreply.github.com> Date: Thu, 22 Aug 2024 10:05:23 -0700 Subject: [PATCH 39/74] Disable SSL when installing nltk wordnet (#930) --- py/core/main/api/routes/auth/base.py | 4 +- py/core/main/api/routes/ingestion/base.py | 4 +- py/core/main/api/routes/management/base.py | 4 +- py/core/main/api/routes/restructure/base.py | 4 +- py/core/main/api/routes/retrieval/base.py | 4 +- py/core/main/services/management_service.py | 8 +- py/core/pipelines/ingestion_pipeline.py | 4 +- py/poetry.lock | 131 ++------------------ py/scripts/download_nltk_data.py | 9 ++ 9 files changed, 42 insertions(+), 130 deletions(-) diff --git a/py/core/main/api/routes/auth/base.py b/py/core/main/api/routes/auth/base.py index 245341348..49871643c 100644 --- a/py/core/main/api/routes/auth/base.py +++ b/py/core/main/api/routes/auth/base.py @@ -20,7 +20,9 @@ class AuthRouter(BaseRouter): - def __init__(self, engine: "R2REngine", run_type: RunType = RunType.INGESTION): + def __init__( + self, engine: "R2REngine", run_type: RunType = RunType.INGESTION + ): super().__init__(engine, run_type) self.setup_routes() diff --git a/py/core/main/api/routes/ingestion/base.py b/py/core/main/api/routes/ingestion/base.py index bc5b334e1..f0510e944 100644 --- a/py/core/main/api/routes/ingestion/base.py +++ b/py/core/main/api/routes/ingestion/base.py @@ -19,7 +19,9 @@ class IngestionRouter(BaseRouter): - def __init__(self, engine: R2REngine, run_type: RunType = RunType.INGESTION): + def __init__( + self, engine: R2REngine, run_type: RunType = RunType.INGESTION + ): super().__init__(engine, run_type) self.openapi_extras = self.load_openapi_extras() self.setup_routes() diff --git a/py/core/main/api/routes/management/base.py b/py/core/main/api/routes/management/base.py index 00c89a31a..a062fa75c 100644 --- a/py/core/main/api/routes/management/base.py +++ b/py/core/main/api/routes/management/base.py @@ -31,7 +31,9 @@ class ManagementRouter(BaseRouter): - def __init__(self, engine: R2REngine, run_type: RunType = RunType.MANAGEMENT): + def __init__( + self, engine: R2REngine, run_type: RunType = RunType.MANAGEMENT + ): super().__init__(engine, run_type) self.start_time = datetime.now(timezone.utc) self.setup_routes() diff --git a/py/core/main/api/routes/restructure/base.py b/py/core/main/api/routes/restructure/base.py index 7e8ca627b..ff7328644 100644 --- a/py/core/main/api/routes/restructure/base.py +++ b/py/core/main/api/routes/restructure/base.py @@ -7,7 +7,9 @@ class RestructureRouter(BaseRouter): - def __init__(self, engine: R2REngine, run_type: RunType = RunType.RESTRUCTURE): + def __init__( + self, engine: R2REngine, run_type: RunType = RunType.RESTRUCTURE + ): super().__init__(engine, run_type) self.setup_routes() diff --git a/py/core/main/api/routes/retrieval/base.py b/py/core/main/api/routes/retrieval/base.py index d562b2b61..4c801a4c0 100644 --- a/py/core/main/api/routes/retrieval/base.py +++ b/py/core/main/api/routes/retrieval/base.py @@ -23,7 +23,9 @@ class RetrievalRouter(BaseRouter): - def __init__(self, engine: R2REngine, run_type: RunType = RunType.RETRIEVAL): + def __init__( + self, engine: R2REngine, run_type: RunType = RunType.RETRIEVAL + ): super().__init__(engine, run_type) self.openapi_extras = self.load_openapi_extras() self.setup_routes() diff --git a/py/core/main/services/management_service.py b/py/core/main/services/management_service.py index 43657bfc4..34dd35a47 100644 --- a/py/core/main/services/management_service.py +++ b/py/core/main/services/management_service.py @@ -63,9 +63,7 @@ async def alogs( aggregated_logs = [] for run in run_info: - run_logs = [ - log for log in logs if log["run_id"] == run.run_id - ] + run_logs = [log for log in logs if log["run_id"] == run.run_id] entries = [ { "key": log["key"], @@ -73,7 +71,9 @@ async def alogs( "timestamp": log["timestamp"], } for log in run_logs - ][::-1] # Reverse order so that earliest logged values appear first. + ][ + ::-1 + ] # Reverse order so that earliest logged values appear first. log_entry = { "run_id": str(run.run_id), diff --git a/py/core/pipelines/ingestion_pipeline.py b/py/core/pipelines/ingestion_pipeline.py index 3de2d095b..6cef2b187 100644 --- a/py/core/pipelines/ingestion_pipeline.py +++ b/py/core/pipelines/ingestion_pipeline.py @@ -123,9 +123,7 @@ async def process_documents(): "embedding_pipeline_output": ( results[0] if self.embedding_pipeline else None ), - "kg_pipeline_output": ( - results[-1] if self.kg_pipeline else None - ), + "kg_pipeline_output": (results[-1] if self.kg_pipeline else None), } def add_pipe( diff --git a/py/poetry.lock b/py/poetry.lock index bfbcfa739..3ca82c165 100644 --- a/py/poetry.lock +++ b/py/poetry.lock @@ -766,21 +766,6 @@ files = [ docs = ["ipython", "matplotlib", "numpydoc", "sphinx"] tests = ["pytest", "pytest-cov", "pytest-xdist"] -[[package]] -name = "dataclasses-json" -version = "0.6.7" -description = "Easily serialize dataclasses to and from JSON." -optional = true -python-versions = "<4.0,>=3.7" -files = [ - {file = "dataclasses_json-0.6.7-py3-none-any.whl", hash = "sha256:0dbf33f26c8d5305befd61b39d2b3414e8a407bedc2834dea9b8d642666fb40a"}, - {file = "dataclasses_json-0.6.7.tar.gz", hash = "sha256:b6b3e528266ea45b9535223bc53ca645f5208833c29229e847b3f26a1cc55fc0"}, -] - -[package.dependencies] -marshmallow = ">=3.18.0,<4.0.0" -typing-inspect = ">=0.4.0,<1" - [[package]] name = "decorator" version = "4.4.2" @@ -1574,21 +1559,25 @@ test = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "p [[package]] name = "importlib-resources" -version = "6.4.3" +version = "6.4.4" description = "Read resources from Python packages" optional = true python-versions = ">=3.8" files = [ - {file = "importlib_resources-6.4.3-py3-none-any.whl", hash = "sha256:2d6dfe3b9e055f72495c2085890837fc8c758984e209115c8792bddcb762cd93"}, - {file = "importlib_resources-6.4.3.tar.gz", hash = "sha256:4a202b9b9d38563b46da59221d77bb73862ab5d79d461307bcb826d725448b98"}, + {file = "importlib_resources-6.4.4-py3-none-any.whl", hash = "sha256:dda242603d1c9cd836c3368b1174ed74cb4049ecd209e7a1a0104620c18c5c11"}, + {file = "importlib_resources-6.4.4.tar.gz", hash = "sha256:20600c8b7361938dc0bb2d5ec0297802e575df486f5a544fa414da65e13721f7"}, ] [package.dependencies] zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} [package.extras] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"] +cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -test = ["jaraco.test (>=5.4)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-ruff (>=0.2.1)", "zipp (>=3.17)"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["jaraco.test (>=5.4)", "pytest (>=6,!=8.1.*)", "zipp (>=3.17)"] +type = ["pytest-mypy"] [[package]] name = "iniconfig" @@ -1716,17 +1705,6 @@ files = [ {file = "joblib-1.4.2.tar.gz", hash = "sha256:2382c5816b2636fbd20a09e0f4e9dad4736765fdfb7dca582943b9c1366b3f0e"}, ] -[[package]] -name = "jsonpath-python" -version = "1.0.6" -description = "A more powerful JSONPath implementation in modern python" -optional = true -python-versions = ">=3.6" -files = [ - {file = "jsonpath-python-1.0.6.tar.gz", hash = "sha256:dd5be4a72d8a2995c3f583cf82bf3cd1a9544cfdabf2d22595b67aff07349666"}, - {file = "jsonpath_python-1.0.6-py3-none-any.whl", hash = "sha256:1e3b78df579f5efc23565293612decee04214609208a2335884b3ee3f786b575"}, -] - [[package]] name = "jsonschema" version = "4.23.0" @@ -2174,25 +2152,6 @@ files = [ {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, ] -[[package]] -name = "marshmallow" -version = "3.22.0" -description = "A lightweight library for converting complex datatypes to and from native Python datatypes." -optional = true -python-versions = ">=3.8" -files = [ - {file = "marshmallow-3.22.0-py3-none-any.whl", hash = "sha256:71a2dce49ef901c3f97ed296ae5051135fd3febd2bf43afe0ae9a82143a494d9"}, - {file = "marshmallow-3.22.0.tar.gz", hash = "sha256:4972f529104a220bb8637d595aa4c9762afbe7f7a77d82dc58c1615d70c5823e"}, -] - -[package.dependencies] -packaging = ">=17.0" - -[package.extras] -dev = ["marshmallow[tests]", "pre-commit (>=3.5,<4.0)", "tox"] -docs = ["alabaster (==1.0.0)", "autodocsumm (==0.2.13)", "sphinx (==8.0.2)", "sphinx-issues (==4.1.0)", "sphinx-version-warning (==1.1.2)"] -tests = ["pytest", "pytz", "simplejson"] - [[package]] name = "matplotlib" version = "3.9.2" @@ -2680,11 +2639,11 @@ files = [ [package.dependencies] numpy = [ {version = ">=1.21.0", markers = "python_version == \"3.9\" and platform_system == \"Darwin\" and platform_machine == \"arm64\""}, - {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, - {version = ">=1.23.5", markers = "python_version >= \"3.11\" and python_version < \"3.12\""}, {version = ">=1.21.4", markers = "python_version >= \"3.10\" and platform_system == \"Darwin\" and python_version < \"3.11\""}, {version = ">=1.21.2", markers = "platform_system != \"Darwin\" and python_version >= \"3.10\" and python_version < \"3.11\""}, {version = ">=1.19.3", markers = "platform_system == \"Linux\" and platform_machine == \"aarch64\" and python_version >= \"3.8\" and python_version < \"3.10\" or python_version > \"3.9\" and python_version < \"3.10\" or python_version >= \"3.9\" and platform_system != \"Darwin\" and python_version < \"3.10\" or python_version >= \"3.9\" and platform_machine != \"arm64\" and python_version < \"3.10\""}, + {version = ">=1.23.5", markers = "python_version >= \"3.11\" and python_version < \"3.12\""}, + {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, ] [[package]] @@ -2767,8 +2726,8 @@ files = [ [package.dependencies] numpy = [ {version = ">=1.22.4", markers = "python_version < \"3.11\""}, - {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, {version = ">=1.23.2", markers = "python_version == \"3.11\""}, + {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, ] python-dateutil = ">=2.8.2" pytz = ">=2020.1" @@ -3823,20 +3782,6 @@ urllib3 = ">=1.21.1,<3" socks = ["PySocks (>=1.5.6,!=1.5.7)"] use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] -[[package]] -name = "requests-toolbelt" -version = "1.0.0" -description = "A utility belt for advanced users of python-requests" -optional = true -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6"}, - {file = "requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06"}, -] - -[package.dependencies] -requests = ">=2.0.1,<3.0.0" - [[package]] name = "rpds-py" version = "0.20.0" @@ -4542,21 +4487,6 @@ files = [ {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, ] -[[package]] -name = "typing-inspect" -version = "0.9.0" -description = "Runtime inspection utilities for typing module." -optional = true -python-versions = "*" -files = [ - {file = "typing_inspect-0.9.0-py3-none-any.whl", hash = "sha256:9ee6fc59062311ef8547596ab6b955e1b8aa46242d854bfc78f4f6b0eff35f9f"}, - {file = "typing_inspect-0.9.0.tar.gz", hash = "sha256:b23fc42ff6f6ef6954e4852c1fb512cdd18dbea03134f91f856a95ccc9461f78"}, -] - -[package.dependencies] -mypy-extensions = ">=0.3.0" -typing-extensions = ">=3.7.4" - [[package]] name = "tzdata" version = "2024.1" @@ -4592,41 +4522,6 @@ parametric-umap = ["tensorflow (>=2.1)"] plot = ["bokeh", "colorcet", "datashader", "holoviews", "matplotlib", "pandas", "scikit-image", "seaborn"] tbb = ["tbb (>=2019.0)"] -[[package]] -name = "unstructured-client" -version = "0.25.5" -description = "Python Client SDK for Unstructured API" -optional = true -python-versions = ">=3.8" -files = [ - {file = "unstructured-client-0.25.5.tar.gz", hash = "sha256:adb97ea56ce65f8b277d5b05f093e9d13a3320ac8dea7265ffa71f5e13ed5f84"}, - {file = "unstructured_client-0.25.5-py3-none-any.whl", hash = "sha256:23537fee984e43d06a75f986a73e420a9659cc92010afb8324fbf67c85962eaf"}, -] - -[package.dependencies] -certifi = ">=2023.7.22" -charset-normalizer = ">=3.2.0" -dataclasses-json = ">=0.6.4" -deepdiff = ">=6.0" -httpx = ">=0.27.0" -idna = ">=3.4" -jsonpath-python = ">=1.0.6" -marshmallow = ">=3.19.0" -mypy-extensions = ">=1.0.0" -nest-asyncio = ">=1.6.0" -packaging = ">=23.1" -pypdf = ">=4.0" -python-dateutil = ">=2.8.2" -requests = ">=2.31.0" -requests-toolbelt = ">=1.0.0" -six = ">=1.16.0" -typing-extensions = ">=4.7.1" -typing-inspect = ">=0.9.0" -urllib3 = ">=1.26.18" - -[package.extras] -dev = ["pylint (==3.1.0)"] - [[package]] name = "urllib3" version = "2.2.2" @@ -4914,10 +4809,10 @@ doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linke test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy", "pytest-ruff (>=0.2.1)"] [extras] -core = ["aiosqlite", "asyncpg", "bcrypt", "beautifulsoup4", "deepdiff", "fire", "fsspec", "graspologic", "gunicorn", "litellm", "markdown", "neo4j", "ollama", "openai", "openpyxl", "passlib", "poppler-utils", "posthog", "psutil", "pydantic", "pyjwt", "pypdf", "python-docx", "python-multipart", "python-pptx", "pyyaml", "redis", "requests", "sqlalchemy", "toml", "types-requests", "unstructured_client", "uvicorn", "vecs"] +core = ["aiosqlite", "asyncpg", "bcrypt", "beautifulsoup4", "deepdiff", "fire", "fsspec", "graspologic", "gunicorn", "litellm", "markdown", "neo4j", "ollama", "openai", "openpyxl", "passlib", "poppler-utils", "posthog", "psutil", "pydantic", "pyjwt", "pypdf", "python-docx", "python-multipart", "python-pptx", "pyyaml", "redis", "requests", "sqlalchemy", "toml", "types-requests", "uvicorn", "vecs"] core-ingest-movies = ["moviepy", "opencv-python"] [metadata] lock-version = "2.0" python-versions = ">=3.9,<3.13" -content-hash = "32a72ff508ce34d83088f25d824aabf7134d70c56332bae6bc495b0bcafa84ec" +content-hash = "e895ee32f5d5aa71a29548d0e48044276b364a43c54b62f7f6da0bb932b53499" diff --git a/py/scripts/download_nltk_data.py b/py/scripts/download_nltk_data.py index f0ed4d6a5..c690b17b2 100644 --- a/py/scripts/download_nltk_data.py +++ b/py/scripts/download_nltk_data.py @@ -1,7 +1,16 @@ +import ssl + import nltk def download_nltk_data(): + try: + _create_unverified_https_context = ssl._create_unverified_context + except AttributeError: + pass + else: + ssl._create_default_https_context = _create_unverified_https_context + nltk.download("wordnet", quiet=True) From 2fd98484a51fcfab43b780ffa8ff82b6f8998bff Mon Sep 17 00:00:00 2001 From: NolanTrem <34580718+NolanTrem@users.noreply.github.com> Date: Thu, 22 Aug 2024 10:34:49 -0700 Subject: [PATCH 40/74] Fix analytics endpoint --- py/core/main/api/routes/management/base.py | 6 ++++-- py/core/main/services/management_service.py | 14 ++++++++------ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/py/core/main/api/routes/management/base.py b/py/core/main/api/routes/management/base.py index a062fa75c..62b312cd1 100644 --- a/py/core/main/api/routes/management/base.py +++ b/py/core/main/api/routes/management/base.py @@ -101,8 +101,10 @@ async def get_analytics_app( try: result = await self.engine.aanalytics( - filter_criteria=LogFilterCriteria(**filter_criteria), - analysis_types=AnalysisTypes(**analysis_types), + filter_criteria=LogFilterCriteria(filters=filter_criteria), + analysis_types=AnalysisTypes( + analysis_types=analysis_types + ), ) return result except json.JSONDecodeError as e: diff --git a/py/core/main/services/management_service.py b/py/core/main/services/management_service.py index 34dd35a47..f572a55e1 100644 --- a/py/core/main/services/management_service.py +++ b/py/core/main/services/management_service.py @@ -1,6 +1,5 @@ import json import logging -import uuid from collections import defaultdict from typing import Any, Dict, List, Optional, Tuple from uuid import UUID @@ -133,8 +132,8 @@ async def aanalytics( ) filtered_logs = dict(log_processor.populations.items()) - results = {"filtered_logs": filtered_logs} + analytics_data = {} if analysis_types and analysis_types.analysis_types: for ( filter_key, @@ -144,14 +143,14 @@ async def aanalytics( analysis_type = analysis_config[0] if analysis_type == "bar_chart": extract_key = analysis_config[1] - results[filter_key] = ( + analytics_data[filter_key] = ( AnalysisTypes.generate_bar_chart_data( filtered_logs[filter_key], extract_key ) ) elif analysis_type == "basic_statistics": extract_key = analysis_config[1] - results[filter_key] = ( + analytics_data[filter_key] = ( AnalysisTypes.calculate_basic_statistics( filtered_logs[filter_key], extract_key ) @@ -159,7 +158,7 @@ async def aanalytics( elif analysis_type == "percentile": extract_key = analysis_config[1] percentile = int(analysis_config[2]) - results[filter_key] = ( + analytics_data[filter_key] = ( AnalysisTypes.calculate_percentile( filtered_logs[filter_key], extract_key, @@ -171,7 +170,10 @@ async def aanalytics( f"Unknown analysis type for filter key '{filter_key}': {analysis_type}" ) - return results + return { + "analytics_data": analytics_data or None, + "filtered_logs": filtered_logs, + } @telemetry_event("AppSettings") async def aapp_settings(self, *args: Any, **kwargs: Any): From b751fa93c91e14e857beeffba5b6788d95ff156a Mon Sep 17 00:00:00 2001 From: Nolan Tremelling <34580718+NolanTrem@users.noreply.github.com> Date: Thu, 22 Aug 2024 10:44:40 -0700 Subject: [PATCH 41/74] Update OpenAI sdk calls (#933) --- py/core/providers/embeddings/openai.py | 15 ++++++--------- py/core/providers/llm/openai.py | 4 ++-- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/py/core/providers/embeddings/openai.py b/py/core/providers/embeddings/openai.py index 2ae812ee2..613fc6b88 100644 --- a/py/core/providers/embeddings/openai.py +++ b/py/core/providers/embeddings/openai.py @@ -1,4 +1,3 @@ -import asyncio import logging import os from typing import Any, List @@ -91,12 +90,10 @@ def _get_dimensions(self): ) def _get_embedding_kwargs(self, **kwargs): - embedding_kwargs = { + return { "model": self.base_model, "dimensions": self._get_dimensions(), - } - embedding_kwargs.update(kwargs) - return embedding_kwargs + } | kwargs async def _execute_task(self, task: dict[str, Any]) -> List[List[float]]: texts = task["texts"] @@ -115,7 +112,7 @@ async def _execute_task(self, task: dict[str, Any]) -> List[List[float]]: except Exception as e: error_msg = f"Error getting embeddings: {str(e)}" logger.error(error_msg) - raise ValueError(error_msg) + raise ValueError(error_msg) from e def _execute_task_sync(self, task: dict[str, Any]) -> List[List[float]]: texts = task["texts"] @@ -133,7 +130,7 @@ def _execute_task_sync(self, task: dict[str, Any]) -> List[List[float]]: except Exception as e: error_msg = f"Error getting embeddings: {str(e)}" logger.error(error_msg) - raise ValueError(error_msg) + raise ValueError(error_msg) from e async def async_get_embedding( self, @@ -229,10 +226,10 @@ def rerank( def tokenize_string(self, text: str, model: str) -> list[int]: try: import tiktoken - except ImportError: + except ImportError as e: raise ValueError( "Must download tiktoken library to run `tokenize_string`." - ) + ) from e if model not in OpenAIEmbeddingProvider.MODEL_TO_TOKENIZER: raise ValueError(f"OpenAI embedding model {model} not supported.") encoding = tiktoken.get_encoding( diff --git a/py/core/providers/llm/openai.py b/py/core/providers/llm/openai.py index f6e522796..f960ef425 100644 --- a/py/core/providers/llm/openai.py +++ b/py/core/providers/llm/openai.py @@ -51,7 +51,7 @@ async def _execute_task(self, task: dict[str, Any]): logger.debug(f"Executing async OpenAI task with args: {args}") try: - response = await self.async_client.chat.completion.create(**args) + response = await self.async_client.chat.completions.create(**args) logger.debug("Async OpenAI task executed successfully") return response except Exception as e: @@ -69,7 +69,7 @@ def _execute_task_sync(self, task: dict[str, Any]): logger.debug(f"Executing sync OpenAI task with args: {args}") try: - response = self.client.chat.completion.create(**args) + response = self.client.chat.completions.create(**args) logger.debug("Sync OpenAI task executed successfully") return response except Exception as e: From 03e6d2959ecf3e6b62ad22cc219cfc80bf5dd01d Mon Sep 17 00:00:00 2001 From: emrgnt-cmplxty <68796651+emrgnt-cmplxty@users.noreply.github.com> Date: Thu, 22 Aug 2024 10:45:05 -0700 Subject: [PATCH 42/74] Feature/revive advanced rag (#932) * rm double logging * revive advanced rag examples * merge (#934) --- py/core/__init__.py | 3 + py/core/base/abstractions/search.py | 2 +- py/core/examples/scripts/run_hyde.py | 32 ---------- py/core/examples/scripts/serve_with_hyde.py | 20 +++++++ .../{run_web_rag.py => serve_with_web.py} | 12 +--- ...eb_multi_rag.py => serve_with_web_hyde.py} | 14 +---- py/core/pipes/other/web_search_pipe.py | 16 ++--- .../pipes/retrieval/query_transform_pipe.py | 2 +- py/core/providers/database/vector.py | 59 ------------------- 9 files changed, 37 insertions(+), 123 deletions(-) delete mode 100644 py/core/examples/scripts/run_hyde.py create mode 100644 py/core/examples/scripts/serve_with_hyde.py rename py/core/examples/scripts/{run_web_rag.py => serve_with_web.py} (50%) rename py/core/examples/scripts/{run_web_multi_rag.py => serve_with_web_hyde.py} (84%) diff --git a/py/core/__init__.py b/py/core/__init__.py index 2ed623e65..28f50891d 100644 --- a/py/core/__init__.py +++ b/py/core/__init__.py @@ -174,6 +174,9 @@ "RelationshipType", "format_entity_types", "format_relations", + ## INTEGRATIONS + # Serper + "SerperClient", ## MAIN ## R2R ABSTRACTIONS "R2RProviders", diff --git a/py/core/base/abstractions/search.py b/py/core/base/abstractions/search.py index 8411faa1a..f43445141 100644 --- a/py/core/base/abstractions/search.py +++ b/py/core/base/abstractions/search.py @@ -15,7 +15,7 @@ class VectorSearchResult(BaseModel): fragment_id: UUID extraction_id: UUID document_id: UUID - user_id: UUID + user_id: Optional[UUID] group_ids: list[UUID] score: float text: str diff --git a/py/core/examples/scripts/run_hyde.py b/py/core/examples/scripts/run_hyde.py deleted file mode 100644 index b5bcc23a7..000000000 --- a/py/core/examples/scripts/run_hyde.py +++ /dev/null @@ -1,32 +0,0 @@ -import fire -from core import R2RBuilder, R2RConfig -from core.base.abstractions.llm import GenerationConfig -from core.main.assembly.factory_extensions import R2RPipeFactoryWithMultiSearch - - -def main(task_prompt_name="hyde", query="Who was aristotle?"): - # Load the configuration file - config = R2RConfig.from_toml() - - app = ( - R2RBuilder(config) - .with_pipe_factory(R2RPipeFactoryWithMultiSearch) - .build( - # Add optional override arguments which propagate to the pipe factory - task_prompt_name=task_prompt_name, - ) - ) - - # Run the RAG pipeline through the R2R application - result = app.rag( - query, - query_transform_generation_config=GenerationConfig(model="gpt-4o"), - rag_generation_config=GenerationConfig(model="gpt-3.5-turbo"), - ) - - print(f"Search Results:\n\n{result.search_results}") - print(f"RAG Results:\n\n{result.completion}") - - -if __name__ == "__main__": - fire.Fire(main) diff --git a/py/core/examples/scripts/serve_with_hyde.py b/py/core/examples/scripts/serve_with_hyde.py new file mode 100644 index 000000000..688e31aab --- /dev/null +++ b/py/core/examples/scripts/serve_with_hyde.py @@ -0,0 +1,20 @@ +from r2r import R2RBuilder, R2RConfig, R2RPipeFactoryWithMultiSearch +import fire + + +def main(task_prompt_name="hyde"): + # Load the default configuration file + config = R2RConfig.from_toml() + + app = ( + R2RBuilder(config) + .with_pipe_factory(R2RPipeFactoryWithMultiSearch) + .build( + # Add optional override arguments which propagate to the pipe factory + task_prompt_name=task_prompt_name, + ) + ) + app.serve() + +if __name__ == "__main__": + fire.Fire(main) diff --git a/py/core/examples/scripts/run_web_rag.py b/py/core/examples/scripts/serve_with_web.py similarity index 50% rename from py/core/examples/scripts/run_web_rag.py rename to py/core/examples/scripts/serve_with_web.py index d16cad68f..79ab45e8c 100644 --- a/py/core/examples/scripts/run_web_rag.py +++ b/py/core/examples/scripts/serve_with_web.py @@ -1,9 +1,8 @@ import fire -from core.base.abstractions.llm import GenerationConfig from r2r import R2RBuilder, SerperClient, WebSearchPipe -def run_rag_pipeline(query="Who was Aristotle?"): +def run_rag_pipeline(): # Create search pipe override and pipes web_search_pipe = WebSearchPipe( serper_client=SerperClient() # TODO - Develop a `WebSearchProvider` for configurability @@ -11,14 +10,7 @@ def run_rag_pipeline(query="Who was Aristotle?"): app = R2RBuilder().with_vector_search_pipe(web_search_pipe).build() - # Run the RAG pipeline through the R2R application - result = app.rag( - query, - rag_generation_config=GenerationConfig(model="gpt-4o"), - ) - - print(f"Search Results:\n\n{result.search_results}") - print(f"RAG Results:\n\n{result.completion}") + app.serve() if __name__ == "__main__": diff --git a/py/core/examples/scripts/run_web_multi_rag.py b/py/core/examples/scripts/serve_with_web_hyde.py similarity index 84% rename from py/core/examples/scripts/run_web_multi_rag.py rename to py/core/examples/scripts/serve_with_web_hyde.py index 915ee5ea9..06eef6990 100644 --- a/py/core/examples/scripts/run_web_multi_rag.py +++ b/py/core/examples/scripts/serve_with_web_hyde.py @@ -4,7 +4,7 @@ from core.main.assembly.factory_extensions import R2RPipeFactoryWithMultiSearch -def run_rag_pipeline(query="Who was Aristotle?"): +def run_rag_pipeline(): # Initialize a web search pipe web_search_pipe = WebSearchPipe(serper_client=SerperClient()) @@ -37,17 +37,7 @@ def run_rag_pipeline(query="Who was Aristotle?"): multi_inner_search_pipe_override=web_search_pipe, query_generation_template_override=synthetic_query_generation_template, ) - ) - - # Run the RAG pipeline through the R2R application - result = app.rag( - query, - rag_generation_config=GenerationConfig(model="gpt-4o"), - ) - - print(f"Search Results:\n\n{result.search_results}") - print(f"RAG Results:\n\n{result.completion}") - + ).serve() if __name__ == "__main__": fire.Fire(run_rag_pipeline) diff --git a/py/core/pipes/other/web_search_pipe.py b/py/core/pipes/other/web_search_pipe.py index 0c0e39178..6db7e9b8c 100644 --- a/py/core/pipes/other/web_search_pipe.py +++ b/py/core/pipes/other/web_search_pipe.py @@ -1,7 +1,7 @@ import json import logging from typing import Any, AsyncGenerator, Optional -from uuid import UUID +import uuid from core.base import ( AsyncPipe, @@ -37,7 +37,7 @@ def __init__( async def search( self, message: str, - run_id: UUID, + run_id: uuid.UUID, *args: Any, **kwargs: Any, ) -> AsyncGenerator[VectorSearchResult, None]: @@ -55,17 +55,17 @@ async def search( for result in results: if result.get("snippet") is None: continue - result.text = result.pop("snippet") + text = result.pop("snippet") search_result = VectorSearchResult( fragment_id=generate_id_from_label(str(result)), - extraction_id=uuid.uuid4(), # Generate a new UUID for extraction_id - document_id=uuid.uuid4(), # Generate a new UUID for document_id + extraction_id=uuid.uuid5(uuid.NAMESPACE_DNS, str(uuid.uuid4())), # Generate a new UUID for extraction_id + document_id=uuid.uuid5(uuid.NAMESPACE_DNS, str(uuid.uuid4())), # Generate a new UUID for document_id user_id=None, # Web search results don't have a user_id group_ids=[], # Web search results don't belong to any group score=result.get( "score", 0 ), # TODO - Consider dynamically generating scores based on similarity - text=result.text, + text=text, metadata=result, ) search_results.append(search_result) @@ -74,14 +74,14 @@ async def search( await self.enqueue_log( run_id=run_id, key="search_results", - value=json.dumps([ele.dict() for ele in search_results]), + value=json.dumps([ele.json() for ele in search_results]), ) async def _run_logic( self, input: AsyncPipe.Input, state: AsyncState, - run_id: UUID, + run_id: uuid.UUID, *args: Any, **kwargs, ) -> AsyncGenerator[VectorSearchResult, None]: diff --git a/py/core/pipes/retrieval/query_transform_pipe.py b/py/core/pipes/retrieval/query_transform_pipe.py index 16dbadccb..f689aa76b 100644 --- a/py/core/pipes/retrieval/query_transform_pipe.py +++ b/py/core/pipes/retrieval/query_transform_pipe.py @@ -74,7 +74,7 @@ async def _run_logic( messages=query_transform_request, generation_config=query_transform_generation_config, ) - content = self.llm_provider.extract_content(response) + content = response.choices[0].message.content outputs = content.split("\n") outputs = [ output.strip() for output in outputs if output.strip() != "" diff --git a/py/core/providers/database/vector.py b/py/core/providers/database/vector.py index f26f017a0..a4aadcba3 100644 --- a/py/core/providers/database/vector.py +++ b/py/core/providers/database/vector.py @@ -223,66 +223,7 @@ def full_text_search( results = self.collection.full_text_search( query_text=query_text, search_settings=search_settings ) - print("results = ", results) return results - # from sqlalchemy import func, select - # from sqlalchemy.sql.expression import or_ - - # words = query_text.split() - # similarity_threshold = 0.3 # Adjust this value to control fuzziness - - # full_text_query = ( - # select( - # self.collection.table.c.fragment_id, - # self.collection.table.c.extraction_id, - # self.collection.table.c.document_id, - # self.collection.table.c.user_id, - # self.collection.table.c.group_ids, - # self.collection.table.c.text, - # self.collection.table.c.metadata, - # (func.ts_rank( - # func.to_tsvector('english', self.collection.table.c.text), - # func.plainto_tsquery('english', query_text), - # ) + - # func.similarity(self.collection.table.c.text, query_text)).label("rank"), - # func.ts_headline( - # 'english', - # self.collection.table.c.text, - # func.plainto_tsquery('english', query_text), - # "StartSel = , StopSel = , MaxWords=35, MinWords=15" - # ).label("headline"), - # ) - # .where( - # or_( - # func.to_tsvector('english', self.collection.table.c.text).op('@@')( - # func.plainto_tsquery('english', query_text) - # ), - # func.similarity(self.collection.table.c.text, query_text) > similarity_threshold - # ) - # ) - # .order_by(text("rank DESC")) - # .limit(search_settings.hybrid_search_settings.full_text_limit) - # ) - - # print(f"Full-text query: {full_text_query}") - - # with self.vx.Session() as session: - # results = session.execute(full_text_query).fetchall() - # print('results = ', results) - - # return [ - # VectorSearchResult( - # fragment_id=result.fragment_id, - # extraction_id=result.extraction_id, - # document_id=result.document_id, - # user_id=result.user_id, - # group_ids=result.group_ids, - # text=result.text, - # score=float(result.rank), - # metadata={**result.metadata, "headline": result.headline}, - # ) - # for result in results - # ] def hybrid_search( self, From cb3ba3cbd5a97206a998e086a5d02fb4fa678bd0 Mon Sep 17 00:00:00 2001 From: emrgnt-cmplxty <68796651+emrgnt-cmplxty@users.noreply.github.com> Date: Thu, 22 Aug 2024 10:54:08 -0700 Subject: [PATCH 43/74] sync model (#935) --- py/sdk/models.py | 54 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 5 deletions(-) diff --git a/py/sdk/models.py b/py/sdk/models.py index 8dd86cf71..e0355fc7e 100644 --- a/py/sdk/models.py +++ b/py/sdk/models.py @@ -209,6 +209,10 @@ class VectorSearchSettings(BaseModel): use_vector_search: bool = Field( default=True, description="Whether to use vector search" ) + use_hybrid_search: bool = Field( + default=False, + description="Whether to perform a hybrid search (combining vector and keyword search)", + ) filters: dict[str, Any] = Field( default_factory=dict, description="Filters to apply to the vector search", @@ -217,19 +221,59 @@ class VectorSearchSettings(BaseModel): default=10, description="Maximum number of results to return", ge=1, - le=100, - ) - use_hybrid_search: bool = Field( - default=False, - description="Whether to perform a hybrid search (combining vector and keyword search)", + le=1_000, ) selected_group_ids: list[UUID] = Field( default_factory=list, description="Group IDs to search for", ) + index_measure: IndexMeasure = Field( + default=IndexMeasure.cosine_distance, + description="The distance measure to use for indexing", + ) + include_values: bool = Field( + default=True, + description="Whether to include search score values in the search results", + ) + include_metadatas: bool = Field( + default=True, + description="Whether to include element metadata in the search results", + ) + probes: Optional[int] = Field( + default=10, + description="Number of ivfflat index lists to query. Higher increases accuracy but decreases speed.", + ) + ef_search: Optional[int] = Field( + default=40, + description="Size of the dynamic candidate list for HNSW index search. Higher increases accuracy but decreases speed.", + ) + hybrid_search_settings: Optional[HybridSearchSettings] = Field( + default=HybridSearchSettings(), + description="Settings for hybrid search", + ) class Config: json_encoders = {UUID: str} + json_schema_extra = { + "use_vector_search": True, + "use_hybrid_search": True, + "filters": {"category": "technology"}, + "search_limit": 20, + "selected_group_ids": [ + "2acb499e-8428-543b-bd85-0d9098718220", + "3e157b3a-8469-51db-90d9-52e7d896b49b", + ], + "index_measure": "cosine_distance", + "include_metadata": True, + "probes": 10, + "ef_search": 40, + "hybrid_search_settings": { + "full_text_weight": 1.0, + "semantic_weight": 5.0, + "full_text_limit": 200, + "rrf_k": 50, + }, + } def model_dump(self, *args, **kwargs): dump = super().model_dump(*args, **kwargs) From b8501ff2618a15f27c8ae880f33f52441af52ab6 Mon Sep 17 00:00:00 2001 From: emrgnt-cmplxty <68796651+emrgnt-cmplxty@users.noreply.github.com> Date: Thu, 22 Aug 2024 11:20:28 -0700 Subject: [PATCH 44/74] Feature/remove version from ingestion end pt (#936) * sync model * remove ability to set version * tweak versions impl * fix version bug --- py/cli/commands/ingestion.py | 10 ++----- py/core/main/api/routes/ingestion/base.py | 6 +---- py/core/main/services/ingestion_service.py | 16 ++++++----- py/core/pipes/ingestion/parsing_pipe.py | 6 ++--- py/sdk/ingestion.py | 7 ----- py/sdk/models.py | 31 ++++++++++++++++++++++ 6 files changed, 45 insertions(+), 31 deletions(-) diff --git a/py/cli/commands/ingestion.py b/py/cli/commands/ingestion.py index 403aaa632..77a98946f 100644 --- a/py/cli/commands/ingestion.py +++ b/py/cli/commands/ingestion.py @@ -21,21 +21,15 @@ @click.option( "--metadatas", type=JSON, help="Metadatas for ingestion as a JSON string" ) -@click.option( - "--versions", - multiple=True, - help="Starting version for ingested files (e.g. `v1`)", -) @click.pass_obj -def ingest_files(client, file_paths, document_ids, metadatas, versions): +def ingest_files(client, file_paths, document_ids, metadatas): """Ingest files into R2R.""" with timer(): file_paths = list(file_paths) document_ids = list(document_ids) if document_ids else None - versions = list(versions) if versions else None response = client.ingest_files( - file_paths, metadatas, document_ids, versions + file_paths, metadatas, document_ids ) click.echo(json.dumps(response, indent=2)) diff --git a/py/core/main/api/routes/ingestion/base.py b/py/core/main/api/routes/ingestion/base.py index f0510e944..d9d429049 100644 --- a/py/core/main/api/routes/ingestion/base.py +++ b/py/core/main/api/routes/ingestion/base.py @@ -34,7 +34,7 @@ def load_openapi_extras(self): def setup_routes(self): # Note, we use the following verbose input parameters because FastAPI struggles to handle `File` input and `Body` inputs - # at the same time. Therefore, we must ues `Form` inputs for the metadata, document_ids, and versions inputs. + # at the same time. Therefore, we must ues `Form` inputs for the metadata, document_ids ingest_files_extras = self.openapi_extras.get("ingest_files", {}) ingest_files_descriptions = ingest_files_extras.get( "input_descriptions", {} @@ -53,9 +53,6 @@ async def ingest_files_app( None, description=ingest_files_descriptions.get("document_ids"), ), - versions: Optional[Json[list[str]]] = Form( - None, description=ingest_files_descriptions.get("versions") - ), metadatas: Optional[Json[list[dict]]] = Form( None, description=ingest_files_descriptions.get("metadatas") ), @@ -107,7 +104,6 @@ async def ingest_files_app( files=files, metadatas=metadatas, document_ids=document_ids, - versions=versions, user=auth_user, chunking_provider=chunking_provider, ) diff --git a/py/core/main/services/ingestion_service.py b/py/core/main/services/ingestion_service.py index c035e2933..abc4da6c1 100644 --- a/py/core/main/services/ingestion_service.py +++ b/py/core/main/services/ingestion_service.py @@ -28,7 +28,7 @@ logger = logging.getLogger(__name__) MB_CONVERSION_FACTOR = 1024 * 1024 - +STARTING_VERSION = "v0" class IngestionService(Service): def __init__( @@ -56,7 +56,6 @@ async def ingest_files( user: UserResponse, metadatas: Optional[list[dict]] = None, document_ids: Optional[list[UUID]] = None, - versions: Optional[list[str]] = None, chunking_provider: Optional[ChunkingProvider] = None, *args: Any, **kwargs: Any, @@ -89,7 +88,6 @@ async def ingest_files( # ingests all documents in parallel return await self.ingest_documents( documents, - versions, chunking_provider=chunking_provider, *args, **kwargs, @@ -178,10 +176,11 @@ async def update_files( ) documents.append(document) + ingestion_results = await self.ingest_documents( documents, - versions=new_versions, chunking_provider=chunking_provider, + versions=new_versions, *args, **kwargs, ) @@ -252,7 +251,7 @@ async def ingest_documents( } for iteration, document in enumerate(documents): - version = versions[iteration] if versions else "v0" + version = versions[iteration] if versions else STARTING_VERSION # Check for duplicates within the current batch if document.id in processed_documents: @@ -263,7 +262,8 @@ async def ingest_documents( if ( document.id in existing_document_info - and existing_document_info[document.id].version == version + # apply `geq` check to prevent re-ingestion of updated documents + and (existing_document_info[document.id].version >= version) and existing_document_info[document.id].status == "success" ): logger.error( @@ -305,6 +305,9 @@ async def ingest_documents( processed_documents[document.id] = document.metadata.get( "title", str(document.id) ) + # Add version to metadata to propagate through pipeline + document.metadata["version"] = version + if duplicate_documents: duplicate_details = [ @@ -336,7 +339,6 @@ async def ingest_documents( not in [skipped["id"] for skipped in skipped_documents] ], ), - versions=[info.version for info in document_infos], run_manager=self.run_manager, *args, **kwargs, diff --git a/py/core/pipes/ingestion/parsing_pipe.py b/py/core/pipes/ingestion/parsing_pipe.py index 9b4bdebff..b1b4c8373 100644 --- a/py/core/pipes/ingestion/parsing_pipe.py +++ b/py/core/pipes/ingestion/parsing_pipe.py @@ -72,11 +72,9 @@ async def _run_logic( input: Input, state: AsyncState, run_id: UUID, - versions: Optional[list[str]] = None, *args, **kwargs, ) -> AsyncGenerator[DocumentExtraction, None]: async for document in input.message: - version = versions[0] if versions else "v0" - async for result in self._parse(document, run_id, version): - yield result + async for result in self._parse(document, run_id, document.metadata.get("version", "1.0")): + yield result \ No newline at end of file diff --git a/py/sdk/ingestion.py b/py/sdk/ingestion.py index 48037973e..0f58eb5df 100644 --- a/py/sdk/ingestion.py +++ b/py/sdk/ingestion.py @@ -15,7 +15,6 @@ async def ingest_files( file_paths: list[str], document_ids: Optional[list[Union[str, UUID]]] = None, metadatas: Optional[list[dict]] = None, - versions: Optional[list[str]] = None, chunking_settings: Optional[Union[dict, ChunkingConfig]] = None, ) -> dict: """ @@ -25,7 +24,6 @@ async def ingest_files( file_paths (List[str]): List of file paths to ingest. document_ids (Optional[List[str]]): List of document IDs. metadatas (Optional[List[dict]]): List of metadata dictionaries for each file. - versions (Optional[List[str]]): List of version strings for each file. chunking_settings (Optional[Union[dict, ChunkingConfig]]): Custom chunking configuration. Returns: @@ -39,10 +37,6 @@ async def ingest_files( raise ValueError( "Number of metadatas must match number of document IDs." ) - if versions is not None and len(file_paths) != len(versions): - raise ValueError( - "Number of versions must match number of document IDs." - ) if ( chunking_settings is not None and chunking_settings is not ChunkingConfig @@ -80,7 +74,6 @@ async def ingest_files( if document_ids else None ), - "versions": json.dumps(versions) if versions else None, "chunking_settings": ( json.dumps( chunking_settings.model_dump() diff --git a/py/sdk/models.py b/py/sdk/models.py index e0355fc7e..03b690610 100644 --- a/py/sdk/models.py +++ b/py/sdk/models.py @@ -205,6 +205,37 @@ class Token(BaseModel): token_type: str +class IndexMeasure(str, Enum): + """ + An enum representing the types of distance measures available for indexing. + + Attributes: + cosine_distance (str): The cosine distance measure for indexing. + l2_distance (str): The Euclidean (L2) distance measure for indexing. + max_inner_product (str): The maximum inner product measure for indexing. + """ + + cosine_distance = "cosine_distance" + l2_distance = "l2_distance" + max_inner_product = "max_inner_product" + + + +class HybridSearchSettings(BaseModel): + full_text_weight: float = Field( + default=1.0, description="Weight to apply to full text search" + ) + semantic_weight: float = Field( + default=5.0, description="Weight to apply to semantic search" + ) + full_text_limit: int = Field( + default=200, + description="Maximum number of results to return from full text search", + ) + rrf_k: int = Field( + default=50, description="K-value for RRF (Rank Reciprocal Fusion)" + ) + class VectorSearchSettings(BaseModel): use_vector_search: bool = Field( default=True, description="Whether to use vector search" From 19759e0c672bc343ccd98944bc0cca314c6fa102 Mon Sep 17 00:00:00 2001 From: Nolan Tremelling <34580718+NolanTrem@users.noreply.github.com> Date: Thu, 22 Aug 2024 11:20:42 -0700 Subject: [PATCH 45/74] Move docker (#938) * Move docker * remove from root --- .dockerignore => py/.dockerignore | 0 .flake8 => py/.flake8 | 0 .isort.cfg => py/.isort.cfg | 0 .pre-commit-config.yaml => py/.pre-commit-config.yaml | 0 Dockerfile => py/Dockerfile | 0 Dockerfile.unstructured => py/Dockerfile.unstructured | 0 compose.neo4j.yaml => py/compose.neo4j.yaml | 0 compose.ollama.yaml => py/compose.ollama.yaml | 0 compose.postgres.yaml => py/compose.postgres.yaml | 0 compose.yaml => py/compose.yaml | 0 10 files changed, 0 insertions(+), 0 deletions(-) rename .dockerignore => py/.dockerignore (100%) rename .flake8 => py/.flake8 (100%) rename .isort.cfg => py/.isort.cfg (100%) rename .pre-commit-config.yaml => py/.pre-commit-config.yaml (100%) rename Dockerfile => py/Dockerfile (100%) rename Dockerfile.unstructured => py/Dockerfile.unstructured (100%) rename compose.neo4j.yaml => py/compose.neo4j.yaml (100%) rename compose.ollama.yaml => py/compose.ollama.yaml (100%) rename compose.postgres.yaml => py/compose.postgres.yaml (100%) rename compose.yaml => py/compose.yaml (100%) diff --git a/.dockerignore b/py/.dockerignore similarity index 100% rename from .dockerignore rename to py/.dockerignore diff --git a/.flake8 b/py/.flake8 similarity index 100% rename from .flake8 rename to py/.flake8 diff --git a/.isort.cfg b/py/.isort.cfg similarity index 100% rename from .isort.cfg rename to py/.isort.cfg diff --git a/.pre-commit-config.yaml b/py/.pre-commit-config.yaml similarity index 100% rename from .pre-commit-config.yaml rename to py/.pre-commit-config.yaml diff --git a/Dockerfile b/py/Dockerfile similarity index 100% rename from Dockerfile rename to py/Dockerfile diff --git a/Dockerfile.unstructured b/py/Dockerfile.unstructured similarity index 100% rename from Dockerfile.unstructured rename to py/Dockerfile.unstructured diff --git a/compose.neo4j.yaml b/py/compose.neo4j.yaml similarity index 100% rename from compose.neo4j.yaml rename to py/compose.neo4j.yaml diff --git a/compose.ollama.yaml b/py/compose.ollama.yaml similarity index 100% rename from compose.ollama.yaml rename to py/compose.ollama.yaml diff --git a/compose.postgres.yaml b/py/compose.postgres.yaml similarity index 100% rename from compose.postgres.yaml rename to py/compose.postgres.yaml diff --git a/compose.yaml b/py/compose.yaml similarity index 100% rename from compose.yaml rename to py/compose.yaml From 70510077d6c8a6eefc94ccc3dfb9dcbcc73f50c1 Mon Sep 17 00:00:00 2001 From: NolanTrem <34580718+NolanTrem@users.noreply.github.com> Date: Thu, 22 Aug 2024 11:23:51 -0700 Subject: [PATCH 46/74] Clean up sdk/restructure.py --- py/sdk/restructure.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/py/sdk/restructure.py b/py/sdk/restructure.py index fd3df0ebf..33c86348f 100644 --- a/py/sdk/restructure.py +++ b/py/sdk/restructure.py @@ -1,7 +1,3 @@ -from typing import Any, Dict, List, Optional, Union - -from core.base import Document - from .models import KGEnrichmentResponse, KGEnrichmentSettings @@ -14,6 +10,9 @@ async def enrich_graph( """ Perform graph enrichment over the entire graph. + Args: + KGEnrichmentSettings (KGEnrichmentSettings): Settings for the graph enrichment process. + Returns: KGEnrichmentResponse: Results of the graph enrichment process. """ From 4f26300f7485e436ad9c6a21481f7814bdbfbff5 Mon Sep 17 00:00:00 2001 From: Nolan Tremelling <34580718+NolanTrem@users.noreply.github.com> Date: Thu, 22 Aug 2024 13:20:23 -0700 Subject: [PATCH 47/74] Fix js tests, completion scoring (#939) --- .../r2rClientIntegrationSuperUser.test.ts | 31 +- .../r2rClientIntegrationUser.test.ts | 37 +- js/sdk/pnpm-lock.yaml | 3061 +++++++++++------ js/sdk/src/r2rClient.ts | 49 +- py/cli/commands/management.py | 9 +- py/core/main/services/management_service.py | 2 +- 6 files changed, 2073 insertions(+), 1116 deletions(-) diff --git a/js/sdk/__tests__/r2rClientIntegrationSuperUser.test.ts b/js/sdk/__tests__/r2rClientIntegrationSuperUser.test.ts index f192c8de4..ff8547dc2 100644 --- a/js/sdk/__tests__/r2rClientIntegrationSuperUser.test.ts +++ b/js/sdk/__tests__/r2rClientIntegrationSuperUser.test.ts @@ -85,15 +85,14 @@ describe("r2rClient Integration Tests", () => { await expect(client.agent(messages)).resolves.not.toThrow(); }, 30000); - // TODO: Fix this test - // test("Score completion", async () => { - // const message_id = "4173d5f9-f62e-5981-8e35-5154b9883c7f"; - // const score = 0.5; + test("Score completion", async () => { + const message_id = "906bb0a8-e6f6-5474-a5d4-7d7f28937f41"; + const score = 0.5; - // await expect( - // client.scoreCompletion(message_id, score), - // ).resolves.not.toThrow(); - // }); + await expect( + client.scoreCompletion(message_id, score), + ).resolves.not.toThrow(); + }); // TOOD: Fix in R2R, table logs has no column named run_id // test("Agentic RAG response with streaming", async () => { @@ -126,10 +125,9 @@ describe("r2rClient Integration Tests", () => { ).resolves.toBe(""); }); - // TODO: verfiy that this works, blocked by R2R logging issues - // test("Get logs", async () => { - // await expect(client.logs()).resolves.not.toThrow(); - // }); + test("Get logs", async () => { + await expect(client.logs()).resolves.not.toThrow(); + }); test("App settings", async () => { await expect(client.appSettings()).resolves.not.toThrow(); @@ -137,15 +135,11 @@ describe("r2rClient Integration Tests", () => { test("Get analytics", async () => { const filterCriteria: Record | string = { - filters: { - search_latencies: "search_latency", - }, + search_latencies: "search_latency", }; const analysisTypes: Record | string = { - analysis_types: { - search_latencies: ["basic_statistics", "search_latency"], - }, + search_latencies: ["basic_statistics", "search_latency"], }; await expect( @@ -173,7 +167,6 @@ describe("r2rClient Integration Tests", () => { client.delete({ document_id: "73749580-1ade-50c6-8fbe-a5e9e87783c8" }), ).resolves.toBe(""); - // Deletes myshkin.txt await expect( client.delete({ document_id: "2e05b285-2746-5778-9e4a-e293db92f3be" }), diff --git a/js/sdk/__tests__/r2rClientIntegrationUser.test.ts b/js/sdk/__tests__/r2rClientIntegrationUser.test.ts index 013b629e2..5b1664c4c 100644 --- a/js/sdk/__tests__/r2rClientIntegrationUser.test.ts +++ b/js/sdk/__tests__/r2rClientIntegrationUser.test.ts @@ -3,6 +3,12 @@ const fs = require("fs"); const baseUrl = "http://localhost:8000"; +/** + * raskolnikov.txt should have an id of `91662726-7271-51a5-a0ae-34818509e1fd` + * karamozov.txt should have an id of `00f69fa0-c947-5f5f-a374-1837a1283366` + * myshkin.txt should have an id of `0b80081e-a37a-579f-a06d-7d2032435d65` + */ + describe("r2rClient Integration Tests", () => { let client: r2rClient; @@ -20,12 +26,6 @@ describe("r2rClient Integration Tests", () => { ).resolves.not.toThrow(); }); - test("Verify Email throws a 400 error", async () => { - await expect(client.verifyEmail("verification_code")).rejects.toThrow( - "Status 400: Email verification is not required", - ); - }); - test("Login", async () => { await expect( client.login("test@gmail.com", "password"), @@ -39,7 +39,7 @@ describe("r2rClient Integration Tests", () => { await expect( client.ingestFiles(files, { - metadatas: [{ title: "myshkin.txt" }, { title: "karamozov.txt" }], + metadatas: [{ title: "raskolnikov.txt" }], skip_document_info: false, }), ).resolves.not.toThrow(); @@ -57,7 +57,7 @@ describe("r2rClient Integration Tests", () => { ]; await expect( client.updateFiles(updated_file, { - document_ids: ["06f6aab5-daa1-5b22-809c-d73a378600ed"], + document_ids: ["0b80081e-a37a-579f-a06d-7d2032435d65"], metadatas: [{ title: "updated_karamozov.txt" }], }), ).resolves.not.toThrow(); @@ -67,13 +67,10 @@ describe("r2rClient Integration Tests", () => { await expect(client.search("test")).resolves.not.toThrow(); }); - test("Generate RAG response", async () => { - await expect(client.rag("test")).resolves.not.toThrow(); - }, 30000); - + // Deletes rasolnikov.txt test("Delete document", async () => { await expect( - client.delete({ document_id: "c621c119-e21d-5d11-a099-bab1993f76d0" }), + client.delete({ document_id: "91662726-7271-51a5-a0ae-34818509e1fd" }), ).resolves.not.toThrow(); }); @@ -98,12 +95,14 @@ describe("r2rClient Integration Tests", () => { }); test("Clean up remaining documents", async () => { + // Deletes karamozov.txt await expect( - client.delete({ document_id: "f58d4ec4-0274-56fa-b1ce-16aa3ba9ce3c" }), + client.delete({ document_id: "00f69fa0-c947-5f5f-a374-1837a1283366" }), ).resolves.not.toThrow(); + // Deletes myshkin.txt await expect( - client.delete({ document_id: "06f6aab5-daa1-5b22-809c-d73a378600ed" }), + client.delete({ document_id: "0b80081e-a37a-579f-a06d-7d2032435d65" }), ).resolves.not.toThrow; }); @@ -113,7 +112,9 @@ describe("r2rClient Integration Tests", () => { ).resolves.not.toThrow(); }); - test("Delete User", async () => { - await expect(client.deleteUser("new_password")).resolves.not.toThrow(); - }); + // TODO: Fix this test + // test("Delete User", async () => { + // const currentUser = await client.user(); + // await expect(client.deleteUser(currentUser.id, "new_password")).resolves.not.toThrow(); + // }); }); diff --git a/js/sdk/pnpm-lock.yaml b/js/sdk/pnpm-lock.yaml index a61b8a357..c38e0ba65 100644 --- a/js/sdk/pnpm-lock.yaml +++ b/js/sdk/pnpm-lock.yaml @@ -1,11 +1,10 @@ -lockfileVersion: '9.0' +lockfileVersion: "9.0" settings: autoInstallPeers: true excludeLinksFromLockfile: false importers: - .: dependencies: axios: @@ -24,16 +23,16 @@ importers: specifier: ^10.0.0 version: 10.0.0 devDependencies: - '@types/jest': + "@types/jest": specifier: ^29.5.12 version: 29.5.12 - '@types/mocha': + "@types/mocha": specifier: ^10.0.7 version: 10.0.7 - '@types/node': + "@types/node": specifier: ^20.14.15 version: 20.14.15 - '@types/uuid': + "@types/uuid": specifier: ^10.0.0 version: 10.0.0 jest: @@ -53,537 +52,932 @@ importers: version: 5.5.4 packages: - - '@ampproject/remapping@2.3.0': - resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} - engines: {node: '>=6.0.0'} - - '@babel/code-frame@7.24.7': - resolution: {integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==} - engines: {node: '>=6.9.0'} - - '@babel/compat-data@7.25.2': - resolution: {integrity: sha512-bYcppcpKBvX4znYaPEeFau03bp89ShqNMLs+rmdptMw+heSZh9+z84d2YG+K7cYLbWwzdjtDoW/uqZmPjulClQ==} - engines: {node: '>=6.9.0'} - - '@babel/core@7.25.2': - resolution: {integrity: sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==} - engines: {node: '>=6.9.0'} - - '@babel/generator@7.25.0': - resolution: {integrity: sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-compilation-targets@7.25.2': - resolution: {integrity: sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-module-imports@7.24.7': - resolution: {integrity: sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==} - engines: {node: '>=6.9.0'} - - '@babel/helper-module-transforms@7.25.2': - resolution: {integrity: sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==} - engines: {node: '>=6.9.0'} + "@ampproject/remapping@2.3.0": + resolution: + { + integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==, + } + engines: { node: ">=6.0.0" } + + "@babel/code-frame@7.24.7": + resolution: + { + integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==, + } + engines: { node: ">=6.9.0" } + + "@babel/compat-data@7.25.2": + resolution: + { + integrity: sha512-bYcppcpKBvX4znYaPEeFau03bp89ShqNMLs+rmdptMw+heSZh9+z84d2YG+K7cYLbWwzdjtDoW/uqZmPjulClQ==, + } + engines: { node: ">=6.9.0" } + + "@babel/core@7.25.2": + resolution: + { + integrity: sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==, + } + engines: { node: ">=6.9.0" } + + "@babel/generator@7.25.0": + resolution: + { + integrity: sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw==, + } + engines: { node: ">=6.9.0" } + + "@babel/helper-compilation-targets@7.25.2": + resolution: + { + integrity: sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==, + } + engines: { node: ">=6.9.0" } + + "@babel/helper-module-imports@7.24.7": + resolution: + { + integrity: sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==, + } + engines: { node: ">=6.9.0" } + + "@babel/helper-module-transforms@7.25.2": + resolution: + { + integrity: sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==, + } + engines: { node: ">=6.9.0" } peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/helper-plugin-utils@7.24.8': - resolution: {integrity: sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==} - engines: {node: '>=6.9.0'} - - '@babel/helper-simple-access@7.24.7': - resolution: {integrity: sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==} - engines: {node: '>=6.9.0'} - - '@babel/helper-string-parser@7.24.8': - resolution: {integrity: sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==} - engines: {node: '>=6.9.0'} - - '@babel/helper-validator-identifier@7.24.7': - resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==} - engines: {node: '>=6.9.0'} - - '@babel/helper-validator-option@7.24.8': - resolution: {integrity: sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==} - engines: {node: '>=6.9.0'} - - '@babel/helpers@7.25.0': - resolution: {integrity: sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw==} - engines: {node: '>=6.9.0'} - - '@babel/highlight@7.24.7': - resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==} - engines: {node: '>=6.9.0'} - - '@babel/parser@7.25.3': - resolution: {integrity: sha512-iLTJKDbJ4hMvFPgQwwsVoxtHyWpKKPBrxkANrSYewDPaPpT5py5yeVkgPIJ7XYXhndxJpaA3PyALSXQ7u8e/Dw==} - engines: {node: '>=6.0.0'} + "@babel/core": ^7.0.0 + + "@babel/helper-plugin-utils@7.24.8": + resolution: + { + integrity: sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==, + } + engines: { node: ">=6.9.0" } + + "@babel/helper-simple-access@7.24.7": + resolution: + { + integrity: sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==, + } + engines: { node: ">=6.9.0" } + + "@babel/helper-string-parser@7.24.8": + resolution: + { + integrity: sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==, + } + engines: { node: ">=6.9.0" } + + "@babel/helper-validator-identifier@7.24.7": + resolution: + { + integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==, + } + engines: { node: ">=6.9.0" } + + "@babel/helper-validator-option@7.24.8": + resolution: + { + integrity: sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==, + } + engines: { node: ">=6.9.0" } + + "@babel/helpers@7.25.0": + resolution: + { + integrity: sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw==, + } + engines: { node: ">=6.9.0" } + + "@babel/highlight@7.24.7": + resolution: + { + integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==, + } + engines: { node: ">=6.9.0" } + + "@babel/parser@7.25.3": + resolution: + { + integrity: sha512-iLTJKDbJ4hMvFPgQwwsVoxtHyWpKKPBrxkANrSYewDPaPpT5py5yeVkgPIJ7XYXhndxJpaA3PyALSXQ7u8e/Dw==, + } + engines: { node: ">=6.0.0" } hasBin: true - '@babel/plugin-syntax-async-generators@7.8.4': - resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} + "@babel/plugin-syntax-async-generators@7.8.4": + resolution: + { + integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==, + } peerDependencies: - '@babel/core': ^7.0.0-0 + "@babel/core": ^7.0.0-0 - '@babel/plugin-syntax-bigint@7.8.3': - resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} + "@babel/plugin-syntax-bigint@7.8.3": + resolution: + { + integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==, + } peerDependencies: - '@babel/core': ^7.0.0-0 + "@babel/core": ^7.0.0-0 - '@babel/plugin-syntax-class-properties@7.12.13': - resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} + "@babel/plugin-syntax-class-properties@7.12.13": + resolution: + { + integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==, + } peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-class-static-block@7.14.5': - resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} - engines: {node: '>=6.9.0'} + "@babel/core": ^7.0.0-0 + + "@babel/plugin-syntax-class-static-block@7.14.5": + resolution: + { + integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==, + } + engines: { node: ">=6.9.0" } peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-import-attributes@7.24.7': - resolution: {integrity: sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==} - engines: {node: '>=6.9.0'} + "@babel/core": ^7.0.0-0 + + "@babel/plugin-syntax-import-attributes@7.24.7": + resolution: + { + integrity: sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==, + } + engines: { node: ">=6.9.0" } peerDependencies: - '@babel/core': ^7.0.0-0 + "@babel/core": ^7.0.0-0 - '@babel/plugin-syntax-import-meta@7.10.4': - resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} + "@babel/plugin-syntax-import-meta@7.10.4": + resolution: + { + integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==, + } peerDependencies: - '@babel/core': ^7.0.0-0 + "@babel/core": ^7.0.0-0 - '@babel/plugin-syntax-json-strings@7.8.3': - resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} + "@babel/plugin-syntax-json-strings@7.8.3": + resolution: + { + integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==, + } peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-jsx@7.24.7': - resolution: {integrity: sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==} - engines: {node: '>=6.9.0'} + "@babel/core": ^7.0.0-0 + + "@babel/plugin-syntax-jsx@7.24.7": + resolution: + { + integrity: sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==, + } + engines: { node: ">=6.9.0" } peerDependencies: - '@babel/core': ^7.0.0-0 + "@babel/core": ^7.0.0-0 - '@babel/plugin-syntax-logical-assignment-operators@7.10.4': - resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} + "@babel/plugin-syntax-logical-assignment-operators@7.10.4": + resolution: + { + integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==, + } peerDependencies: - '@babel/core': ^7.0.0-0 + "@babel/core": ^7.0.0-0 - '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3': - resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} + "@babel/plugin-syntax-nullish-coalescing-operator@7.8.3": + resolution: + { + integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==, + } peerDependencies: - '@babel/core': ^7.0.0-0 + "@babel/core": ^7.0.0-0 - '@babel/plugin-syntax-numeric-separator@7.10.4': - resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} + "@babel/plugin-syntax-numeric-separator@7.10.4": + resolution: + { + integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==, + } peerDependencies: - '@babel/core': ^7.0.0-0 + "@babel/core": ^7.0.0-0 - '@babel/plugin-syntax-object-rest-spread@7.8.3': - resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} + "@babel/plugin-syntax-object-rest-spread@7.8.3": + resolution: + { + integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==, + } peerDependencies: - '@babel/core': ^7.0.0-0 + "@babel/core": ^7.0.0-0 - '@babel/plugin-syntax-optional-catch-binding@7.8.3': - resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} + "@babel/plugin-syntax-optional-catch-binding@7.8.3": + resolution: + { + integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==, + } peerDependencies: - '@babel/core': ^7.0.0-0 + "@babel/core": ^7.0.0-0 - '@babel/plugin-syntax-optional-chaining@7.8.3': - resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} + "@babel/plugin-syntax-optional-chaining@7.8.3": + resolution: + { + integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==, + } peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-private-property-in-object@7.14.5': - resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} - engines: {node: '>=6.9.0'} + "@babel/core": ^7.0.0-0 + + "@babel/plugin-syntax-private-property-in-object@7.14.5": + resolution: + { + integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==, + } + engines: { node: ">=6.9.0" } peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-top-level-await@7.14.5': - resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} - engines: {node: '>=6.9.0'} + "@babel/core": ^7.0.0-0 + + "@babel/plugin-syntax-top-level-await@7.14.5": + resolution: + { + integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==, + } + engines: { node: ">=6.9.0" } peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-typescript@7.24.7': - resolution: {integrity: sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA==} - engines: {node: '>=6.9.0'} + "@babel/core": ^7.0.0-0 + + "@babel/plugin-syntax-typescript@7.24.7": + resolution: + { + integrity: sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA==, + } + engines: { node: ">=6.9.0" } peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/template@7.25.0': - resolution: {integrity: sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==} - engines: {node: '>=6.9.0'} - - '@babel/traverse@7.25.3': - resolution: {integrity: sha512-HefgyP1x754oGCsKmV5reSmtV7IXj/kpaE1XYY+D9G5PvKKoFfSbiS4M77MdjuwlZKDIKFCffq9rPU+H/s3ZdQ==} - engines: {node: '>=6.9.0'} - - '@babel/types@7.25.2': - resolution: {integrity: sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q==} - engines: {node: '>=6.9.0'} - - '@bcoe/v8-coverage@0.2.3': - resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} - - '@cspotcode/source-map-support@0.8.1': - resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} - engines: {node: '>=12'} - - '@istanbuljs/load-nyc-config@1.1.0': - resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} - engines: {node: '>=8'} - - '@istanbuljs/schema@0.1.3': - resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} - engines: {node: '>=8'} - - '@jest/console@29.7.0': - resolution: {integrity: sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/core@29.7.0': - resolution: {integrity: sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + "@babel/core": ^7.0.0-0 + + "@babel/template@7.25.0": + resolution: + { + integrity: sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==, + } + engines: { node: ">=6.9.0" } + + "@babel/traverse@7.25.3": + resolution: + { + integrity: sha512-HefgyP1x754oGCsKmV5reSmtV7IXj/kpaE1XYY+D9G5PvKKoFfSbiS4M77MdjuwlZKDIKFCffq9rPU+H/s3ZdQ==, + } + engines: { node: ">=6.9.0" } + + "@babel/types@7.25.2": + resolution: + { + integrity: sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q==, + } + engines: { node: ">=6.9.0" } + + "@bcoe/v8-coverage@0.2.3": + resolution: + { + integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==, + } + + "@cspotcode/source-map-support@0.8.1": + resolution: + { + integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==, + } + engines: { node: ">=12" } + + "@istanbuljs/load-nyc-config@1.1.0": + resolution: + { + integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==, + } + engines: { node: ">=8" } + + "@istanbuljs/schema@0.1.3": + resolution: + { + integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==, + } + engines: { node: ">=8" } + + "@jest/console@29.7.0": + resolution: + { + integrity: sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + "@jest/core@29.7.0": + resolution: + { + integrity: sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 peerDependenciesMeta: node-notifier: optional: true - '@jest/environment@29.7.0': - resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/expect-utils@29.7.0': - resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/expect@29.7.0': - resolution: {integrity: sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/fake-timers@29.7.0': - resolution: {integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/globals@29.7.0': - resolution: {integrity: sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/reporters@29.7.0': - resolution: {integrity: sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + "@jest/environment@29.7.0": + resolution: + { + integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + "@jest/expect-utils@29.7.0": + resolution: + { + integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + "@jest/expect@29.7.0": + resolution: + { + integrity: sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + "@jest/fake-timers@29.7.0": + resolution: + { + integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + "@jest/globals@29.7.0": + resolution: + { + integrity: sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + "@jest/reporters@29.7.0": + resolution: + { + integrity: sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 peerDependenciesMeta: node-notifier: optional: true - '@jest/schemas@29.6.3': - resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/source-map@29.6.3': - resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/test-result@29.7.0': - resolution: {integrity: sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/test-sequencer@29.7.0': - resolution: {integrity: sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/transform@29.7.0': - resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/types@29.6.3': - resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jridgewell/gen-mapping@0.3.5': - resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} - engines: {node: '>=6.0.0'} - - '@jridgewell/resolve-uri@3.1.2': - resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} - engines: {node: '>=6.0.0'} - - '@jridgewell/set-array@1.2.1': - resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} - engines: {node: '>=6.0.0'} - - '@jridgewell/sourcemap-codec@1.5.0': - resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} - - '@jridgewell/trace-mapping@0.3.25': - resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} - - '@jridgewell/trace-mapping@0.3.9': - resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} - - '@sinclair/typebox@0.27.8': - resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} - - '@sinonjs/commons@3.0.1': - resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} - - '@sinonjs/fake-timers@10.3.0': - resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} - - '@tsconfig/node10@1.0.11': - resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} - - '@tsconfig/node12@1.0.11': - resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} - - '@tsconfig/node14@1.0.3': - resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} - - '@tsconfig/node16@1.0.4': - resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} - - '@types/babel__core@7.20.5': - resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} - - '@types/babel__generator@7.6.8': - resolution: {integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==} - - '@types/babel__template@7.4.4': - resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} - - '@types/babel__traverse@7.20.6': - resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==} - - '@types/graceful-fs@4.1.9': - resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} - - '@types/istanbul-lib-coverage@2.0.6': - resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} - - '@types/istanbul-lib-report@3.0.3': - resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} - - '@types/istanbul-reports@3.0.4': - resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} - - '@types/jest@29.5.12': - resolution: {integrity: sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==} - - '@types/mocha@10.0.7': - resolution: {integrity: sha512-GN8yJ1mNTcFcah/wKEFIJckJx9iJLoMSzWcfRRuxz/Jk+U6KQNnml+etbtxFK8lPjzOw3zp4Ha/kjSst9fsHYw==} - - '@types/node@20.14.15': - resolution: {integrity: sha512-Fz1xDMCF/B00/tYSVMlmK7hVeLh7jE5f3B7X1/hmV0MJBwE27KlS7EvD/Yp+z1lm8mVhwV5w+n8jOZG8AfTlKw==} - - '@types/stack-utils@2.0.3': - resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} - - '@types/uuid@10.0.0': - resolution: {integrity: sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==} - - '@types/yargs-parser@21.0.3': - resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} - - '@types/yargs@17.0.33': - resolution: {integrity: sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==} + "@jest/schemas@29.6.3": + resolution: + { + integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + "@jest/source-map@29.6.3": + resolution: + { + integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + "@jest/test-result@29.7.0": + resolution: + { + integrity: sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + "@jest/test-sequencer@29.7.0": + resolution: + { + integrity: sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + "@jest/transform@29.7.0": + resolution: + { + integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + "@jest/types@29.6.3": + resolution: + { + integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + "@jridgewell/gen-mapping@0.3.5": + resolution: + { + integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==, + } + engines: { node: ">=6.0.0" } + + "@jridgewell/resolve-uri@3.1.2": + resolution: + { + integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==, + } + engines: { node: ">=6.0.0" } + + "@jridgewell/set-array@1.2.1": + resolution: + { + integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==, + } + engines: { node: ">=6.0.0" } + + "@jridgewell/sourcemap-codec@1.5.0": + resolution: + { + integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==, + } + + "@jridgewell/trace-mapping@0.3.25": + resolution: + { + integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==, + } + + "@jridgewell/trace-mapping@0.3.9": + resolution: + { + integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==, + } + + "@sinclair/typebox@0.27.8": + resolution: + { + integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==, + } + + "@sinonjs/commons@3.0.1": + resolution: + { + integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==, + } + + "@sinonjs/fake-timers@10.3.0": + resolution: + { + integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==, + } + + "@tsconfig/node10@1.0.11": + resolution: + { + integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==, + } + + "@tsconfig/node12@1.0.11": + resolution: + { + integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==, + } + + "@tsconfig/node14@1.0.3": + resolution: + { + integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==, + } + + "@tsconfig/node16@1.0.4": + resolution: + { + integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==, + } + + "@types/babel__core@7.20.5": + resolution: + { + integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==, + } + + "@types/babel__generator@7.6.8": + resolution: + { + integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==, + } + + "@types/babel__template@7.4.4": + resolution: + { + integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==, + } + + "@types/babel__traverse@7.20.6": + resolution: + { + integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==, + } + + "@types/graceful-fs@4.1.9": + resolution: + { + integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==, + } + + "@types/istanbul-lib-coverage@2.0.6": + resolution: + { + integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==, + } + + "@types/istanbul-lib-report@3.0.3": + resolution: + { + integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==, + } + + "@types/istanbul-reports@3.0.4": + resolution: + { + integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==, + } + + "@types/jest@29.5.12": + resolution: + { + integrity: sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==, + } + + "@types/mocha@10.0.7": + resolution: + { + integrity: sha512-GN8yJ1mNTcFcah/wKEFIJckJx9iJLoMSzWcfRRuxz/Jk+U6KQNnml+etbtxFK8lPjzOw3zp4Ha/kjSst9fsHYw==, + } + + "@types/node@20.14.15": + resolution: + { + integrity: sha512-Fz1xDMCF/B00/tYSVMlmK7hVeLh7jE5f3B7X1/hmV0MJBwE27KlS7EvD/Yp+z1lm8mVhwV5w+n8jOZG8AfTlKw==, + } + + "@types/stack-utils@2.0.3": + resolution: + { + integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==, + } + + "@types/uuid@10.0.0": + resolution: + { + integrity: sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==, + } + + "@types/yargs-parser@21.0.3": + resolution: + { + integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==, + } + + "@types/yargs@17.0.33": + resolution: + { + integrity: sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==, + } acorn-walk@8.3.3: - resolution: {integrity: sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==} - engines: {node: '>=0.4.0'} + resolution: + { + integrity: sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==, + } + engines: { node: ">=0.4.0" } acorn@8.12.1: - resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==} - engines: {node: '>=0.4.0'} + resolution: + { + integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==, + } + engines: { node: ">=0.4.0" } hasBin: true ansi-escapes@4.3.2: - resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==, + } + engines: { node: ">=8" } ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==, + } + engines: { node: ">=8" } ansi-styles@3.2.1: - resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==, + } + engines: { node: ">=4" } ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==, + } + engines: { node: ">=8" } ansi-styles@5.2.0: - resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==, + } + engines: { node: ">=10" } anymatch@3.1.3: - resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} - engines: {node: '>= 8'} + resolution: + { + integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==, + } + engines: { node: ">= 8" } arg@4.1.3: - resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + resolution: + { + integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==, + } argparse@1.0.10: - resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + resolution: + { + integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==, + } async@3.2.5: - resolution: {integrity: sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==} + resolution: + { + integrity: sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==, + } asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + resolution: + { + integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==, + } axios@1.7.4: - resolution: {integrity: sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==} + resolution: + { + integrity: sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==, + } babel-jest@29.7.0: - resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } peerDependencies: - '@babel/core': ^7.8.0 + "@babel/core": ^7.8.0 babel-plugin-istanbul@6.1.1: - resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==, + } + engines: { node: ">=8" } babel-plugin-jest-hoist@29.6.3: - resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } babel-preset-current-node-syntax@1.1.0: - resolution: {integrity: sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==} + resolution: + { + integrity: sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==, + } peerDependencies: - '@babel/core': ^7.0.0 + "@babel/core": ^7.0.0 babel-preset-jest@29.6.3: - resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } peerDependencies: - '@babel/core': ^7.0.0 + "@babel/core": ^7.0.0 balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + resolution: + { + integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==, + } brace-expansion@1.1.11: - resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + resolution: + { + integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==, + } brace-expansion@2.0.1: - resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + resolution: + { + integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==, + } braces@3.0.3: - resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==, + } + engines: { node: ">=8" } browserslist@4.23.3: - resolution: {integrity: sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + resolution: + { + integrity: sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==, + } + engines: { node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7 } hasBin: true bs-logger@0.2.6: - resolution: {integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==} - engines: {node: '>= 6'} + resolution: + { + integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==, + } + engines: { node: ">= 6" } bser@2.1.1: - resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} + resolution: + { + integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==, + } buffer-from@1.1.2: - resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + resolution: + { + integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==, + } callsites@3.1.0: - resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==, + } + engines: { node: ">=6" } camelcase@5.3.1: - resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==, + } + engines: { node: ">=6" } camelcase@6.3.0: - resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==, + } + engines: { node: ">=10" } caniuse-lite@1.0.30001651: - resolution: {integrity: sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==} + resolution: + { + integrity: sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==, + } chalk@2.4.2: - resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==, + } + engines: { node: ">=4" } chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==, + } + engines: { node: ">=10" } char-regex@1.0.2: - resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==, + } + engines: { node: ">=10" } ci-info@3.9.0: - resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==, + } + engines: { node: ">=8" } cjs-module-lexer@1.3.1: - resolution: {integrity: sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==} + resolution: + { + integrity: sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==, + } cliui@8.0.1: - resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==, + } + engines: { node: ">=12" } co@4.6.0: - resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} - engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} + resolution: + { + integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==, + } + engines: { iojs: ">= 1.0.0", node: ">= 0.12.0" } collect-v8-coverage@1.0.2: - resolution: {integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==} + resolution: + { + integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==, + } color-convert@1.9.3: - resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + resolution: + { + integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==, + } color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} + resolution: + { + integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==, + } + engines: { node: ">=7.0.0" } color-name@1.1.3: - resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + resolution: + { + integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==, + } color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + resolution: + { + integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==, + } combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==, + } + engines: { node: ">= 0.8" } concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + resolution: + { + integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==, + } convert-source-map@2.0.0: - resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + resolution: + { + integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==, + } create-jest@29.7.0: - resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } hasBin: true create-require@1.1.1: - resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + resolution: + { + integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==, + } cross-spawn@7.0.3: - resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} - engines: {node: '>= 8'} + resolution: + { + integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==, + } + engines: { node: ">= 8" } debug@4.3.6: - resolution: {integrity: sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==} - engines: {node: '>=6.0'} + resolution: + { + integrity: sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==, + } + engines: { node: ">=6.0" } peerDependencies: - supports-color: '*' + supports-color: "*" peerDependenciesMeta: supports-color: optional: true dedent@1.5.3: - resolution: {integrity: sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==} + resolution: + { + integrity: sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==, + } peerDependencies: babel-plugin-macros: ^3.1.0 peerDependenciesMeta: @@ -591,244 +985,427 @@ packages: optional: true deepmerge@4.3.1: - resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==, + } + engines: { node: ">=0.10.0" } delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} + resolution: + { + integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==, + } + engines: { node: ">=0.4.0" } detect-newline@3.1.0: - resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==, + } + engines: { node: ">=8" } diff-sequences@29.6.3: - resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } diff@4.0.2: - resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} - engines: {node: '>=0.3.1'} + resolution: + { + integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==, + } + engines: { node: ">=0.3.1" } ejs@3.1.10: - resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==, + } + engines: { node: ">=0.10.0" } hasBin: true electron-to-chromium@1.5.9: - resolution: {integrity: sha512-HfkT8ndXR0SEkU8gBQQM3rz035bpE/hxkZ1YIt4KJPEFES68HfIU6LzKukH0H794Lm83WJtkSAMfEToxCs15VA==} + resolution: + { + integrity: sha512-HfkT8ndXR0SEkU8gBQQM3rz035bpE/hxkZ1YIt4KJPEFES68HfIU6LzKukH0H794Lm83WJtkSAMfEToxCs15VA==, + } emittery@0.13.1: - resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==, + } + engines: { node: ">=12" } emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + resolution: + { + integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==, + } error-ex@1.3.2: - resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + resolution: + { + integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==, + } escalade@3.1.2: - resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==, + } + engines: { node: ">=6" } escape-string-regexp@1.0.5: - resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} - engines: {node: '>=0.8.0'} + resolution: + { + integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==, + } + engines: { node: ">=0.8.0" } escape-string-regexp@2.0.0: - resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==, + } + engines: { node: ">=8" } esprima@4.0.1: - resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==, + } + engines: { node: ">=4" } hasBin: true execa@5.1.1: - resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==, + } + engines: { node: ">=10" } exit@0.1.2: - resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} - engines: {node: '>= 0.8.0'} + resolution: + { + integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==, + } + engines: { node: ">= 0.8.0" } expect@29.7.0: - resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } fast-json-stable-stringify@2.1.0: - resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + resolution: + { + integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==, + } fb-watchman@2.0.2: - resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} + resolution: + { + integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==, + } fflate@0.4.8: - resolution: {integrity: sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA==} + resolution: + { + integrity: sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA==, + } filelist@1.0.4: - resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} + resolution: + { + integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==, + } fill-range@7.1.1: - resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==, + } + engines: { node: ">=8" } find-up@4.1.0: - resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==, + } + engines: { node: ">=8" } follow-redirects@1.15.6: - resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==} - engines: {node: '>=4.0'} + resolution: + { + integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==, + } + engines: { node: ">=4.0" } peerDependencies: - debug: '*' + debug: "*" peerDependenciesMeta: debug: optional: true form-data@4.0.0: - resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} - engines: {node: '>= 6'} + resolution: + { + integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==, + } + engines: { node: ">= 6" } fs.realpath@1.0.0: - resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + resolution: + { + integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==, + } fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + resolution: + { + integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==, + } + engines: { node: ^8.16.0 || ^10.6.0 || >=11.0.0 } os: [darwin] function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + resolution: + { + integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==, + } gensync@1.0.0-beta.2: - resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==, + } + engines: { node: ">=6.9.0" } get-caller-file@2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} + resolution: + { + integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==, + } + engines: { node: 6.* || 8.* || >= 10.* } get-package-type@0.1.0: - resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} - engines: {node: '>=8.0.0'} + resolution: + { + integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==, + } + engines: { node: ">=8.0.0" } get-stream@6.0.1: - resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==, + } + engines: { node: ">=10" } glob@7.2.3: - resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + resolution: + { + integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==, + } deprecated: Glob versions prior to v9 are no longer supported globals@11.12.0: - resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==, + } + engines: { node: ">=4" } graceful-fs@4.2.11: - resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + resolution: + { + integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==, + } has-flag@3.0.0: - resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==, + } + engines: { node: ">=4" } has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==, + } + engines: { node: ">=8" } hasown@2.0.2: - resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==, + } + engines: { node: ">= 0.4" } html-escaper@2.0.2: - resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + resolution: + { + integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==, + } human-signals@2.1.0: - resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} - engines: {node: '>=10.17.0'} + resolution: + { + integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==, + } + engines: { node: ">=10.17.0" } import-local@3.2.0: - resolution: {integrity: sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==, + } + engines: { node: ">=8" } hasBin: true imurmurhash@0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} + resolution: + { + integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==, + } + engines: { node: ">=0.8.19" } inflight@1.0.6: - resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + resolution: + { + integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==, + } deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + resolution: + { + integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==, + } is-arrayish@0.2.1: - resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + resolution: + { + integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==, + } is-core-module@2.15.0: - resolution: {integrity: sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==, + } + engines: { node: ">= 0.4" } is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==, + } + engines: { node: ">=8" } is-generator-fn@2.1.0: - resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==, + } + engines: { node: ">=6" } is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} + resolution: + { + integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==, + } + engines: { node: ">=0.12.0" } is-stream@2.0.1: - resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==, + } + engines: { node: ">=8" } isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + resolution: + { + integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==, + } istanbul-lib-coverage@3.2.2: - resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==, + } + engines: { node: ">=8" } istanbul-lib-instrument@5.2.1: - resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==, + } + engines: { node: ">=8" } istanbul-lib-instrument@6.0.3: - resolution: {integrity: sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==, + } + engines: { node: ">=10" } istanbul-lib-report@3.0.1: - resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==, + } + engines: { node: ">=10" } istanbul-lib-source-maps@4.0.1: - resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==, + } + engines: { node: ">=10" } istanbul-reports@3.1.7: - resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==, + } + engines: { node: ">=8" } jake@10.9.2: - resolution: {integrity: sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==, + } + engines: { node: ">=10" } hasBin: true jest-changed-files@29.7.0: - resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } jest-circus@29.7.0: - resolution: {integrity: sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } jest-cli@29.7.0: - resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } hasBin: true peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 @@ -837,109 +1414,178 @@ packages: optional: true jest-config@29.7.0: - resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } peerDependencies: - '@types/node': '*' - ts-node: '>=9.0.0' + "@types/node": "*" + ts-node: ">=9.0.0" peerDependenciesMeta: - '@types/node': + "@types/node": optional: true ts-node: optional: true jest-diff@29.7.0: - resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } jest-docblock@29.7.0: - resolution: {integrity: sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } jest-each@29.7.0: - resolution: {integrity: sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } jest-environment-node@29.7.0: - resolution: {integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } jest-get-type@29.6.3: - resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } jest-haste-map@29.7.0: - resolution: {integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } jest-leak-detector@29.7.0: - resolution: {integrity: sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } jest-matcher-utils@29.7.0: - resolution: {integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } jest-message-util@29.7.0: - resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } jest-mock@29.7.0: - resolution: {integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } jest-pnp-resolver@1.2.3: - resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==, + } + engines: { node: ">=6" } peerDependencies: - jest-resolve: '*' + jest-resolve: "*" peerDependenciesMeta: jest-resolve: optional: true jest-regex-util@29.6.3: - resolution: {integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } jest-resolve-dependencies@29.7.0: - resolution: {integrity: sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } jest-resolve@29.7.0: - resolution: {integrity: sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } jest-runner@29.7.0: - resolution: {integrity: sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } jest-runtime@29.7.0: - resolution: {integrity: sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } jest-snapshot@29.7.0: - resolution: {integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } jest-util@29.7.0: - resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } jest-validate@29.7.0: - resolution: {integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } jest-watcher@29.7.0: - resolution: {integrity: sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } jest-worker@29.7.0: - resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } jest@29.7.0: - resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } hasBin: true peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 @@ -948,328 +1594,577 @@ packages: optional: true js-tokens@4.0.0: - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + resolution: + { + integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==, + } js-yaml@3.14.1: - resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + resolution: + { + integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==, + } hasBin: true jsesc@2.5.2: - resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==, + } + engines: { node: ">=4" } hasBin: true json-parse-even-better-errors@2.3.1: - resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + resolution: + { + integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==, + } json5@2.2.3: - resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==, + } + engines: { node: ">=6" } hasBin: true kleur@3.0.3: - resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==, + } + engines: { node: ">=6" } leven@3.1.0: - resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==, + } + engines: { node: ">=6" } lines-and-columns@1.2.4: - resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + resolution: + { + integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==, + } locate-path@5.0.0: - resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==, + } + engines: { node: ">=8" } lodash.memoize@4.1.2: - resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} + resolution: + { + integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==, + } lru-cache@5.1.1: - resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + resolution: + { + integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==, + } make-dir@4.0.0: - resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==, + } + engines: { node: ">=10" } make-error@1.3.6: - resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + resolution: + { + integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==, + } makeerror@1.0.12: - resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} + resolution: + { + integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==, + } merge-stream@2.0.0: - resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + resolution: + { + integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==, + } micromatch@4.0.7: - resolution: {integrity: sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==} - engines: {node: '>=8.6'} + resolution: + { + integrity: sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==, + } + engines: { node: ">=8.6" } mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==, + } + engines: { node: ">= 0.6" } mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==, + } + engines: { node: ">= 0.6" } mimic-fn@2.1.0: - resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==, + } + engines: { node: ">=6" } minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + resolution: + { + integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==, + } minimatch@5.1.6: - resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==, + } + engines: { node: ">=10" } ms@2.1.2: - resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + resolution: + { + integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==, + } natural-compare@1.4.0: - resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + resolution: + { + integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==, + } node-int64@0.4.0: - resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} + resolution: + { + integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==, + } node-releases@2.0.18: - resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} + resolution: + { + integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==, + } normalize-path@3.0.0: - resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==, + } + engines: { node: ">=0.10.0" } npm-run-path@4.0.1: - resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==, + } + engines: { node: ">=8" } once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + resolution: + { + integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==, + } onetime@5.1.2: - resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==, + } + engines: { node: ">=6" } p-limit@2.3.0: - resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==, + } + engines: { node: ">=6" } p-limit@3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==, + } + engines: { node: ">=10" } p-locate@4.1.0: - resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==, + } + engines: { node: ">=8" } p-try@2.2.0: - resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==, + } + engines: { node: ">=6" } parse-json@5.2.0: - resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==, + } + engines: { node: ">=8" } path-exists@4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==, + } + engines: { node: ">=8" } path-is-absolute@1.0.1: - resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==, + } + engines: { node: ">=0.10.0" } path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==, + } + engines: { node: ">=8" } path-parse@1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + resolution: + { + integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==, + } picocolors@1.0.1: - resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} + resolution: + { + integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==, + } picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} + resolution: + { + integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==, + } + engines: { node: ">=8.6" } pirates@4.0.6: - resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} - engines: {node: '>= 6'} + resolution: + { + integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==, + } + engines: { node: ">= 6" } pkg-dir@4.2.0: - resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==, + } + engines: { node: ">=8" } posthog-js@1.155.4: - resolution: {integrity: sha512-suxwAsmZGqMDXJe/RaCKI3PaDEHiuMDDhKcJklgGAg7eDnywieRkr5CoPcOOvnqTDMnuOPETr98jpYBXKUwGFQ==} + resolution: + { + integrity: sha512-suxwAsmZGqMDXJe/RaCKI3PaDEHiuMDDhKcJklgGAg7eDnywieRkr5CoPcOOvnqTDMnuOPETr98jpYBXKUwGFQ==, + } posthog-node@4.1.0: - resolution: {integrity: sha512-Fd+aMWLjUttlPrfOniDWs35v62rOEIqP5GBzUvRswsNY8rr1g1KuDobqaRFGMCNnrtDmhzUN8y7QucrcwMY/+w==} - engines: {node: '>=15.0.0'} + resolution: + { + integrity: sha512-Fd+aMWLjUttlPrfOniDWs35v62rOEIqP5GBzUvRswsNY8rr1g1KuDobqaRFGMCNnrtDmhzUN8y7QucrcwMY/+w==, + } + engines: { node: ">=15.0.0" } preact@10.23.2: - resolution: {integrity: sha512-kKYfePf9rzKnxOAKDpsWhg/ysrHPqT+yQ7UW4JjdnqjFIeNUnNcEJvhuA8fDenxAGWzUqtd51DfVg7xp/8T9NA==} + resolution: + { + integrity: sha512-kKYfePf9rzKnxOAKDpsWhg/ysrHPqT+yQ7UW4JjdnqjFIeNUnNcEJvhuA8fDenxAGWzUqtd51DfVg7xp/8T9NA==, + } prettier@3.3.3: - resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} - engines: {node: '>=14'} + resolution: + { + integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==, + } + engines: { node: ">=14" } hasBin: true pretty-format@29.7.0: - resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } prompts@2.4.2: - resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} - engines: {node: '>= 6'} + resolution: + { + integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==, + } + engines: { node: ">= 6" } proxy-from-env@1.1.0: - resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + resolution: + { + integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==, + } pure-rand@6.1.0: - resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} + resolution: + { + integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==, + } react-is@18.3.1: - resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + resolution: + { + integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==, + } require-directory@2.1.1: - resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==, + } + engines: { node: ">=0.10.0" } resolve-cwd@3.0.0: - resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==, + } + engines: { node: ">=8" } resolve-from@5.0.0: - resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==, + } + engines: { node: ">=8" } resolve.exports@2.0.2: - resolution: {integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==, + } + engines: { node: ">=10" } resolve@1.22.8: - resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} + resolution: + { + integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==, + } hasBin: true rusha@0.8.14: - resolution: {integrity: sha512-cLgakCUf6PedEu15t8kbsjnwIFFR2D4RfL+W3iWFJ4iac7z4B0ZI8fxy4R3J956kAI68HclCFGL8MPoUVC3qVA==} + resolution: + { + integrity: sha512-cLgakCUf6PedEu15t8kbsjnwIFFR2D4RfL+W3iWFJ4iac7z4B0ZI8fxy4R3J956kAI68HclCFGL8MPoUVC3qVA==, + } semver@6.3.1: - resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + resolution: + { + integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==, + } hasBin: true semver@7.6.3: - resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==, + } + engines: { node: ">=10" } hasBin: true shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==, + } + engines: { node: ">=8" } shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==, + } + engines: { node: ">=8" } signal-exit@3.0.7: - resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + resolution: + { + integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==, + } sisteransi@1.0.5: - resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + resolution: + { + integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==, + } slash@3.0.0: - resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==, + } + engines: { node: ">=8" } source-map-support@0.5.13: - resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} + resolution: + { + integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==, + } source-map@0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==, + } + engines: { node: ">=0.10.0" } sprintf-js@1.0.3: - resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + resolution: + { + integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==, + } stack-utils@2.0.6: - resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==, + } + engines: { node: ">=10" } string-length@4.0.2: - resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==, + } + engines: { node: ">=10" } string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==, + } + engines: { node: ">=8" } strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==, + } + engines: { node: ">=8" } strip-bom@4.0.0: - resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==, + } + engines: { node: ">=8" } strip-final-newline@2.0.0: - resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==, + } + engines: { node: ">=6" } strip-json-comments@3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==, + } + engines: { node: ">=8" } supports-color@5.5.0: - resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==, + } + engines: { node: ">=4" } supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==, + } + engines: { node: ">=8" } supports-color@8.1.1: - resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==, + } + engines: { node: ">=10" } supports-preserve-symlinks-flag@1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==, + } + engines: { node: ">= 0.4" } test-exclude@6.0.0: - resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==, + } + engines: { node: ">=8" } tmpl@1.0.5: - resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} + resolution: + { + integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==, + } to-fast-properties@2.0.0: - resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==, + } + engines: { node: ">=4" } to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} + resolution: + { + integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==, + } + engines: { node: ">=8.0" } ts-jest@29.2.4: - resolution: {integrity: sha512-3d6tgDyhCI29HlpwIq87sNuI+3Q6GLTTCeYRHCs7vDz+/3GCMwEtV9jezLyl4ZtnBgx00I7hm8PCP8cTksMGrw==} - engines: {node: ^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0} + resolution: + { + integrity: sha512-3d6tgDyhCI29HlpwIq87sNuI+3Q6GLTTCeYRHCs7vDz+/3GCMwEtV9jezLyl4ZtnBgx00I7hm8PCP8cTksMGrw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0 } hasBin: true peerDependencies: - '@babel/core': '>=7.0.0-beta.0 <8' - '@jest/transform': ^29.0.0 - '@jest/types': ^29.0.0 + "@babel/core": ">=7.0.0-beta.0 <8" + "@jest/transform": ^29.0.0 + "@jest/types": ^29.0.0 babel-jest: ^29.0.0 - esbuild: '*' + esbuild: "*" jest: ^29.0.0 - typescript: '>=4.3 <6' + typescript: ">=4.3 <6" peerDependenciesMeta: - '@babel/core': + "@babel/core": optional: true - '@jest/transform': + "@jest/transform": optional: true - '@jest/types': + "@jest/types": optional: true babel-jest: optional: true @@ -1277,123 +2172,185 @@ packages: optional: true ts-node@10.9.2: - resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} + resolution: + { + integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==, + } hasBin: true peerDependencies: - '@swc/core': '>=1.2.50' - '@swc/wasm': '>=1.2.50' - '@types/node': '*' - typescript: '>=2.7' + "@swc/core": ">=1.2.50" + "@swc/wasm": ">=1.2.50" + "@types/node": "*" + typescript: ">=2.7" peerDependenciesMeta: - '@swc/core': + "@swc/core": optional: true - '@swc/wasm': + "@swc/wasm": optional: true type-detect@4.0.8: - resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==, + } + engines: { node: ">=4" } type-fest@0.21.3: - resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==, + } + engines: { node: ">=10" } typescript@5.5.4: - resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==} - engines: {node: '>=14.17'} + resolution: + { + integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==, + } + engines: { node: ">=14.17" } hasBin: true undici-types@5.26.5: - resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + resolution: + { + integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==, + } update-browserslist-db@1.1.0: - resolution: {integrity: sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==} + resolution: + { + integrity: sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==, + } hasBin: true peerDependencies: - browserslist: '>= 4.21.0' + browserslist: ">= 4.21.0" uuid@10.0.0: - resolution: {integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==} + resolution: + { + integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==, + } hasBin: true v8-compile-cache-lib@3.0.1: - resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + resolution: + { + integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==, + } v8-to-istanbul@9.3.0: - resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} - engines: {node: '>=10.12.0'} + resolution: + { + integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==, + } + engines: { node: ">=10.12.0" } walker@1.0.8: - resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} + resolution: + { + integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==, + } web-vitals@4.2.3: - resolution: {integrity: sha512-/CFAm1mNxSmOj6i0Co+iGFJ58OS4NRGVP+AWS/l509uIK5a1bSoIVaHz/ZumpHTfHSZBpgrJ+wjfpAOrTHok5Q==} + resolution: + { + integrity: sha512-/CFAm1mNxSmOj6i0Co+iGFJ58OS4NRGVP+AWS/l509uIK5a1bSoIVaHz/ZumpHTfHSZBpgrJ+wjfpAOrTHok5Q==, + } which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} + resolution: + { + integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==, + } + engines: { node: ">= 8" } hasBin: true wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==, + } + engines: { node: ">=10" } wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + resolution: + { + integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==, + } write-file-atomic@4.0.2: - resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + resolution: + { + integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==, + } + engines: { node: ^12.13.0 || ^14.15.0 || >=16.0.0 } y18n@5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==, + } + engines: { node: ">=10" } yallist@3.1.1: - resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + resolution: + { + integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==, + } yargs-parser@21.1.1: - resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==, + } + engines: { node: ">=12" } yargs@17.7.2: - resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==, + } + engines: { node: ">=12" } yn@3.1.1: - resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==, + } + engines: { node: ">=6" } yocto-queue@0.1.0: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==, + } + engines: { node: ">=10" } snapshots: - - '@ampproject/remapping@2.3.0': + "@ampproject/remapping@2.3.0": dependencies: - '@jridgewell/gen-mapping': 0.3.5 - '@jridgewell/trace-mapping': 0.3.25 + "@jridgewell/gen-mapping": 0.3.5 + "@jridgewell/trace-mapping": 0.3.25 - '@babel/code-frame@7.24.7': + "@babel/code-frame@7.24.7": dependencies: - '@babel/highlight': 7.24.7 + "@babel/highlight": 7.24.7 picocolors: 1.0.1 - '@babel/compat-data@7.25.2': {} + "@babel/compat-data@7.25.2": {} - '@babel/core@7.25.2': + "@babel/core@7.25.2": dependencies: - '@ampproject/remapping': 2.3.0 - '@babel/code-frame': 7.24.7 - '@babel/generator': 7.25.0 - '@babel/helper-compilation-targets': 7.25.2 - '@babel/helper-module-transforms': 7.25.2(@babel/core@7.25.2) - '@babel/helpers': 7.25.0 - '@babel/parser': 7.25.3 - '@babel/template': 7.25.0 - '@babel/traverse': 7.25.3 - '@babel/types': 7.25.2 + "@ampproject/remapping": 2.3.0 + "@babel/code-frame": 7.24.7 + "@babel/generator": 7.25.0 + "@babel/helper-compilation-targets": 7.25.2 + "@babel/helper-module-transforms": 7.25.2(@babel/core@7.25.2) + "@babel/helpers": 7.25.0 + "@babel/parser": 7.25.3 + "@babel/template": 7.25.0 + "@babel/traverse": 7.25.3 + "@babel/types": 7.25.2 convert-source-map: 2.0.0 debug: 4.3.6 gensync: 1.0.0-beta.2 @@ -1402,185 +2359,185 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/generator@7.25.0': + "@babel/generator@7.25.0": dependencies: - '@babel/types': 7.25.2 - '@jridgewell/gen-mapping': 0.3.5 - '@jridgewell/trace-mapping': 0.3.25 + "@babel/types": 7.25.2 + "@jridgewell/gen-mapping": 0.3.5 + "@jridgewell/trace-mapping": 0.3.25 jsesc: 2.5.2 - '@babel/helper-compilation-targets@7.25.2': + "@babel/helper-compilation-targets@7.25.2": dependencies: - '@babel/compat-data': 7.25.2 - '@babel/helper-validator-option': 7.24.8 + "@babel/compat-data": 7.25.2 + "@babel/helper-validator-option": 7.24.8 browserslist: 4.23.3 lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-module-imports@7.24.7': + "@babel/helper-module-imports@7.24.7": dependencies: - '@babel/traverse': 7.25.3 - '@babel/types': 7.25.2 + "@babel/traverse": 7.25.3 + "@babel/types": 7.25.2 transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.25.2(@babel/core@7.25.2)': + "@babel/helper-module-transforms@7.25.2(@babel/core@7.25.2)": dependencies: - '@babel/core': 7.25.2 - '@babel/helper-module-imports': 7.24.7 - '@babel/helper-simple-access': 7.24.7 - '@babel/helper-validator-identifier': 7.24.7 - '@babel/traverse': 7.25.3 + "@babel/core": 7.25.2 + "@babel/helper-module-imports": 7.24.7 + "@babel/helper-simple-access": 7.24.7 + "@babel/helper-validator-identifier": 7.24.7 + "@babel/traverse": 7.25.3 transitivePeerDependencies: - supports-color - '@babel/helper-plugin-utils@7.24.8': {} + "@babel/helper-plugin-utils@7.24.8": {} - '@babel/helper-simple-access@7.24.7': + "@babel/helper-simple-access@7.24.7": dependencies: - '@babel/traverse': 7.25.3 - '@babel/types': 7.25.2 + "@babel/traverse": 7.25.3 + "@babel/types": 7.25.2 transitivePeerDependencies: - supports-color - '@babel/helper-string-parser@7.24.8': {} + "@babel/helper-string-parser@7.24.8": {} - '@babel/helper-validator-identifier@7.24.7': {} + "@babel/helper-validator-identifier@7.24.7": {} - '@babel/helper-validator-option@7.24.8': {} + "@babel/helper-validator-option@7.24.8": {} - '@babel/helpers@7.25.0': + "@babel/helpers@7.25.0": dependencies: - '@babel/template': 7.25.0 - '@babel/types': 7.25.2 + "@babel/template": 7.25.0 + "@babel/types": 7.25.2 - '@babel/highlight@7.24.7': + "@babel/highlight@7.24.7": dependencies: - '@babel/helper-validator-identifier': 7.24.7 + "@babel/helper-validator-identifier": 7.24.7 chalk: 2.4.2 js-tokens: 4.0.0 picocolors: 1.0.1 - '@babel/parser@7.25.3': + "@babel/parser@7.25.3": dependencies: - '@babel/types': 7.25.2 + "@babel/types": 7.25.2 - '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.25.2)': + "@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.25.2)": dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + "@babel/core": 7.25.2 + "@babel/helper-plugin-utils": 7.24.8 - '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.25.2)': + "@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.25.2)": dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + "@babel/core": 7.25.2 + "@babel/helper-plugin-utils": 7.24.8 - '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.25.2)': + "@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.25.2)": dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + "@babel/core": 7.25.2 + "@babel/helper-plugin-utils": 7.24.8 - '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.25.2)': + "@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.25.2)": dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + "@babel/core": 7.25.2 + "@babel/helper-plugin-utils": 7.24.8 - '@babel/plugin-syntax-import-attributes@7.24.7(@babel/core@7.25.2)': + "@babel/plugin-syntax-import-attributes@7.24.7(@babel/core@7.25.2)": dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + "@babel/core": 7.25.2 + "@babel/helper-plugin-utils": 7.24.8 - '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.25.2)': + "@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.25.2)": dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + "@babel/core": 7.25.2 + "@babel/helper-plugin-utils": 7.24.8 - '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.25.2)': + "@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.25.2)": dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + "@babel/core": 7.25.2 + "@babel/helper-plugin-utils": 7.24.8 - '@babel/plugin-syntax-jsx@7.24.7(@babel/core@7.25.2)': + "@babel/plugin-syntax-jsx@7.24.7(@babel/core@7.25.2)": dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + "@babel/core": 7.25.2 + "@babel/helper-plugin-utils": 7.24.8 - '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.25.2)': + "@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.25.2)": dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + "@babel/core": 7.25.2 + "@babel/helper-plugin-utils": 7.24.8 - '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.25.2)': + "@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.25.2)": dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + "@babel/core": 7.25.2 + "@babel/helper-plugin-utils": 7.24.8 - '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.25.2)': + "@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.25.2)": dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + "@babel/core": 7.25.2 + "@babel/helper-plugin-utils": 7.24.8 - '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.25.2)': + "@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.25.2)": dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + "@babel/core": 7.25.2 + "@babel/helper-plugin-utils": 7.24.8 - '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.25.2)': + "@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.25.2)": dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + "@babel/core": 7.25.2 + "@babel/helper-plugin-utils": 7.24.8 - '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.25.2)': + "@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.25.2)": dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + "@babel/core": 7.25.2 + "@babel/helper-plugin-utils": 7.24.8 - '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.25.2)': + "@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.25.2)": dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + "@babel/core": 7.25.2 + "@babel/helper-plugin-utils": 7.24.8 - '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.25.2)': + "@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.25.2)": dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + "@babel/core": 7.25.2 + "@babel/helper-plugin-utils": 7.24.8 - '@babel/plugin-syntax-typescript@7.24.7(@babel/core@7.25.2)': + "@babel/plugin-syntax-typescript@7.24.7(@babel/core@7.25.2)": dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + "@babel/core": 7.25.2 + "@babel/helper-plugin-utils": 7.24.8 - '@babel/template@7.25.0': + "@babel/template@7.25.0": dependencies: - '@babel/code-frame': 7.24.7 - '@babel/parser': 7.25.3 - '@babel/types': 7.25.2 + "@babel/code-frame": 7.24.7 + "@babel/parser": 7.25.3 + "@babel/types": 7.25.2 - '@babel/traverse@7.25.3': + "@babel/traverse@7.25.3": dependencies: - '@babel/code-frame': 7.24.7 - '@babel/generator': 7.25.0 - '@babel/parser': 7.25.3 - '@babel/template': 7.25.0 - '@babel/types': 7.25.2 + "@babel/code-frame": 7.24.7 + "@babel/generator": 7.25.0 + "@babel/parser": 7.25.3 + "@babel/template": 7.25.0 + "@babel/types": 7.25.2 debug: 4.3.6 globals: 11.12.0 transitivePeerDependencies: - supports-color - '@babel/types@7.25.2': + "@babel/types@7.25.2": dependencies: - '@babel/helper-string-parser': 7.24.8 - '@babel/helper-validator-identifier': 7.24.7 + "@babel/helper-string-parser": 7.24.8 + "@babel/helper-validator-identifier": 7.24.7 to-fast-properties: 2.0.0 - '@bcoe/v8-coverage@0.2.3': {} + "@bcoe/v8-coverage@0.2.3": {} - '@cspotcode/source-map-support@0.8.1': + "@cspotcode/source-map-support@0.8.1": dependencies: - '@jridgewell/trace-mapping': 0.3.9 + "@jridgewell/trace-mapping": 0.3.9 - '@istanbuljs/load-nyc-config@1.1.0': + "@istanbuljs/load-nyc-config@1.1.0": dependencies: camelcase: 5.3.1 find-up: 4.1.0 @@ -1588,25 +2545,25 @@ snapshots: js-yaml: 3.14.1 resolve-from: 5.0.0 - '@istanbuljs/schema@0.1.3': {} + "@istanbuljs/schema@0.1.3": {} - '@jest/console@29.7.0': + "@jest/console@29.7.0": dependencies: - '@jest/types': 29.6.3 - '@types/node': 20.14.15 + "@jest/types": 29.6.3 + "@types/node": 20.14.15 chalk: 4.1.2 jest-message-util: 29.7.0 jest-util: 29.7.0 slash: 3.0.0 - '@jest/core@29.7.0(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))': + "@jest/core@29.7.0(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))": dependencies: - '@jest/console': 29.7.0 - '@jest/reporters': 29.7.0 - '@jest/test-result': 29.7.0 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 20.14.15 + "@jest/console": 29.7.0 + "@jest/reporters": 29.7.0 + "@jest/test-result": 29.7.0 + "@jest/transform": 29.7.0 + "@jest/types": 29.6.3 + "@types/node": 20.14.15 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.9.0 @@ -1634,51 +2591,51 @@ snapshots: - supports-color - ts-node - '@jest/environment@29.7.0': + "@jest/environment@29.7.0": dependencies: - '@jest/fake-timers': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 20.14.15 + "@jest/fake-timers": 29.7.0 + "@jest/types": 29.6.3 + "@types/node": 20.14.15 jest-mock: 29.7.0 - '@jest/expect-utils@29.7.0': + "@jest/expect-utils@29.7.0": dependencies: jest-get-type: 29.6.3 - '@jest/expect@29.7.0': + "@jest/expect@29.7.0": dependencies: expect: 29.7.0 jest-snapshot: 29.7.0 transitivePeerDependencies: - supports-color - '@jest/fake-timers@29.7.0': + "@jest/fake-timers@29.7.0": dependencies: - '@jest/types': 29.6.3 - '@sinonjs/fake-timers': 10.3.0 - '@types/node': 20.14.15 + "@jest/types": 29.6.3 + "@sinonjs/fake-timers": 10.3.0 + "@types/node": 20.14.15 jest-message-util: 29.7.0 jest-mock: 29.7.0 jest-util: 29.7.0 - '@jest/globals@29.7.0': + "@jest/globals@29.7.0": dependencies: - '@jest/environment': 29.7.0 - '@jest/expect': 29.7.0 - '@jest/types': 29.6.3 + "@jest/environment": 29.7.0 + "@jest/expect": 29.7.0 + "@jest/types": 29.6.3 jest-mock: 29.7.0 transitivePeerDependencies: - supports-color - '@jest/reporters@29.7.0': + "@jest/reporters@29.7.0": dependencies: - '@bcoe/v8-coverage': 0.2.3 - '@jest/console': 29.7.0 - '@jest/test-result': 29.7.0 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - '@jridgewell/trace-mapping': 0.3.25 - '@types/node': 20.14.15 + "@bcoe/v8-coverage": 0.2.3 + "@jest/console": 29.7.0 + "@jest/test-result": 29.7.0 + "@jest/transform": 29.7.0 + "@jest/types": 29.6.3 + "@jridgewell/trace-mapping": 0.3.25 + "@types/node": 20.14.15 chalk: 4.1.2 collect-v8-coverage: 1.0.2 exit: 0.1.2 @@ -1699,35 +2656,35 @@ snapshots: transitivePeerDependencies: - supports-color - '@jest/schemas@29.6.3': + "@jest/schemas@29.6.3": dependencies: - '@sinclair/typebox': 0.27.8 + "@sinclair/typebox": 0.27.8 - '@jest/source-map@29.6.3': + "@jest/source-map@29.6.3": dependencies: - '@jridgewell/trace-mapping': 0.3.25 + "@jridgewell/trace-mapping": 0.3.25 callsites: 3.1.0 graceful-fs: 4.2.11 - '@jest/test-result@29.7.0': + "@jest/test-result@29.7.0": dependencies: - '@jest/console': 29.7.0 - '@jest/types': 29.6.3 - '@types/istanbul-lib-coverage': 2.0.6 + "@jest/console": 29.7.0 + "@jest/types": 29.6.3 + "@types/istanbul-lib-coverage": 2.0.6 collect-v8-coverage: 1.0.2 - '@jest/test-sequencer@29.7.0': + "@jest/test-sequencer@29.7.0": dependencies: - '@jest/test-result': 29.7.0 + "@jest/test-result": 29.7.0 graceful-fs: 4.2.11 jest-haste-map: 29.7.0 slash: 3.0.0 - '@jest/transform@29.7.0': + "@jest/transform@29.7.0": dependencies: - '@babel/core': 7.25.2 - '@jest/types': 29.6.3 - '@jridgewell/trace-mapping': 0.3.25 + "@babel/core": 7.25.2 + "@jest/types": 29.6.3 + "@jridgewell/trace-mapping": 0.3.25 babel-plugin-istanbul: 6.1.1 chalk: 4.1.2 convert-source-map: 2.0.0 @@ -1743,110 +2700,110 @@ snapshots: transitivePeerDependencies: - supports-color - '@jest/types@29.6.3': + "@jest/types@29.6.3": dependencies: - '@jest/schemas': 29.6.3 - '@types/istanbul-lib-coverage': 2.0.6 - '@types/istanbul-reports': 3.0.4 - '@types/node': 20.14.15 - '@types/yargs': 17.0.33 + "@jest/schemas": 29.6.3 + "@types/istanbul-lib-coverage": 2.0.6 + "@types/istanbul-reports": 3.0.4 + "@types/node": 20.14.15 + "@types/yargs": 17.0.33 chalk: 4.1.2 - '@jridgewell/gen-mapping@0.3.5': + "@jridgewell/gen-mapping@0.3.5": dependencies: - '@jridgewell/set-array': 1.2.1 - '@jridgewell/sourcemap-codec': 1.5.0 - '@jridgewell/trace-mapping': 0.3.25 + "@jridgewell/set-array": 1.2.1 + "@jridgewell/sourcemap-codec": 1.5.0 + "@jridgewell/trace-mapping": 0.3.25 - '@jridgewell/resolve-uri@3.1.2': {} + "@jridgewell/resolve-uri@3.1.2": {} - '@jridgewell/set-array@1.2.1': {} + "@jridgewell/set-array@1.2.1": {} - '@jridgewell/sourcemap-codec@1.5.0': {} + "@jridgewell/sourcemap-codec@1.5.0": {} - '@jridgewell/trace-mapping@0.3.25': + "@jridgewell/trace-mapping@0.3.25": dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.0 + "@jridgewell/resolve-uri": 3.1.2 + "@jridgewell/sourcemap-codec": 1.5.0 - '@jridgewell/trace-mapping@0.3.9': + "@jridgewell/trace-mapping@0.3.9": dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.0 + "@jridgewell/resolve-uri": 3.1.2 + "@jridgewell/sourcemap-codec": 1.5.0 - '@sinclair/typebox@0.27.8': {} + "@sinclair/typebox@0.27.8": {} - '@sinonjs/commons@3.0.1': + "@sinonjs/commons@3.0.1": dependencies: type-detect: 4.0.8 - '@sinonjs/fake-timers@10.3.0': + "@sinonjs/fake-timers@10.3.0": dependencies: - '@sinonjs/commons': 3.0.1 + "@sinonjs/commons": 3.0.1 - '@tsconfig/node10@1.0.11': {} + "@tsconfig/node10@1.0.11": {} - '@tsconfig/node12@1.0.11': {} + "@tsconfig/node12@1.0.11": {} - '@tsconfig/node14@1.0.3': {} + "@tsconfig/node14@1.0.3": {} - '@tsconfig/node16@1.0.4': {} + "@tsconfig/node16@1.0.4": {} - '@types/babel__core@7.20.5': + "@types/babel__core@7.20.5": dependencies: - '@babel/parser': 7.25.3 - '@babel/types': 7.25.2 - '@types/babel__generator': 7.6.8 - '@types/babel__template': 7.4.4 - '@types/babel__traverse': 7.20.6 + "@babel/parser": 7.25.3 + "@babel/types": 7.25.2 + "@types/babel__generator": 7.6.8 + "@types/babel__template": 7.4.4 + "@types/babel__traverse": 7.20.6 - '@types/babel__generator@7.6.8': + "@types/babel__generator@7.6.8": dependencies: - '@babel/types': 7.25.2 + "@babel/types": 7.25.2 - '@types/babel__template@7.4.4': + "@types/babel__template@7.4.4": dependencies: - '@babel/parser': 7.25.3 - '@babel/types': 7.25.2 + "@babel/parser": 7.25.3 + "@babel/types": 7.25.2 - '@types/babel__traverse@7.20.6': + "@types/babel__traverse@7.20.6": dependencies: - '@babel/types': 7.25.2 + "@babel/types": 7.25.2 - '@types/graceful-fs@4.1.9': + "@types/graceful-fs@4.1.9": dependencies: - '@types/node': 20.14.15 + "@types/node": 20.14.15 - '@types/istanbul-lib-coverage@2.0.6': {} + "@types/istanbul-lib-coverage@2.0.6": {} - '@types/istanbul-lib-report@3.0.3': + "@types/istanbul-lib-report@3.0.3": dependencies: - '@types/istanbul-lib-coverage': 2.0.6 + "@types/istanbul-lib-coverage": 2.0.6 - '@types/istanbul-reports@3.0.4': + "@types/istanbul-reports@3.0.4": dependencies: - '@types/istanbul-lib-report': 3.0.3 + "@types/istanbul-lib-report": 3.0.3 - '@types/jest@29.5.12': + "@types/jest@29.5.12": dependencies: expect: 29.7.0 pretty-format: 29.7.0 - '@types/mocha@10.0.7': {} + "@types/mocha@10.0.7": {} - '@types/node@20.14.15': + "@types/node@20.14.15": dependencies: undici-types: 5.26.5 - '@types/stack-utils@2.0.3': {} + "@types/stack-utils@2.0.3": {} - '@types/uuid@10.0.0': {} + "@types/uuid@10.0.0": {} - '@types/yargs-parser@21.0.3': {} + "@types/yargs-parser@21.0.3": {} - '@types/yargs@17.0.33': + "@types/yargs@17.0.33": dependencies: - '@types/yargs-parser': 21.0.3 + "@types/yargs-parser": 21.0.3 acorn-walk@8.3.3: dependencies: @@ -1895,9 +2852,9 @@ snapshots: babel-jest@29.7.0(@babel/core@7.25.2): dependencies: - '@babel/core': 7.25.2 - '@jest/transform': 29.7.0 - '@types/babel__core': 7.20.5 + "@babel/core": 7.25.2 + "@jest/transform": 29.7.0 + "@types/babel__core": 7.20.5 babel-plugin-istanbul: 6.1.1 babel-preset-jest: 29.6.3(@babel/core@7.25.2) chalk: 4.1.2 @@ -1908,9 +2865,9 @@ snapshots: babel-plugin-istanbul@6.1.1: dependencies: - '@babel/helper-plugin-utils': 7.24.8 - '@istanbuljs/load-nyc-config': 1.1.0 - '@istanbuljs/schema': 0.1.3 + "@babel/helper-plugin-utils": 7.24.8 + "@istanbuljs/load-nyc-config": 1.1.0 + "@istanbuljs/schema": 0.1.3 istanbul-lib-instrument: 5.2.1 test-exclude: 6.0.0 transitivePeerDependencies: @@ -1918,33 +2875,33 @@ snapshots: babel-plugin-jest-hoist@29.6.3: dependencies: - '@babel/template': 7.25.0 - '@babel/types': 7.25.2 - '@types/babel__core': 7.20.5 - '@types/babel__traverse': 7.20.6 + "@babel/template": 7.25.0 + "@babel/types": 7.25.2 + "@types/babel__core": 7.20.5 + "@types/babel__traverse": 7.20.6 babel-preset-current-node-syntax@1.1.0(@babel/core@7.25.2): dependencies: - '@babel/core': 7.25.2 - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.25.2) - '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.25.2) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.25.2) - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.25.2) - '@babel/plugin-syntax-import-attributes': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.25.2) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.25.2) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.25.2) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.25.2) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.25.2) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.25.2) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.25.2) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.25.2) - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.25.2) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.25.2) + "@babel/core": 7.25.2 + "@babel/plugin-syntax-async-generators": 7.8.4(@babel/core@7.25.2) + "@babel/plugin-syntax-bigint": 7.8.3(@babel/core@7.25.2) + "@babel/plugin-syntax-class-properties": 7.12.13(@babel/core@7.25.2) + "@babel/plugin-syntax-class-static-block": 7.14.5(@babel/core@7.25.2) + "@babel/plugin-syntax-import-attributes": 7.24.7(@babel/core@7.25.2) + "@babel/plugin-syntax-import-meta": 7.10.4(@babel/core@7.25.2) + "@babel/plugin-syntax-json-strings": 7.8.3(@babel/core@7.25.2) + "@babel/plugin-syntax-logical-assignment-operators": 7.10.4(@babel/core@7.25.2) + "@babel/plugin-syntax-nullish-coalescing-operator": 7.8.3(@babel/core@7.25.2) + "@babel/plugin-syntax-numeric-separator": 7.10.4(@babel/core@7.25.2) + "@babel/plugin-syntax-object-rest-spread": 7.8.3(@babel/core@7.25.2) + "@babel/plugin-syntax-optional-catch-binding": 7.8.3(@babel/core@7.25.2) + "@babel/plugin-syntax-optional-chaining": 7.8.3(@babel/core@7.25.2) + "@babel/plugin-syntax-private-property-in-object": 7.14.5(@babel/core@7.25.2) + "@babel/plugin-syntax-top-level-await": 7.14.5(@babel/core@7.25.2) babel-preset-jest@29.6.3(@babel/core@7.25.2): dependencies: - '@babel/core': 7.25.2 + "@babel/core": 7.25.2 babel-plugin-jest-hoist: 29.6.3 babel-preset-current-node-syntax: 1.1.0(@babel/core@7.25.2) @@ -2037,7 +2994,7 @@ snapshots: create-jest@29.7.0(@types/node@20.14.15)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)): dependencies: - '@jest/types': 29.6.3 + "@jest/types": 29.6.3 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 @@ -2045,7 +3002,7 @@ snapshots: jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: - - '@types/node' + - "@types/node" - babel-plugin-macros - supports-color - ts-node @@ -2112,7 +3069,7 @@ snapshots: expect@29.7.0: dependencies: - '@jest/expect-utils': 29.7.0 + "@jest/expect-utils": 29.7.0 jest-get-type: 29.6.3 jest-matcher-utils: 29.7.0 jest-message-util: 29.7.0 @@ -2221,9 +3178,9 @@ snapshots: istanbul-lib-instrument@5.2.1: dependencies: - '@babel/core': 7.25.2 - '@babel/parser': 7.25.3 - '@istanbuljs/schema': 0.1.3 + "@babel/core": 7.25.2 + "@babel/parser": 7.25.3 + "@istanbuljs/schema": 0.1.3 istanbul-lib-coverage: 3.2.2 semver: 6.3.1 transitivePeerDependencies: @@ -2231,9 +3188,9 @@ snapshots: istanbul-lib-instrument@6.0.3: dependencies: - '@babel/core': 7.25.2 - '@babel/parser': 7.25.3 - '@istanbuljs/schema': 0.1.3 + "@babel/core": 7.25.2 + "@babel/parser": 7.25.3 + "@istanbuljs/schema": 0.1.3 istanbul-lib-coverage: 3.2.2 semver: 7.6.3 transitivePeerDependencies: @@ -2273,11 +3230,11 @@ snapshots: jest-circus@29.7.0: dependencies: - '@jest/environment': 29.7.0 - '@jest/expect': 29.7.0 - '@jest/test-result': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 20.14.15 + "@jest/environment": 29.7.0 + "@jest/expect": 29.7.0 + "@jest/test-result": 29.7.0 + "@jest/types": 29.6.3 + "@types/node": 20.14.15 chalk: 4.1.2 co: 4.6.0 dedent: 1.5.3 @@ -2299,9 +3256,9 @@ snapshots: jest-cli@29.7.0(@types/node@20.14.15)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)) - '@jest/test-result': 29.7.0 - '@jest/types': 29.6.3 + "@jest/core": 29.7.0(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)) + "@jest/test-result": 29.7.0 + "@jest/types": 29.6.3 chalk: 4.1.2 create-jest: 29.7.0(@types/node@20.14.15)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)) exit: 0.1.2 @@ -2311,16 +3268,16 @@ snapshots: jest-validate: 29.7.0 yargs: 17.7.2 transitivePeerDependencies: - - '@types/node' + - "@types/node" - babel-plugin-macros - supports-color - ts-node jest-config@29.7.0(@types/node@20.14.15)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)): dependencies: - '@babel/core': 7.25.2 - '@jest/test-sequencer': 29.7.0 - '@jest/types': 29.6.3 + "@babel/core": 7.25.2 + "@jest/test-sequencer": 29.7.0 + "@jest/types": 29.6.3 babel-jest: 29.7.0(@babel/core@7.25.2) chalk: 4.1.2 ci-info: 3.9.0 @@ -2341,7 +3298,7 @@ snapshots: slash: 3.0.0 strip-json-comments: 3.1.1 optionalDependencies: - '@types/node': 20.14.15 + "@types/node": 20.14.15 ts-node: 10.9.2(@types/node@20.14.15)(typescript@5.5.4) transitivePeerDependencies: - babel-plugin-macros @@ -2360,7 +3317,7 @@ snapshots: jest-each@29.7.0: dependencies: - '@jest/types': 29.6.3 + "@jest/types": 29.6.3 chalk: 4.1.2 jest-get-type: 29.6.3 jest-util: 29.7.0 @@ -2368,10 +3325,10 @@ snapshots: jest-environment-node@29.7.0: dependencies: - '@jest/environment': 29.7.0 - '@jest/fake-timers': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 20.14.15 + "@jest/environment": 29.7.0 + "@jest/fake-timers": 29.7.0 + "@jest/types": 29.6.3 + "@types/node": 20.14.15 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -2379,9 +3336,9 @@ snapshots: jest-haste-map@29.7.0: dependencies: - '@jest/types': 29.6.3 - '@types/graceful-fs': 4.1.9 - '@types/node': 20.14.15 + "@jest/types": 29.6.3 + "@types/graceful-fs": 4.1.9 + "@types/node": 20.14.15 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 @@ -2407,9 +3364,9 @@ snapshots: jest-message-util@29.7.0: dependencies: - '@babel/code-frame': 7.24.7 - '@jest/types': 29.6.3 - '@types/stack-utils': 2.0.3 + "@babel/code-frame": 7.24.7 + "@jest/types": 29.6.3 + "@types/stack-utils": 2.0.3 chalk: 4.1.2 graceful-fs: 4.2.11 micromatch: 4.0.7 @@ -2419,8 +3376,8 @@ snapshots: jest-mock@29.7.0: dependencies: - '@jest/types': 29.6.3 - '@types/node': 20.14.15 + "@jest/types": 29.6.3 + "@types/node": 20.14.15 jest-util: 29.7.0 jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): @@ -2450,12 +3407,12 @@ snapshots: jest-runner@29.7.0: dependencies: - '@jest/console': 29.7.0 - '@jest/environment': 29.7.0 - '@jest/test-result': 29.7.0 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 20.14.15 + "@jest/console": 29.7.0 + "@jest/environment": 29.7.0 + "@jest/test-result": 29.7.0 + "@jest/transform": 29.7.0 + "@jest/types": 29.6.3 + "@types/node": 20.14.15 chalk: 4.1.2 emittery: 0.13.1 graceful-fs: 4.2.11 @@ -2476,14 +3433,14 @@ snapshots: jest-runtime@29.7.0: dependencies: - '@jest/environment': 29.7.0 - '@jest/fake-timers': 29.7.0 - '@jest/globals': 29.7.0 - '@jest/source-map': 29.6.3 - '@jest/test-result': 29.7.0 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 20.14.15 + "@jest/environment": 29.7.0 + "@jest/fake-timers": 29.7.0 + "@jest/globals": 29.7.0 + "@jest/source-map": 29.6.3 + "@jest/test-result": 29.7.0 + "@jest/transform": 29.7.0 + "@jest/types": 29.6.3 + "@types/node": 20.14.15 chalk: 4.1.2 cjs-module-lexer: 1.3.1 collect-v8-coverage: 1.0.2 @@ -2503,14 +3460,14 @@ snapshots: jest-snapshot@29.7.0: dependencies: - '@babel/core': 7.25.2 - '@babel/generator': 7.25.0 - '@babel/plugin-syntax-jsx': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-syntax-typescript': 7.24.7(@babel/core@7.25.2) - '@babel/types': 7.25.2 - '@jest/expect-utils': 29.7.0 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 + "@babel/core": 7.25.2 + "@babel/generator": 7.25.0 + "@babel/plugin-syntax-jsx": 7.24.7(@babel/core@7.25.2) + "@babel/plugin-syntax-typescript": 7.24.7(@babel/core@7.25.2) + "@babel/types": 7.25.2 + "@jest/expect-utils": 29.7.0 + "@jest/transform": 29.7.0 + "@jest/types": 29.6.3 babel-preset-current-node-syntax: 1.1.0(@babel/core@7.25.2) chalk: 4.1.2 expect: 29.7.0 @@ -2528,8 +3485,8 @@ snapshots: jest-util@29.7.0: dependencies: - '@jest/types': 29.6.3 - '@types/node': 20.14.15 + "@jest/types": 29.6.3 + "@types/node": 20.14.15 chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 @@ -2537,7 +3494,7 @@ snapshots: jest-validate@29.7.0: dependencies: - '@jest/types': 29.6.3 + "@jest/types": 29.6.3 camelcase: 6.3.0 chalk: 4.1.2 jest-get-type: 29.6.3 @@ -2546,9 +3503,9 @@ snapshots: jest-watcher@29.7.0: dependencies: - '@jest/test-result': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 20.14.15 + "@jest/test-result": 29.7.0 + "@jest/types": 29.6.3 + "@types/node": 20.14.15 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 @@ -2557,19 +3514,19 @@ snapshots: jest-worker@29.7.0: dependencies: - '@types/node': 20.14.15 + "@types/node": 20.14.15 jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 jest@29.7.0(@types/node@20.14.15)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)) - '@jest/types': 29.6.3 + "@jest/core": 29.7.0(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)) + "@jest/types": 29.6.3 import-local: 3.2.0 jest-cli: 29.7.0(@types/node@20.14.15)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)) transitivePeerDependencies: - - '@types/node' + - "@types/node" - babel-plugin-macros - supports-color - ts-node @@ -2674,7 +3631,7 @@ snapshots: parse-json@5.2.0: dependencies: - '@babel/code-frame': 7.24.7 + "@babel/code-frame": 7.24.7 error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 @@ -2716,7 +3673,7 @@ snapshots: pretty-format@29.7.0: dependencies: - '@jest/schemas': 29.6.3 + "@jest/schemas": 29.6.3 ansi-styles: 5.2.0 react-is: 18.3.1 @@ -2815,7 +3772,7 @@ snapshots: test-exclude@6.0.0: dependencies: - '@istanbuljs/schema': 0.1.3 + "@istanbuljs/schema": 0.1.3 glob: 7.2.3 minimatch: 3.1.2 @@ -2841,19 +3798,19 @@ snapshots: typescript: 5.5.4 yargs-parser: 21.1.1 optionalDependencies: - '@babel/core': 7.25.2 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 + "@babel/core": 7.25.2 + "@jest/transform": 29.7.0 + "@jest/types": 29.6.3 babel-jest: 29.7.0(@babel/core@7.25.2) ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4): dependencies: - '@cspotcode/source-map-support': 0.8.1 - '@tsconfig/node10': 1.0.11 - '@tsconfig/node12': 1.0.11 - '@tsconfig/node14': 1.0.3 - '@tsconfig/node16': 1.0.4 - '@types/node': 20.14.15 + "@cspotcode/source-map-support": 0.8.1 + "@tsconfig/node10": 1.0.11 + "@tsconfig/node12": 1.0.11 + "@tsconfig/node14": 1.0.3 + "@tsconfig/node16": 1.0.4 + "@types/node": 20.14.15 acorn: 8.12.1 acorn-walk: 8.3.3 arg: 4.1.3 @@ -2884,8 +3841,8 @@ snapshots: v8-to-istanbul@9.3.0: dependencies: - '@jridgewell/trace-mapping': 0.3.25 - '@types/istanbul-lib-coverage': 2.0.6 + "@jridgewell/trace-mapping": 0.3.25 + "@types/istanbul-lib-coverage": 2.0.6 convert-source-map: 2.0.0 walker@1.0.8: diff --git a/js/sdk/src/r2rClient.ts b/js/sdk/src/r2rClient.ts index 61ec76d5c..3d706cd66 100644 --- a/js/sdk/src/r2rClient.ts +++ b/js/sdk/src/r2rClient.ts @@ -122,6 +122,9 @@ export class r2rClient { config.data = JSON.stringify(options.data); if (method !== "DELETE") { config.headers["Content-Type"] = "application/json"; + } else { + config.headers["Content-Type"] = "application/json"; + config.data = JSON.stringify(options.data); } } else { config.data = options.data; @@ -203,9 +206,9 @@ export class r2rClient { * @returns A promise that resolves to the response from the server. */ @feature("verifyEmail") - async verifyEmail(verification_code: string): Promise> { + async verifyEmail(verification_code: string): Promise { return await this._makeRequest("POST", "verify_email", { - json: { verification_code: verification_code }, + data: { verification_code }, }); } @@ -367,19 +370,21 @@ export class r2rClient { /** * Deletes the user with the given user ID. - * @param user_id The ID of the user to delete. + * @param user_id The ID of the user to delete, defaults to the currently authenticated user. * @param password The password of the user to delete. * @returns A promise that resolves to the response from the server. */ @feature("deleteUser") - async deleteUser(user_id: string, password?: string): Promise { + async deleteUser(userId: string, password?: string): Promise { this._ensureAuthenticated(); - const response = await this._makeRequest("DELETE", "user", { - data: { user_id, password }, - }); - this.accessToken = null; - this.refreshToken = null; - return response; + + const data: Record = { user_id: userId }; + + if (password) { + data.password = password; + } + + return await this._makeRequest("DELETE", "user", { data }); } // ----------------------------------------------------------------------------- @@ -640,16 +645,16 @@ export class r2rClient { if (filter_criteria) { params.filter_criteria = - typeof filter_criteria === "object" - ? JSON.stringify(filter_criteria) - : filter_criteria; + typeof filter_criteria === "string" + ? filter_criteria + : JSON.stringify(filter_criteria); } if (analysis_types) { params.analysis_types = - typeof analysis_types === "object" - ? JSON.stringify(analysis_types) - : analysis_types; + typeof analysis_types === "string" + ? analysis_types + : JSON.stringify(analysis_types); } return this._makeRequest("GET", "analytics", { params }); @@ -775,15 +780,11 @@ export class r2rClient { async documentChunks(document_id: string): Promise { this._ensureAuthenticated(); - return this._makeRequest( - "GET", - `document_chunks/${document_id}`, - { - headers: { - "Content-Type": "application/json", - }, + return this._makeRequest("GET", `document_chunks/${document_id}`, { + headers: { + "Content-Type": "application/json", }, - ); + }); } /** diff --git a/py/cli/commands/management.py b/py/cli/commands/management.py index 52ffc6742..7f8925290 100644 --- a/py/cli/commands/management.py +++ b/py/cli/commands/management.py @@ -44,8 +44,13 @@ def users_overview(client, user_ids): with timer(): response = client.users_overview(user_ids) - for user in response: - click.echo(user) + if 'results' in response: + click.echo("\nUser Overview:") + click.echo(f"{'User ID':<40} {'Num Files':<10} {'Total Size (bytes)':<20} Document IDs") + for user in response['results']: + click.echo(f"{user['user_id']:<40} {user['num_files']:<10} {user['total_size_in_bytes']:<20} {', '.join(user['document_ids'][:3]) + ('...' if len(user['document_ids']) > 3 else '')}") + else: + click.echo("No users found.") @cli.command() diff --git a/py/core/main/services/management_service.py b/py/core/main/services/management_service.py index f572a55e1..778f337df 100644 --- a/py/core/main/services/management_service.py +++ b/py/core/main/services/management_service.py @@ -234,7 +234,7 @@ async def ascore_completion( except Exception as e: logger.error(f"An error occurred in ascore_completion: {e}") - return "ok" + return {"message": "Completion scored successfully"} @telemetry_event("UsersOverview") async def ausers_overview( From a75705f013cc588624fc6cd10e3b74715decee4a Mon Sep 17 00:00:00 2001 From: Shreyas Pimpalgaonkar Date: Thu, 22 Aug 2024 17:38:07 -0400 Subject: [PATCH 48/74] Shreyas/unstructured docker image (#940) unstructured docker image --- .github/workflows/build-main.yml | 13 ++++++++++++ .github/workflows/build-mainv2.yml | 28 +++++++++++-------------- py/cli/utils/docker_utils.py | 3 +++ py/core/main/assembly/factory.py | 1 - py/poetry.lock | 33 +++++++++++------------------- 5 files changed, 40 insertions(+), 38 deletions(-) diff --git a/.github/workflows/build-main.yml b/.github/workflows/build-main.yml index b91de2c3f..a52f332a2 100644 --- a/.github/workflows/build-main.yml +++ b/.github/workflows/build-main.yml @@ -62,6 +62,9 @@ jobs: tags: | type=raw,value=${{ steps.version.outputs.RELEASE_VERSION }} type=raw,value=latest + tags_unstructured: | + type=raw,value=${{ steps.version.outputs.RELEASE_VERSION }} + type=raw,value=latest-unstructured - name: Build and Push Docker Image uses: docker/build-push-action@v5 @@ -73,6 +76,16 @@ jobs: labels: ${{ steps.meta.outputs.labels }} platforms: linux/amd64,linux/arm64 + - name: Build and Push Docker Image + uses: docker/build-push-action@v5 + with: + context: . + file: ./Dockerfile.unstructured + push: true + tags: ${{ steps.meta.outputs.tags_unstructured }} + labels: ${{ steps.meta.outputs.labels_unstructured }} + platforms: linux/amd64,linux/arm64 + - name: Trigger Dependent Repositories if: success() run: | diff --git a/.github/workflows/build-mainv2.yml b/.github/workflows/build-mainv2.yml index e0277a593..93e53649d 100644 --- a/.github/workflows/build-mainv2.yml +++ b/.github/workflows/build-mainv2.yml @@ -52,12 +52,19 @@ jobs: tags: | type=raw,value=${{ steps.version.outputs.RELEASE_VERSION }} type=raw,value=latest + tags_unstructured: | + type=raw,value=${{ steps.version.outputs.RELEASE_VERSION }} + type=raw,value=latest-unstructured + labels: | + type=raw,value=latest + labels_unstructured: | + type=raw,value=latest-unstructured - name: Build and Push Docker Image (Standard) uses: docker/build-push-action@v5 with: context: . - file: ./Dockerfile + file: ./py/Dockerfile push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} @@ -69,21 +76,10 @@ jobs: uses: docker/build-push-action@v5 with: context: . - file: ./Dockerfile.unstructured + file: ./py/Dockerfile.unstructured push: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} + tags: ${{ steps.meta.outputs.tags_unstructured }} + labels: ${{ steps.meta.outputs.labels_unstructured }} platforms: linux/amd64,linux/arm64 build-args: | - CACHE_BUST=${{ steps.cache-buster.outputs.CACHE_BUSTER }} - - - name: Modify and Push Unstructured Tags - run: | - for tag in ${{ steps.meta.outputs.tags }}; do - IFS=':' read -ra PARTS <<< "$tag" - REPO="${PARTS[0]}" - VERSION="${PARTS[1]}" - NEW_TAG="${REPO}:${VERSION}-unstructured" - docker tag $tag $NEW_TAG - docker push $NEW_TAG - done + CACHE_BUST=${{ steps.cache-buster.outputs.CACHE_BUSTER }} \ No newline at end of file diff --git a/py/cli/utils/docker_utils.py b/py/cli/utils/docker_utils.py index 16e47a0a8..a80b9e24d 100644 --- a/py/cli/utils/docker_utils.py +++ b/py/cli/utils/docker_utils.py @@ -124,6 +124,9 @@ def run_docker_serve( config = R2RConfig.from_toml(R2RBuilder.CONFIG_OPTIONS[config_name]) + if config.parsing.provider == "unstructured" and not image: + image = "ragtoriches/prod_unstructured" + completion_provider = config.completion.provider completion_model = config.completion.generation_config.model completion_model_provider = completion_model.split("/")[0] diff --git a/py/core/main/assembly/factory.py b/py/core/main/assembly/factory.py index 7c45864a4..120920412 100644 --- a/py/core/main/assembly/factory.py +++ b/py/core/main/assembly/factory.py @@ -215,7 +215,6 @@ def create_prompt_provider( prompt_provider = None if prompt_config.provider == "r2r": from core.providers import R2RPromptProvider - prompt_provider = R2RPromptProvider(prompt_config) else: raise ValueError( diff --git a/py/poetry.lock b/py/poetry.lock index 3ca82c165..d45ad242b 100644 --- a/py/poetry.lock +++ b/py/poetry.lock @@ -291,18 +291,20 @@ tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] [[package]] name = "autograd" -version = "1.6.2" -description = "Efficiently computes derivatives of numpy code." +version = "1.7.0" +description = "Efficiently computes derivatives of NumPy code." optional = true -python-versions = "*" +python-versions = ">=3.8" files = [ - {file = "autograd-1.6.2-py3-none-any.whl", hash = "sha256:208dde2a938e63b4f8f5049b1985505139e529068b0d26f8cd7771fd3eb145d5"}, - {file = "autograd-1.6.2.tar.gz", hash = "sha256:8731e08a0c4e389d8695a40072ada4512641c113b6cace8f4cfbe8eb7e9aedeb"}, + {file = "autograd-1.7.0-py3-none-any.whl", hash = "sha256:49680300f842f3a8722b060ac0d3ed7aca071d1ad4d3d38c9fdadafdcc73c30b"}, + {file = "autograd-1.7.0.tar.gz", hash = "sha256:de743fd368d6df523cd37305dcd171861a9752a144493677d2c9f5a56983ff2f"}, ] [package.dependencies] -future = ">=0.15.2" -numpy = ">=1.12" +numpy = "*" + +[package.extras] +scipy = ["scipy"] [[package]] name = "backoff" @@ -1165,17 +1167,6 @@ test-downstream = ["aiobotocore (>=2.5.4,<3.0.0)", "dask-expr", "dask[dataframe, test-full = ["adlfs", "aiohttp (!=4.0.0a0,!=4.0.0a1)", "cloudpickle", "dask", "distributed", "dropbox", "dropboxdrivefs", "fastparquet", "fusepy", "gcsfs", "jinja2", "kerchunk", "libarchive-c", "lz4", "notebook", "numpy", "ocifs", "pandas", "panel", "paramiko", "pyarrow", "pyarrow (>=1)", "pyftpdlib", "pygit2", "pytest", "pytest-asyncio (!=0.22.0)", "pytest-benchmark", "pytest-cov", "pytest-mock", "pytest-recording", "pytest-rerunfailures", "python-snappy", "requests", "smbprotocol", "tqdm", "urllib3", "zarr", "zstandard"] tqdm = ["tqdm"] -[[package]] -name = "future" -version = "1.0.0" -description = "Clean single-source support for Python 3 and 2" -optional = true -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" -files = [ - {file = "future-1.0.0-py3-none-any.whl", hash = "sha256:929292d34f5872e70396626ef385ec22355a1fae8ad29e1a734c3e43f9fbc216"}, - {file = "future-1.0.0.tar.gz", hash = "sha256:bd2968309307861edae1458a4f8a4f3598c03be43b97521076aebf5d94c07b05"}, -] - [[package]] name = "gensim" version = "4.3.3" @@ -1855,13 +1846,13 @@ files = [ [[package]] name = "litellm" -version = "1.44.1" +version = "1.44.2" description = "Library to easily interface with LLM API providers" optional = true python-versions = "!=2.7.*,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,!=3.7.*,>=3.8" files = [ - {file = "litellm-1.44.1-py3-none-any.whl", hash = "sha256:6367cfafbdd5d6a5125cefd21375df89f0b8a0d77044616cd88462be77d05564"}, - {file = "litellm-1.44.1.tar.gz", hash = "sha256:b9013df8b255335a08df1e9e7ac589dab97b7fe8adb0c614e2ef4b65adcc33fb"}, + {file = "litellm-1.44.2-py3-none-any.whl", hash = "sha256:7c94618f06c5990f8103b65a6752c7713da334524f9c0334346b8f63df5cdfb5"}, + {file = "litellm-1.44.2.tar.gz", hash = "sha256:b9290b1414caf6a955a5a493fb1b1dce95b2710a934e968c9ab04d0a3fba804c"}, ] [package.dependencies] From 18e8f2e003023ebb1d394dc6704e6d0080a6410c Mon Sep 17 00:00:00 2001 From: Nolan Tremelling <34580718+NolanTrem@users.noreply.github.com> Date: Thu, 22 Aug 2024 15:02:30 -0700 Subject: [PATCH 49/74] Update JS (#941) --- js/sdk/README.md | 1 - js/sdk/__tests__/r2rClientIntegrationSuperUser.test.ts | 1 - js/sdk/__tests__/r2rClientIntegrationUser.test.ts | 1 - js/sdk/examples/hello_r2r.js | 1 - js/sdk/src/models.tsx | 9 ++++++++- js/sdk/src/r2rClient.ts | 7 ------- py/cli/commands/management.py | 1 - 7 files changed, 8 insertions(+), 13 deletions(-) diff --git a/js/sdk/README.md b/js/sdk/README.md index ba9c34d27..930ab6dc6 100644 --- a/js/sdk/README.md +++ b/js/sdk/README.md @@ -75,7 +75,6 @@ const ingestResult = await client.ingestFiles(files, { "123e4567-e89b-12d3-a456-426614174000", "123e4567-e89b-12d3-a456-426614174000", ], - skip_document_info: false, }); console.log(ingestResult); ``` diff --git a/js/sdk/__tests__/r2rClientIntegrationSuperUser.test.ts b/js/sdk/__tests__/r2rClientIntegrationSuperUser.test.ts index ff8547dc2..2b9548c95 100644 --- a/js/sdk/__tests__/r2rClientIntegrationSuperUser.test.ts +++ b/js/sdk/__tests__/r2rClientIntegrationSuperUser.test.ts @@ -38,7 +38,6 @@ describe("r2rClient Integration Tests", () => { await expect( client.ingestFiles(files, { metadatas: [{ title: "raskolnikov.txt" }, { title: "karamozov.txt" }], - skip_document_info: false, }), ).resolves.not.toThrow(); }); diff --git a/js/sdk/__tests__/r2rClientIntegrationUser.test.ts b/js/sdk/__tests__/r2rClientIntegrationUser.test.ts index 5b1664c4c..0154a54a1 100644 --- a/js/sdk/__tests__/r2rClientIntegrationUser.test.ts +++ b/js/sdk/__tests__/r2rClientIntegrationUser.test.ts @@ -40,7 +40,6 @@ describe("r2rClient Integration Tests", () => { await expect( client.ingestFiles(files, { metadatas: [{ title: "raskolnikov.txt" }], - skip_document_info: false, }), ).resolves.not.toThrow(); }); diff --git a/js/sdk/examples/hello_r2r.js b/js/sdk/examples/hello_r2r.js index a1bb8b572..2362672e8 100644 --- a/js/sdk/examples/hello_r2r.js +++ b/js/sdk/examples/hello_r2r.js @@ -16,7 +16,6 @@ async function main() { console.log("Ingesting file..."); const ingestResult = await client.ingestFiles(files, { metadatas: [{ title: "raskolnikov.txt" }], - skip_document_info: false, }); console.log("Ingest result:", JSON.stringify(ingestResult, null, 2)); diff --git a/js/sdk/src/models.tsx b/js/sdk/src/models.tsx index eee1eb834..265dd2a07 100644 --- a/js/sdk/src/models.tsx +++ b/js/sdk/src/models.tsx @@ -35,9 +35,16 @@ export interface GenerationConfig { export interface VectorSearchSettings { use_vector_search?: boolean; + use_hybrid_search?: boolean; filters?: Record; search_limit?: number; - use_hybrid_search?: boolean; + selected_group_ids?: string[]; + // TODO: add index measure + // TODO: add include vars + // TODO: add include metadatas + // TODO: add include probes + // TODO: add ef_search + // TODO: add hybrid_search_settings } export interface KGSearchSettings { diff --git a/js/sdk/src/r2rClient.ts b/js/sdk/src/r2rClient.ts index 3d706cd66..2cd811b7e 100644 --- a/js/sdk/src/r2rClient.ts +++ b/js/sdk/src/r2rClient.ts @@ -407,9 +407,7 @@ export class r2rClient { metadatas?: Record[]; document_ids?: string[]; user_ids?: (string | null)[]; - versions?: string[]; chunking_settings?: Record; - skip_document_info?: boolean; } = {}, ): Promise { this._ensureAuthenticated(); @@ -472,14 +470,9 @@ export class r2rClient { ? JSON.stringify(options.document_ids) : undefined, user_ids: options.user_ids ? JSON.stringify(options.user_ids) : undefined, - versions: options.versions ? JSON.stringify(options.versions) : undefined, chunking_settings: options.chunking_settings ? JSON.stringify(options.chunking_settings) : undefined, - skip_document_info: - options.skip_document_info !== undefined - ? JSON.stringify(options.skip_document_info) - : undefined, }; Object.entries(data).forEach(([key, value]) => { diff --git a/py/cli/commands/management.py b/py/cli/commands/management.py index 7f8925290..ff3bf0861 100644 --- a/py/cli/commands/management.py +++ b/py/cli/commands/management.py @@ -8,7 +8,6 @@ # TODO: Implement update_prompt -# TODO: Update @cli.command() @click.option("--filters", type=JSON, help="Filters for analytics as JSON") @click.option("--analysis-types", type=JSON, help="Analysis types as JSON") From 7d6c7f2b5c6c5fadcc30bf613a85973270b8bb46 Mon Sep 17 00:00:00 2001 From: Nolan Tremelling <34580718+NolanTrem@users.noreply.github.com> Date: Thu, 22 Aug 2024 15:31:03 -0700 Subject: [PATCH 50/74] Update models (#942) --- js/sdk/src/models.tsx | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/js/sdk/src/models.tsx b/js/sdk/src/models.tsx index 265dd2a07..d2b74b61d 100644 --- a/js/sdk/src/models.tsx +++ b/js/sdk/src/models.tsx @@ -17,34 +17,36 @@ export interface RefreshTokenResponse { } export interface GenerationConfig { + model?: string; temperature?: number; top_p?: number; - top_k?: number; max_tokens_to_sample?: number; - model?: string; stream?: boolean; functions?: Array>; - skip_special_tokens?: boolean; - stop_token?: string; - num_beams?: number; - do_sample?: boolean; - generate_with_chat?: boolean; + tools?: Array>; add_generation_kwargs?: Record; api_base?: string; } +export interface HybridSearchSettings { + full_text_weight: number; + semantic_weight: number; + full_text_limit: number; + rrf_k: number; +} + export interface VectorSearchSettings { use_vector_search?: boolean; use_hybrid_search?: boolean; filters?: Record; search_limit?: number; selected_group_ids?: string[]; - // TODO: add index measure - // TODO: add include vars - // TODO: add include metadatas - // TODO: add include probes - // TODO: add ef_search - // TODO: add hybrid_search_settings + index_measure: IndexMeasure; + include_values?: boolean; + include_metadatas?: boolean; + probes?: number; + ef_search?: number; + hybrid_search_settings?: HybridSearchSettings; } export interface KGSearchSettings { @@ -66,3 +68,9 @@ export interface Message { export interface R2RDocumentChunksRequest { document_id: string; } + +export enum IndexMeasure { + COSINE_DISTANCE = "cosine_distance", + L2_DISTANCE = "l2_distance", + MAX_INNER_PRODUCT = "max_inner_product", +} From e6fdecab2ad5dedff3b67f94cdec784364d16e79 Mon Sep 17 00:00:00 2001 From: emrgnt-cmplxty <68796651+emrgnt-cmplxty@users.noreply.github.com> Date: Thu, 22 Aug 2024 17:40:11 -0700 Subject: [PATCH 51/74] Feature/complete group logic (#945) * fix group logic * up --- py/cli/commands/management.py | 95 +++++---- py/core/base/abstractions/document.py | 2 +- .../base/api/models/management/responses.py | 1 + .../examples/scripts/advanced_kg_cookbook.py | 2 +- py/core/examples/scripts/run_auth_workflow.py | 1 - .../examples/scripts/run_group_workflow.py | 164 ++++++++++++++++ py/core/main/api/routes/auth/base.py | 18 +- py/core/main/api/routes/management/base.py | 57 ++++-- py/core/main/api/routes/retrieval/base.py | 14 +- py/core/main/app.py | 12 +- py/core/main/engine.py | 22 ++- py/core/main/services/auth_service.py | 4 + py/core/main/services/management_service.py | 81 ++++---- py/core/main/services/retrieval_service.py | 1 - py/core/parsers/media/audio_parser.py | 2 +- py/core/parsers/media/img_parser.py | 2 +- py/core/parsers/media/openai_helpers.py | 4 +- py/core/providers/database/document.py | 31 +-- py/core/providers/database/group.py | 140 +++++++++++++- py/core/providers/database/user.py | 48 ++++- py/core/providers/database/vecs/collection.py | 42 ++-- py/core/providers/database/vector.py | 182 +++++++++++++++--- py/core/providers/parsing/r2r_parsing.py | 1 + py/sdk/auth.py | 20 +- py/sdk/client.py | 2 +- py/sdk/management.py | 110 +++++++++-- py/tests/test_client.py | 6 +- py/tests/test_groups.py | 12 +- 28 files changed, 844 insertions(+), 232 deletions(-) create mode 100644 py/core/examples/scripts/run_group_workflow.py diff --git a/py/cli/commands/management.py b/py/cli/commands/management.py index ff3bf0861..114943c3d 100644 --- a/py/cli/commands/management.py +++ b/py/cli/commands/management.py @@ -35,13 +35,23 @@ def app_settings(client): @cli.command() @click.option("--user-ids", multiple=True, help="User IDs to overview") +@click.option( + "--offset", + default=None, + help="The offset to start from. Defaults to 0.", +) +@click.option( + "--limit", + default=None, + help="The maximum number of nodes to return. Defaults to 100.", +) @click.pass_obj -def users_overview(client, user_ids): +def users_overview(client, user_ids, offset, limit): """Get an overview of users.""" user_ids = list(user_ids) if user_ids else None with timer(): - response = client.users_overview(user_ids) + response = client.users_overview(user_ids, offset, limit) if 'results' in response: click.echo("\nUser Overview:") @@ -77,13 +87,23 @@ def delete(client, filter): @cli.command() @click.option("--document-ids", multiple=True, help="Document IDs to overview") +@click.option( + "--offset", + default=None, + help="The offset to start from. Defaults to 0.", +) +@click.option( + "--limit", + default=None, + help="The maximum number of nodes to return. Defaults to 100.", +) @click.pass_obj -def documents_overview(client, document_ids): +def documents_overview(client, document_ids, offset, limit): """Get an overview of documents.""" document_ids = list(document_ids) if document_ids else None with timer(): - response = client.documents_overview(document_ids) + response = client.documents_overview(document_ids, offset, limit) for document in response["results"]: click.echo(document) @@ -91,11 +111,21 @@ def documents_overview(client, document_ids): @cli.command() @click.option("--document-id", help="Document ID to retrieve chunks for") +@click.option( + "--offset", + default=None, + help="The offset to start from. Defaults to 0.", +) +@click.option( + "--limit", + default=None, + help="The maximum number of nodes to return. Defaults to 100.", +) @click.pass_obj -def document_chunks(client, document_id): +def document_chunks(client, document_id, offset, limit): """Get chunks of a specific document.""" with timer(): - response = client.document_chunks(document_id) + response = client.document_chunks(document_id, offset, limit) chunks = response.get("results", []) click.echo(f"\nNumber of chunks: {len(chunks)}") @@ -107,57 +137,20 @@ def document_chunks(client, document_id): @cli.command() +@click.option( + "--offset", + default=None, + help="The offset to start from. Defaults to 0.", +) @click.option( "--limit", default=None, help="The maximum number of nodes to return. Defaults to 100.", ) @click.pass_obj -def inspect_knowledge_graph(client, limit): +def inspect_knowledge_graph(client, offset, limit): """Inspect the knowledge graph.""" with timer(): - response = client.inspect_knowledge_graph(limit) - - click.echo(response) - - -## TODO: Implement groups_overview - - -## TODO: Implement create_group - - -## TODO: Implement get_group - - -## TODO: Implement update_group - - -## TODO: Implement delete_group - - -## TODO: Implement list_groups - - -## TODO: Implement add_user_to_group - - -## TODO: Implement remove_user_from_group - - -## TODO: Implement get_users_in_group - - -## TODO: Implement get_groups_for_user - - -## TODO: Implement assign_document_to_group - - -## TODO: Implement remove_document_from_group - - -## TODO: Implement get_document_groups - + response = client.inspect_knowledge_graph(offset, limit) -## TODO: Implement get_documents_in_group + click.echo(response) \ No newline at end of file diff --git a/py/core/base/abstractions/document.py b/py/core/base/abstractions/document.py index 3b9b936c1..12cf53b42 100644 --- a/py/core/base/abstractions/document.py +++ b/py/core/base/abstractions/document.py @@ -26,10 +26,10 @@ class DocumentStatus(str, Enum): class DocumentType(str, Enum): """Types of documents that can be stored.""" - CSV = "csv" DOCX = "docx" HTML = "html" + HTM = "htm" JSON = "json" MD = "md" PDF = "pdf" diff --git a/py/core/base/api/models/management/responses.py b/py/core/base/api/models/management/responses.py index 64636c6ee..ffc3d5dc2 100644 --- a/py/core/base/api/models/management/responses.py +++ b/py/core/base/api/models/management/responses.py @@ -61,6 +61,7 @@ class DocumentOverviewResponse(BaseModel): updated_at: datetime status: str version: str + group_ids: list[UUID] metadata: Dict[str, Any] diff --git a/py/core/examples/scripts/advanced_kg_cookbook.py b/py/core/examples/scripts/advanced_kg_cookbook.py index 8eaa2ea73..f69d0a486 100644 --- a/py/core/examples/scripts/advanced_kg_cookbook.py +++ b/py/core/examples/scripts/advanced_kg_cookbook.py @@ -155,7 +155,7 @@ def main( print("Inspecting Knowledge Graph") print( - client.inspect_knowledge_graph(1000, print_descriptions=True)[ + client.inspect_knowledge_graph(0, 1000, print_descriptions=True)[ "results" ] ) diff --git a/py/core/examples/scripts/run_auth_workflow.py b/py/core/examples/scripts/run_auth_workflow.py index ad4837fc6..1729a7679 100644 --- a/py/core/examples/scripts/run_auth_workflow.py +++ b/py/core/examples/scripts/run_auth_workflow.py @@ -1,4 +1,3 @@ -# TODO: need to import this from the package, not from the local directory from r2r import R2RClient if __name__ == "__main__": diff --git a/py/core/examples/scripts/run_group_workflow.py b/py/core/examples/scripts/run_group_workflow.py new file mode 100644 index 000000000..38353ef20 --- /dev/null +++ b/py/core/examples/scripts/run_group_workflow.py @@ -0,0 +1,164 @@ +import os +from r2r import R2RClient + + +if __name__ == "__main__": + # Initialize the R2R client + client = R2RClient("http://localhost:8000") # Replace with your R2R deployment URL + + # Admin login + print("Logging in as admin...") + login_result = client.login("admin@example.com", "change_me_immediately") + print("Admin login result:", login_result) + + # Create two groups + print("\nCreating two groups...") + group1_result = client.create_group("TestGroup1", "A test group for document access") + group2_result = client.create_group("TestGroup2", "Another test group") + print("Group1 creation result:", group1_result) + print("Group2 creation result:", group2_result) + group1_id = group1_result['results']['group_id'] + group2_id = group2_result['results']['group_id'] + + # Get groups overview + print("\nGetting groups overview...") + groups_overview = client.groups_overview() + print("Groups overview:", groups_overview) + + # Get specific group + print("\nGetting specific group...") + group1_details = client.get_group(group1_id) + print("Group1 details:", group1_details) + + # List all groups + print("\nListing all groups...") + groups_list = client.list_groups() + print("Groups list:", groups_list) + + # Update a group + print("\nUpdating Group1...") + update_result = client.update_group(group1_id, name="UpdatedTestGroup1", description="Updated description") + print("Group update result:", update_result) + + # Ingest two documents + print("\nIngesting two documents...") + script_path = os.path.dirname(__file__) + sample_file1 = os.path.join(script_path, "core", "examples", "data", "aristotle_v2.txt") + sample_file2 = os.path.join(script_path, "core", "examples", "data", "aristotle.txt") + ingestion_result1 = client.ingest_files([sample_file1]) + ingestion_result2 = client.ingest_files([sample_file2]) + print("Document1 ingestion result:", ingestion_result1) + print("Document2 ingestion result:", ingestion_result2) + document1_id = ingestion_result1['results']['processed_documents'][0]['id'] + document2_id = ingestion_result2['results']['processed_documents'][0]['id'] + + # Assign documents to groups + print("\nAssigning documents to groups...") + assign_result1 = client.assign_document_to_group(document1_id, group1_id) + assign_result2 = client.assign_document_to_group(document2_id, group2_id) + print("Document1 assignment result:", assign_result1) + print("Document2 assignment result:", assign_result2) + + # document1_id = "c3291abf-8a4e-5d9d-80fd-232ef6fd8526" + # Get document groups + print("\nGetting groups for Document1...") + doc1_groups = client.document_groups(document1_id) + print("Document1 groups:", doc1_groups) + + # Create three test users + print("\nCreating three test users...") + user1_result = client.register("user1@test.com", "password123") + user2_result = client.register("user2@test.com", "password123") + user3_result = client.register("user3@test.com", "password123") + print("User1 creation result:", user1_result) + print("User2 creation result:", user2_result) + print("User3 creation result:", user3_result) + + # Add users to groups + print("\nAdding users to groups...") + add_user1_result = client.add_user_to_group(user1_result['results']['id'], group1_id) + add_user2_result = client.add_user_to_group(user2_result['results']['id'], group2_id) + add_user3_result1 = client.add_user_to_group(user3_result['results']['id'], group1_id) + add_user3_result2 = client.add_user_to_group(user3_result['results']['id'], group2_id) + print("Add user1 to group1 result:", add_user1_result) + print("Add user2 to group2 result:", add_user2_result) + print("Add user3 to group1 result:", add_user3_result1) + print("Add user3 to group2 result:", add_user3_result2) + + # Get users in a group + print("\nGetting users in Group1...") + users_in_group1 = client.user_groups(group1_id) + print("Users in Group1:", users_in_group1) + + # Get groups for a user + print("\nGetting groups for User3...") + user3_groups = client.user_groups(user3_result['results']['id']) + print("User3 groups:", user3_groups) + + # Get documents in a group + print("\nGetting documents in Group1...") + docs_in_group1 = client.documents_in_group(group1_id) + print("Documents in Group1:", docs_in_group1) + + # Remove user from group + print("\nRemoving User3 from Group1...") + remove_user_result = client.remove_user_from_group(user3_result['results']['id'], group1_id) + print("Remove user result:", remove_user_result) + + # Remove document from group + print("\nRemoving Document1 from Group1...") + remove_doc_result = client.remove_document_from_group(document1_id, group1_id) + print("Remove document result:", remove_doc_result) + + # Logout admin + print("\nLogging out admin...") + client.logout() + + # Login as user1 + print("\nLogging in as user1...") + client.login("user1@test.com", "password123") + + # Search for documents (should see document1 but not document2) + print("\nUser1 searching for documents...") + search_result_user1 = client.search("philosophy", {"selected_group_ids": [group1_id]}) + print("User1 search result:", search_result_user1) + + # Logout user1 + print("\nLogging out user1...") + client.logout() + + # Login as user3 + print("\nLogging in as user3...") + client.login("user3@test.com", "password123") + + # Search for documents (should see only document2 after removal from Group1) + print("\nUser3 searching for documents...") + try: + search_result_user3 = client.search("philosophy", {"selected_group_ids": [group1_id, group2_id]}) + except Exception as e: + print("User3 search result error:", e) + search_result_user3 = client.search("philosophy", {"selected_group_ids": [group2_id]}) + + print("User3 search result:", search_result_user3) + + # Logout user3 + print("\nLogging out user3...") + client.logout() + + # Clean up + print("\nCleaning up...") + # Login as admin again + client.login("admin@example.com", "change_me_immediately") + + # Delete the groups + print("Deleting the groups...") + client.delete_group(group1_id) + client.delete_group(group2_id) + + # Logout admin + print("\nLogging out admin...") + client.logout() + + print("\nWorkflow completed.") + + \ No newline at end of file diff --git a/py/core/main/api/routes/auth/base.py b/py/core/main/api/routes/auth/base.py index 49871643c..94a85dab2 100644 --- a/py/core/main/api/routes/auth/base.py +++ b/py/core/main/api/routes/auth/base.py @@ -1,5 +1,5 @@ import uuid -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Optional from core.base.api.models.auth.responses import ( GenericMessageResponse, @@ -7,7 +7,7 @@ WrappedTokenResponse, WrappedUserResponse, ) -from fastapi import Body, Depends +from fastapi import Path, Body, Depends from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm from pydantic import EmailStr @@ -200,14 +200,18 @@ async def reset_password_app( return GenericMessageResponse(message=result["message"]) @self.router.delete( - "/user", response_model=WrappedGenericMessageResponse + "/user/{user_id}", response_model=WrappedGenericMessageResponse ) @self.base_endpoint async def delete_user_app( - user_id: str = Body(..., description="ID of the user to delete"), - password: str | None = Body( + user_id: str = Path(..., description="ID of the user to delete"), + password: Optional[str] = Body( None, description="User's current password" ), + delete_vector_data: Optional[bool] = Body( + False, + description="Whether to delete the user's vector data", + ), auth_user=Depends(self.engine.providers.auth.auth_wrapper), ): """ @@ -218,6 +222,8 @@ async def delete_user_app( """ if auth_user.id != user_id and not auth_user.is_superuser: raise Exception("User ID does not match authenticated user") + if not auth_user.is_superuser and not password: + raise Exception("Password is required for non-superusers") user_uuid = uuid.UUID(user_id) - result = await self.engine.adelete_user(user_uuid, password) + result = await self.engine.adelete_user(user_uuid, password, delete_vector_data) return GenericMessageResponse(message=result["message"]) diff --git a/py/core/main/api/routes/management/base.py b/py/core/main/api/routes/management/base.py index 62b312cd1..05623d7b9 100644 --- a/py/core/main/api/routes/management/base.py +++ b/py/core/main/api/routes/management/base.py @@ -162,6 +162,8 @@ async def score_completion( @self.base_endpoint async def users_overview_app( user_ids: Optional[list[str]] = Query([]), + offset: int = Query(0, ge=0), + limit: int = Query(100, ge=1, le=1000), auth_user=Depends(self.engine.providers.auth.auth_wrapper), ) -> WrappedUserOverviewResponse: if not auth_user.is_superuser: @@ -174,7 +176,7 @@ async def users_overview_app( [UUID(user_id) for user_id in user_ids] if user_ids else None ) - return await self.engine.ausers_overview(user_ids=user_uuids) + return await self.engine.ausers_overview(user_ids=user_uuids, offset=offset, limit=limit) @self.router.delete("/delete", status_code=204) @self.base_endpoint @@ -189,6 +191,8 @@ async def delete_app( @self.base_endpoint async def documents_overview_app( document_ids: list[str] = Query([]), + offset: int = Query(0, ge=0), + limit: int = Query(100, ge=1, le=1000), auth_user=Depends(self.engine.providers.auth.auth_wrapper), ) -> WrappedDocumentOverviewResponse: request_user_ids = ( @@ -201,6 +205,8 @@ async def documents_overview_app( user_ids=request_user_ids, group_ids=auth_user.group_ids, document_ids=document_uuids, + offset=offset, + limit=limit, ) return result @@ -208,10 +214,12 @@ async def documents_overview_app( @self.base_endpoint async def document_chunks_app( document_id: str = Path(...), + offset: Optional[int] = Query(0, ge=0), + limit: Optional[int] = Query(100, ge=0), auth_user=Depends(self.engine.providers.auth.auth_wrapper), ) -> WrappedDocumentChunkResponse: document_uuid = UUID(document_id) - chunks = await self.engine.adocument_chunks(document_uuid) + chunks = await self.engine.adocument_chunks(document_uuid, offset, limit) if not chunks: raise R2RException( @@ -232,6 +240,7 @@ async def document_chunks_app( @self.router.get("/inspect_knowledge_graph") @self.base_endpoint async def inspect_knowledge_graph( + offset: int = 0, limit: int = 100, print_descriptions: bool = False, auth_user=Depends(self.engine.providers.auth.auth_wrapper), @@ -242,15 +251,15 @@ async def inspect_knowledge_graph( 403, ) return await self.engine.ainspect_knowledge_graph( - limit=limit, print_descriptions=print_descriptions + offset=offset, limit=limit, print_descriptions=print_descriptions ) @self.router.get("/groups_overview") @self.base_endpoint async def groups_overview_app( group_ids: Optional[list[str]] = Query(None), - limit: Optional[int] = Query(100, ge=1, le=1000), offset: Optional[int] = Query(0, ge=0), + limit: Optional[int] = Query(100, ge=1, le=1000), auth_user=Depends(self.engine.providers.auth.auth_wrapper), ) -> WrappedGroupOverviewResponse: if not auth_user.is_superuser: @@ -265,7 +274,7 @@ async def groups_overview_app( else None ) return await self.engine.agroups_overview( - group_ids=group_uuids, limit=limit, offset=offset + group_ids=group_uuids, offset=offset, limit=limit ) @self.router.post("/create_group") @@ -317,7 +326,7 @@ async def update_group_app( async def delete_group_app( group_id: str = Path(..., description="Group ID"), auth_user=Depends(self.engine.providers.auth.auth_wrapper), - ) -> WrappedGroupResponse: + ): if not auth_user.is_superuser: raise R2RException("Only a superuser can delete groups.", 403) group_uuid = UUID(group_id) @@ -362,16 +371,17 @@ async def remove_user_from_group_app( user_id: str = Body(..., description="User ID"), group_id: str = Body(..., description="Group ID"), auth_user=Depends(self.engine.providers.auth.auth_wrapper), - ) -> WrappedGroupResponse: + ): if not auth_user.is_superuser: raise R2RException( "Only a superuser can remove users from groups.", 403 ) user_uuid = UUID(user_id) group_uuid = UUID(group_id) - return await self.engine.aremove_user_from_group( + await self.engine.aremove_user_from_group( user_uuid, group_uuid ) + return None # TODO - Proivde response model @self.router.get("/get_users_in_group/{group_id}") @@ -395,10 +405,14 @@ async def get_users_in_group_app( limit=min(max(limit, 1), 1000), ) - @self.router.get("/get_groups_for_user/{user_id}") + @self.router.get("/user_groups/{user_id}") @self.base_endpoint async def get_groups_for_user_app( user_id: str = Path(..., description="User ID"), + offset: int = Query(0, ge=0, description="Pagination offset"), + limit: int = Query( + 100, ge=1, le=1000, description="Pagination limit" + ), auth_user=Depends(self.engine.providers.auth.auth_wrapper), ): if not auth_user.is_superuser: @@ -406,7 +420,7 @@ async def get_groups_for_user_app( "Only a superuser can get groups for a user.", 403 ) user_uuid = UUID(user_id) - return await self.engine.aget_groups_for_user(user_uuid) + return await self.engine.aget_groups_for_user(user_uuid, offset, limit) @self.router.post("/assign_document_to_group") @self.base_endpoint @@ -414,7 +428,7 @@ async def assign_document_to_group_app( document_id: str = Body(..., description="Document ID"), group_id: str = Body(..., description="Group ID"), auth_user=Depends(self.engine.providers.auth.auth_wrapper), - ) -> WrappedGroupResponse: + ): if not auth_user.is_superuser: raise R2RException( "Only a superuser can assign documents to groups.", 403 @@ -431,28 +445,35 @@ async def remove_document_from_group_app( document_id: str = Body(..., description="Document ID"), group_id: str = Body(..., description="Group ID"), auth_user=Depends(self.engine.providers.auth.auth_wrapper), - ) -> WrappedGroupResponse: + ) -> None: if not auth_user.is_superuser: raise R2RException( "Only a superuser can remove documents from groups.", 403 ) document_uuid = UUID(document_id) group_uuid = UUID(group_id) - return await self.engine.aremove_document_from_group( + await self.engine.aremove_document_from_group( document_uuid, group_uuid ) + return None - @self.router.get("/get_document_groups/{document_id}") + @self.router.get("/document_groups/{document_id}") @self.base_endpoint - async def get_document_groups_app( + async def document_groups_app( document_id: str = Path(..., description="Document ID"), + offset: int = Query(0, ge=0), + limit: int = Query(100, ge=1, le=1000), auth_user=Depends(self.engine.providers.auth.auth_wrapper), ) -> WrappedGroupListResponse: - return await self.engine.aget_document_groups(document_id) + if not auth_user.is_superuser: + raise R2RException( + "Only a superuser can get the groups belonging to a document.", 403 + ) + return await self.engine.adocument_groups(document_id, offset, limit) @self.router.get("/group/{group_id}/documents") @self.base_endpoint - async def get_documents_in_group_app( + async def documents_in_group_app( group_id: str = Path(..., description="Group ID"), offset: int = Query(0, ge=0), limit: int = Query(100, ge=1, le=1000), @@ -463,6 +484,6 @@ async def get_documents_in_group_app( "Only a superuser can get documents in a group.", 403 ) group_uuid = UUID(group_id) - return await self.engine.aget_documents_in_group( + return await self.engine.adocuments_in_group( group_uuid, offset, limit ) diff --git a/py/core/main/api/routes/retrieval/base.py b/py/core/main/api/routes/retrieval/base.py index 4c801a4c0..b65c3f776 100644 --- a/py/core/main/api/routes/retrieval/base.py +++ b/py/core/main/api/routes/retrieval/base.py @@ -72,6 +72,13 @@ async def search_app( Allowed operators include `eq`, `neq`, `gt`, `gte`, `lt`, `lte`, `like`, `ilike`, `in`, and `nin`. """ + print('auth_user = ', auth_user) + print('initial vector_search_settings = ', vector_search_settings) + + print(f"Received query: {query}") + print(f"Received vector_search_settings: {vector_search_settings}") + print(f"Received kg_search_settings: {kg_search_settings}") + print(f"Auth user: {auth_user}") user_groups = set(auth_user.group_ids) selected_groups = set(vector_search_settings.selected_group_ids) @@ -81,10 +88,12 @@ async def search_app( "User does not have access to the specified group(s): " f"{selected_groups - allowed_groups}" ) + print('initial vector_search_settings filters = ', vector_search_settings.filters) filters = { "$or": [ - {"user_id": str(auth_user.id)}, + {"user_id": {"$eq": str(auth_user.id)}}, + # {"group_ids": {"$any": list([str(ele) for ele in allowed_groups])}}, {"group_ids": {"$overlap": list(allowed_groups)}}, ] } @@ -92,7 +101,8 @@ async def search_app( filters = {"$and": [filters, vector_search_settings.filters]} vector_search_settings.filters = filters - + print('final vector_search_settings = ', vector_search_settings) + print('final vector_search_settings filters = ', vector_search_settings.filters) results = await self.engine.asearch( query=query, vector_search_settings=vector_search_settings, diff --git a/py/core/main/app.py b/py/core/main/app.py index 8276c8e7e..54d60f536 100644 --- a/py/core/main/app.py +++ b/py/core/main/app.py @@ -42,13 +42,13 @@ def _setup_routes(self): ) # Include routers in the app - self.app.include_router(ingestion_router, prefix="/v1") - self.app.include_router(management_router, prefix="/v1") - self.app.include_router(retrieval_router, prefix="/v1") - self.app.include_router(auth_router, prefix="/v1") - self.app.include_router(restructure_router, prefix="/v1") + self.app.include_router(ingestion_router, prefix="/v2") + self.app.include_router(management_router, prefix="/v2") + self.app.include_router(retrieval_router, prefix="/v2") + self.app.include_router(auth_router, prefix="/v2") + self.app.include_router(restructure_router, prefix="/v2") - @self.app.router.get("/v1/openapi_spec") + @self.app.router.get("/v2/openapi_spec") async def openapi_spec(): from fastapi.openapi.utils import get_openapi diff --git a/py/core/main/engine.py b/py/core/main/engine.py index 3fbb6f1e0..9a759a02b 100644 --- a/py/core/main/engine.py +++ b/py/core/main/engine.py @@ -251,12 +251,30 @@ async def aget_groups_for_user(self, *args, **kwargs): *args, **kwargs ) + @syncable + async def aassign_document_to_group(self, *args, **kwargs): + return await self.management_service.aassign_document_to_group( + *args, **kwargs + ) + @syncable async def agroups_overview(self, *args, **kwargs): return await self.management_service.agroups_overview(*args, **kwargs) @syncable - async def aget_documents_in_group(self, *args, **kwargs): - return await self.management_service.aget_documents_in_group( + async def adocuments_in_group(self, *args, **kwargs): + return await self.management_service.adocuments_in_group( + *args, **kwargs + ) + + @syncable + async def adocument_groups(self, *args, **kwargs): + return await self.management_service.adocument_groups( *args, **kwargs ) + + @syncable + async def aremove_document_from_group(self, *args, **kwargs): + return await self.management_service.aremove_document_from_group( + *args, **kwargs + ) \ No newline at end of file diff --git a/py/core/main/services/auth_service.py b/py/core/main/services/auth_service.py index 5fd0fb9d7..84b318729 100644 --- a/py/core/main/services/auth_service.py +++ b/py/core/main/services/auth_service.py @@ -133,6 +133,7 @@ async def delete_user( self, user_id: UUID, password: Optional[str] = None, + delete_vector_data: bool = False, is_superuser: bool = False, ) -> dict[str, str]: user = self.providers.database.relational.get_user_by_id(user_id) @@ -146,6 +147,9 @@ async def delete_user( ): raise R2RException(status_code=400, message="Incorrect password") self.providers.database.relational.delete_user(user_id) + if (delete_vector_data): + self.providers.database.vector.delete_user(user_id) + return {"message": f"User account {user_id} deleted successfully."} @telemetry_event("CleanExpiredBlacklistedTokens") diff --git a/py/core/main/services/management_service.py b/py/core/main/services/management_service.py index 778f337df..5a85d6f45 100644 --- a/py/core/main/services/management_service.py +++ b/py/core/main/services/management_service.py @@ -240,11 +240,13 @@ async def ascore_completion( async def ausers_overview( self, user_ids: Optional[list[UUID]] = None, + offset: int = 0, + limit: int = 100, *args, **kwargs, ): return self.providers.database.relational.get_users_overview( - [str(ele) for ele in user_ids] if user_ids else None + [str(ele) for ele in user_ids] if user_ids else None, offset=offset, limit=limit ) @telemetry_event("Delete") @@ -290,6 +292,8 @@ async def adocuments_overview( user_ids: Optional[list[UUID]] = None, group_ids: Optional[list[UUID]] = None, document_ids: Optional[list[UUID]] = None, + offset: Optional[int] = 0, + limit: Optional[int] = 100, *args: Any, **kwargs: Any, ): @@ -297,32 +301,39 @@ async def adocuments_overview( filter_document_ids=document_ids, filter_user_ids=user_ids, filter_group_ids=group_ids, + offset=offset, + limit=limit, ) @telemetry_event("DocumentChunks") async def document_chunks( self, document_id: UUID, + offset: int = 0, + limit: int = 100, *args, **kwargs, ): - return self.providers.database.vector.get_document_chunks(document_id) + return self.providers.database.vector.get_document_chunks(document_id, offset=offset, limit=limit) @telemetry_event("UsersOverview") async def users_overview( self, user_ids: Optional[list[UUID]], + offset: int = 0, + limit: int = 100, *args, **kwargs, ): return self.providers.database.relational.get_users_overview( - [str(ele) for ele in user_ids] + [str(ele) for ele in user_ids], offset=offset, limit=limit ) @telemetry_event("InspectKnowledgeGraph") async def inspect_knowledge_graph( self, - limit=10000, + offset: int = 0, + limit=1000, print_descriptions: bool = False, *args: Any, **kwargs: Any, @@ -335,6 +346,7 @@ async def inspect_knowledge_graph( rel_query = f""" MATCH (n1)-[r]->(n2) return n1.name AS subject, n1.description AS subject_description, n2.name AS object, n2.description AS object_description, type(r) AS relation, r.description AS relation_description + SKIP {offset} LIMIT {limit} """ @@ -408,33 +420,30 @@ async def aassign_document_to_group( self, document_id: str, group_id: UUID ): - if self.providers.database.vector.assign_document_to_group( + self.providers.database.relational.assign_document_to_group( document_id, group_id - ): - return {"message": "Document assigned to group successfully"} - else: - raise R2RException( - status_code=404, - message="Document not found or assignment failed", - ) + ) + self.providers.database.vector.assign_document_to_group( + document_id, group_id + ) + return {"message": "Document assigned to group successfully"} @telemetry_event("RemoveDocumentFromGroup") async def aremove_document_from_group( self, document_id: str, group_id: UUID ): - if self.providers.database.vector.remove_document_from_group( + self.providers.database.relational.remove_document_from_group( document_id, group_id - ): - return {"message": "Document removed from group successfully"} - else: - raise R2RException( - status_code=404, message="Document not found or removal failed" - ) + ) + self.providers.database.vector.remove_document_from_group( + document_id, group_id + ) + return {"message": "Document removed from group successfully"} - @telemetry_event("GetDocumentGroups") - async def aget_document_groups(self, document_id: str): - group_ids = self.providers.database.relational.get_document_groups( - document_id + @telemetry_event("DocumentGroups") + async def adocument_groups(self, document_id: str, offset: int = 0, limit: int = 100): + group_ids = self.providers.database.relational.document_groups( + document_id, offset=offset, limit=limit ) return {"group_ids": [str(group_id) for group_id in group_ids]} @@ -557,8 +566,10 @@ async def aupdate_group( @telemetry_event("DeleteGroup") async def adelete_group(self, group_id: UUID) -> bool: - return self.providers.database.relational.delete_group(group_id) - + self.providers.database.relational.delete_group(group_id) + self.providers.database.vector.delete_group(group_id) + return True + @telemetry_event("ListGroups") async def alist_groups( self, offset: int = 0, limit: int = 100 @@ -586,12 +597,12 @@ async def aget_users_in_group( self, group_id: UUID, offset: int = 0, limit: int = 100 ) -> list[dict]: return self.providers.database.relational.get_users_in_group( - group_id, offset, limit + group_id, offset=offset, limit=limit ) @telemetry_event("GetGroupsForUser") - async def aget_groups_for_user(self, user_id: UUID) -> list[dict]: - return self.providers.database.relational.get_groups_for_user(user_id) + async def aget_groups_for_user(self, user_id: UUID, offset: int = 0, limit: int = 100) -> list[dict]: + return self.providers.database.relational.get_groups_for_user(user_id, offset, limit) @telemetry_event("GroupsOverview") async def agroups_overview( @@ -604,14 +615,18 @@ async def agroups_overview( ): return self.providers.database.relational.get_groups_overview( [str(ele) for ele in group_ids] if group_ids else None, - offset, - limit, + offset=offset, + limit=limit, ) @telemetry_event("GetDocumentsInGroup") - async def aget_documents_in_group( + async def adocuments_in_group( self, group_id: UUID, offset: int = 0, limit: int = 100 ) -> list[dict]: - return self.providers.database.relational.get_documents_in_group( - group_id, offset, limit + return self.providers.database.relational.documents_in_group( + group_id, offset=offset, limit=limit ) + + @telemetry_event("DocumentGroups") + async def adocument_groups(self, document_id: str, offset: int = 0, limit: int = 100) -> list[str]: + return self.providers.database.relational.document_groups(document_id, offset, limit) \ No newline at end of file diff --git a/py/core/main/services/retrieval_service.py b/py/core/main/services/retrieval_service.py index d9e72bc8a..6e570041f 100644 --- a/py/core/main/services/retrieval_service.py +++ b/py/core/main/services/retrieval_service.py @@ -54,7 +54,6 @@ async def search( query: str, vector_search_settings: VectorSearchSettings = VectorSearchSettings(), kg_search_settings: KGSearchSettings = KGSearchSettings(), - user: Optional[UserResponse] = None, *args, **kwargs, ) -> SearchResponse: diff --git a/py/core/parsers/media/audio_parser.py b/py/core/parsers/media/audio_parser.py index 000857b99..81e0ef4f3 100644 --- a/py/core/parsers/media/audio_parser.py +++ b/py/core/parsers/media/audio_parser.py @@ -9,7 +9,7 @@ class AudioParser(AsyncParser[bytes]): """A parser for audio data.""" def __init__( - self, api_base: str = "https://api.openai.com/v1/audio/transcriptions" + self, api_base: str = "https://api.openai.com/v2/audio/transcriptions" ): self.api_base = api_base self.openai_api_key = os.environ.get("OPENAI_API_KEY") diff --git a/py/core/parsers/media/img_parser.py b/py/core/parsers/media/img_parser.py index 67cc80e8e..c679b2772 100644 --- a/py/core/parsers/media/img_parser.py +++ b/py/core/parsers/media/img_parser.py @@ -13,7 +13,7 @@ def __init__( self, model: str = "gpt-4o", max_tokens: int = 2_048, - api_base: str = "https://api.openai.com/v1/chat/completions", + api_base: str = "https://api.openai.com/v2/chat/completions", ): self.model = model self.max_tokens = max_tokens diff --git a/py/core/parsers/media/openai_helpers.py b/py/core/parsers/media/openai_helpers.py index 583a685e9..910261cca 100644 --- a/py/core/parsers/media/openai_helpers.py +++ b/py/core/parsers/media/openai_helpers.py @@ -8,7 +8,7 @@ def process_frame_with_openai( api_key: str, model: str = "gpt-4o", max_tokens: int = 2_048, - api_base: str = "https://api.openai.com/v1/chat/completions", + api_base: str = "https://api.openai.com/v2/chat/completions", ) -> str: headers = { "Content-Type": "application/json", @@ -43,7 +43,7 @@ def process_frame_with_openai( def process_audio_with_openai( audio_file, api_key: str, - audio_api_base: str = "https://api.openai.com/v1/audio/transcriptions", + audio_api_base: str = "https://api.openai.com/v2/audio/transcriptions", ) -> str: headers = {"Authorization": f"Bearer {api_key}"} diff --git a/py/core/providers/database/document.py b/py/core/providers/database/document.py index 0af205ec3..f14915c1f 100644 --- a/py/core/providers/database/document.py +++ b/py/core/providers/database/document.py @@ -1,7 +1,8 @@ from typing import Optional from uuid import UUID -from core.base import DocumentInfo, DocumentStatus, DocumentType +from core.base import DocumentInfo, DocumentStatus, DocumentType, R2RException +from core.base.api.models.management.responses import GroupResponse from .base import DatabaseMixin @@ -69,9 +70,11 @@ def get_documents_overview( filter_user_ids: Optional[list[UUID]] = None, filter_document_ids: Optional[list[UUID]] = None, filter_group_ids: Optional[list[UUID]] = None, + offset: int = 0, + limit: int = 100, ): conditions = [] - params = {} + params = {"offset": offset, "limit": limit} if filter_document_ids: conditions.append("document_id = ANY(:document_ids)") @@ -92,8 +95,15 @@ def get_documents_overview( if conditions: query += " WHERE " + " AND ".join(conditions) + query += """ + ORDER BY created_at DESC + OFFSET :offset + LIMIT :limit + """ + results = self.execute_query(query, params).fetchall() - return [ + print('results = ', results) + documents = [ DocumentInfo( id=row[0], group_ids=row[1], @@ -110,15 +120,12 @@ def get_documents_overview( for row in results ] - def get_document_groups(self, document_id: str) -> list[str]: - query = f""" - SELECT group_ids + # Get total count for pagination metadata + count_query = f""" + SELECT COUNT(*) FROM {self._get_table_name('document_info')} - WHERE document_id = :document_id """ - params = {"document_id": document_id} - result = self.execute_query(query, params).fetchone() + if conditions: + count_query += " WHERE " + " AND ".join(conditions) - if result and result[0]: - return [str(group_id) for group_id in result[0]] - return [] + return documents \ No newline at end of file diff --git a/py/core/providers/database/group.py b/py/core/providers/database/group.py index ab3cb811e..4d4ea9972 100644 --- a/py/core/providers/database/group.py +++ b/py/core/providers/database/group.py @@ -105,17 +105,34 @@ def update_group( created_at=result[3], updated_at=result[4], ) - + def delete_group(self, group_id: UUID) -> None: - query = f""" + # Remove group_id from users + user_update_query = f""" + UPDATE {self._get_table_name('users')} + SET group_ids = array_remove(group_ids, :group_id) + WHERE :group_id = ANY(group_ids) + """ + self.execute_query(user_update_query, {"group_id": group_id}) + + # Remove group_id from documents in the relational database + doc_update_query = f""" + UPDATE {self._get_table_name('document_info')} + SET group_ids = array_remove(group_ids, :group_id) + WHERE :group_id = ANY(group_ids) + """ + self.execute_query(doc_update_query, {"group_id": group_id}) + + # Delete the group + delete_query = f""" DELETE FROM {self._get_table_name('groups')} WHERE group_id = :group_id RETURNING group_id """ - result = self.execute_query(query, {"group_id": group_id}).fetchone() + result = self.execute_query(delete_query, {"group_id": group_id}).fetchone() + if not result: raise R2RException(status_code=404, message="Group not found") - return None def list_groups( self, offset: int = 0, limit: int = 100 @@ -258,7 +275,7 @@ def get_users_in_group( for row in results ] - def get_documents_in_group( + def documents_in_group( self, group_id: UUID, offset: int = 0, limit: int = 100 ) -> list[DocumentInfo]: """ @@ -376,3 +393,116 @@ def get_groups_for_user( ) for row in results ] + + def assign_document_to_group(self, document_id: UUID, group_id: UUID) -> None: + """ + Assign a document to a group. + + Args: + document_id (UUID): The ID of the document to assign. + group_id (UUID): The ID of the group to assign the document to. + + Raises: + R2RException: If the group doesn't exist, if the document is not found, + or if there's a database error. + """ + try: + if not self.group_exists(group_id): + raise R2RException(status_code=404, message="Group not found") + + # First, check if the document exists + document_check_query = f""" + SELECT 1 FROM {self._get_table_name('document_info')} + WHERE document_id = :document_id + """ + document_exists = self.execute_query( + document_check_query, {"document_id": document_id} + ).fetchone() + + if not document_exists: + raise R2RException(status_code=404, message="Document not found") + + # If document exists, proceed with the assignment + assign_query = f""" + UPDATE {self._get_table_name('document_info')} + SET group_ids = array_append(group_ids, :group_id) + WHERE document_id = :document_id AND NOT (:group_id = ANY(group_ids)) + RETURNING document_id + """ + result = self.execute_query( + assign_query, {"document_id": document_id, "group_id": group_id} + ).fetchone() + + if not result: + # Document exists but was already assigned to the group + raise R2RException( + status_code=409, + message="Document is already assigned to the group" + ) + + except R2RException: + # Re-raise R2RExceptions as they are already handled + raise + except Exception as e: + raise R2RException( + status_code=500, + message="An error occurred while assigning the document to the group" + ) + + def document_groups(self, document_id: UUID, offset: int = 0, limit: int = 100) -> list[GroupResponse]: + query = f""" + SELECT g.group_id, g.name, g.description, g.created_at, g.updated_at + FROM {self._get_table_name('groups')} g + JOIN {self._get_table_name('document_info')} d ON g.group_id = ANY(d.group_ids) + WHERE d.document_id = :document_id + ORDER BY g.name + OFFSET :offset + LIMIT :limit + """ + params = { + "document_id": document_id, + "offset": offset, + "limit": limit + } + results = self.execute_query(query, params).fetchall() + + return [ + GroupResponse( + group_id=row[0], + name=row[1], + description=row[2], + created_at=row[3], + updated_at=row[4], + ) + for row in results + ] + + def remove_document_from_group(self, document_id: UUID, group_id: UUID) -> None: + """ + Remove a document from a group. + + Args: + document_id (UUID): The ID of the document to remove. + group_id (UUID): The ID of the group to remove the document from. + + Raises: + R2RException: If the group doesn't exist or if the document is not in the group. + """ + if not self.group_exists(group_id): + raise R2RException(status_code=404, message="Group not found") + + query = f""" + UPDATE {self._get_table_name('document_info')} + SET group_ids = array_remove(group_ids, :group_id) + WHERE document_id = :document_id AND :group_id = ANY(group_ids) + RETURNING document_id + """ + result = self.execute_query( + query, {"document_id": document_id, "group_id": group_id} + ).fetchone() + + if not result: + raise R2RException( + status_code=404, + message="Document not found in the specified group" + ) \ No newline at end of file diff --git a/py/core/providers/database/user.py b/py/core/providers/database/user.py index 7208b1859..5ff701e26 100644 --- a/py/core/providers/database/user.py +++ b/py/core/providers/database/user.py @@ -193,13 +193,53 @@ def update_user(self, user: UserResponse) -> UserResponse: group_ids=result[10], ) - def delete_user(self, user_id: UUID): - query = f""" + + def delete_user(self, user_id: UUID) -> None: + print("A") + # Get the groups the user belongs to + group_query = f""" + SELECT group_ids FROM {self._get_table_name('users')} + WHERE user_id = :user_id + """ + group_result = self.execute_query(group_query, {"user_id": user_id}).fetchone() + + print("B") + if not group_result: + raise R2RException(status_code=404, message="User not found") + + user_groups = group_result[0] + + print("C") + # Remove user from all groups they belong to + if user_groups: + group_update_query = f""" + UPDATE {self._get_table_name('groups')} + SET user_ids = array_remove(user_ids, :user_id) + WHERE group_id = ANY(:group_ids) + """ + self.execute_query(group_update_query, {"user_id": user_id, "group_ids": user_groups}) + + print("D") + # Remove user from documents + doc_update_query = f""" + UPDATE {self._get_table_name('document_info')} + SET user_id = NULL + WHERE user_id = :user_id + """ + self.execute_query(doc_update_query, {"user_id": user_id}) + + print("E") + # Delete the user + delete_query = f""" DELETE FROM {self._get_table_name('users')} WHERE user_id = :user_id + RETURNING user_id """ - result = self.execute_query(query, {"user_id": user_id}) - if result.rowcount == 0: + + print("F") + result = self.execute_query(delete_query, {"user_id": user_id}).fetchone() + + if not result: raise R2RException(status_code=404, message="User not found") def update_user_password(self, user_id: UUID, new_hashed_password: str): diff --git a/py/core/providers/database/vecs/collection.py b/py/core/providers/database/vecs/collection.py index ccae50c00..d9f3485a2 100644 --- a/py/core/providers/database/vecs/collection.py +++ b/py/core/providers/database/vecs/collection.py @@ -703,26 +703,31 @@ def expand_query(query: str) -> str: combined_rank, ) .where( - sa.or_( - self.table.c.fts.op("@@")(ts_query), - sa.func.similarity(self.table.c.text, query_text) > 0.1, - self.table.c.fts.op("@@")( - sa.func.phraseto_tsquery("english", query_text) - ), - self.table.c.fts.op("@@")( - sa.func.to_tsquery( - "english", - " & ".join( - f"{word}:*" for word in query_text.split() - ), - ) + sa.and_( + sa.or_( + self.table.c.fts.op("@@")(ts_query), + sa.func.similarity(self.table.c.text, query_text) > 0.1, + self.table.c.fts.op("@@")( + sa.func.phraseto_tsquery("english", query_text) + ), + self.table.c.fts.op("@@")( + sa.func.to_tsquery( + "english", + " & ".join( + f"{word}:*" for word in query_text.split() + ), + ) + ), ), + self.build_filters(search_settings.filters) ) ) .order_by(sa.desc("rank")) .limit(search_settings.hybrid_search_settings.full_text_limit) ) + + with self.client.Session() as sess: results = sess.execute(stmt).fetchall() @@ -776,6 +781,14 @@ def parse_condition(key, value): return ~column.in_(clause) elif op == "$overlap": return column.overlap(clause) + elif op == "$contains": + return column.contains(clause) + elif op == "$any": + if key == "group_ids": + # Use ANY for UUID array comparison + return func.array_to_string(column, ',').like(f"%{clause}%") + # New operator for checking if any element in the array matches + return column.any(clause) else: raise FilterError( f"Unsupported operator for column {key}: {op}" @@ -785,6 +798,9 @@ def parse_condition(key, value): else: # Handle JSON-based filters json_col = self.table.c.metadata + if not key.startswith("metadata."): + raise FilterError("metadata key must start with 'metadata.'") + key = key.split('metadata.')[1] if isinstance(value, dict): if len(value) > 1: raise FilterError("only one operator permitted") diff --git a/py/core/providers/database/vector.py b/py/core/providers/database/vector.py index a4aadcba3..48b7197c6 100644 --- a/py/core/providers/database/vector.py +++ b/py/core/providers/database/vector.py @@ -1,3 +1,4 @@ +from uuid import UUID import logging import os from typing import Any, Optional @@ -176,19 +177,6 @@ def upsert_entries(self, entries: list[VectorEntry]) -> None: ] ) - def get_document_groups(self, document_id: str) -> list[str]: - query = text( - f""" - SELECT group_ids - FROM document_info_{self.collection_name} - WHERE document_id = :document_id - """ - ) - with self.vx.Session() as sess: - result = sess.execute(query, {"document_id": document_id}) - group_ids = result.scalar() - return [str(group_id) for group_id in (group_ids or [])] - def semantic_search( self, query_vector: list[float], search_settings: VectorSearchSettings ) -> list[VectorSearchResult]: @@ -337,7 +325,136 @@ def delete( return self.collection.delete(filters=filters) - def get_document_chunks(self, document_id: str) -> list[dict]: + def assign_document_to_group(self, document_id: str, group_id: str) -> None: + """ + Assign a document to a group in the vector database. + + Args: + document_id (str): The ID of the document to assign. + group_id (str): The ID of the group to assign the document to. + + Raises: + ValueError: If the collection is not initialized. + """ + if self.collection is None: + raise ValueError( + "Please call `initialize_collection` before attempting to run `assign_document_to_group`." + ) + + table_name = self.collection.table.name + query = text( + f""" + UPDATE vecs."{table_name}" + SET group_ids = array_append(group_ids, :group_id) + WHERE document_id = :document_id AND NOT (:group_id = ANY(group_ids)) + RETURNING document_id + """ + ) + + with self.vx.Session() as sess: + result = sess.execute(query, {"document_id": document_id, "group_id": group_id}) + sess.commit() + + if result.rowcount == 0: + logger.warning(f"Document {document_id} not found or already assigned to group {group_id}") + + def remove_document_from_group(self, document_id: str, group_id: str) -> None: + """ + Remove a document from a group in the vector database. + + Args: + document_id (str): The ID of the document to remove. + group_id (str): The ID of the group to remove the document from. + + Raises: + ValueError: If the collection is not initialized. + """ + if self.collection is None: + raise ValueError( + "Please call `initialize_collection` before attempting to run `remove_document_from_group`." + ) + + table_name = self.collection.table.name + query = text( + f""" + UPDATE vecs."{table_name}" + SET group_ids = array_remove(group_ids, :group_id) + WHERE document_id = :document_id AND :group_id = ANY(group_ids) + RETURNING document_id + """ + ) + + with self.vx.Session() as sess: + result = sess.execute(query, {"document_id": document_id, "group_id": group_id}) + sess.commit() + + if result.rowcount == 0: + logger.warning(f"Document {document_id} not found in group {group_id} or already removed") + + def remove_group_from_documents(self, group_id: str) -> None: + if self.collection is None: + raise ValueError("Collection is not initialized.") + + table_name = self.collection.table.name + query = text( + f""" + UPDATE vecs."{table_name}" + SET group_ids = array_remove(group_ids, :group_id) + WHERE :group_id = ANY(group_ids) + """ + ) + + with self.vx.Session() as sess: + sess.execute(query, {"group_id": group_id}) + sess.commit() + + def delete_user(self, user_id: str) -> None: + if self.collection is None: + raise ValueError("Collection is not initialized.") + + table_name = self.collection.table.name + query = text( + f""" + UPDATE vecs."{table_name}" + SET user_id = NULL + WHERE user_id = :user_id + """ + ) + + with self.vx.Session() as sess: + sess.execute(query, {"user_id": user_id}) + sess.commit() + + def delete_group(self, group_id: str) -> None: + """ + Remove the specified group ID from all documents in the vector database. + + Args: + group_id (str): The ID of the group to remove from all documents. + + Raises: + ValueError: If the collection is not initialized. + """ + if self.collection is None: + raise ValueError("Collection is not initialized.") + + table_name = self.collection.table.name + query = text( + f""" + UPDATE vecs."{table_name}" + SET group_ids = array_remove(group_ids, :group_id) + WHERE :group_id = ANY(group_ids) + """ + ) + + with self.vx.Session() as sess: + result = sess.execute(query, {"group_id": group_id}) + sess.commit() + + affected_rows = result.rowcount + logger.info(f"Removed group {group_id} from {affected_rows} documents.") + + def get_document_chunks(self, document_id: str, offset: int = 0, limit: int = 100) -> dict: if not self.collection: raise ValueError("Collection is not initialized.") @@ -348,22 +465,33 @@ def get_document_chunks(self, document_id: str) -> list[dict]: FROM vecs."{table_name}" WHERE document_id = :document_id ORDER BY CAST(metadata->>'chunk_order' AS INTEGER) + LIMIT :limit OFFSET :offset + """ + ) + + count_query = text( + f""" + SELECT COUNT(*) + FROM vecs."{table_name}" + WHERE document_id = :document_id """ ) - params = {"document_id": document_id} + params = {"document_id": document_id, "limit": limit, "offset": offset} with self.vx.Session() as sess: results = sess.execute(query, params).fetchall() - return [ - { - "fragment_id": result[0], - "extraction_id": result[1], - "document_id": result[2], - "user_id": result[3], - "group_ids": result[4], - "text": result[5], - "metadata": result[6], - } - for result in results - ] + total_count = sess.execute(count_query, {"document_id": document_id}).scalar() + + return [ + { + "fragment_id": result[0], + "extraction_id": result[1], + "document_id": result[2], + "user_id": result[3], + "group_ids": result[4], + "text": result[5], + "metadata": result[6], + } + for result in results + ] \ No newline at end of file diff --git a/py/core/providers/parsing/r2r_parsing.py b/py/core/providers/parsing/r2r_parsing.py index 55cbeb37c..0ad60a085 100644 --- a/py/core/providers/parsing/r2r_parsing.py +++ b/py/core/providers/parsing/r2r_parsing.py @@ -21,6 +21,7 @@ class R2RParsingProvider(ParsingProvider): DocumentType.CSV: [parsers.CSVParser, parsers.CSVParserAdvanced], DocumentType.DOCX: [parsers.DOCXParser], DocumentType.HTML: [parsers.HTMLParser], + DocumentType.HTM: [parsers.HTMLParser], DocumentType.JSON: [parsers.JSONParser], DocumentType.MD: [parsers.MDParser], DocumentType.PDF: [parsers.PDFParser, parsers.PDFParserUnstructured], diff --git a/py/sdk/auth.py b/py/sdk/auth.py index e71f7bbe2..5ef62b89e 100644 --- a/py/sdk/auth.py +++ b/py/sdk/auth.py @@ -170,22 +170,4 @@ async def confirm_password_reset( dict: The response from the server. """ data = {"reset_token": reset_token, "new_password": new_password} - return await client._make_request("POST", "reset_password", json=data) - - @staticmethod - async def delete_user(client, user_id: str, password: str = None) -> dict: - """ - Deletes the user with the given user ID. - - Args: - user_id (str): The ID of the user to delete. - password (str, optional): The password of the user to delete. - - Returns: - dict: The response from the server. - """ - data = {"user_id": user_id, "password": password} - response = await client._make_request("DELETE", "user", json=data) - client.access_token = None - client._refresh_token = None - return response + return await client._make_request("POST", "reset_password", json=data) \ No newline at end of file diff --git a/py/sdk/client.py b/py/sdk/client.py index 8de4ac637..8c8d38d3b 100644 --- a/py/sdk/client.py +++ b/py/sdk/client.py @@ -76,7 +76,7 @@ class R2RAsyncClient: def __init__( self, base_url: str = "http://localhost:8000", - prefix: str = "/v1", + prefix: str = "/v2", custom_client=None, timeout: float = 300.0, ): diff --git a/py/sdk/management.py b/py/sdk/management.py index 3abff1b00..1c95c4445 100644 --- a/py/sdk/management.py +++ b/py/sdk/management.py @@ -95,6 +95,8 @@ async def score_completion( async def users_overview( client, user_ids: Optional[list[str]] = None, + offset: Optional[int] = None, + limit: Optional[int] = None, ) -> dict: """ An overview of users in the R2R deployment. @@ -108,6 +110,10 @@ async def users_overview( params = {} if user_ids is not None: params["user_ids"] = [str(uid) for uid in user_ids] + if offset is not None: + params["offset"] = offset + if limit is not None: + params["limit"] = limit return await client._make_request( "GET", "users_overview", params=params ) @@ -136,6 +142,8 @@ async def delete( async def documents_overview( client, document_ids: Optional[list[Union[UUID, str]]] = None, + offset: Optional[int] = None, + limit: Optional[int] = None, ) -> dict: """ Get an overview of documents in the R2R deployment. @@ -152,7 +160,10 @@ async def documents_overview( ) if document_ids: params["document_ids"] = document_ids - + if offset is not None: + params["offset"] = offset + if limit is not None: + params["limit"] = limit return await client._make_request( "GET", "documents_overview", params=params ) @@ -161,6 +172,8 @@ async def documents_overview( async def document_chunks( client, document_id: str, + offset: Optional[int] = None, + limit: Optional[int] = None, ) -> dict: """ Get the chunks for a document. @@ -171,13 +184,24 @@ async def document_chunks( Returns: dict: The chunks for the document. """ - return await client._make_request( - "GET", f"document_chunks/{document_id}" - ) + params = {} + if offset is not None: + params["offset"] = offset + if limit is not None: + params["limit"] = limit + if params: + return await client._make_request( + "GET", f"document_chunks/{document_id}" + ) + else: + return await client._make_request( + "GET", f"document_chunks/{document_id}", params=params + ) @staticmethod async def inspect_knowledge_graph( client, + offset: Optional[int] = None, limit: Optional[int] = None, ) -> dict: """ @@ -190,6 +214,8 @@ async def inspect_knowledge_graph( dict: The knowledge graph inspection results. """ params = {} + if offset is not None: + params["offset"] = offset if limit is not None: params["limit"] = limit return await client._make_request( @@ -200,8 +226,8 @@ async def inspect_knowledge_graph( async def groups_overview( client, group_ids: Optional[list[str]] = None, - limit: Optional[int] = None, offset: Optional[int] = None, + limit: Optional[int] = None, ) -> dict: """ Get an overview of existing groups. @@ -217,10 +243,10 @@ async def groups_overview( params = {} if group_ids: params["group_ids"] = group_ids - if limit: - params["limit"] = limit if offset: params["offset"] = offset + if limit: + params["limit"] = limit return await client._make_request( "GET", "groups_overview", params=params ) @@ -305,6 +331,34 @@ async def delete_group( """ return await client._make_request("DELETE", f"delete_group/{group_id}") + + @staticmethod + async def delete_user( + client, + user_id: str, + password: Optional[str] = None, + delete_vector_data: bool = False, + ) -> dict: + """ + Delete a group by its ID. + + Args: + group_id (str): The ID of the group to delete. + + Returns: + dict: The response from the server. + """ + params = {} + if password is not None: + params["password"] = password + if delete_vector_data: + params["delete_vector_data"] = delete_vector_data + if params == {}: + return await client._make_request("DELETE", f"user/{user_id}") + else: + return await client._make_request("DELETE", f"user/{user_id}", json=params) + + @staticmethod async def list_groups( client, @@ -404,9 +458,11 @@ async def get_users_in_group( ) @staticmethod - async def get_groups_for_user( + async def user_groups( client, user_id: str, + offset: Optional[int] = None, + limit: Optional[int] = None, ) -> dict: """ Get all groups that a user is a member of. @@ -417,9 +473,19 @@ async def get_groups_for_user( Returns: dict: The list of groups that the user is a member of. """ - return await client._make_request( - "GET", f"get_groups_for_user/{user_id}" - ) + params = {} + if offset is not None: + params["offset"] = offset + if limit is not None: + params["limit"] = limit + if params: + return await client._make_request( + "GET", f"user_groups/{user_id}" + ) + else: + return await client._make_request( + "GET", f"user_groups/{user_id}", params=params + ) @staticmethod async def assign_document_to_group( @@ -471,9 +537,11 @@ async def remove_document_from_group( ) @staticmethod - async def get_document_groups( + async def document_groups( client, document_id: str, + offset: Optional[int] = None, + limit: Optional[int] = None ) -> dict: """ Get all groups that a document is assigned to. @@ -484,12 +552,22 @@ async def get_document_groups( Returns: dict: The list of groups that the document is assigned to. """ - return await client._make_request( - "GET", f"get_document_groups/{document_id}" - ) + params = {} + if offset is not None: + params["offset"] = offset + if limit is not None: + params["limit"] = limit + if params: + return await client._make_request( + "GET", f"document_groups/{document_id}", params=params + ) + else: + return await client._make_request( + "GET", f"document_groups/{document_id}" + ) @staticmethod - async def get_documents_in_group( + async def documents_in_group( client, group_id: str, offset: Optional[int] = None, diff --git a/py/tests/test_client.py b/py/tests/test_client.py index ff983cc9a..312e6ebfe 100644 --- a/py/tests/test_client.py +++ b/py/tests/test_client.py @@ -100,7 +100,7 @@ def update_user(user): return updated_user db.relational.update_user.side_effect = update_user - db.relational.get_documents_in_group.return_value = [ + db.relational.documents_in_group.return_value = [ DocumentInfo( user_id=uuid.uuid4(), id=uuid.uuid4(), @@ -357,7 +357,7 @@ async def test_user_profile(r2r_client, mock_db): @pytest.mark.asyncio -async def test_get_documents_in_group(r2r_client, mock_db): +async def test_documents_in_group(r2r_client, mock_db): # Register and login as a superuser user_data = {"email": "superuser@example.com", "password": "password123"} r2r_client.register(**user_data) @@ -369,7 +369,7 @@ async def test_get_documents_in_group(r2r_client, mock_db): # Get documents in group group_id = uuid.uuid4() - response = r2r_client.get_documents_in_group(group_id) + response = r2r_client.documents_in_group(group_id) assert "results" in response assert len(response["results"]) == 100 # Default limit diff --git a/py/tests/test_groups.py b/py/tests/test_groups.py index 2562bd38a..0e13c2212 100644 --- a/py/tests/test_groups.py +++ b/py/tests/test_groups.py @@ -362,21 +362,21 @@ def test_get_groups_for_user_with_pagination(pg_db, test_user): pg_db.relational.delete_group(group.group_id) -def test_get_documents_in_group(pg_db, test_group, test_documents): +def test_documents_in_group(pg_db, test_group, test_documents): # Test getting all documents - all_docs = pg_db.relational.get_documents_in_group(test_group.group_id) + all_docs = pg_db.relational.documents_in_group(test_group.group_id) assert len(all_docs) == 5 assert all(isinstance(doc, DocumentInfo) for doc in all_docs) assert all(test_group.group_id in doc.group_ids for doc in all_docs) # Test pagination - first page - first_page = pg_db.relational.get_documents_in_group( + first_page = pg_db.relational.documents_in_group( test_group.group_id, offset=0, limit=3 ) assert len(first_page) == 3 # Test pagination - second page - second_page = pg_db.relational.get_documents_in_group( + second_page = pg_db.relational.documents_in_group( test_group.group_id, offset=3, limit=3 ) assert len(second_page) == 2 @@ -394,11 +394,11 @@ def test_get_documents_in_group(pg_db, test_group, test_documents): # Test with non-existent group non_existent_id = UUID("00000000-0000-0000-0000-000000000000") with pytest.raises(R2RException): - pg_db.relational.get_documents_in_group(non_existent_id) + pg_db.relational.documents_in_group(non_existent_id) # Test with empty group empty_group = pg_db.relational.create_group("Empty Group", "No documents") - empty_docs = pg_db.relational.get_documents_in_group(empty_group.group_id) + empty_docs = pg_db.relational.documents_in_group(empty_group.group_id) assert len(empty_docs) == 0 # Clean up From 0debda8361de37c0f1a34471193340a8ea7cf5d3 Mon Sep 17 00:00:00 2001 From: Nolan Tremelling <34580718+NolanTrem@users.noreply.github.com> Date: Thu, 22 Aug 2024 17:40:59 -0700 Subject: [PATCH 52/74] Fix Dockerbuild, Symlink Readme (#944) * Add back tast prompt override and include title if availible * Fix docker, sym link readme * Fix compose file path --- README.md | 99 +-------------------------------- js/sdk/src/r2rClient.ts | 6 ++ py/.dockerignore | 2 +- py/Dockerfile | 26 ++++----- py/README.md | 98 ++++++++++++++++++++++++++++++++ py/cli/utils/docker_utils.py | 2 +- py/core/main/assembly/config.py | 4 +- py/pyproject.toml | 2 +- r2r.toml => py/r2r.toml | 0 py/sdk/retrieval.py | 12 ++-- 10 files changed, 129 insertions(+), 122 deletions(-) mode change 100644 => 120000 README.md rename r2r.toml => py/r2r.toml (100%) diff --git a/README.md b/README.md deleted file mode 100644 index 01f1520a1..000000000 --- a/README.md +++ /dev/null @@ -1,98 +0,0 @@ -

- Docs - Discord - Github Stars - Commits-per-week - License: MIT -

- -R2R Answer Engine -

-Build, scale, and manage user-facing Retrieval-Augmented Generation applications in production. -

- -# About -R2R was designed to bridge the gap between local LLM experimentation and scalable, production-ready Retrieval-Augmented Generation (RAG) applications. R2R provides a the latest techniques in RAG and is built around a RESTful API for ease of use. - -For a more complete view of R2R, check out the [full documentation](https://r2r-docs.sciphi.ai/). - -## Key Features -- **📁 Multimodal Support**: Ingest files ranging from `.txt`, `.pdf`, `.json` to `.png`, `.mp3`, and more. -- **🔍 Hybrid Search**: Combine semantic and keyword search with reciprocal rank fusion for enhanced relevancy. -- **🔗 Graph RAG**: Automatically extract relationships and build knowledge graphs. -- **🗂️ App Management**: Efficiently manage documents and users with full authentication. -- **🔭 Observability**: Observe and analyze your RAG engine performance. -- **🧩 Configurable**: Provision your application using intuitive configuration files. -- **🔌 Extensibility**: Develop your application further with easy builder + factory pattern. -- **🖥️ Dashboard**: Use the [R2R Dashboard](https://github.com/SciPhi-AI/R2R-Dashboard), an open-source React+Next.js app with optional authentication, to interact with R2R via GUI. - - -## Install with pip -The recommended way to get started with R2R is by using our CLI. - -```bash -pip install r2r -``` - -Then, after installing R2R, it is recommended to launch with Docker, if possible: - -```bash -# export OPENAI_API_KEY=sk-... -r2r serve --docker -``` - -Alternatively, you may run R2R directly from the python package, but additional dependencies like Postgres+pgvector must be configured: - -```bash -# export OPENAI_API_KEY=sk-... -# export POSTGRES... -r2r --config-name=default serve -``` - - -## Quickstart -After [installing](https://r2r-docs.sciphi.ai/installation), the [R2R Quickstart](https://r2r-docs.sciphi.ai/quickstart) is your go to for a step-by-step guide to get up and running with R2R in minutes. The guide demonstrates R2R's Retrieval-Augmented Generation (RAG) system by ingesting sample documents and then showcasing features for search, RAG, logging, analytics, and document management. -## Getting Started - -To get started with R2R, we recommend starting with the quickstart and then moving on to specific cookbooks. - -- [Installation](https://r2r-docs.sciphi.ai/installation): Quick setup using Docker or `pip` -- [R2R Quickstart](https://r2r-docs.sciphi.ai/quickstart): A quickstart guide designed to get you familiarized with R2R. - - -### API & SDKs -- [Pyhon SDK](https://r2r-docs.sciphi.ai/python-sdk) -- [JS SDK](https://r2r-docs.sciphi.ai/js-sdk) -- [API Reference](https://r2r-docs.sciphi.ai/api-reference/introduction) - - -### Auth & Admin Features -- [User Auth](https://r2r-docs.sciphi.ai/cookbooks/user-auth): A cookbook showing how to authenticate users using R2R. -- [Analytics & Observability](https://r2r-docs.sciphi.ai/cookbooks/observability): A cookbook showing R2Rs end to end logging and analytics. -- [Dashboard](https://r2r-docs.sciphi.ai/cookbooks/dashboard): A how-to guide on connecting with the R2R Admin/User Dashboard. - -### RAG Cookbooks - -- [Multiple LLMs](https://r2r-docs.sciphi.ai/cookbooks/multiple-llms): A simple cookbook showing how R2R supports multiple LLMs. -- [Hybrid Search](https://r2r-docs.sciphi.ai/cookbooks/hybrid-search): A brief introduction to running hybrid search with R2R. -- [Multimodal RAG](https://r2r-docs.sciphi.ai/cookbooks/multimodal): A cookbook on multimodal RAG with R2R. -- [Knowledge Graphs](https://r2r-docs.sciphi.ai/cookbooks/knowledge-graph): A walkthrough of automatic knowledge graph generation with R2R. -- [Advanced Graphs](https://r2r-docs.sciphi.ai/cookbooks/advanced-rag): A walkthrough of R2Rs advanced RAG features. -- [Local RAG](https://r2r-docs.sciphi.ai/cookbooks/local-rag): A quick cookbook demonstration of how to run R2R with local LLMs. -- [Reranking](https://r2r-docs.sciphi.ai/cookbooks/rerank-search): A short guide on how to apply reranking to R2R results. - -## Community - -[Join our Discord server](https://discord.gg/p6KqD2kjtB) to get support and connect with both the R2R team and other developers in the community. Whether you're encountering issues, looking for advice on best practices, or just want to share your experiences, we're here to help. - -# Contributing - -We welcome contributions of all sizes! Here's how you can help: - -- Open a PR for new features, improvements, or better documentation. -- Submit a [feature request](https://github.com/SciPhi-AI/R2R/issues/new?assignees=&labels=&projects=&template=feature_request.md&title=) or [bug report](https://github.com/SciPhi-AI/R2R/issues/new?assignees=&labels=&projects=&template=bug_report.md&title=) - -### Our Contributors - - - diff --git a/README.md b/README.md new file mode 120000 index 000000000..69f9ab844 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +py/README.md \ No newline at end of file diff --git a/js/sdk/src/r2rClient.ts b/js/sdk/src/r2rClient.ts index 2cd811b7e..34dd2e141 100644 --- a/js/sdk/src/r2rClient.ts +++ b/js/sdk/src/r2rClient.ts @@ -1139,6 +1139,8 @@ export class r2rClient { * @param vector_search_settings Vector search settings. * @param kg_search_settings KG search settings. * @param rag_generation_config RAG generation configuration. + * @param task_prompt_override Task prompt override. + * @param include_title_if_available Include title if available. * @returns A promise that resolves to the response from the server. */ @feature("rag") @@ -1147,6 +1149,8 @@ export class r2rClient { vector_search_settings?: VectorSearchSettings | Record, kg_search_settings?: KGSearchSettings | Record, rag_generation_config?: GenerationConfig | Record, + task_prompt_override?: string, + include_title_if_available?: boolean, ): Promise { this._ensureAuthenticated(); @@ -1155,6 +1159,8 @@ export class r2rClient { vector_search_settings, kg_search_settings, rag_generation_config, + task_prompt_override, + include_title_if_available, }; Object.keys(json_data).forEach( diff --git a/py/.dockerignore b/py/.dockerignore index c4730648b..8d12d1ab3 100644 --- a/py/.dockerignore +++ b/py/.dockerignore @@ -17,4 +17,4 @@ coverage.xml .git .mypy_cache .pytest_cache -.hypothesis +.hypothesis \ No newline at end of file diff --git a/py/Dockerfile b/py/Dockerfile index 0ea128c9f..9d1a79ecc 100644 --- a/py/Dockerfile +++ b/py/Dockerfile @@ -12,40 +12,40 @@ WORKDIR /app RUN pip install --no-cache-dir poetry -# Copy the dependencies files -COPY py/pyproject.toml py/poetry.lock* ./ +# Copy the entire project into the container +COPY . /app -# Install the dependencies, including gunicorn and uvicorn +# Ensure that the working directory is set to /app/py +WORKDIR /app/py + +# Install dependencies RUN poetry config virtualenvs.create false \ && poetry install --extras "core" --no-dev --no-root \ && pip install --no-cache-dir gunicorn uvicorn -# Create the final image +# Final stage to keep the image small FROM python:3.10-slim -# Install healthcheck dependency +# Install runtime dependencies RUN apt-get update \ && apt-get install -y --no-install-recommends curl \ && apt-get clean && rm -rf /var/lib/apt/lists/* -WORKDIR /app/py +WORKDIR /app # Copy the installed packages from the builder COPY --from=builder /usr/local/lib/python3.10/site-packages /usr/local/lib/python3.10/site-packages COPY --from=builder /usr/local/bin /usr/local/bin -# Copy the application and config -COPY py/core /app/py/core +# Copy the necessary application files +COPY core /app/core +COPY r2r /app/r2r COPY r2r.toml /app/r2r.toml -COPY py/pyproject.toml /app/py/pyproject.toml - -ENV PYTHONPATH="${PYTHONPATH}:/app/py" +COPY pyproject.toml /app/pyproject.toml -# Expose the port ARG PORT=8000 ARG HOST=0.0.0.0 ENV PORT=$PORT HOST=$HOST EXPOSE $PORT -# Run the application CMD ["sh", "-c", "uvicorn core.main.app_entry:app --host $HOST --port $PORT"] diff --git a/py/README.md b/py/README.md index e69de29bb..01f1520a1 100644 --- a/py/README.md +++ b/py/README.md @@ -0,0 +1,98 @@ +

+ Docs + Discord + Github Stars + Commits-per-week + License: MIT +

+ +R2R Answer Engine +

+Build, scale, and manage user-facing Retrieval-Augmented Generation applications in production. +

+ +# About +R2R was designed to bridge the gap between local LLM experimentation and scalable, production-ready Retrieval-Augmented Generation (RAG) applications. R2R provides a the latest techniques in RAG and is built around a RESTful API for ease of use. + +For a more complete view of R2R, check out the [full documentation](https://r2r-docs.sciphi.ai/). + +## Key Features +- **📁 Multimodal Support**: Ingest files ranging from `.txt`, `.pdf`, `.json` to `.png`, `.mp3`, and more. +- **🔍 Hybrid Search**: Combine semantic and keyword search with reciprocal rank fusion for enhanced relevancy. +- **🔗 Graph RAG**: Automatically extract relationships and build knowledge graphs. +- **🗂️ App Management**: Efficiently manage documents and users with full authentication. +- **🔭 Observability**: Observe and analyze your RAG engine performance. +- **🧩 Configurable**: Provision your application using intuitive configuration files. +- **🔌 Extensibility**: Develop your application further with easy builder + factory pattern. +- **🖥️ Dashboard**: Use the [R2R Dashboard](https://github.com/SciPhi-AI/R2R-Dashboard), an open-source React+Next.js app with optional authentication, to interact with R2R via GUI. + + +## Install with pip +The recommended way to get started with R2R is by using our CLI. + +```bash +pip install r2r +``` + +Then, after installing R2R, it is recommended to launch with Docker, if possible: + +```bash +# export OPENAI_API_KEY=sk-... +r2r serve --docker +``` + +Alternatively, you may run R2R directly from the python package, but additional dependencies like Postgres+pgvector must be configured: + +```bash +# export OPENAI_API_KEY=sk-... +# export POSTGRES... +r2r --config-name=default serve +``` + + +## Quickstart +After [installing](https://r2r-docs.sciphi.ai/installation), the [R2R Quickstart](https://r2r-docs.sciphi.ai/quickstart) is your go to for a step-by-step guide to get up and running with R2R in minutes. The guide demonstrates R2R's Retrieval-Augmented Generation (RAG) system by ingesting sample documents and then showcasing features for search, RAG, logging, analytics, and document management. +## Getting Started + +To get started with R2R, we recommend starting with the quickstart and then moving on to specific cookbooks. + +- [Installation](https://r2r-docs.sciphi.ai/installation): Quick setup using Docker or `pip` +- [R2R Quickstart](https://r2r-docs.sciphi.ai/quickstart): A quickstart guide designed to get you familiarized with R2R. + + +### API & SDKs +- [Pyhon SDK](https://r2r-docs.sciphi.ai/python-sdk) +- [JS SDK](https://r2r-docs.sciphi.ai/js-sdk) +- [API Reference](https://r2r-docs.sciphi.ai/api-reference/introduction) + + +### Auth & Admin Features +- [User Auth](https://r2r-docs.sciphi.ai/cookbooks/user-auth): A cookbook showing how to authenticate users using R2R. +- [Analytics & Observability](https://r2r-docs.sciphi.ai/cookbooks/observability): A cookbook showing R2Rs end to end logging and analytics. +- [Dashboard](https://r2r-docs.sciphi.ai/cookbooks/dashboard): A how-to guide on connecting with the R2R Admin/User Dashboard. + +### RAG Cookbooks + +- [Multiple LLMs](https://r2r-docs.sciphi.ai/cookbooks/multiple-llms): A simple cookbook showing how R2R supports multiple LLMs. +- [Hybrid Search](https://r2r-docs.sciphi.ai/cookbooks/hybrid-search): A brief introduction to running hybrid search with R2R. +- [Multimodal RAG](https://r2r-docs.sciphi.ai/cookbooks/multimodal): A cookbook on multimodal RAG with R2R. +- [Knowledge Graphs](https://r2r-docs.sciphi.ai/cookbooks/knowledge-graph): A walkthrough of automatic knowledge graph generation with R2R. +- [Advanced Graphs](https://r2r-docs.sciphi.ai/cookbooks/advanced-rag): A walkthrough of R2Rs advanced RAG features. +- [Local RAG](https://r2r-docs.sciphi.ai/cookbooks/local-rag): A quick cookbook demonstration of how to run R2R with local LLMs. +- [Reranking](https://r2r-docs.sciphi.ai/cookbooks/rerank-search): A short guide on how to apply reranking to R2R results. + +## Community + +[Join our Discord server](https://discord.gg/p6KqD2kjtB) to get support and connect with both the R2R team and other developers in the community. Whether you're encountering issues, looking for advice on best practices, or just want to share your experiences, we're here to help. + +# Contributing + +We welcome contributions of all sizes! Here's how you can help: + +- Open a PR for new features, improvements, or better documentation. +- Submit a [feature request](https://github.com/SciPhi-AI/R2R/issues/new?assignees=&labels=&projects=&template=feature_request.md&title=) or [bug report](https://github.com/SciPhi-AI/R2R/issues/new?assignees=&labels=&projects=&template=bug_report.md&title=) + +### Our Contributors + + + diff --git a/py/cli/utils/docker_utils.py b/py/cli/utils/docker_utils.py index a80b9e24d..7975933e8 100644 --- a/py/cli/utils/docker_utils.py +++ b/py/cli/utils/docker_utils.py @@ -311,7 +311,7 @@ def set_ollama_api_base(exclude_ollama): def get_compose_files(): package_dir = os.path.join( - os.path.dirname(os.path.abspath(__file__)), "..", "..", ".." + os.path.dirname(os.path.abspath(__file__)), "..", "..", ) compose_files = { "base": os.path.join(package_dir, "compose.yaml"), diff --git a/py/core/main/assembly/config.py b/py/core/main/assembly/config.py index 8b9ed61bd..547d292bd 100644 --- a/py/core/main/assembly/config.py +++ b/py/core/main/assembly/config.py @@ -117,7 +117,7 @@ def from_toml(cls, config_path: str = None) -> "R2RConfig": # Get the root directory of the project file_dir = os.path.dirname(os.path.abspath(__file__)) config_path = os.path.join( - file_dir, "..", "..", "..", "..", "r2r.toml" + file_dir, "..", "..", "..", "r2r.toml" ) # Load configuration from TOML file @@ -151,7 +151,7 @@ def load_default_config(cls) -> dict: # Get the root directory of the project file_dir = os.path.dirname(os.path.abspath(__file__)) default_config_path = os.path.join( - file_dir, "..", "..", "..", "..", "r2r.toml" + file_dir, "..", "..", "..", "r2r.toml" ) # Load default configuration from TOML file with open(default_config_path) as f: diff --git a/py/pyproject.toml b/py/pyproject.toml index 03881ebf6..2a2d380b2 100644 --- a/py/pyproject.toml +++ b/py/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api" [tool.poetry] name = "r2r" -readme = "../README.md" +readme = "README.md" version = "0.3.0" description = "SciPhi R2R" authors = ["Owen Colegrove "] diff --git a/r2r.toml b/py/r2r.toml similarity index 100% rename from r2r.toml rename to py/r2r.toml diff --git a/py/sdk/retrieval.py b/py/sdk/retrieval.py index b64cf6d39..67ca4b6e3 100644 --- a/py/sdk/retrieval.py +++ b/py/sdk/retrieval.py @@ -19,8 +19,6 @@ async def search( Union[dict, VectorSearchSettings] ] = None, kg_search_settings: Optional[Union[dict, KGSearchSettings]] = None, - *args, - **kwargs, ) -> SearchResponse: """ Conduct a vector and/or KG search. @@ -56,8 +54,8 @@ async def rag( Union[dict, VectorSearchSettings] ] = None, kg_search_settings: Optional[Union[dict, KGSearchSettings]] = None, - *args, - **kwargs, + task_prompt_override: Optional[str] = None, + include_title_if_available: Optional[bool] = False, ) -> Union[RAGResponse, AsyncGenerator[RAGResponse, None]]: """ Conducts a Retrieval Augmented Generation (RAG) search with the given query. @@ -67,6 +65,8 @@ async def rag( rag_generation_config (Optional[Union[dict, GenerationConfig]]): RAG generation configuration. vector_search_settings (Optional[Union[dict, VectorSearchSettings]]): Vector search settings. kg_search_settings (Optional[Union[dict, KGSearchSettings]]): KG search settings. + task_prompt_override (Optional[str]): Task prompt override. + include_title_if_available (Optional[bool]): Include the title if available. Returns: Union[RAGResponse, AsyncGenerator[RAGResponse, None]]: The RAG response @@ -87,6 +87,8 @@ async def rag( "rag_generation_config": rag_generation_config, "vector_search_settings": vector_search_settings, "kg_search_settings": kg_search_settings, + "task_prompt_override": task_prompt_override, + "include_title_if_available": include_title_if_available, } if rag_generation_config and rag_generation_config.get( @@ -107,8 +109,6 @@ async def agent( kg_search_settings: Optional[Union[dict, KGSearchSettings]] = None, task_prompt_override: Optional[str] = None, include_title_if_available: Optional[bool] = False, - *args, - **kwargs, ) -> Union[list[Message], AsyncGenerator[Message, None]]: """ Performs a single turn in a conversation with a RAG agent. From 0af19cb82bd00e892c3c7e907e1565abc993adb1 Mon Sep 17 00:00:00 2001 From: Shreyas Pimpalgaonkar Date: Thu, 22 Aug 2024 20:41:19 -0400 Subject: [PATCH 53/74] Shreyas/KG Search Result model (#937) * return type to kg_search_result * add model * local and global results * modify config --- py/core/base/abstractions/search.py | 36 ++++++++++++++++++- py/core/configs/neo4j_kg.toml | 16 +++------ .../pipes/retrieval/kg_search_search_pipe.py | 20 +++++------ py/sdk/models.py | 18 +++++++++- 4 files changed, 67 insertions(+), 23 deletions(-) diff --git a/py/core/base/abstractions/search.py b/py/core/base/abstractions/search.py index f43445141..affc9cb9f 100644 --- a/py/core/base/abstractions/search.py +++ b/py/core/base/abstractions/search.py @@ -54,8 +54,42 @@ class Config: }, } +class KGLocalSearchResult(BaseModel): + """Result of a local knowledge graph search operation.""" + query: str + entities: list[dict[str, Any]] + relationships: list[dict[str, Any]] + communities: list[dict[str, Any]] -KGSearchResult = list[Tuple[str, list[Dict[str, Any]]]] + def __str__(self) -> str: + return f"LocalSearchResult(query={self.query}, search_result={self.search_result})" + + def __repr__(self) -> str: + return self.__str__() + + +class KGGlobalSearchResult(BaseModel): + """Result of a global knowledge graph search operation.""" + query: str + search_result: list[Dict[str, Any]] + + def __str__(self) -> str: + return f"GlobalSearchResult(query={self.query}, search_result={self.search_result})" + + def __repr__(self) -> str: + return self.__str__() + + +class KGSearchResult(BaseModel): + """Result of a knowledge graph search operation.""" + local_result: Optional[KGLocalSearchResult] = None + global_result: Optional[KGGlobalSearchResult] = None + + def __str__(self) -> str: + return f"KGSearchResult(local_result={self.local_result}, global_result={self.global_result})" + + def __repr__(self) -> str: + return self.__str__() class AggregateSearchResult(BaseModel): diff --git a/py/core/configs/neo4j_kg.toml b/py/core/configs/neo4j_kg.toml index ad43a10f9..cbaa13a0d 100644 --- a/py/core/configs/neo4j_kg.toml +++ b/py/core/configs/neo4j_kg.toml @@ -25,22 +25,16 @@ provider = "neo4j" batch_size = 256 kg_extraction_prompt = "graphrag_triplet_extraction_zero_shot" - [kg.kg_extraction_config] model = "gpt-4o-mini" - temperature = 0.1 - top_p = 1 - max_tokens_to_sample = 1_024 - stream = false - add_generation_kwargs = { } + + [kg.kg_enrichment_config] + max_knowledge_triples = 100 + generation_config = { model = "gpt-4o-mini" } # and other params + leiden_params = { max_cluster_size = 1000 } # more params in graspologic/partition/leiden.py [kg.kg_search_config] model = "gpt-4o-mini" - temperature = 0.1 - top_p = 1 - max_tokens_to_sample = 1_024 - stream = false - add_generation_kwargs = { } [database] provider = "postgres" diff --git a/py/core/pipes/retrieval/kg_search_search_pipe.py b/py/core/pipes/retrieval/kg_search_search_pipe.py index 16c26d2c1..e5664fae5 100644 --- a/py/core/pipes/retrieval/kg_search_search_pipe.py +++ b/py/core/pipes/retrieval/kg_search_search_pipe.py @@ -15,11 +15,11 @@ RunLoggingSingleton, ) +from core.base.abstractions.search import KGLocalSearchResult, KGGlobalSearchResult, KGSearchResult from ..abstractions.generator_pipe import GeneratorPipe logger = logging.getLogger(__name__) - class KGSearchSearchPipe(GeneratorPipe): """ Embeds and stores documents using a specified embedding model and database. @@ -102,7 +102,7 @@ async def local_search( kg_search_settings: KGSearchSettings, *args: Any, **kwargs: Any, - ): + ) -> KGLocalSearchResult: # search over communities and # do 3 searches. One over entities, one over relationships, one over communities @@ -127,7 +127,7 @@ async def local_search( ) all_search_results.append(search_result) - yield message, all_search_results + yield KGLocalSearchResult(query=message, entities=all_search_results[0], relationships=all_search_results[1], communities=all_search_results[2]) async def global_search( self, @@ -137,7 +137,7 @@ async def global_search( kg_search_settings: KGSearchSettings, *args: Any, **kwargs: Any, - ): + ) -> KGGlobalSearchResult: # map reduce async for message in input.message: map_responses = [] @@ -209,7 +209,7 @@ async def process_community(merged_report): output = output.choices[0].message.content - yield message, [{"output": output}] + yield KGGlobalSearchResult(query=message, search_result=output, citations=None) async def _run_logic( self, @@ -219,19 +219,19 @@ async def _run_logic( kg_search_settings: KGSearchSettings, *args: Any, **kwargs: Any, - ): + ) -> KGSearchResult: logger.info("Performing global search") kg_search_type = kg_search_settings.kg_search_type if kg_search_type == "local": - async for query, result in self.local_search( + async for result in self.local_search( input, state, run_id, kg_search_settings ): - yield (query, result) + yield KGSearchResult(local_result=result) else: - async for query, result in self.global_search( + async for result in self.global_search( input, state, run_id, kg_search_settings ): - yield (query, result) + yield KGSearchResult(global_result=result) diff --git a/py/sdk/models.py b/py/sdk/models.py index 03b690610..895f632d5 100644 --- a/py/sdk/models.py +++ b/py/sdk/models.py @@ -188,8 +188,24 @@ class Config: } -KGSearchResult = list[Tuple[str, list[Dict[str, Any]]]] +class KGSearchResult(BaseModel): + query: str + results: list[Dict[str, Any]] + class Config: + json_schema_extra = { + "example": { + "query": "What is the capital of France?", + "results": [ + { + "Paris": { + "name": "Paris", + "description": "Paris is the capital of France." + } + } + ] + } + } class R2RException(Exception): def __init__( From cac8e1dc9f34f3f97ae67da67b0656477434b03c Mon Sep 17 00:00:00 2001 From: emrgnt-cmplxty <68796651+emrgnt-cmplxty@users.noreply.github.com> Date: Thu, 22 Aug 2024 17:45:58 -0700 Subject: [PATCH 54/74] refresh should not be gated by auth (#946) --- py/core/main/api/routes/auth/base.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/py/core/main/api/routes/auth/base.py b/py/core/main/api/routes/auth/base.py index 94a85dab2..3cd899c9e 100644 --- a/py/core/main/api/routes/auth/base.py +++ b/py/core/main/api/routes/auth/base.py @@ -132,8 +132,7 @@ async def put_user_app( ) @self.base_endpoint async def refresh_access_token_app( - refresh_token: str = Body(..., description="Refresh token"), - auth_user=Depends(self.engine.providers.auth.auth_wrapper), + refresh_token: str = Body(..., description="Refresh token") ): """ Refresh the access token using a refresh token. From cf8097c776a1ed0ec225981e86e80c7f793cc813 Mon Sep 17 00:00:00 2001 From: Nolan Tremelling <34580718+NolanTrem@users.noreply.github.com> Date: Thu, 22 Aug 2024 17:52:59 -0700 Subject: [PATCH 55/74] Linting sync (#947) --- .github/workflows/build-mainv2.yml | 2 +- ...mit-config.yaml => .pre-commit-config.yaml | 0 py/.dockerignore | 2 +- py/Dockerfile.unstructured | 2 +- py/cli/command_group.py | 1 + py/cli/commands/auth.py | 1 + py/cli/commands/ingestion.py | 5 +- py/cli/commands/management.py | 15 ++-- py/cli/commands/restructure.py | 4 +- py/cli/commands/retrieval.py | 1 + py/cli/commands/server.py | 3 +- py/cli/utils/docker_utils.py | 7 +- py/core/base/abstractions/document.py | 1 + py/core/base/agent/agent.py | 3 +- py/core/base/agent/base.py | 3 +- py/core/base/api/models/auth/responses.py | 3 +- .../base/api/models/ingestion/responses.py | 3 +- .../base/api/models/management/responses.py | 3 +- .../base/api/models/restructure/responses.py | 3 +- .../base/api/models/retrieval/responses.py | 3 +- py/core/base/pipes/base_pipe.py | 3 +- .../examples/scripts/advanced_kg_cookbook.py | 1 + .../examples/scripts/run_group_workflow.py | 70 +++++++++++++------ py/core/examples/scripts/serve_with_hyde.py | 4 +- py/core/examples/scripts/serve_with_web.py | 1 + .../examples/scripts/serve_with_web_hyde.py | 2 + py/core/main/abstractions.py | 3 +- py/core/main/api/routes/auth/base.py | 11 +-- py/core/main/api/routes/base_router.py | 5 +- py/core/main/api/routes/ingestion/base.py | 5 +- py/core/main/api/routes/management/base.py | 32 ++++++--- py/core/main/api/routes/restructure/base.py | 3 +- py/core/main/api/routes/retrieval/base.py | 21 ++++-- py/core/main/assembly/config.py | 4 +- py/core/main/assembly/factory.py | 1 + py/core/main/engine.py | 8 +-- py/core/main/services/auth_service.py | 2 +- py/core/main/services/ingestion_service.py | 6 +- py/core/main/services/management_service.py | 31 +++++--- py/core/parsers/text/html_parser.py | 1 + py/core/parsers/text/md_parser.py | 1 + py/core/pipes/ingestion/parsing_pipe.py | 6 +- py/core/pipes/kg/clustering.py | 1 + py/core/pipes/other/web_search_pipe.py | 10 ++- py/core/providers/auth/r2r_auth.py | 5 +- py/core/providers/database/document.py | 4 +- py/core/providers/database/group.py | 45 +++++++----- py/core/providers/database/relational.py | 3 +- py/core/providers/database/user.py | 19 +++-- py/core/providers/database/vecs/collection.py | 22 +++--- py/core/providers/database/vector.py | 49 +++++++++---- py/core/providers/embeddings/litellm.py | 3 +- py/core/providers/embeddings/ollama.py | 3 +- py/core/providers/embeddings/openai.py | 5 +- py/core/providers/llm/openai.py | 3 +- py/core/providers/prompts/r2r_prompts.py | 1 + py/core/telemetry/posthog.py | 1 + py/pyproject.toml | 5 +- py/r2r.toml | 2 +- py/sdk/auth.py | 2 +- py/sdk/management.py | 12 ++-- py/sdk/models.py | 2 +- py/tests/cli/commands/test_auth.py | 3 +- py/tests/cli/commands/test_ingestion.py | 3 +- py/tests/cli/commands/test_management.py | 3 +- py/tests/cli/commands/test_restructure.py | 3 +- py/tests/cli/test_cli.py | 3 +- py/tests/cli/test_command_group.py | 3 +- py/tests/cli/utils/test_docker_utils.py | 3 +- py/tests/cli/utils/test_param_types.py | 1 + py/tests/cli/utils/test_timer.py | 1 + py/tests/regression/runner.py | 2 +- py/tests/test_abstractions.py | 1 + py/tests/test_auth.py | 1 + py/tests/test_cli.py | 3 +- py/tests/test_client.py | 7 +- py/tests/test_config.py | 1 + py/tests/test_database.py | 3 +- py/tests/test_embedding.py | 1 + py/tests/test_end_to_end.py | 3 +- py/tests/test_groups.py | 1 + py/tests/test_groups_client.py | 5 +- py/tests/test_ingestion_service.py | 3 +- py/tests/test_kg.py | 1 + py/tests/test_llms.py | 1 + py/tests/test_logging.py | 1 + py/tests/test_parser.py | 1 + py/tests/test_pipeline.py | 1 + py/tests/test_vector_db.py | 1 + 89 files changed, 355 insertions(+), 188 deletions(-) rename py/.pre-commit-config.yaml => .pre-commit-config.yaml (100%) diff --git a/.github/workflows/build-mainv2.yml b/.github/workflows/build-mainv2.yml index 93e53649d..ab02f156f 100644 --- a/.github/workflows/build-mainv2.yml +++ b/.github/workflows/build-mainv2.yml @@ -82,4 +82,4 @@ jobs: labels: ${{ steps.meta.outputs.labels_unstructured }} platforms: linux/amd64,linux/arm64 build-args: | - CACHE_BUST=${{ steps.cache-buster.outputs.CACHE_BUSTER }} \ No newline at end of file + CACHE_BUST=${{ steps.cache-buster.outputs.CACHE_BUSTER }} diff --git a/py/.pre-commit-config.yaml b/.pre-commit-config.yaml similarity index 100% rename from py/.pre-commit-config.yaml rename to .pre-commit-config.yaml diff --git a/py/.dockerignore b/py/.dockerignore index 8d12d1ab3..c4730648b 100644 --- a/py/.dockerignore +++ b/py/.dockerignore @@ -17,4 +17,4 @@ coverage.xml .git .mypy_cache .pytest_cache -.hypothesis \ No newline at end of file +.hypothesis diff --git a/py/Dockerfile.unstructured b/py/Dockerfile.unstructured index 989fa42d1..7250e432e 100644 --- a/py/Dockerfile.unstructured +++ b/py/Dockerfile.unstructured @@ -28,7 +28,7 @@ RUN poetry config virtualenvs.create false \ # Create the final image FROM python:3.10-slim -# Install runtime dependencies +# Install runtime dependencies RUN apt-get update \ && apt-get install -y --no-install-recommends \ curl tesseract-ocr poppler-utils libmagic1 \ diff --git a/py/cli/command_group.py b/py/cli/command_group.py index bcc4e30ed..ecf878c47 100644 --- a/py/cli/command_group.py +++ b/py/cli/command_group.py @@ -1,4 +1,5 @@ import click + from sdk.client import R2RClient diff --git a/py/cli/commands/auth.py b/py/cli/commands/auth.py index 5a241477f..c9c699d42 100644 --- a/py/cli/commands/auth.py +++ b/py/cli/commands/auth.py @@ -1,6 +1,7 @@ import secrets import click + from cli.command_group import cli diff --git a/py/cli/commands/ingestion.py b/py/cli/commands/ingestion.py index 77a98946f..1099b299f 100644 --- a/py/cli/commands/ingestion.py +++ b/py/cli/commands/ingestion.py @@ -6,6 +6,7 @@ import click import requests + from cli.command_group import cli from cli.utils.param_types import JSON from cli.utils.timer import timer @@ -28,9 +29,7 @@ def ingest_files(client, file_paths, document_ids, metadatas): file_paths = list(file_paths) document_ids = list(document_ids) if document_ids else None - response = client.ingest_files( - file_paths, metadatas, document_ids - ) + response = client.ingest_files(file_paths, metadatas, document_ids) click.echo(json.dumps(response, indent=2)) diff --git a/py/cli/commands/management.py b/py/cli/commands/management.py index 114943c3d..474b7b648 100644 --- a/py/cli/commands/management.py +++ b/py/cli/commands/management.py @@ -1,6 +1,7 @@ from typing import Any, Dict import click + from cli.command_group import cli from cli.utils.param_types import JSON from cli.utils.timer import timer @@ -53,11 +54,15 @@ def users_overview(client, user_ids, offset, limit): with timer(): response = client.users_overview(user_ids, offset, limit) - if 'results' in response: + if "results" in response: click.echo("\nUser Overview:") - click.echo(f"{'User ID':<40} {'Num Files':<10} {'Total Size (bytes)':<20} Document IDs") - for user in response['results']: - click.echo(f"{user['user_id']:<40} {user['num_files']:<10} {user['total_size_in_bytes']:<20} {', '.join(user['document_ids'][:3]) + ('...' if len(user['document_ids']) > 3 else '')}") + click.echo( + f"{'User ID':<40} {'Num Files':<10} {'Total Size (bytes)':<20} Document IDs" + ) + for user in response["results"]: + click.echo( + f"{user['user_id']:<40} {user['num_files']:<10} {user['total_size_in_bytes']:<20} {', '.join(user['document_ids'][:3]) + ('...' if len(user['document_ids']) > 3 else '')}" + ) else: click.echo("No users found.") @@ -153,4 +158,4 @@ def inspect_knowledge_graph(client, offset, limit): with timer(): response = client.inspect_knowledge_graph(offset, limit) - click.echo(response) \ No newline at end of file + click.echo(response) diff --git a/py/cli/commands/restructure.py b/py/cli/commands/restructure.py index 770678a9a..bbc0af40f 100644 --- a/py/cli/commands/restructure.py +++ b/py/cli/commands/restructure.py @@ -1,8 +1,6 @@ -from typing import Any, Dict - import click + from cli.command_group import cli -from cli.utils.param_types import JSON from cli.utils.timer import timer diff --git a/py/cli/commands/retrieval.py b/py/cli/commands/retrieval.py index c1897ff73..3255b95a2 100644 --- a/py/cli/commands/retrieval.py +++ b/py/cli/commands/retrieval.py @@ -1,4 +1,5 @@ import click + from cli.command_group import cli from cli.utils.param_types import JSON from cli.utils.timer import timer diff --git a/py/cli/commands/server.py b/py/cli/commands/server.py index c71c003e6..5355b4e8f 100644 --- a/py/cli/commands/server.py +++ b/py/cli/commands/server.py @@ -5,6 +5,8 @@ import sys import click +from dotenv import load_dotenv + from cli.command_group import cli from cli.utils.docker_utils import ( bring_down_docker_compose, @@ -13,7 +15,6 @@ run_local_serve, ) from cli.utils.timer import timer -from dotenv import load_dotenv @cli.command() diff --git a/py/cli/utils/docker_utils.py b/py/cli/utils/docker_utils.py index 7975933e8..4d6e48824 100644 --- a/py/cli/utils/docker_utils.py +++ b/py/cli/utils/docker_utils.py @@ -9,8 +9,9 @@ import click import requests -from core.main import R2RBuilder, R2RConfig from requests.exceptions import RequestException + +from core.main import R2RBuilder, R2RConfig from sdk import R2RClient @@ -311,7 +312,9 @@ def set_ollama_api_base(exclude_ollama): def get_compose_files(): package_dir = os.path.join( - os.path.dirname(os.path.abspath(__file__)), "..", "..", + os.path.dirname(os.path.abspath(__file__)), + "..", + "..", ) compose_files = { "base": os.path.join(package_dir, "compose.yaml"), diff --git a/py/core/base/abstractions/document.py b/py/core/base/abstractions/document.py index 12cf53b42..5e8f2f558 100644 --- a/py/core/base/abstractions/document.py +++ b/py/core/base/abstractions/document.py @@ -26,6 +26,7 @@ class DocumentStatus(str, Enum): class DocumentType(str, Enum): """Types of documents that can be stored.""" + CSV = "csv" DOCX = "docx" HTML = "html" diff --git a/py/core/base/agent/agent.py b/py/core/base/agent/agent.py index ce39c3d20..e4945b005 100644 --- a/py/core/base/agent/agent.py +++ b/py/core/base/agent/agent.py @@ -2,13 +2,14 @@ from abc import ABC, abstractmethod from typing import Any, AsyncGenerator, Dict, List, Optional, Type, Union +from pydantic import BaseModel + from core.base.abstractions import ( GenerationConfig, LLMChatCompletion, MessageType, ) from core.base.providers import CompletionProvider, PromptProvider -from pydantic import BaseModel from .base import Message, Tool, ToolResult diff --git a/py/core/base/agent/base.py b/py/core/base/agent/base.py index 386e6af7d..201728b6f 100644 --- a/py/core/base/agent/base.py +++ b/py/core/base/agent/base.py @@ -1,8 +1,9 @@ from typing import Any, Callable, Dict, Optional, Union -from core.base.abstractions import MessageType from pydantic import BaseModel +from core.base.abstractions import MessageType + class Tool(BaseModel): name: str diff --git a/py/core/base/api/models/auth/responses.py b/py/core/base/api/models/auth/responses.py index b5eb702ae..3c9a1e1b5 100644 --- a/py/core/base/api/models/auth/responses.py +++ b/py/core/base/api/models/auth/responses.py @@ -2,9 +2,10 @@ from typing import Optional from uuid import UUID +from pydantic import BaseModel + from core.base.abstractions import Token from core.base.api.models.base import ResultsWrapper -from pydantic import BaseModel class TokenResponse(BaseModel): diff --git a/py/core/base/api/models/ingestion/responses.py b/py/core/base/api/models/ingestion/responses.py index 011c4569a..370785cbe 100644 --- a/py/core/base/api/models/ingestion/responses.py +++ b/py/core/base/api/models/ingestion/responses.py @@ -1,9 +1,10 @@ from typing import Any, List, TypeVar from uuid import UUID -from core.base.api.models.base import ResultsWrapper from pydantic import BaseModel, Field +from core.base.api.models.base import ResultsWrapper + T = TypeVar("T") diff --git a/py/core/base/api/models/management/responses.py b/py/core/base/api/models/management/responses.py index ffc3d5dc2..fdeb7f9dc 100644 --- a/py/core/base/api/models/management/responses.py +++ b/py/core/base/api/models/management/responses.py @@ -2,9 +2,10 @@ from typing import Any, Dict, List, Optional from uuid import UUID -from core.base.api.models.base import ResultsWrapper from pydantic import BaseModel +from core.base.api.models.base import ResultsWrapper + class PromptResponse(BaseModel): message: str diff --git a/py/core/base/api/models/restructure/responses.py b/py/core/base/api/models/restructure/responses.py index ed35bd437..766cd6700 100644 --- a/py/core/base/api/models/restructure/responses.py +++ b/py/core/base/api/models/restructure/responses.py @@ -2,9 +2,10 @@ from typing import Any, Dict, List, Optional from uuid import UUID -from core.base.api.models.base import ResultsWrapper from pydantic import BaseModel +from core.base.api.models.base import ResultsWrapper + class KGEnrichmentResponse(BaseModel): enriched_content: Dict[str, Any] diff --git a/py/core/base/api/models/retrieval/responses.py b/py/core/base/api/models/retrieval/responses.py index 9e64e96cf..6bb086971 100644 --- a/py/core/base/api/models/retrieval/responses.py +++ b/py/core/base/api/models/retrieval/responses.py @@ -1,8 +1,9 @@ from typing import Any, Optional +from pydantic import BaseModel, Field + from core.base.abstractions import KGSearchResult, Message, VectorSearchResult from core.base.api.models.base import ResultsWrapper -from pydantic import BaseModel, Field class SearchResponse(BaseModel): diff --git a/py/core/base/pipes/base_pipe.py b/py/core/base/pipes/base_pipe.py index 37ae962a2..5069b3899 100644 --- a/py/core/base/pipes/base_pipe.py +++ b/py/core/base/pipes/base_pipe.py @@ -5,9 +5,10 @@ from typing import Any, AsyncGenerator, Optional from uuid import UUID +from pydantic import BaseModel + from core.base.logging.run_logger import RunLoggingSingleton from core.base.logging.run_manager import RunManager, manage_run -from pydantic import BaseModel logger = logging.getLogger(__name__) diff --git a/py/core/examples/scripts/advanced_kg_cookbook.py b/py/core/examples/scripts/advanced_kg_cookbook.py index f69d0a486..555677450 100644 --- a/py/core/examples/scripts/advanced_kg_cookbook.py +++ b/py/core/examples/scripts/advanced_kg_cookbook.py @@ -3,6 +3,7 @@ import fire import requests from bs4 import BeautifulSoup, Comment + from r2r import EntityType, R2RClient, R2RPromptProvider, RelationshipType diff --git a/py/core/examples/scripts/run_group_workflow.py b/py/core/examples/scripts/run_group_workflow.py index 38353ef20..57b4d3059 100644 --- a/py/core/examples/scripts/run_group_workflow.py +++ b/py/core/examples/scripts/run_group_workflow.py @@ -1,10 +1,12 @@ import os -from r2r import R2RClient +from r2r import R2RClient if __name__ == "__main__": # Initialize the R2R client - client = R2RClient("http://localhost:8000") # Replace with your R2R deployment URL + client = R2RClient( + "http://localhost:8000" + ) # Replace with your R2R deployment URL # Admin login print("Logging in as admin...") @@ -13,12 +15,14 @@ # Create two groups print("\nCreating two groups...") - group1_result = client.create_group("TestGroup1", "A test group for document access") + group1_result = client.create_group( + "TestGroup1", "A test group for document access" + ) group2_result = client.create_group("TestGroup2", "Another test group") print("Group1 creation result:", group1_result) print("Group2 creation result:", group2_result) - group1_id = group1_result['results']['group_id'] - group2_id = group2_result['results']['group_id'] + group1_id = group1_result["results"]["group_id"] + group2_id = group2_result["results"]["group_id"] # Get groups overview print("\nGetting groups overview...") @@ -37,20 +41,26 @@ # Update a group print("\nUpdating Group1...") - update_result = client.update_group(group1_id, name="UpdatedTestGroup1", description="Updated description") + update_result = client.update_group( + group1_id, name="UpdatedTestGroup1", description="Updated description" + ) print("Group update result:", update_result) # Ingest two documents print("\nIngesting two documents...") script_path = os.path.dirname(__file__) - sample_file1 = os.path.join(script_path, "core", "examples", "data", "aristotle_v2.txt") - sample_file2 = os.path.join(script_path, "core", "examples", "data", "aristotle.txt") + sample_file1 = os.path.join( + script_path, "core", "examples", "data", "aristotle_v2.txt" + ) + sample_file2 = os.path.join( + script_path, "core", "examples", "data", "aristotle.txt" + ) ingestion_result1 = client.ingest_files([sample_file1]) ingestion_result2 = client.ingest_files([sample_file2]) print("Document1 ingestion result:", ingestion_result1) print("Document2 ingestion result:", ingestion_result2) - document1_id = ingestion_result1['results']['processed_documents'][0]['id'] - document2_id = ingestion_result2['results']['processed_documents'][0]['id'] + document1_id = ingestion_result1["results"]["processed_documents"][0]["id"] + document2_id = ingestion_result2["results"]["processed_documents"][0]["id"] # Assign documents to groups print("\nAssigning documents to groups...") @@ -76,10 +86,18 @@ # Add users to groups print("\nAdding users to groups...") - add_user1_result = client.add_user_to_group(user1_result['results']['id'], group1_id) - add_user2_result = client.add_user_to_group(user2_result['results']['id'], group2_id) - add_user3_result1 = client.add_user_to_group(user3_result['results']['id'], group1_id) - add_user3_result2 = client.add_user_to_group(user3_result['results']['id'], group2_id) + add_user1_result = client.add_user_to_group( + user1_result["results"]["id"], group1_id + ) + add_user2_result = client.add_user_to_group( + user2_result["results"]["id"], group2_id + ) + add_user3_result1 = client.add_user_to_group( + user3_result["results"]["id"], group1_id + ) + add_user3_result2 = client.add_user_to_group( + user3_result["results"]["id"], group2_id + ) print("Add user1 to group1 result:", add_user1_result) print("Add user2 to group2 result:", add_user2_result) print("Add user3 to group1 result:", add_user3_result1) @@ -92,7 +110,7 @@ # Get groups for a user print("\nGetting groups for User3...") - user3_groups = client.user_groups(user3_result['results']['id']) + user3_groups = client.user_groups(user3_result["results"]["id"]) print("User3 groups:", user3_groups) # Get documents in a group @@ -102,12 +120,16 @@ # Remove user from group print("\nRemoving User3 from Group1...") - remove_user_result = client.remove_user_from_group(user3_result['results']['id'], group1_id) + remove_user_result = client.remove_user_from_group( + user3_result["results"]["id"], group1_id + ) print("Remove user result:", remove_user_result) # Remove document from group print("\nRemoving Document1 from Group1...") - remove_doc_result = client.remove_document_from_group(document1_id, group1_id) + remove_doc_result = client.remove_document_from_group( + document1_id, group1_id + ) print("Remove document result:", remove_doc_result) # Logout admin @@ -120,7 +142,9 @@ # Search for documents (should see document1 but not document2) print("\nUser1 searching for documents...") - search_result_user1 = client.search("philosophy", {"selected_group_ids": [group1_id]}) + search_result_user1 = client.search( + "philosophy", {"selected_group_ids": [group1_id]} + ) print("User1 search result:", search_result_user1) # Logout user1 @@ -134,10 +158,14 @@ # Search for documents (should see only document2 after removal from Group1) print("\nUser3 searching for documents...") try: - search_result_user3 = client.search("philosophy", {"selected_group_ids": [group1_id, group2_id]}) + search_result_user3 = client.search( + "philosophy", {"selected_group_ids": [group1_id, group2_id]} + ) except Exception as e: print("User3 search result error:", e) - search_result_user3 = client.search("philosophy", {"selected_group_ids": [group2_id]}) + search_result_user3 = client.search( + "philosophy", {"selected_group_ids": [group2_id]} + ) print("User3 search result:", search_result_user3) @@ -160,5 +188,3 @@ client.logout() print("\nWorkflow completed.") - - \ No newline at end of file diff --git a/py/core/examples/scripts/serve_with_hyde.py b/py/core/examples/scripts/serve_with_hyde.py index 688e31aab..c5c4e8008 100644 --- a/py/core/examples/scripts/serve_with_hyde.py +++ b/py/core/examples/scripts/serve_with_hyde.py @@ -1,6 +1,7 @@ -from r2r import R2RBuilder, R2RConfig, R2RPipeFactoryWithMultiSearch import fire +from r2r import R2RBuilder, R2RConfig, R2RPipeFactoryWithMultiSearch + def main(task_prompt_name="hyde"): # Load the default configuration file @@ -16,5 +17,6 @@ def main(task_prompt_name="hyde"): ) app.serve() + if __name__ == "__main__": fire.Fire(main) diff --git a/py/core/examples/scripts/serve_with_web.py b/py/core/examples/scripts/serve_with_web.py index 79ab45e8c..5e41c1165 100644 --- a/py/core/examples/scripts/serve_with_web.py +++ b/py/core/examples/scripts/serve_with_web.py @@ -1,4 +1,5 @@ import fire + from r2r import R2RBuilder, SerperClient, WebSearchPipe diff --git a/py/core/examples/scripts/serve_with_web_hyde.py b/py/core/examples/scripts/serve_with_web_hyde.py index 06eef6990..aef0a0326 100644 --- a/py/core/examples/scripts/serve_with_web_hyde.py +++ b/py/core/examples/scripts/serve_with_web_hyde.py @@ -1,4 +1,5 @@ import fire + from core import R2RBuilder, SerperClient, WebSearchPipe from core.base.abstractions.llm import GenerationConfig from core.main.assembly.factory_extensions import R2RPipeFactoryWithMultiSearch @@ -39,5 +40,6 @@ def run_rag_pipeline(): ) ).serve() + if __name__ == "__main__": fire.Fire(run_rag_pipeline) diff --git a/py/core/main/abstractions.py b/py/core/main/abstractions.py index cb7f2e774..e2599a299 100644 --- a/py/core/main/abstractions.py +++ b/py/core/main/abstractions.py @@ -1,5 +1,7 @@ from typing import Optional +from pydantic import BaseModel + from core.agent import R2RRAGAgent, R2RStreamingRAGAgent from core.base.pipes import AsyncPipe from core.base.providers import ( @@ -18,7 +20,6 @@ RAGPipeline, SearchPipeline, ) -from pydantic import BaseModel class R2RProviders(BaseModel): diff --git a/py/core/main/api/routes/auth/base.py b/py/core/main/api/routes/auth/base.py index 3cd899c9e..408ee555e 100644 --- a/py/core/main/api/routes/auth/base.py +++ b/py/core/main/api/routes/auth/base.py @@ -1,15 +1,16 @@ import uuid from typing import TYPE_CHECKING, Optional +from fastapi import Body, Depends, Path +from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm +from pydantic import EmailStr + from core.base.api.models.auth.responses import ( GenericMessageResponse, WrappedGenericMessageResponse, WrappedTokenResponse, WrappedUserResponse, ) -from fastapi import Path, Body, Depends -from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm -from pydantic import EmailStr from ..base_router import BaseRouter, RunType @@ -224,5 +225,7 @@ async def delete_user_app( if not auth_user.is_superuser and not password: raise Exception("Password is required for non-superusers") user_uuid = uuid.UUID(user_id) - result = await self.engine.adelete_user(user_uuid, password, delete_vector_data) + result = await self.engine.adelete_user( + user_uuid, password, delete_vector_data + ) return GenericMessageResponse(message=result["message"]) diff --git a/py/core/main/api/routes/base_router.py b/py/core/main/api/routes/base_router.py index f9acfa1ba..c621ab94f 100644 --- a/py/core/main/api/routes/base_router.py +++ b/py/core/main/api/routes/base_router.py @@ -2,11 +2,12 @@ import logging from abc import abstractmethod -from core.base import R2RException, manage_run -from core.base.logging.base import RunType from fastapi import APIRouter, HTTPException from fastapi.responses import StreamingResponse +from core.base import R2RException, manage_run +from core.base.logging.base import RunType + logger = logging.getLogger(__name__) diff --git a/py/core/main/api/routes/ingestion/base.py b/py/core/main/api/routes/ingestion/base.py index d9d429049..fe0524d88 100644 --- a/py/core/main/api/routes/ingestion/base.py +++ b/py/core/main/api/routes/ingestion/base.py @@ -5,11 +5,12 @@ from uuid import UUID import yaml +from fastapi import Depends, File, Form, UploadFile +from pydantic import Json + from core.base import ChunkingConfig, R2RException from core.base.api.models.ingestion.responses import WrappedIngestionResponse from core.base.utils import generate_user_document_id -from fastapi import Depends, File, Form, UploadFile -from pydantic import Json from ....assembly.factory import R2RProviderFactory from ....engine import R2REngine diff --git a/py/core/main/api/routes/management/base.py b/py/core/main/api/routes/management/base.py index 05623d7b9..7a1ebded8 100644 --- a/py/core/main/api/routes/management/base.py +++ b/py/core/main/api/routes/management/base.py @@ -5,6 +5,9 @@ from uuid import UUID import psutil +from fastapi import Body, Depends, Path, Query +from pydantic import Json + from core.base import R2RException from core.base.api.models.management.responses import ( WrappedAddUserResponse, @@ -23,8 +26,6 @@ WrappedUserOverviewResponse, ) from core.base.logging import AnalysisTypes, LogFilterCriteria -from fastapi import Body, Depends, Path, Query -from pydantic import Json from ....engine import R2REngine from ..base_router import BaseRouter, RunType @@ -176,7 +177,9 @@ async def users_overview_app( [UUID(user_id) for user_id in user_ids] if user_ids else None ) - return await self.engine.ausers_overview(user_ids=user_uuids, offset=offset, limit=limit) + return await self.engine.ausers_overview( + user_ids=user_uuids, offset=offset, limit=limit + ) @self.router.delete("/delete", status_code=204) @self.base_endpoint @@ -219,7 +222,9 @@ async def document_chunks_app( auth_user=Depends(self.engine.providers.auth.auth_wrapper), ) -> WrappedDocumentChunkResponse: document_uuid = UUID(document_id) - chunks = await self.engine.adocument_chunks(document_uuid, offset, limit) + chunks = await self.engine.adocument_chunks( + document_uuid, offset, limit + ) if not chunks: raise R2RException( @@ -251,7 +256,9 @@ async def inspect_knowledge_graph( 403, ) return await self.engine.ainspect_knowledge_graph( - offset=offset, limit=limit, print_descriptions=print_descriptions + offset=offset, + limit=limit, + print_descriptions=print_descriptions, ) @self.router.get("/groups_overview") @@ -378,9 +385,7 @@ async def remove_user_from_group_app( ) user_uuid = UUID(user_id) group_uuid = UUID(group_id) - await self.engine.aremove_user_from_group( - user_uuid, group_uuid - ) + await self.engine.aremove_user_from_group(user_uuid, group_uuid) return None # TODO - Proivde response model @@ -420,7 +425,9 @@ async def get_groups_for_user_app( "Only a superuser can get groups for a user.", 403 ) user_uuid = UUID(user_id) - return await self.engine.aget_groups_for_user(user_uuid, offset, limit) + return await self.engine.aget_groups_for_user( + user_uuid, offset, limit + ) @self.router.post("/assign_document_to_group") @self.base_endpoint @@ -467,9 +474,12 @@ async def document_groups_app( ) -> WrappedGroupListResponse: if not auth_user.is_superuser: raise R2RException( - "Only a superuser can get the groups belonging to a document.", 403 + "Only a superuser can get the groups belonging to a document.", + 403, ) - return await self.engine.adocument_groups(document_id, offset, limit) + return await self.engine.adocument_groups( + document_id, offset, limit + ) @self.router.get("/group/{group_id}/documents") @self.base_endpoint diff --git a/py/core/main/api/routes/restructure/base.py b/py/core/main/api/routes/restructure/base.py index ff7328644..005feeed9 100644 --- a/py/core/main/api/routes/restructure/base.py +++ b/py/core/main/api/routes/restructure/base.py @@ -1,9 +1,10 @@ from typing import Union +from fastapi import Body, Depends + from core.base import KGEnrichmentSettings from core.main.api.routes.base_router import BaseRouter, RunType from core.main.engine import R2REngine -from fastapi import Body, Depends class RestructureRouter(BaseRouter): diff --git a/py/core/main/api/routes/retrieval/base.py b/py/core/main/api/routes/retrieval/base.py index b65c3f776..44c5eeca9 100644 --- a/py/core/main/api/routes/retrieval/base.py +++ b/py/core/main/api/routes/retrieval/base.py @@ -2,6 +2,9 @@ from typing import Optional import yaml +from fastapi import Body, Depends +from fastapi.responses import StreamingResponse + from core.base import ( GenerationConfig, KGSearchSettings, @@ -15,8 +18,6 @@ WrappedRAGResponse, WrappedSearchResponse, ) -from fastapi import Body, Depends -from fastapi.responses import StreamingResponse from ....engine import R2REngine from ..base_router import BaseRouter @@ -72,8 +73,8 @@ async def search_app( Allowed operators include `eq`, `neq`, `gt`, `gte`, `lt`, `lte`, `like`, `ilike`, `in`, and `nin`. """ - print('auth_user = ', auth_user) - print('initial vector_search_settings = ', vector_search_settings) + print("auth_user = ", auth_user) + print("initial vector_search_settings = ", vector_search_settings) print(f"Received query: {query}") print(f"Received vector_search_settings: {vector_search_settings}") @@ -88,7 +89,10 @@ async def search_app( "User does not have access to the specified group(s): " f"{selected_groups - allowed_groups}" ) - print('initial vector_search_settings filters = ', vector_search_settings.filters) + print( + "initial vector_search_settings filters = ", + vector_search_settings.filters, + ) filters = { "$or": [ @@ -101,8 +105,11 @@ async def search_app( filters = {"$and": [filters, vector_search_settings.filters]} vector_search_settings.filters = filters - print('final vector_search_settings = ', vector_search_settings) - print('final vector_search_settings filters = ', vector_search_settings.filters) + print("final vector_search_settings = ", vector_search_settings) + print( + "final vector_search_settings filters = ", + vector_search_settings.filters, + ) results = await self.engine.asearch( query=query, vector_search_settings=vector_search_settings, diff --git a/py/core/main/assembly/config.py b/py/core/main/assembly/config.py index 547d292bd..302b32686 100644 --- a/py/core/main/assembly/config.py +++ b/py/core/main/assembly/config.py @@ -116,9 +116,7 @@ def from_toml(cls, config_path: str = None) -> "R2RConfig": if config_path is None: # Get the root directory of the project file_dir = os.path.dirname(os.path.abspath(__file__)) - config_path = os.path.join( - file_dir, "..", "..", "..", "r2r.toml" - ) + config_path = os.path.join(file_dir, "..", "..", "..", "r2r.toml") # Load configuration from TOML file with open(config_path) as f: diff --git a/py/core/main/assembly/factory.py b/py/core/main/assembly/factory.py index 120920412..7c45864a4 100644 --- a/py/core/main/assembly/factory.py +++ b/py/core/main/assembly/factory.py @@ -215,6 +215,7 @@ def create_prompt_provider( prompt_provider = None if prompt_config.provider == "r2r": from core.providers import R2RPromptProvider + prompt_provider = R2RPromptProvider(prompt_config) else: raise ValueError( diff --git a/py/core/main/engine.py b/py/core/main/engine.py index 9a759a02b..c9ae9c361 100644 --- a/py/core/main/engine.py +++ b/py/core/main/engine.py @@ -256,7 +256,7 @@ async def aassign_document_to_group(self, *args, **kwargs): return await self.management_service.aassign_document_to_group( *args, **kwargs ) - + @syncable async def agroups_overview(self, *args, **kwargs): return await self.management_service.agroups_overview(*args, **kwargs) @@ -269,12 +269,10 @@ async def adocuments_in_group(self, *args, **kwargs): @syncable async def adocument_groups(self, *args, **kwargs): - return await self.management_service.adocument_groups( - *args, **kwargs - ) + return await self.management_service.adocument_groups(*args, **kwargs) @syncable async def aremove_document_from_group(self, *args, **kwargs): return await self.management_service.aremove_document_from_group( *args, **kwargs - ) \ No newline at end of file + ) diff --git a/py/core/main/services/auth_service.py b/py/core/main/services/auth_service.py index 84b318729..5229ed3a0 100644 --- a/py/core/main/services/auth_service.py +++ b/py/core/main/services/auth_service.py @@ -147,7 +147,7 @@ async def delete_user( ): raise R2RException(status_code=400, message="Incorrect password") self.providers.database.relational.delete_user(user_id) - if (delete_vector_data): + if delete_vector_data: self.providers.database.vector.delete_user(user_id) return {"message": f"User account {user_id} deleted successfully."} diff --git a/py/core/main/services/ingestion_service.py b/py/core/main/services/ingestion_service.py index abc4da6c1..ba1f5724c 100644 --- a/py/core/main/services/ingestion_service.py +++ b/py/core/main/services/ingestion_service.py @@ -4,6 +4,8 @@ from typing import Any, Optional from uuid import UUID +from fastapi import UploadFile + from core.base import ( Document, DocumentInfo, @@ -19,7 +21,6 @@ from core.base.api.models import IngestionResponse from core.base.providers import ChunkingProvider from core.telemetry.telemetry_decorator import telemetry_event -from fastapi import UploadFile from ...base.api.models.auth.responses import UserResponse from ..abstractions import R2RAgents, R2RPipelines, R2RProviders @@ -30,6 +31,7 @@ MB_CONVERSION_FACTOR = 1024 * 1024 STARTING_VERSION = "v0" + class IngestionService(Service): def __init__( self, @@ -176,7 +178,6 @@ async def update_files( ) documents.append(document) - ingestion_results = await self.ingest_documents( documents, chunking_provider=chunking_provider, @@ -308,7 +309,6 @@ async def ingest_documents( # Add version to metadata to propagate through pipeline document.metadata["version"] = version - if duplicate_documents: duplicate_details = [ f"{doc_id}: {', '.join(titles)}" diff --git a/py/core/main/services/management_service.py b/py/core/main/services/management_service.py index 5a85d6f45..af4108bf5 100644 --- a/py/core/main/services/management_service.py +++ b/py/core/main/services/management_service.py @@ -5,6 +5,7 @@ from uuid import UUID import toml + from core.base import ( AnalysisTypes, LogFilterCriteria, @@ -246,7 +247,9 @@ async def ausers_overview( **kwargs, ): return self.providers.database.relational.get_users_overview( - [str(ele) for ele in user_ids] if user_ids else None, offset=offset, limit=limit + [str(ele) for ele in user_ids] if user_ids else None, + offset=offset, + limit=limit, ) @telemetry_event("Delete") @@ -314,7 +317,9 @@ async def document_chunks( *args, **kwargs, ): - return self.providers.database.vector.get_document_chunks(document_id, offset=offset, limit=limit) + return self.providers.database.vector.get_document_chunks( + document_id, offset=offset, limit=limit + ) @telemetry_event("UsersOverview") async def users_overview( @@ -441,7 +446,9 @@ async def aremove_document_from_group( return {"message": "Document removed from group successfully"} @telemetry_event("DocumentGroups") - async def adocument_groups(self, document_id: str, offset: int = 0, limit: int = 100): + async def adocument_groups( + self, document_id: str, offset: int = 0, limit: int = 100 + ): group_ids = self.providers.database.relational.document_groups( document_id, offset=offset, limit=limit ) @@ -569,7 +576,7 @@ async def adelete_group(self, group_id: UUID) -> bool: self.providers.database.relational.delete_group(group_id) self.providers.database.vector.delete_group(group_id) return True - + @telemetry_event("ListGroups") async def alist_groups( self, offset: int = 0, limit: int = 100 @@ -601,8 +608,12 @@ async def aget_users_in_group( ) @telemetry_event("GetGroupsForUser") - async def aget_groups_for_user(self, user_id: UUID, offset: int = 0, limit: int = 100) -> list[dict]: - return self.providers.database.relational.get_groups_for_user(user_id, offset, limit) + async def aget_groups_for_user( + self, user_id: UUID, offset: int = 0, limit: int = 100 + ) -> list[dict]: + return self.providers.database.relational.get_groups_for_user( + user_id, offset, limit + ) @telemetry_event("GroupsOverview") async def agroups_overview( @@ -628,5 +639,9 @@ async def adocuments_in_group( ) @telemetry_event("DocumentGroups") - async def adocument_groups(self, document_id: str, offset: int = 0, limit: int = 100) -> list[str]: - return self.providers.database.relational.document_groups(document_id, offset, limit) \ No newline at end of file + async def adocument_groups( + self, document_id: str, offset: int = 0, limit: int = 100 + ) -> list[str]: + return self.providers.database.relational.document_groups( + document_id, offset, limit + ) diff --git a/py/core/parsers/text/html_parser.py b/py/core/parsers/text/html_parser.py index 6d87f38f2..a0f209439 100644 --- a/py/core/parsers/text/html_parser.py +++ b/py/core/parsers/text/html_parser.py @@ -1,6 +1,7 @@ from typing import AsyncGenerator from bs4 import BeautifulSoup + from core.base.abstractions.document import DataType from core.base.parsers.base_parser import AsyncParser diff --git a/py/core/parsers/text/md_parser.py b/py/core/parsers/text/md_parser.py index 515dba3f1..efe129ac9 100644 --- a/py/core/parsers/text/md_parser.py +++ b/py/core/parsers/text/md_parser.py @@ -1,6 +1,7 @@ from typing import AsyncGenerator from bs4 import BeautifulSoup + from core.base.abstractions.document import DataType from core.base.parsers.base_parser import AsyncParser diff --git a/py/core/pipes/ingestion/parsing_pipe.py b/py/core/pipes/ingestion/parsing_pipe.py index b1b4c8373..21b622657 100644 --- a/py/core/pipes/ingestion/parsing_pipe.py +++ b/py/core/pipes/ingestion/parsing_pipe.py @@ -76,5 +76,7 @@ async def _run_logic( **kwargs, ) -> AsyncGenerator[DocumentExtraction, None]: async for document in input.message: - async for result in self._parse(document, run_id, document.metadata.get("version", "1.0")): - yield result \ No newline at end of file + async for result in self._parse( + document, run_id, document.metadata.get("version", "1.0") + ): + yield result diff --git a/py/core/pipes/kg/clustering.py b/py/core/pipes/kg/clustering.py index 53f3e4b13..964d7bab1 100644 --- a/py/core/pipes/kg/clustering.py +++ b/py/core/pipes/kg/clustering.py @@ -10,6 +10,7 @@ from uuid import UUID import networkx as nx + from core.base import ( AsyncPipe, AsyncState, diff --git a/py/core/pipes/other/web_search_pipe.py b/py/core/pipes/other/web_search_pipe.py index 6db7e9b8c..c46e7e442 100644 --- a/py/core/pipes/other/web_search_pipe.py +++ b/py/core/pipes/other/web_search_pipe.py @@ -1,7 +1,7 @@ import json import logging -from typing import Any, AsyncGenerator, Optional import uuid +from typing import Any, AsyncGenerator, Optional from core.base import ( AsyncPipe, @@ -58,8 +58,12 @@ async def search( text = result.pop("snippet") search_result = VectorSearchResult( fragment_id=generate_id_from_label(str(result)), - extraction_id=uuid.uuid5(uuid.NAMESPACE_DNS, str(uuid.uuid4())), # Generate a new UUID for extraction_id - document_id=uuid.uuid5(uuid.NAMESPACE_DNS, str(uuid.uuid4())), # Generate a new UUID for document_id + extraction_id=uuid.uuid5( + uuid.NAMESPACE_DNS, str(uuid.uuid4()) + ), # Generate a new UUID for extraction_id + document_id=uuid.uuid5( + uuid.NAMESPACE_DNS, str(uuid.uuid4()) + ), # Generate a new UUID for document_id user_id=None, # Web search results don't have a user_id group_ids=[], # Web search results don't belong to any group score=result.get( diff --git a/py/core/providers/auth/r2r_auth.py b/py/core/providers/auth/r2r_auth.py index cceea2d4c..7dab2d02a 100644 --- a/py/core/providers/auth/r2r_auth.py +++ b/py/core/providers/auth/r2r_auth.py @@ -4,6 +4,9 @@ from typing import Dict import jwt +from fastapi import Depends +from fastapi.security import OAuth2PasswordBearer + from core.base import ( AuthConfig, AuthProvider, @@ -14,8 +17,6 @@ TokenData, ) from core.base.api.models.auth.responses import UserResponse -from fastapi import Depends -from fastapi.security import OAuth2PasswordBearer logger = logging.getLogger(__name__) oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") diff --git a/py/core/providers/database/document.py b/py/core/providers/database/document.py index f14915c1f..4c578b699 100644 --- a/py/core/providers/database/document.py +++ b/py/core/providers/database/document.py @@ -102,7 +102,7 @@ def get_documents_overview( """ results = self.execute_query(query, params).fetchall() - print('results = ', results) + print("results = ", results) documents = [ DocumentInfo( id=row[0], @@ -128,4 +128,4 @@ def get_documents_overview( if conditions: count_query += " WHERE " + " AND ".join(conditions) - return documents \ No newline at end of file + return documents diff --git a/py/core/providers/database/group.py b/py/core/providers/database/group.py index 4d4ea9972..9ec8d48ce 100644 --- a/py/core/providers/database/group.py +++ b/py/core/providers/database/group.py @@ -105,7 +105,7 @@ def update_group( created_at=result[3], updated_at=result[4], ) - + def delete_group(self, group_id: UUID) -> None: # Remove group_id from users user_update_query = f""" @@ -129,7 +129,9 @@ def delete_group(self, group_id: UUID) -> None: WHERE group_id = :group_id RETURNING group_id """ - result = self.execute_query(delete_query, {"group_id": group_id}).fetchone() + result = self.execute_query( + delete_query, {"group_id": group_id} + ).fetchone() if not result: raise R2RException(status_code=404, message="Group not found") @@ -393,8 +395,10 @@ def get_groups_for_user( ) for row in results ] - - def assign_document_to_group(self, document_id: UUID, group_id: UUID) -> None: + + def assign_document_to_group( + self, document_id: UUID, group_id: UUID + ) -> None: """ Assign a document to a group. @@ -420,7 +424,9 @@ def assign_document_to_group(self, document_id: UUID, group_id: UUID) -> None: ).fetchone() if not document_exists: - raise R2RException(status_code=404, message="Document not found") + raise R2RException( + status_code=404, message="Document not found" + ) # If document exists, proceed with the assignment assign_query = f""" @@ -430,14 +436,15 @@ def assign_document_to_group(self, document_id: UUID, group_id: UUID) -> None: RETURNING document_id """ result = self.execute_query( - assign_query, {"document_id": document_id, "group_id": group_id} + assign_query, + {"document_id": document_id, "group_id": group_id}, ).fetchone() if not result: # Document exists but was already assigned to the group raise R2RException( status_code=409, - message="Document is already assigned to the group" + message="Document is already assigned to the group", ) except R2RException: @@ -446,10 +453,12 @@ def assign_document_to_group(self, document_id: UUID, group_id: UUID) -> None: except Exception as e: raise R2RException( status_code=500, - message="An error occurred while assigning the document to the group" + message="An error occurred while assigning the document to the group", ) - - def document_groups(self, document_id: UUID, offset: int = 0, limit: int = 100) -> list[GroupResponse]: + + def document_groups( + self, document_id: UUID, offset: int = 0, limit: int = 100 + ) -> list[GroupResponse]: query = f""" SELECT g.group_id, g.name, g.description, g.created_at, g.updated_at FROM {self._get_table_name('groups')} g @@ -459,11 +468,7 @@ def document_groups(self, document_id: UUID, offset: int = 0, limit: int = 100) OFFSET :offset LIMIT :limit """ - params = { - "document_id": document_id, - "offset": offset, - "limit": limit - } + params = {"document_id": document_id, "offset": offset, "limit": limit} results = self.execute_query(query, params).fetchall() return [ @@ -476,8 +481,10 @@ def document_groups(self, document_id: UUID, offset: int = 0, limit: int = 100) ) for row in results ] - - def remove_document_from_group(self, document_id: UUID, group_id: UUID) -> None: + + def remove_document_from_group( + self, document_id: UUID, group_id: UUID + ) -> None: """ Remove a document from a group. @@ -504,5 +511,5 @@ def remove_document_from_group(self, document_id: UUID, group_id: UUID) -> None: if not result: raise R2RException( status_code=404, - message="Document not found in the specified group" - ) \ No newline at end of file + message="Document not found in the specified group", + ) diff --git a/py/core/providers/database/relational.py b/py/core/providers/database/relational.py index 04e7c3fef..e07282cbb 100644 --- a/py/core/providers/database/relational.py +++ b/py/core/providers/database/relational.py @@ -1,11 +1,12 @@ import logging +from sqlalchemy import exc, text + from core.providers.database.base import DatabaseMixin, execute_query from core.providers.database.document import DocumentMixin from core.providers.database.group import GroupMixin from core.providers.database.tokens import BlacklistedTokensMixin from core.providers.database.user import UserMixin -from sqlalchemy import exc, text logger = logging.getLogger(__name__) diff --git a/py/core/providers/database/user.py b/py/core/providers/database/user.py index 5ff701e26..92a0a6a97 100644 --- a/py/core/providers/database/user.py +++ b/py/core/providers/database/user.py @@ -2,10 +2,11 @@ from typing import Optional from uuid import UUID +from sqlalchemy import text + from core.base.abstractions import R2RException, UserStats from core.base.api.models.auth.responses import UserResponse from core.base.utils import generate_id_from_label -from sqlalchemy import text from .base import DatabaseMixin, QueryBuilder @@ -193,7 +194,6 @@ def update_user(self, user: UserResponse) -> UserResponse: group_ids=result[10], ) - def delete_user(self, user_id: UUID) -> None: print("A") # Get the groups the user belongs to @@ -201,12 +201,14 @@ def delete_user(self, user_id: UUID) -> None: SELECT group_ids FROM {self._get_table_name('users')} WHERE user_id = :user_id """ - group_result = self.execute_query(group_query, {"user_id": user_id}).fetchone() + group_result = self.execute_query( + group_query, {"user_id": user_id} + ).fetchone() print("B") if not group_result: raise R2RException(status_code=404, message="User not found") - + user_groups = group_result[0] print("C") @@ -217,7 +219,10 @@ def delete_user(self, user_id: UUID) -> None: SET user_ids = array_remove(user_ids, :user_id) WHERE group_id = ANY(:group_ids) """ - self.execute_query(group_update_query, {"user_id": user_id, "group_ids": user_groups}) + self.execute_query( + group_update_query, + {"user_id": user_id, "group_ids": user_groups}, + ) print("D") # Remove user from documents @@ -237,7 +242,9 @@ def delete_user(self, user_id: UUID) -> None: """ print("F") - result = self.execute_query(delete_query, {"user_id": user_id}).fetchone() + result = self.execute_query( + delete_query, {"user_id": user_id} + ).fetchone() if not result: raise R2RException(status_code=404, message="User not found") diff --git a/py/core/providers/database/vecs/collection.py b/py/core/providers/database/vecs/collection.py index d9f3485a2..a692ff48d 100644 --- a/py/core/providers/database/vecs/collection.py +++ b/py/core/providers/database/vecs/collection.py @@ -25,8 +25,6 @@ import psycopg2 import sqlalchemy as sa -from core.base import VectorSearchResult -from core.base.abstractions import VectorSearchSettings from flupy import flu from nltk.corpus import wordnet from nltk.stem import SnowballStemmer @@ -49,6 +47,9 @@ from sqlalchemy.dialects import postgresql from sqlalchemy.types import Float, UserDefinedType +from core.base import VectorSearchResult +from core.base.abstractions import VectorSearchSettings + from .adapter import Adapter, AdapterContext, NoOp, Record from .exc import ( ArgError, @@ -706,7 +707,8 @@ def expand_query(query: str) -> str: sa.and_( sa.or_( self.table.c.fts.op("@@")(ts_query), - sa.func.similarity(self.table.c.text, query_text) > 0.1, + sa.func.similarity(self.table.c.text, query_text) + > 0.1, self.table.c.fts.op("@@")( sa.func.phraseto_tsquery("english", query_text) ), @@ -719,15 +721,13 @@ def expand_query(query: str) -> str: ) ), ), - self.build_filters(search_settings.filters) + self.build_filters(search_settings.filters), ) ) .order_by(sa.desc("rank")) .limit(search_settings.hybrid_search_settings.full_text_limit) ) - - with self.client.Session() as sess: results = sess.execute(stmt).fetchall() @@ -786,7 +786,9 @@ def parse_condition(key, value): elif op == "$any": if key == "group_ids": # Use ANY for UUID array comparison - return func.array_to_string(column, ',').like(f"%{clause}%") + return func.array_to_string(column, ",").like( + f"%{clause}%" + ) # New operator for checking if any element in the array matches return column.any(clause) else: @@ -799,8 +801,10 @@ def parse_condition(key, value): # Handle JSON-based filters json_col = self.table.c.metadata if not key.startswith("metadata."): - raise FilterError("metadata key must start with 'metadata.'") - key = key.split('metadata.')[1] + raise FilterError( + "metadata key must start with 'metadata.'" + ) + key = key.split("metadata.")[1] if isinstance(value, dict): if len(value) > 1: raise FilterError("only one operator permitted") diff --git a/py/core/providers/database/vector.py b/py/core/providers/database/vector.py index 48b7197c6..3a140b556 100644 --- a/py/core/providers/database/vector.py +++ b/py/core/providers/database/vector.py @@ -1,7 +1,10 @@ -from uuid import UUID import logging import os from typing import Any, Optional +from uuid import UUID + +from sqlalchemy import text +from sqlalchemy.engine.url import make_url from core.base import ( DatabaseConfig, @@ -10,8 +13,6 @@ VectorSearchResult, ) from core.base.abstractions import VectorSearchSettings -from sqlalchemy import text -from sqlalchemy.engine.url import make_url from .vecs import Client, Collection, create_client @@ -325,7 +326,9 @@ def delete( return self.collection.delete(filters=filters) - def assign_document_to_group(self, document_id: str, group_id: str) -> None: + def assign_document_to_group( + self, document_id: str, group_id: str + ) -> None: """ Assign a document to a group in the vector database. @@ -352,13 +355,19 @@ def assign_document_to_group(self, document_id: str, group_id: str) -> None: ) with self.vx.Session() as sess: - result = sess.execute(query, {"document_id": document_id, "group_id": group_id}) + result = sess.execute( + query, {"document_id": document_id, "group_id": group_id} + ) sess.commit() if result.rowcount == 0: - logger.warning(f"Document {document_id} not found or already assigned to group {group_id}") + logger.warning( + f"Document {document_id} not found or already assigned to group {group_id}" + ) - def remove_document_from_group(self, document_id: str, group_id: str) -> None: + def remove_document_from_group( + self, document_id: str, group_id: str + ) -> None: """ Remove a document from a group in the vector database. @@ -385,11 +394,15 @@ def remove_document_from_group(self, document_id: str, group_id: str) -> None: ) with self.vx.Session() as sess: - result = sess.execute(query, {"document_id": document_id, "group_id": group_id}) + result = sess.execute( + query, {"document_id": document_id, "group_id": group_id} + ) sess.commit() if result.rowcount == 0: - logger.warning(f"Document {document_id} not found in group {group_id} or already removed") + logger.warning( + f"Document {document_id} not found in group {group_id} or already removed" + ) def remove_group_from_documents(self, group_id: str) -> None: if self.collection is None: @@ -407,7 +420,7 @@ def remove_group_from_documents(self, group_id: str) -> None: with self.vx.Session() as sess: sess.execute(query, {"group_id": group_id}) sess.commit() - + def delete_user(self, user_id: str) -> None: if self.collection is None: raise ValueError("Collection is not initialized.") @@ -423,7 +436,7 @@ def delete_user(self, user_id: str) -> None: with self.vx.Session() as sess: sess.execute(query, {"user_id": user_id}) - sess.commit() + sess.commit() def delete_group(self, group_id: str) -> None: """ @@ -452,9 +465,13 @@ def delete_group(self, group_id: str) -> None: sess.commit() affected_rows = result.rowcount - logger.info(f"Removed group {group_id} from {affected_rows} documents.") + logger.info( + f"Removed group {group_id} from {affected_rows} documents." + ) - def get_document_chunks(self, document_id: str, offset: int = 0, limit: int = 100) -> dict: + def get_document_chunks( + self, document_id: str, offset: int = 0, limit: int = 100 + ) -> dict: if not self.collection: raise ValueError("Collection is not initialized.") @@ -481,7 +498,9 @@ def get_document_chunks(self, document_id: str, offset: int = 0, limit: int = 10 with self.vx.Session() as sess: results = sess.execute(query, params).fetchall() - total_count = sess.execute(count_query, {"document_id": document_id}).scalar() + total_count = sess.execute( + count_query, {"document_id": document_id} + ).scalar() return [ { @@ -494,4 +513,4 @@ def get_document_chunks(self, document_id: str, offset: int = 0, limit: int = 10 "metadata": result[6], } for result in results - ] \ No newline at end of file + ] diff --git a/py/core/providers/embeddings/litellm.py b/py/core/providers/embeddings/litellm.py index 359a7a964..6edc17b01 100644 --- a/py/core/providers/embeddings/litellm.py +++ b/py/core/providers/embeddings/litellm.py @@ -2,6 +2,8 @@ import logging from typing import Any, List +from litellm import aembedding, embedding + from core.base import ( EmbeddingConfig, EmbeddingProvider, @@ -9,7 +11,6 @@ R2RException, VectorSearchResult, ) -from litellm import aembedding, embedding logger = logging.getLogger(__name__) diff --git a/py/core/providers/embeddings/ollama.py b/py/core/providers/embeddings/ollama.py index 6a6cc624c..c18880b96 100644 --- a/py/core/providers/embeddings/ollama.py +++ b/py/core/providers/embeddings/ollama.py @@ -2,6 +2,8 @@ import os from typing import Any, List +from ollama import AsyncClient, Client + from core.base import ( EmbeddingConfig, EmbeddingProvider, @@ -9,7 +11,6 @@ R2RException, VectorSearchResult, ) -from ollama import AsyncClient, Client logger = logging.getLogger(__name__) diff --git a/py/core/providers/embeddings/openai.py b/py/core/providers/embeddings/openai.py index 613fc6b88..129f033a6 100644 --- a/py/core/providers/embeddings/openai.py +++ b/py/core/providers/embeddings/openai.py @@ -2,14 +2,15 @@ import os from typing import Any, List +from openai import AsyncOpenAI, AuthenticationError, OpenAI +from openai._types import NOT_GIVEN + from core.base import ( EmbeddingConfig, EmbeddingProvider, EmbeddingPurpose, VectorSearchResult, ) -from openai import AsyncOpenAI, AuthenticationError, OpenAI -from openai._types import NOT_GIVEN logger = logging.getLogger(__name__) diff --git a/py/core/providers/llm/openai.py b/py/core/providers/llm/openai.py index f960ef425..d4dddd46b 100644 --- a/py/core/providers/llm/openai.py +++ b/py/core/providers/llm/openai.py @@ -2,9 +2,10 @@ import os from typing import Any +from openai import AsyncOpenAI, OpenAI + from core.base.abstractions.llm import GenerationConfig from core.base.providers.llm import CompletionConfig, CompletionProvider -from openai import AsyncOpenAI, OpenAI logger = logging.getLogger(__name__) diff --git a/py/core/providers/prompts/r2r_prompts.py b/py/core/providers/prompts/r2r_prompts.py index 4cf93460c..ef0a74fc0 100644 --- a/py/core/providers/prompts/r2r_prompts.py +++ b/py/core/providers/prompts/r2r_prompts.py @@ -5,6 +5,7 @@ import toml import yaml + from core.base import Prompt, PromptConfig, PromptProvider logger = logging.getLogger(__name__) diff --git a/py/core/telemetry/posthog.py b/py/core/telemetry/posthog.py index ce2df4d40..05bc5c3fb 100644 --- a/py/core/telemetry/posthog.py +++ b/py/core/telemetry/posthog.py @@ -2,6 +2,7 @@ import os import posthog + from core.telemetry.events import BaseTelemetryEvent logger = logging.getLogger(__name__) diff --git a/py/pyproject.toml b/py/pyproject.toml index 2a2d380b2..c7a2a3c39 100644 --- a/py/pyproject.toml +++ b/py/pyproject.toml @@ -106,6 +106,10 @@ extend-exclude = ''' )/ ''' +[tool.isort] +line_length = 79 +profile = "black" + [tool.mypy] ignore_missing_imports = true exclude = 'playground/.*|deprecated/.*|dump/.*|docs/source|vecs/*' @@ -128,4 +132,3 @@ filterwarnings = [ "ignore::DeprecationWarning", "ignore::pytest.PytestUnraisableExceptionWarning", ] - diff --git a/py/r2r.toml b/py/r2r.toml index 7bd15e132..a32c89229 100644 --- a/py/r2r.toml +++ b/py/r2r.toml @@ -57,4 +57,4 @@ provider = "r2r" [agent] system_instruction_name = "rag_agent" -tool_names = ["search"] \ No newline at end of file +tool_names = ["search"] diff --git a/py/sdk/auth.py b/py/sdk/auth.py index 5ef62b89e..6a63f0f48 100644 --- a/py/sdk/auth.py +++ b/py/sdk/auth.py @@ -170,4 +170,4 @@ async def confirm_password_reset( dict: The response from the server. """ data = {"reset_token": reset_token, "new_password": new_password} - return await client._make_request("POST", "reset_password", json=data) \ No newline at end of file + return await client._make_request("POST", "reset_password", json=data) diff --git a/py/sdk/management.py b/py/sdk/management.py index 1c95c4445..a8f82522b 100644 --- a/py/sdk/management.py +++ b/py/sdk/management.py @@ -331,7 +331,6 @@ async def delete_group( """ return await client._make_request("DELETE", f"delete_group/{group_id}") - @staticmethod async def delete_user( client, @@ -356,8 +355,9 @@ async def delete_user( if params == {}: return await client._make_request("DELETE", f"user/{user_id}") else: - return await client._make_request("DELETE", f"user/{user_id}", json=params) - + return await client._make_request( + "DELETE", f"user/{user_id}", json=params + ) @staticmethod async def list_groups( @@ -479,9 +479,7 @@ async def user_groups( if limit is not None: params["limit"] = limit if params: - return await client._make_request( - "GET", f"user_groups/{user_id}" - ) + return await client._make_request("GET", f"user_groups/{user_id}") else: return await client._make_request( "GET", f"user_groups/{user_id}", params=params @@ -541,7 +539,7 @@ async def document_groups( client, document_id: str, offset: Optional[int] = None, - limit: Optional[int] = None + limit: Optional[int] = None, ) -> dict: """ Get all groups that a document is assigned to. diff --git a/py/sdk/models.py b/py/sdk/models.py index 895f632d5..bba344f50 100644 --- a/py/sdk/models.py +++ b/py/sdk/models.py @@ -236,7 +236,6 @@ class IndexMeasure(str, Enum): max_inner_product = "max_inner_product" - class HybridSearchSettings(BaseModel): full_text_weight: float = Field( default=1.0, description="Weight to apply to full text search" @@ -252,6 +251,7 @@ class HybridSearchSettings(BaseModel): default=50, description="K-value for RRF (Rank Reciprocal Fusion)" ) + class VectorSearchSettings(BaseModel): use_vector_search: bool = Field( default=True, description="Whether to use vector search" diff --git a/py/tests/cli/commands/test_auth.py b/py/tests/cli/commands/test_auth.py index b1670c214..a2c5631e3 100644 --- a/py/tests/cli/commands/test_auth.py +++ b/py/tests/cli/commands/test_auth.py @@ -1,7 +1,8 @@ import pytest -from cli.commands.auth import generate_private_key from click.testing import CliRunner +from cli.commands.auth import generate_private_key + @pytest.fixture def runner(): diff --git a/py/tests/cli/commands/test_ingestion.py b/py/tests/cli/commands/test_ingestion.py index 28c26a3dc..16cdf7636 100644 --- a/py/tests/cli/commands/test_ingestion.py +++ b/py/tests/cli/commands/test_ingestion.py @@ -3,9 +3,10 @@ import click import pytest -from cli.cli import cli from click.testing import CliRunner +from cli.cli import cli + @pytest.fixture def runner(): diff --git a/py/tests/cli/commands/test_management.py b/py/tests/cli/commands/test_management.py index fe1854590..68435dba9 100644 --- a/py/tests/cli/commands/test_management.py +++ b/py/tests/cli/commands/test_management.py @@ -3,9 +3,10 @@ import click import pytest -from cli.cli import cli from click.testing import CliRunner +from cli.cli import cli + @pytest.fixture def runner(): diff --git a/py/tests/cli/commands/test_restructure.py b/py/tests/cli/commands/test_restructure.py index fb5967e9e..e7ebaf5ba 100644 --- a/py/tests/cli/commands/test_restructure.py +++ b/py/tests/cli/commands/test_restructure.py @@ -3,9 +3,10 @@ import click import pytest -from cli.cli import cli from click.testing import CliRunner +from cli.cli import cli + @pytest.fixture def runner(): diff --git a/py/tests/cli/test_cli.py b/py/tests/cli/test_cli.py index 8605a5d23..c4be1cd1c 100644 --- a/py/tests/cli/test_cli.py +++ b/py/tests/cli/test_cli.py @@ -1,7 +1,8 @@ import pytest -from cli.cli import cli, main from click.testing import CliRunner +from cli.cli import cli, main + @pytest.fixture def runner(): diff --git a/py/tests/cli/test_command_group.py b/py/tests/cli/test_command_group.py index bb4e113da..408703027 100644 --- a/py/tests/cli/test_command_group.py +++ b/py/tests/cli/test_command_group.py @@ -1,7 +1,8 @@ import pytest -from cli.command_group import cli from click.testing import CliRunner +from cli.command_group import cli + @pytest.fixture def runner(): diff --git a/py/tests/cli/utils/test_docker_utils.py b/py/tests/cli/utils/test_docker_utils.py index abc4e7408..121a096da 100644 --- a/py/tests/cli/utils/test_docker_utils.py +++ b/py/tests/cli/utils/test_docker_utils.py @@ -3,6 +3,8 @@ from unittest.mock import MagicMock, patch import pytest +from click.testing import CliRunner + from cli.utils.docker_utils import ( bring_down_docker_compose, build_docker_command, @@ -12,7 +14,6 @@ find_available_port, remove_r2r_network, ) -from click.testing import CliRunner @pytest.fixture diff --git a/py/tests/cli/utils/test_param_types.py b/py/tests/cli/utils/test_param_types.py index 71c6368e7..67d19e11e 100644 --- a/py/tests/cli/utils/test_param_types.py +++ b/py/tests/cli/utils/test_param_types.py @@ -2,6 +2,7 @@ import click import pytest + from cli.utils.param_types import JSON, JsonParamType diff --git a/py/tests/cli/utils/test_timer.py b/py/tests/cli/utils/test_timer.py index 109bc3e02..7081d9b5c 100644 --- a/py/tests/cli/utils/test_timer.py +++ b/py/tests/cli/utils/test_timer.py @@ -2,6 +2,7 @@ from unittest.mock import patch import pytest + from cli.utils.timer import timer diff --git a/py/tests/regression/runner.py b/py/tests/regression/runner.py index c62784ae2..ac83e0bfb 100644 --- a/py/tests/regression/runner.py +++ b/py/tests/regression/runner.py @@ -4,10 +4,10 @@ from typing import List from colorama import Fore, Style, init +from test_cases.base import BaseTest, RegressionTest # TODO: need to import this from the package, not from the local directory from r2r import R2RClient -from test_cases.base import BaseTest, RegressionTest class RegressionTestRunner: diff --git a/py/tests/test_abstractions.py b/py/tests/test_abstractions.py index 2e167e70e..b9e81ad1d 100644 --- a/py/tests/test_abstractions.py +++ b/py/tests/test_abstractions.py @@ -3,6 +3,7 @@ from datetime import datetime import pytest + from core import ( AsyncPipe, AsyncState, diff --git a/py/tests/test_auth.py b/py/tests/test_auth.py index 152617f0e..e4199f1a7 100644 --- a/py/tests/test_auth.py +++ b/py/tests/test_auth.py @@ -3,6 +3,7 @@ from unittest.mock import Mock, patch import pytest + from core import ( AuthConfig, BCryptConfig, diff --git a/py/tests/test_cli.py b/py/tests/test_cli.py index cedd40a71..2a3c50263 100644 --- a/py/tests/test_cli.py +++ b/py/tests/test_cli.py @@ -2,9 +2,10 @@ import click import pytest +from click.testing import CliRunner + from cli.cli import cli from cli.utils.param_types import JSON -from click.testing import CliRunner @pytest.fixture diff --git a/py/tests/test_client.py b/py/tests/test_client.py index 312e6ebfe..9040c0206 100644 --- a/py/tests/test_client.py +++ b/py/tests/test_client.py @@ -3,6 +3,10 @@ from unittest.mock import MagicMock import pytest +from fastapi import Body, Depends +from fastapi.security import OAuth2PasswordBearer +from fastapi.testclient import TestClient + from core import ( DocumentInfo, R2RApp, @@ -12,9 +16,6 @@ Token, UserResponse, ) -from fastapi import Body, Depends -from fastapi.security import OAuth2PasswordBearer -from fastapi.testclient import TestClient # TODO: need to import this from the package, not from the local directory from r2r import R2RClient diff --git a/py/tests/test_config.py b/py/tests/test_config.py index a84df71cb..5d2ffc28f 100644 --- a/py/tests/test_config.py +++ b/py/tests/test_config.py @@ -3,6 +3,7 @@ import pytest import toml + from core import DocumentType, R2RConfig diff --git a/py/tests/test_database.py b/py/tests/test_database.py index 81681b1ba..7a327030e 100644 --- a/py/tests/test_database.py +++ b/py/tests/test_database.py @@ -2,6 +2,8 @@ import uuid import pytest +from dotenv import load_dotenv + from core import ( DatabaseConfig, DatabaseProvider, @@ -11,7 +13,6 @@ generate_id_from_label, ) from core.providers import PostgresDBProvider -from dotenv import load_dotenv load_dotenv() diff --git a/py/tests/test_embedding.py b/py/tests/test_embedding.py index 8cca96d4f..b55394833 100644 --- a/py/tests/test_embedding.py +++ b/py/tests/test_embedding.py @@ -2,6 +2,7 @@ from unittest.mock import patch import pytest + from core import EmbeddingConfig diff --git a/py/tests/test_end_to_end.py b/py/tests/test_end_to_end.py index 3ff675544..b74d6b61e 100644 --- a/py/tests/test_end_to_end.py +++ b/py/tests/test_end_to_end.py @@ -3,6 +3,8 @@ import uuid import pytest +from fastapi.datastructures import UploadFile + from core import ( Document, DocumentInfo, @@ -19,7 +21,6 @@ VectorSearchSettings, generate_id_from_label, ) -from fastapi.datastructures import UploadFile @pytest.fixture(scope="session", autouse=True) diff --git a/py/tests/test_groups.py b/py/tests/test_groups.py index 0e13c2212..11129b0a8 100644 --- a/py/tests/test_groups.py +++ b/py/tests/test_groups.py @@ -3,6 +3,7 @@ from uuid import UUID import pytest + from core import DatabaseConfig, R2RException from core.base.abstractions import DocumentInfo, DocumentStatus, DocumentType from core.providers import BCryptConfig, BCryptProvider, PostgresDBProvider diff --git a/py/tests/test_groups_client.py b/py/tests/test_groups_client.py index dfc691af5..06e0520ea 100644 --- a/py/tests/test_groups_client.py +++ b/py/tests/test_groups_client.py @@ -3,11 +3,12 @@ from unittest.mock import MagicMock import pytest -from core import R2RApp, R2RBuilder, R2REngine, Token, UserResponse -from core.base import GroupResponse from fastapi import Depends from fastapi.security import OAuth2PasswordBearer from fastapi.testclient import TestClient + +from core import R2RApp, R2RBuilder, R2REngine, Token, UserResponse +from core.base import GroupResponse from r2r import R2RClient oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") diff --git a/py/tests/test_ingestion_service.py b/py/tests/test_ingestion_service.py index 2fdc7fa01..a0bf419aa 100644 --- a/py/tests/test_ingestion_service.py +++ b/py/tests/test_ingestion_service.py @@ -6,6 +6,8 @@ from unittest.mock import AsyncMock, MagicMock, Mock import pytest +from fastapi import UploadFile + from core import R2RAgents from core.base import ( Document, @@ -18,7 +20,6 @@ ) from core.main import R2RPipelines, R2RProviders from core.main.services.ingestion_service import IngestionService -from fastapi import UploadFile logger = logging.getLogger(__name__) diff --git a/py/tests/test_kg.py b/py/tests/test_kg.py index 1236c492c..3059b9009 100644 --- a/py/tests/test_kg.py +++ b/py/tests/test_kg.py @@ -3,6 +3,7 @@ from uuid import uuid4 import pytest + from core.base import Community, DocumentFragment, Entity, KGExtraction, Triple from core.pipes.kg.clustering import KGClusteringPipe from core.pipes.kg.extraction import KGTriplesExtractionPipe diff --git a/py/tests/test_llms.py b/py/tests/test_llms.py index 0430d0459..6a22b494a 100644 --- a/py/tests/test_llms.py +++ b/py/tests/test_llms.py @@ -3,6 +3,7 @@ from unittest.mock import AsyncMock, MagicMock, patch import pytest + from core import CompletionConfig, GenerationConfig from core.base.abstractions.llm import ( LLMChatCompletion, diff --git a/py/tests/test_logging.py b/py/tests/test_logging.py index d58a32728..860d8a8bc 100644 --- a/py/tests/test_logging.py +++ b/py/tests/test_logging.py @@ -5,6 +5,7 @@ from uuid import UUID import pytest + from core import ( LocalRunLoggingProvider, LoggingConfig, diff --git a/py/tests/test_parser.py b/py/tests/test_parser.py index be6108a1a..b0e174c8c 100644 --- a/py/tests/test_parser.py +++ b/py/tests/test_parser.py @@ -3,6 +3,7 @@ from unittest.mock import MagicMock, patch import pytest + from core.parsers.media.docx_parser import DOCXParser from core.parsers.media.pdf_parser import PDFParser from core.parsers.media.ppt_parser import PPTParser diff --git a/py/tests/test_pipeline.py b/py/tests/test_pipeline.py index 5a228821f..3a1f12d77 100644 --- a/py/tests/test_pipeline.py +++ b/py/tests/test_pipeline.py @@ -2,6 +2,7 @@ from typing import Any, AsyncGenerator import pytest + from core import AsyncPipe, AsyncPipeline, PipeType diff --git a/py/tests/test_vector_db.py b/py/tests/test_vector_db.py index 342940a6e..b852b4a39 100644 --- a/py/tests/test_vector_db.py +++ b/py/tests/test_vector_db.py @@ -2,6 +2,7 @@ from uuid import UUID, uuid4 import pytest + from core.base import DatabaseConfig, Vector, VectorEntry, VectorSearchSettings from core.providers import PostgresDBProvider From 76cd6db1642b076ceafb1b9cedca345d21c6ddee Mon Sep 17 00:00:00 2001 From: Nolan Tremelling <34580718+NolanTrem@users.noreply.github.com> Date: Thu, 22 Aug 2024 18:03:34 -0700 Subject: [PATCH 56/74] Remove email from refresh (#948) --- py/core/base/abstractions/search.py | 4 ++++ py/core/base/providers/auth.py | 4 +--- py/core/main/api/routes/auth/base.py | 1 - py/core/main/services/auth_service.py | 6 ++---- .../pipes/retrieval/kg_search_search_pipe.py | 18 +++++++++++++++--- py/core/providers/auth/r2r_auth.py | 15 +++------------ py/sdk/models.py | 5 +++-- 7 files changed, 28 insertions(+), 25 deletions(-) diff --git a/py/core/base/abstractions/search.py b/py/core/base/abstractions/search.py index affc9cb9f..565728794 100644 --- a/py/core/base/abstractions/search.py +++ b/py/core/base/abstractions/search.py @@ -54,8 +54,10 @@ class Config: }, } + class KGLocalSearchResult(BaseModel): """Result of a local knowledge graph search operation.""" + query: str entities: list[dict[str, Any]] relationships: list[dict[str, Any]] @@ -70,6 +72,7 @@ def __repr__(self) -> str: class KGGlobalSearchResult(BaseModel): """Result of a global knowledge graph search operation.""" + query: str search_result: list[Dict[str, Any]] @@ -82,6 +85,7 @@ def __repr__(self) -> str: class KGSearchResult(BaseModel): """Result of a knowledge graph search operation.""" + local_result: Optional[KGLocalSearchResult] = None global_result: Optional[KGGlobalSearchResult] = None diff --git a/py/core/base/providers/auth.py b/py/core/base/providers/auth.py index f979f38ba..17f2a2508 100644 --- a/py/core/base/providers/auth.py +++ b/py/core/base/providers/auth.py @@ -90,9 +90,7 @@ def login(self, email: str, password: str) -> Dict[str, Token]: pass @abstractmethod - def refresh_access_token( - self, user_email: str, refresh_token: str - ) -> Dict[str, str]: + def refresh_access_token(self, refresh_token: str) -> Dict[str, str]: pass async def auth_wrapper( diff --git a/py/core/main/api/routes/auth/base.py b/py/core/main/api/routes/auth/base.py index 408ee555e..9dac245b9 100644 --- a/py/core/main/api/routes/auth/base.py +++ b/py/core/main/api/routes/auth/base.py @@ -141,7 +141,6 @@ async def refresh_access_token_app( This endpoint allows users to obtain a new access token using their refresh token. """ refresh_result = await self.engine.arefresh_access_token( - user_email=auth_user.email, refresh_token=refresh_token, ) return refresh_result diff --git a/py/core/main/services/auth_service.py b/py/core/main/services/auth_service.py index 5229ed3a0..d704ae91d 100644 --- a/py/core/main/services/auth_service.py +++ b/py/core/main/services/auth_service.py @@ -74,11 +74,9 @@ async def user(self, token: str) -> UserResponse: @telemetry_event("RefreshToken") async def refresh_access_token( - self, user_email: str, refresh_token: str + self, refresh_token: str ) -> dict[str, Token]: - return self.providers.auth.refresh_access_token( - user_email, refresh_token - ) + return self.providers.auth.refresh_access_token(refresh_token) @telemetry_event("ChangePassword") async def change_password( diff --git a/py/core/pipes/retrieval/kg_search_search_pipe.py b/py/core/pipes/retrieval/kg_search_search_pipe.py index e5664fae5..fcd37889a 100644 --- a/py/core/pipes/retrieval/kg_search_search_pipe.py +++ b/py/core/pipes/retrieval/kg_search_search_pipe.py @@ -14,12 +14,17 @@ PromptProvider, RunLoggingSingleton, ) +from core.base.abstractions.search import ( + KGGlobalSearchResult, + KGLocalSearchResult, + KGSearchResult, +) -from core.base.abstractions.search import KGLocalSearchResult, KGGlobalSearchResult, KGSearchResult from ..abstractions.generator_pipe import GeneratorPipe logger = logging.getLogger(__name__) + class KGSearchSearchPipe(GeneratorPipe): """ Embeds and stores documents using a specified embedding model and database. @@ -127,7 +132,12 @@ async def local_search( ) all_search_results.append(search_result) - yield KGLocalSearchResult(query=message, entities=all_search_results[0], relationships=all_search_results[1], communities=all_search_results[2]) + yield KGLocalSearchResult( + query=message, + entities=all_search_results[0], + relationships=all_search_results[1], + communities=all_search_results[2], + ) async def global_search( self, @@ -209,7 +219,9 @@ async def process_community(merged_report): output = output.choices[0].message.content - yield KGGlobalSearchResult(query=message, search_result=output, citations=None) + yield KGGlobalSearchResult( + query=message, search_result=output, citations=None + ) async def _run_logic( self, diff --git a/py/core/providers/auth/r2r_auth.py b/py/core/providers/auth/r2r_auth.py index 7dab2d02a..d82257f73 100644 --- a/py/core/providers/auth/r2r_auth.py +++ b/py/core/providers/auth/r2r_auth.py @@ -197,25 +197,18 @@ def login(self, email: str, password: str) -> Dict[str, Token]: raise R2RException(status_code=401, message="Email not verified") access_token = self.create_access_token(data={"sub": user.email}) - refresh_token = self.create_refresh_token(data={"sub": user.email}) + refresh_token = self.create_refresh_token() return { "access_token": Token(token=access_token, token_type="access"), "refresh_token": Token(token=refresh_token, token_type="refresh"), } - def refresh_access_token( - self, user_email: str, refresh_token: str - ) -> Dict[str, Token]: + def refresh_access_token(self, refresh_token: str) -> Dict[str, Token]: token_data = self.decode_token(refresh_token) if token_data.token_type != "refresh": raise R2RException( status_code=401, message="Invalid refresh token" ) - if token_data.email != user_email: - raise R2RException( - status_code=402, - message="Invalid email address attached to token", - ) # Invalidate the old refresh token and create a new one self.db_provider.relational.blacklist_token(refresh_token) @@ -223,9 +216,7 @@ def refresh_access_token( new_access_token = self.create_access_token( data={"sub": token_data.email} ) - new_refresh_token = self.create_refresh_token( - data={"sub": token_data.email} - ) + new_refresh_token = self.create_refresh_token() return { "access_token": Token(token=new_access_token, token_type="access"), "refresh_token": Token( diff --git a/py/sdk/models.py b/py/sdk/models.py index bba344f50..571659dfb 100644 --- a/py/sdk/models.py +++ b/py/sdk/models.py @@ -200,13 +200,14 @@ class Config: { "Paris": { "name": "Paris", - "description": "Paris is the capital of France." + "description": "Paris is the capital of France.", } } - ] + ], } } + class R2RException(Exception): def __init__( self, message: str, status_code: int, detail: Optional[Any] = None From 274c32b88835c975254d44272782428177e66178 Mon Sep 17 00:00:00 2001 From: NolanTrem <34580718+NolanTrem@users.noreply.github.com> Date: Thu, 22 Aug 2024 18:13:46 -0700 Subject: [PATCH 57/74] Fix link to image --- assets/quickstart.gif | Bin 5034602 -> 0 bytes assets/r2r.png | Bin 1248884 -> 0 bytes py/README.md | 2 +- 3 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 assets/quickstart.gif delete mode 100644 assets/r2r.png diff --git a/assets/quickstart.gif b/assets/quickstart.gif deleted file mode 100644 index 16e44b5c7956cf18d4183efbaf931c2813a11031..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5034602 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

N)BTZW@bLKFE|UV%V8YZFqxq;B`y4VRW}1AyXz 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⪙O=yk`Z^OEfEHu6|u$b^`e$bv#}P4;!nD94mkBQTtY+ zD$ltlt?6g&SP?AzSv#i2qX0G}7?TB@jRLu`Nr`i{DO~SkiR(Uhzz00)Mr!IN4(bY( zYvPpOzmI-DTu?VLP%|Y_o1$Oa99E0(Fm4Ys=EgvHk>IOJ2zM07SsxEc1I`l?$n}*F z1W1+yswKcrVIXHk>Nc}MI5)`T2`I+Hp{DhuN%fSqb+jxETs0xwLvJ`yat$9^A(yE(j+Q>` zXS}oTND1ihtn6@4gd5n$@pp#D565}Hxv}kN&m=mvcsh~~J%Q(rt!jkl3d;l1| z1>u0z4%ow~g=&YgI+K(u+ZljUNRUee(o@(a8j&f^3P?uu%~kXzY(eC@8WM>6eO3Ea zCg3lv;1?$#;|qWn6EI?5qZ0v;rh(jW@F=bL2|4?3K-O4xeZuTKKU;Lj(OO&Vx%v0JB^Jt5zrnD{vM_j8yJ=EURP+ojG`1H4l;OR`;vL}CU1JdJSiRQ3()IB;i}BW?@mS}sQ%BF{OzZNc z2jhzRC~(fPTz!=j@F6q!$$Bqt6!6%g8ZJBDC-9yo4djAhdFrd~#M-}M9ovOZoeG}{ z?HW(=Xo29SAo5(-})6B>S&4}Ngkc^zEDVp&bo=J$VP%4J= zAY9I4?o0B1j?J2^)EbG&8eEwetQmt-Je}G*>W=G}k$0?tC&8&Es?SH&!MDGN%Fk2D zx9CmYe-qKNR|&_9MP^vD0x=W5d@R7Q1Dw!?j^Bbj2?IS?0k6m}{A^2cO+OGM{iQ`vr)>W7s5-ggpIlE>tmWATpS=PvWwwO{T%6XQdZ|3hJNwF*}WwQ zxhI~mJY<+tv;HJIaN22;(HlJTW}bB&&h`f6cr#n7^_36tl{fVhzxR;1Y#j+9dv4!2 zPy}dDeP-E!FLuvfd=n{sry}QI(~YI&d@&%OWI?0|qKCgSc(3=RtShkB@S(w_xE5aI zRwm`QM6IncfmSx%))6!Cd_9EC3@q`Qel^_s%=B}rStL_xCDjy;ACDt$?!X7^Vru7! zVQVfblNDS$z!jWjpOaq{1`;n*~Yp52nfO?-q5E#c$^d zGJU?ete3A}bh{}*f5o8KtnMi>vw{6ktfZkEdbxzhHhnoaS|*zk4L5GT z_d3E8vl!tJc@`F*--X=b(MeSdh&gY2I`3w-cKXTYB=|SW?qoS{JPE7uJJnBCrwS~_ zw;#+_zFNA?#%i){KU(H6)to%`$fnVTq15@%pk%z=*_mB6#dPoCd{=Vce1yT~XtU$l zPsy@FB@+u1b>5`xw-4RE3g2ami9A#3JU9~eNtpc(-gAFzZEEPu(f5tzg14uJZ02C-1LkjUB7DxL^2FS*W>>i7>lXbdKrD^s=v%1vWyIVTS)&0s`Zx7$; z5w32f=}xdX_vqaTkT6g->?+lTJ2goRU9#aiebdaFSkj2+iI?83yU&y*M^1%woz}KU z4UjYj2b=k4XNzB8sW`m^A zv36(PL$L0EL>5{kRGCX&PY+|70d(g}tba<}id`|7xK<*0JM_r^JJsj@R%Wn;X>Lp5LZ~jy<<}w7k7`${dcp_FhML zKRtL}bo}(lyUW}A*kWz!m?$_OpuwP0_^}W?omw7|Fvh3U*u?#zcCe^ofj2wf$9b2UFoZ5+M)ubu05xIQ2FV^QdE#a zVHB;8bR(4fd9Z5ZvlGuN8~1phhv=|8JC!col7nwm?B3mHyX>bbw|zp)^ZR{{Z`)1fWqAhQPnw?- zB2rV9{3;y&*qrkNc>TJ;MFs!x^TcJr;u-B2k88R%AM3`aA^Q1Ze9!4F(ez7N z-|A0>2PVBH&a2Y;sP-~(iV7vwP^I-C@=?N^_<~q(ytaAq%j8Bv;n;^zIG%rzvQ;=I zw>hHjwO;z_=(`mU%2r3dh`p!ZG#i)w83jgu?MNx-x54Lg84FP&l?G z6pq^%Z$5wcJd-Q=%k>-k*P@FbhX^?@ow$3Z?<}EktUxFnyAle=lTkTx$fj*lav3-`rV;A^o4 zW$n+39Gs_2rt{^ix(7U+%L;aJgu?O0TJ)RIZ!33-7>pX!pP>VsC-0spkZlqkbc=8< z#1RU|Q-s2CHKB0qKqwryN0uf#Pgp4x$n-`IKF*RTS|k*XdkBT&1VZ6hh)_88b&S6& z%gJg-sXe;B{h)43Xvs0Gi^5T~a)G6oC9I=uhWk`ym(Y*Gu{5D@>@-j&yz-);?S^G+ z!thq{L_PEEVF$xkg`965b=9>_`IB$$#nWx@%#lF8&y5aSp;`W_ogAa$ZPGa7B zcL0;psP+j?K5|nGuwal#NpI~}YGX*OJDs6&3iuz}gY{HfBa_=#smHe8aT z7~Q0MU!0{I1j}bb?o`mLv^kQ0-KE*m;lmBR8kbR^UKDLVdEs3k=~e3rdsapE0{ z1=^1IV6$?u23(RAt~b8N>OGQogn3S(=MtvwG%}vj?3TiX{jMO(Y`?M9#bn8Z&uZh} zvSy-fv|jgoP9`~*qm(Rs<5_}Ns-y&sMzZa*^n?K==dFT}Gj?$H=)p3B<)Q}@dS)AE z^6R#@^n6(D3uqFD;S$?#s}k%jyrW0D=vPY9%?xaGn2QF=w~gN>J5)F(jy>4gu2?$b z_+Tn}d~R^1s&~TB8UKbEz2>rmm}YhQ)SWmPQnpjal<4H85HocYv-$yY8}38PQc5hf zYk49C*(01Zo$kE*={oa+kkptjbcSn9qLaoEPAuiDJG=HuY!An-oT)e!Db}{)@bJrf zqq!NAt&S6PkK&=B^AbCKT@Rj?KHnHe%IxeFyR$uBrb%8LlGyJp>v%}CV6?PrDdQS+ z_}xoY?vsDEdwr4oqKH*8)?~veq3-GBv}eg07E(1#FH>Chij&v2oDaq}nO&eP% zQD2iQm==`S%X*&S(q5?Fc*Jd*a!>0((>TDH8Bo%rRbTEAa;t8{fVq)8MmS^ThCw z%J1!2dToUT9j%d$?My3(?)7;05emmSO$u9wuh))_XipzP6(8??fapbn;)=71^+cz+ zA?Ec|59>)gV~AfVju8sS{*h#jiu=9w)SfYv-|NpU)x#Q7PjD*Tg*2Qx3_q>cAa}8W zzMqcXUrFUj15+&>)4K-8{00_(I+j@_YC_?dGmYc)m0Oz)=T^fAh2uIx;kYx5`|(HB zb02xfPxEHtKcdke1(GuP`mbDX`zZYCq%hG{ve6IR%vWFTeH3d971z63fcPZY$sp?g zDe2{>OS4rM8)Ysx#!2;GZOr>5|LT-H(Y05wMkVo(E8^E)C^lXridHbcmhzxcb@hev zt81Tw8`bqL%dX03vM{R8UZbmO)bTv2b6UBLyy@omnp@YJ>ie!Kn<($wHPw13yPa)< zhX)f1$3gXk!ZC~fY}1*qO?O^BH#^qIIXNO=Hac zcg;xKW_$ZOhgp^3*D8|-&9vW}AH1tWinrXl+VZ$F?xA@L*q~w;u4Z1O_3moR9sHr{ZK_sN7Bv&WR=8}dp=PVTshXaB>rGF!8{w@wNov}KYMQmJ>YZxW z$6Hlb)l?2!uTfpU%F?DJcwJGpORhE;8OG zyn0>euuXtUou8$hS5Tctww+5;ozt}aoW1&4&vy23b+)8-mO^#r+IFT+b;j{_`c-wh z!}e2D8YfvgV1gR7vK`c#8dRno6!seAo*ks&8YD>_M1>mA+73vk1~A@%U+FkJ&^Vy% z++)_<73kc)thuG3`PD=dXVZ@WRtZ5N65Q-6sKgKW#WVVU zv#V;ucH+fxowh_>2)?l1Lch|2DVqAB|iBJc$ zc4ob{90Dqe0oT8G+d*`MU{FbnpAxSQ_K+!^>vSO!p-lRr%vm5$Yp>N4?F-mmZhmYNI{aFCX}hGHCou93{i}k01+c+^Ek9S!1}*UX-I zTkCI&++>=-oUsT!ojYK9-KSLT1_$*m{>=fo0IKsvU4qel;%Ni-Bj~6_1|*MqWwS8l zZU%;3y4!^}E=~A=^@E0@C^qREdRmmXi)g&a3=u*UMqB;15)f)#)MNbCX<`g;YS=(e zuHVv(_6hY61#9=Qb^k*zs3b2`1m`Pec9X}*_dH<{C9m&U%zqb-qv%GSbB(+p#D_CM#Kz%e!(2#^H_caK z3lymzaFHY8vw$6U>iH!P4MYuA8VxI8{A3V>=Vds!&Q~A}z2`jMdGJz26%9Ks;VgH{QTC{!wE5lk#|@{&(Ps9ew+P%Y|+L^WZIe$hWI;m#)UvY5!7(-fbUz@v8-Pg zj)^C+bd%FulV2nzXOt&r^(W^nCg+_e7Xl_1qbHZLCYQ@5SDGeQ2PW6%CfBznH;C`7 zmQ4s?z%B=45g4@F!q0`3h%DLPm23D%%$b#fN=UoN%U@aAe{gMdNXYM)&W})5hHU%( zL*dv3OB#qJi@}m-V<`yTVL}dg5KBFerP;>Pl1#(sr%!NCpOly!DG?l&l0*^+;k-sS%H-8Zv z{30~}MR@zm1(F#N`WaE~nTwJ$Vk$G@1~U?tGmaa7d!_Syyh34ZZCL~ETZTae-@6dpUzu4cF*V5&9h2c zDrs9cUjz_HV?kt+e`O3#L_a% zWnQam(He%ao?m<&H?M+U{7vDwB5LV)y*66D zHrBj0KDah9zc#tOHbt_IrC*=sUjHJwKBKb!4~1iShxTm8&-4z-mG;fMI_D- zO@^RN#@J1!oXs;8o6IenEJK^D3!7{^o9v`tIT*hFbK&?Q<%Lb&7UYSY)gR^Lp=Daq z4gO>M6YLuoc5L|=zKQaDyD0TdO!b?%;Wr7ZZ<4Oxq=LRl$9}t%^G&AW+vS$uD;z)W zAo+HI;X&v8LmVC{xPhZxSjNqNRcZOIIrLp?;k)+EcOB9#U52e2JX<%Vwr;6z=^6gJ z!ZEG0@Qyu>`*Uc__v=Fs@2MIQq{1(SW9!&$o1AUiify}=ZTq2ZhlSrS9J}tg2JN`f zx>}UvED9)W-_QAOmA&It@%YK_7LMJl7IuPrTshwFc%<%bMDG3o#|yiWJG;+F_o5i~ z{*MaBANIm3c0x(rX?OPit8lEkpJ}+CWwoE}x}OuYpBuZMm$RQ=v0u=#UpTa1w6I^i zv;T(l0L^glmgk_vX+O?dz6j99KhGu9sxC zz2v=>Z~A|^PR?peRZxgOI@tZTGS&0p!|^dd!iz-_(OYAE$hdQ{zEqNn|A#u6p)*XR znRg~!e9(F(LV7-TCQ^2LapsvK3EyngHF}%b=W5(}voACymu6q;s_@Od(lfA`i#EF5 zHsx8@Wbx%nN>#-dNg?i2uZ69%^TGt}%a`U8kovG$fsNYlgLWHryYmGb?+>?EHa-BPg1CAj z276os8BZbZBbC%D?h{N^aI^8Wq5WnPV z8B+Ljo;zBte_AJt{nW`q9W4!OgIA)0C;pXAW;!42Dk~!`Lh}Im*K~3e4c=XZ?d)%LvLoFOoxG(O zL{_atZ7cnWshyycBmcTi7NPl9I{C!OpE}tn@WRt+N>ep1hLXRelTClaE+@Crbj?evgdYe4p>HfD=fI3%^R2}1c=6f2MR_+ysc1)nm_jFi9 z?lm6u-caN38H`=IDpKvek?!ALb5Q50sj7c|kszLVkaUI4D8Bsy!G2GMUxkrR|AS7x z_lr($!4Y)wDGE)5@5xuFzowJttaPe}YcFc`vC{z)G9A@^Vu~ zfrWxHk@*C|=llN72Y?2RBGtr#%)9ku+Gt;IJID+ka^g2S`Ld|lmBj{XAtUrZ=;Y3O z!{znV?#K;1nZU1d$T||H6-|HF$$PD8lAa(5-MqWf(S~?e`sumcRp^Vq z>EzP57M59(q=w3i@+SDZ0-AFv>qZ|Q=zd~s{hLlMP1&Iu6&2ZQIFT)?J))^dryToM zVGGUNjw6=;FP+SzWwZG-ol1oJTH0&bMIgogWwQUdn7O0?^-K-vMu9TJJ~X@{5X?;uQfV}V=Aj}4BVP|?4=yKVt6#P?IT#)8 zE-$~D7;qu!EDb8qY0XlI|KMCgOW6F!(<+GoD-Jt>oA;rC)x$|!W$uMbCQayXXJ%O|Fk>@HSktRECZF1TT;Yj7Mbg#&bN zHVW^!tUP0{9J;P^c>4S~;utd&)px~E4%7M)#$8ga_UMhYS$Y_dXwxdG?w@XaFIuyK7EZiMp=o@SJWS8QqIBy5M`pgn+#DD zR_>D|js+DIZm!w^BvJ&UjBK{Ml}42A>`_VTB!hx;wRr3YLgShqHb^1a5h!lndo5OQ zMI4j?2H{0hz(jyv1|k>|Ajd(Y&>$TW+{Z!rbRm2k)S}W)FYeMRU;$DN=v4%qus)U! zMmSC>Dh+&9^_GkS$m=1Wk!AwA#Ajd-7Jyt<3Yf!^3p`7ACh zzd4Y0$Q-#VDs6FJi9 z8Wss7=wzbsSp&Ngv$pTpbqtpRYE*+U(!ghF-+sm@wh^;oHL^rHFLESY zLF8Es9TAZ`;%90 zfke7Eq=;qIgE%Vkk!ux$QErvi+6>QAn}AboP-|)6BsP4P8xpq#gyaUFg*{P=kNH3s za*XqgSAM}A@&cOnVrKEh0`E)lOMt#E7!v?IPJ5|m^z1$v^gc3_B8{>#4z8RR6Mo53 zJ)W4Docs$(^f#_(gFridIEf*-bBEFM80Y7qvCn&RgNcUXva3w^qyfcxVrCeG9u4A1 zV<&lI9}|G`-V5d6*sFU`aTGv`1;>E6Lc(@+7!?C5fV}<*KL;f@3_^zh=hOmKo+R|! zm_K8Rf5{Y`hIfgl&a>7ceV!2jF!DNo%Z5{6d_seuOL1^g4&P@xkO-sXujD3qRe&&( zyegeF zAvu~aqjEku@w)L3pzPw7>}=mwZl6*G@1b{K7jcl0$qglF58Dn)7r&#|EBb zdqxo-Gm`DGpN&e$4Xw`Q=FMeq&!Sw)a&*rKH_nT3&l6q9H3`jmZkvl}&xt#epCOZ9 zke%mRot>PYlNy?vIhtR*pYLv&&!L{HIGP-!o`+8Op_5g)3!-GA@0`i5{i&1r<_nT2 z3SZh5c8(Tyt0P)N^V{7EdW?$(-HWhvMeh=F%B%A$LyNFyiod9vjH(CajTU{BDPFEF zUJW&#%a7_?E?Sd$^WFGO!d7uWe*Ti}o5RsJ)1hz5&J?CCzacU~H&dX;`O$^8KXme& zQ1n7RdTJSc+T?8*#oNv5H}o}cS;lf01@ihw-=4c%VzK`=CI2mFVhMj(I(Gs74YY=! zlS^$!N*4D^E_#$o7lermyuCD5D!&qZxu#Iz^1Ex7-IbV2loQ{nk3CWqc%yOfPS*pe z6;^V?q|Ct1_Lg0#VNIE7jTO8GZN^-FPs8fY<+t}WZYxHW+t!3wjg^<`m*;JPhc?E- zA{Av#kd-$0Ll0wT4->b`CSDqr6gW^cDy}-qFGU|Lk~X$0D0e)lL=#u!mQ_5qt4O7T zh!beC1;7bF#nQlA)^P7J_$w1*A4=o6f~th3suarVIEf!L8E*y8=`bris7kLfqeoO$ zIYTB|;i1gNB_8mIL;`oNE##`o(XY)3~Nepi-+EI->~ zrh>BcEszBU6~V@w!GdCF@X-pu&jA%ps}e>-ggBsmd2ptB2#-kJmJ0M-EXZ05Eay~^ z*Ve}j)DwX6Dbt2`VGUD?ZBaa4t0Lr`yXF!7@K(c65O}qqL5YrSF@M(g#*}N7`g#^dP?oa~I z!@cIiwvRAbz+}9M2iF9}ep2*=Z+pP;cH_-4Tn(qGKE}-f0wPe(v=$!$Xml3jf+AE_ z7GT1FsR9ohm?216z@O@qYEq*{IMCEljyGw~$g0iW0{NnV6C%*r1%Lzr5z~Fa4SQOs zS;HFz(1}1L-Qkq=AO+%6ss%&@7A&X>LD#_ZJKKu|{m_CP1gWf_)KN3u(MH<&aTVTZ z-`Sc}Ay*hm%>g~P0P@tfLDN1!v0#5^2Q&?2K?3v~(4|GtlN_?jV$6^Rl8Zp;(jcV; z@C#|+kxM8PP1x^=fp)?96hSfoauIDohXKhsIvH`DrAa@e^0aF6^mv4~J)Cj^Ln{ZA z$pRIfZ~+{?n^_SmI^3EQTp42lxd1>&V36pnN*JP>%j@%kY|U%?c13FATvOu<7#GeY z_(hl>7Xti{*v&KEnWzuqV!M*E03nPEBLEeOf=seBtJF1Imjg5=`e*Iox<&Ata)4eP z+#q7WxN9Jp7|N3b4mCkMpESk>bX&*)#kGJqI;CZ`-_qexnlmJS7oZ%BEgXKmXgIiN_#yRYh3(##W+OPM!IZh7rC>lXx%<&dYbxwo8VSrGb5801pZj!Su%|k2lwWtzD@d6XT9cpJTWt`sIMZh>5^(IN>DX6zgPC zR$ti~a1r^wD0c|s;1a7mRO|ppcfr@q;0*P#!WhDS&AN7~_giw4*hF~T7|2KiEt3N* zgF;$Z+fJadORL!Y+$quIIEIwzvgFC`IymTv6{4Pa+x1B>YAi+{6pI33-Cx2d#ttdR z6`#UC${8yQjZ%p~-#Ap29FCJ{V`8HreXMh^?i5~JPeuX2jh+S^`Wcb4*CXK?x3N$p zHlBFyhBow8B%D-tE+L=-o-*Z-11e zPyi+iJiP6QJ-fa@`@ZFY{HTDenV(r>uiFNYgfmk5*$XHr^g} zpTUgs=#J52mY^JC47v*vUVXBLkT2sn;v$zX+W5xzMa%VF%cMyk9ory+D3Ar+CaM7S zNnWo`fse?JIEH+(>P}_B*2~w9-0l3Daqv}i<6DZ!x882}B^~Hx@ABe-XAsIG)1P&pQdTmRjBYU{)Vy#MLD2+Sm27_LsB3Siv21=+X6ja z6hUldBsMO!0`?o*(GuSzdfK$T;lYKi?o<$=`U!Lw_?!hQbh|CJ#$wk56u!PITL>7_ zLNk(pJ=}tS79G2p_4r`PTo2EXrC>#xXAGJ}|%kAg3QIu#CbTT`> zNdM@|9sGPMeAXMkd;!1ofw124XzdvP_1V`=h2!nxu`Tc8{f!TMACB?Im4FYCdW@*! zcbIR#O>`lmtvp(QR3}y54OYQL$!(|4qvrp;lIbNe#S6&ab+VAzdw-@|^O^|~4wH@X zw-&Th|zGn6CPloRxpZf0vG%Tx15r78JSFv!{@4f0z5vFIQhH*N`dqFOFNs~|djFN%;|tIWphpAYYO?1%YY+k36yvus!YHEuH_EzGR%kbf7Q zKPW7sC8wwrfFV9pN@hbwGB!&#C)xC*@8)r4_?pzk?+`37AahL(bD6S#I!4hDJ_(a?z8CD zbHrSqN)y@G_~%Q`ekS^Z)@>*~=RS^sTiSFOL%PAc6PTUa-b>UV(eR+v4dAR=uYOtR z9WxrQs6nHmK~-vfd%Twq6%yq_Oi$X1V!#dRE9+S&!#wH?Rk94mQT>mz{H_c6i7NJS zCxg6%Z|%Aum!fav*6=gpkw2r8xkfW2M$;#T!vlQza(x96eWJX6W)X%eX`gp>d$hTR zJS2u@zJ~^J`4fz?G!iNiH+%sL3b*?5=lb#?On8xF6#-+Fe?li`jklMLcSM_(Ta0GQ zja@()OCX`&4*l4RM)3iR+S)}!hymlk0o`ID15KRnwcXKR)-f?&zmP1WQaO`%&ZCoC z6H|X!Cr{z%rZ%~zzRpcf%=uoxndS=li2)PR!G?r?>uSas`ZtXhnwf=JPcTi84F?dZ zM46$p%p^FlV(5u6Wvr+!me>+Y^2c>DL*O)H%rukaT_P0(lpDK~1(jno+Y2C4PrK6> zV8DLEXh6ttFq(vOZfYpY|Ckz&fMojx)0s%6ec> zewr=Ym}8yjChQ(%-ROg+I|EHOd(^&ong!fjBRY1zccp$-0b?$Qoz>o+)%k-u`3}iE zf`0xk_xwF>OD#4t&FyLS>^nDMpXpiql$&+WOMX!eH0PWfz5dip1Aj*aKwJZ?kj=Ay zPA4z=sVw>%EC$dlB5ACgvW?Xc^Oh>+){&Ooh}m=5^XDzisEY=f2FR?|{neX^hO_)% z#w`9xo$Rul6S$oFbor(H(u?e=tHq1-a%Sh67HuXMZRckibNby&1zJhH{x2Ht`Yhu1T%nDeg85G|Fe ztmq@xh62}yWB#B{j#*#IUSBR>CjjEX!PTz$RnBeu;6=Uj)DFGnmN>~ZPVSX{0|zsN z)Ar!{pV7&&IPx4EMGkJe8Hd0iyA5VnR>KNgts~f+im2_rZLhx7cIr3Sr2bPn`72M* zSKipKd^rzk3?KBXY@CvE`W$%c1p5P3HitmsjZ-`J-zC4Pz5n_Lb@KOXhToN~zN@%? zS9SU>CiUpzF%l+q^TP2%G|eMXDW|^dKdzHWw-F56cX_t&>1=6}I(>fsShMHx*U85g zs@s29C&%tQd7rc6Ua|AY&_#ITtL4JZ!?mxTq;9AWJ3c(SzEZn>s=NM%y8%|afv&qj zLA$}RyCEO8Q5CzepuVR=ZYMV$+P(iHI(cC)WoIvybU$rsFOp|JLdxBW=a1-Qse@A0 zgLj4pWmX5}ItQ-}C;qKeW@je=2E99&TPiJ^>*CVG&`z%OYap;sm37`SN8Y z1%+F(vX+X9w%4v1UB9lOq4680Y++$xWo@P9e4F)!4pG$&pj97e`*C3_HM4w*eB}Jt z)z#J0)6>`2Hz+75JUl!qD(au5a#mJWUS3{tQ9&I#Zm(MB7pXiSpoP0$_M`rDj)tksC@K4LS_7aq%ynC``Rbd&b=3F&0yj>RUiKM zq%!IMj#NHRkjf#H|GQE-{(n;{^Z$^_`Mj%+e^x3N^A44S{6;GC3+BD63E>jaI9JLU z`6s2a23X3qUXu7vQaPj6o*9&tpuqY z_}8T}?q7D4dw=ODs|8+gNvAYc%c4jBC8=!uLn<4Qh@*c<%6HEaq;e_kL&PUa5j61Er1Balf&(R6)1QXI692oSoXN>15X52n`%-zG z*q0!c)&Ef{OAwil=>AKoYyz3tZuo6SSxVGQ3G4GOr80`z?VqHw_;021CNYK}l}+wd zRsNL9*MCZ7p{o`zei2uAzAq%r|5UnEFnpn+7j9x(VXsa(NoEciH`$_Wtn zw3D*CF~ZO*d;1-IrpPE%6G4iL+@ayt1-j31kV>^yymyL%5+MfxHkeO6sW3>(h#LDT zmAi4G8cLLL&3-RqYb+lbGEMkK`6Uerjgk?WOnx0yBEpMnKv-4}W~CXQSTf-tzBPx? z0msTt=G#8r_EqoXQ9c%24LG83Iu0M?R02UD&4=L?GqXuOVBzQ@OZXsqreBjXAoTujti5~WAq+7$BfUZ-I%lmRW zr?mw>o&D4cJ``rT9_%k_LUw74U-r_KO}Vn}Hu!DN1kzrzeDi+S%kHQ|DCn?5L&uYj znIM(56sd3=6dXqNB@DYQB>q4+TX>)>9hR~tT{vwre(2So_nbOsLir%p>mg32;r1H%uqVxcds-IGs zd&uK}AeHGnKmJN8D`27Yg!*I@1q}z#OG-qe2$15Sk!TQx0{5{{egMM%cd3j4h+)tx z2sphi2*diKVSb>9x15z9DH34epdKm%^`aoOXh;SO&)%`9x+_L!A8Cn(h&>MzPvw~G6nJnQ&v<& zfgD7<96;JGtxW}Roc5Fg1~u2E0UN;F|A)Q142x>t8$Lckw?Rm&q@+r>BHfZhBaM{O zB}hn@(v6BV4BaqvcQ;6PH;m8dKH=Wyocn&Z`+n{h&&BV}{CP#KYh7#BeAnlnVFMCE zd>4QcCHSi`p3<&6u~0Ca%T#RF`UWCX9tvFgktxTs2C45NwV0Tk^{VA6%DhF!9qm@%B5ir$`z7JM#M;C^x@`FA)dL5r{xpP69=NUfpNK*UuM1lM+b-wIe>W^Su*S8R;3F zflRUsz=wkN(xal=qAc%(ED%LAo#9?Bf!X8%$cR8WB|1|L1k(koIs%SLK~QTDo;;A& zIzV47=Hqw*!o>(2kC8$*3$F+ZShmGM0LpNWx0LDNPsR|mzPEwC;Me{TWI!;>Nn%e$ zQl3a0+8oG`65CJ+tl1tXI2SjE7R_*m`&uFzcNhHH1DSCST-_ec|07VQr9^6{L=yxA z3brTRBsTEBgA&^kW40VqC;lT)ewX+hT^*UyPANTU4ibJgV)ZR59BBne!;{KN{OQqy z2z=+%fwLIWfS03?*w05V>p9G0$04mz=A9hj2}kDr92PIQKS?7T{Xx^0 z!)vMLfRA#2ca#;fOgSr4RVGq--9OpQO@p1ILei|#q7B@bXg;n*;71ui|Tn9OSx$6IiqHIn-h84S&-HB z^iL1+b`XwoR_@+j!Y9^H>pxooTulc9*irAVH~f#5-! z>v`_Yi$X4v;-@6`Y*IPGF2&*(HX_*t5|hQUofcA6d2+lZN*kFxFF*M`$hpH%qC8om zO=7A*QmDgQY9M8#hgocRp%YVH8WU4$IjL?e1^s*k(nQ3{^50`+)l7)3i@Jl0hBL2* zyOa?sB370UtZoMJw?k;4z}z2{^80x8SDnz*;WGQcvg9KGTVH6r2!Q%Wul(Eu@^%su zqoMAFsh+S=5rI{I7nZVAo$*_#>=AVbQ7Wf+F=c`t;ekUK z0L&@hOXaRu2oVfOXI+CRTiKw&^nLYc&~n#!7$ySjy@c^s0B%axm;WPHrf#4zZ=g$n zu*!oNV4&U;z(c4XwLA#-@3AtfL;W4Bz*z=xKwuRKqEUv{CmI6P5)vNv{V0_I-~|Q% zk2&OpbW1`cfEKUz$_K!j@&+9M)*NrZ>uNS|1?eyX1WB7rBtqaY27viy%MHGI{Avio zNPa92a^Wj~ByWFb7sTe#K-34qtqyL!0NCv*UZF%m^rD z1e6C=Axh;s(yqo$NV97fURYOLS_>v6cyblQU(pWQts~Ivu4M!;z<|i|z(=g_nfqdm zPd>&OB2Z+&V|m~m%6E%Zh#VPU=m41vYC#mk327i|c>oR`I1(Aiqzj;vuP4OoEHVe2 z=JZ}p*~~Had?jqd=Q<#kqK-Pyg}|n*pevD{ zC~C0L7KFe$fCUQh4X$)|g_v*IgLXl|xe!btFs~B`iq^yc_0!z~1SXCJGL4E|>0eB~ zkIGHiD;tujfw*m1p+E-+G|NI=A*@V@YYJejAqdglhviPh`t&4X4?SfXdZwiw;{v*h ziIb5|HZljXQjV81OoHKLU^Yaod<0+w_?ZRQJg~08^gw{z;Ot;XYvL3GbV@T5(1Qqw z`NsyerbiQ}O|cuMwx;KpW)cj0XgwwoRr&ZvuM^WWBB_p!1dR?4B#KOrFaZeqVws_U zHvh^v1^{y3^dkR!EHaR-4@8OsE@$dv)AjFQYRB!HBfy$Z&zPmqo&crHlg@z1XQq1j z$D{4+qp87+Ow+|R`PlrfTCQ8YRD2>%2Kp4Kr;{GjJX_7J#loR z&mi9gPa~Pzo}P#rUO*#Pr-9GiAYYDSSkcn1jm7WD&+a?bTK3ZViWBnHb<_TV&;)E_ zHNj^&Zg}+m*~CM%!N+q0C2o@yxn+*Bed8vOZwzZ@@Z|RF#U{5BzW9>P%90lh>e*8r zk5d5iuGR#wDST*fv-FbL_CP{pH)hHxNC?ml0iZxXe1D7x3StXs>Ac*i@0n||+}!6{ zO>Exm!P%mv+#0gn8cUj;6sW!f1DVr%J%Ej)g$(R&T788>d@R@e-awW^wxgA6yK%-J z%=I7(4T7M+g>qoq=vJfb8ZG%eYu|R%@T{@gZn^(%vuwydS9DKL4~abB4q%eb13rl_ z1V-#6MSwV|Y7K^H03YgZ&b@&UvhFa^gBxU%C1f|iU5lT5U>HGBBrp&?3>a^IsFcvj zvkmEz1)I<}SoTCBI%dJHalM>|r*em)EJv(ihi$dX3)_{ESBI88Q;LFM<>Xm4cgQ{0 z8q_cl#$^)^PNR16vTpuPz?VsSgW4TxU|>9pYcz=CTQ3N&%6uPBK!qKZMOhy0(M*>MDcJv~(t|C{6-( z4sELs`0AH+D{l9gT(L(v^Z@$AOe-grx=84Ss4?cOh)BvWNHnAvP+- z{I^oshgkV{jv7oY+`w{K1KiTDEHt|<#MjeSIKgXFd{vC zb_3xkH-)nD$qAyI9YFbS>3Dy4l-cl_F9{Z{Yfw!W3&begkq}oV_*3%ys8^VeB&eei zj&kL@A=Vm{i;F%9hWsXkqx{hGX3Z6kftA$5R;r>dhAO3pt@pFpiexxvy+1rd z)Ep4QXr?|j$#DY?b<=e0-f{Mw&m0;SWi{REN)^bQny&;82u8j;%F{I+%|9IFlLz*1 ze>lqcrrHKS9Oe51gcI(lH05(11x#FeJ{$awdcG9z%JlqbzYuBqGqi9m7_y9%>xbGb zo$7~+k+U1TmlHix_@HQ1vBa-x&utXj>Fs0`Z)IO-l;E&jA(rR@N8vHK>HfV`zE5>- zk`|rEV)`ZdU8Q;iiWjpm3$Gi&d`8)FC2x8a3h(AbEkTue5&!)Q^ODgoj25M{?|26? zMH)lfo`vFbS=OAibXwGYL*aW+2d1sw4M*YRd)55-sq3p&3I|Ke>6<~X2VUN7r<8m)0ibvofcO?*pO z>lo|LDR34Mu3GC99_t`*9+Vng>+F|VCUD_hFk0*4UU4Ge>QYZw=jzbTDR}j&U$ySa zV%$OSjp=-J9o%58Owe6>Z?x_k2u z!*rdkjdy~@O4x6?o?(7>l%J{NY^ZSOXyN$FF-F`#ILhC|!vj=5$C43 zoAeGPim{kM#!c@D`^#GvGQxwcii1h!xmtz&`^`+9m8(|E#qP9+hq_M%Q2@EcJJH^U z`5p$|y;0FtP4_-L)b%|Xdz)~zDfav5h|v2FDpe0eLfj4FiwRfQCD=743?1p$i>{EnE;qkqZ0>g1 z8nI!6WK2~Q0Yk+`Yz491MwTDq+YgsHeeTG<+J2v~RK3LAzb0vycM!23H{$yEnIlqdY*&S6i4^?v!aw5kFNi!m z7YVks4J12S#eYIPKpztES&nT@A~fcCBu;o5)789`o|$lLkJ3B#l1$83afwkCETW214>pZ?3Dx_JLWzaWzEFoH0MU6R)N*C<7#)>d6GxikifR%;}xZceG=42MxNxA zjQIjd%F(}oY1dQ2RsM#TLvz^WZeZx>3;1aVR|;DxG#LGkK3NgMQ5GE!eJlOwF7BBV zS8aaynwkN%Lr}X+68ZZxOhXQV*pAyp`;qyyOMsVmf*{BH4KUK>tykkPgO;x`{d}zK z`DZRhDh2Th7{=V63cBrTM-%tDSb2701D%f#ssLmrcGz)!tB(#-M@NlCgdg??mlA!t zTk~8(ZXzwR)K>aoqG_CE+#u)CVY(f$nZilLP#Vg5rUJi`a{fd{uD#uJJ+hZydg4ap zN{({V;$CX0Mvm6BtmnV2QP#tq%x>neR|`)xFJz7%H?})28YZ?dEsLBOez#Flz^`gy zHJLYkY_DBUW?35&KjqGTQh^+AX$L2an%)xKteUS;bLyQeI4X58*h{qP*p8o#K02vm zC$WC(5H*L4x>bKeK;4IBsuv#ec$$VMl&Aik-M>3_kC-F|ti_ zI9d2`X&D^9UG-T`OG3Gf2P-zo?ognn7GL(!=*5;D#!gx13stg_e%Z#{d^ZORhl~Cp z@)M%&#BG+si)pC{hni5o9XH(mS)k6da$JEX15O%`Uh~sd^rXF;uP+zw-gau|%-)R* zy|eU?g|gdnanlfhM~xnI~Vg?ZHoi zZ@t-DDLh{?J~-?Dw!9$5-@1WIayBnWa@JcHvQ@Sdu|-jGzB9{ybt3p$p$-rf1Ehi- zJcNOz2?0t%-MTOoq+ld(p;t~Y^qe4!Vj&m|h9ymfz9?id4#U+X#Jyc_ie7(nljP>J zCwR~6@s*-(+186U2to(zh`Oo?il6ActtZ_KAX}`@-L0qS3P3o@PWAQoKI7ke_B0FO zC`SY!9Ay|+1Dz)RcSrdP!co=?U>s^tihEL|QO%q~#C*HaHMZdq68@uSjkmZP*_&>& z+Y0ZSG;(?0=K3t$65Gh@n!-0EEL_kikmDza)Z~wFl#z%8*qS~FH$79T5HVB zlqqrK%{K6*I0&m9Kq~Q#q5XuFpbXImr^w@omGKSmGPbB*-~Xyoh6-8#gkG68&Y`}ojI7& z*(6<=3|(J%rPHLkK50mQeA$)aBAp!Al~_a|Oo{P`t4d8%D1y=}lGS_iWlbwongiCw zI@Bf7=n3y>^6K@j#cn|Eua;(F?H+Ht1G@A!kgYn*!dAVg>Y5A)Y(-l>00b z816ZF*wrv5V@k(6izF)n?cyYor5E>HD2}EQmwn{uH5}m`Z6aIM?{DEDn-bO|;OO;e z6|~XRlL6JcqkGb0qwt0(o6O{ zh)zr4t{o=g7vtoQW|r@cGI@S$tDh}+fU*RMMMRDb4J<%LNFCYRJM^5qTkdwZ|5HOu zOdo{-O@JtJG%_8SBg~5=SB{oUDd7~AbiS9De`xKQ7v`LjWd(q3RaSgh;mL5AJJ&Ea z@Hs(lA0c(X9mipdSYQE>0@?KQd-cOShFFwt-Smcv9M;3Si3C`H;m6(m+;;NC;wnms z@&~R89LOMW*oes!4@xuz1!_!#v<6|F6F<>nz{Hz3y7&@1dHWS9qGhKd3ldq{s6 z&whFYbxY=mYsf0nixcrIIAWVgrswpIp44idRN|iZQ^o>H#sZtif`)&|Q67f)`;5_s zfgZp-A7O(Zg$>&%BhfVDUM47cSd0$ps+7{HJy`|wIf6OF$9#rCOt9}eUeV)C(o#+q zvQHL?Oco>Vq#90^+WpB=SwypdO#S251T&X9o37XPrWc8!dd!%NgqEsiuzIGOs&)wy z9FrX>n_n%L3H(TY%xB9pZ)@UXqOsk*{e)UIm;7&I$8+Ih* z5^vk1(R81QjA?ZAE19fFBr$pK!J3I75wA-ouVKS!IJVa}_D115XT%?bPh@7 z&y~v9+lcq#vzOF5+%T^$ejTwe@57}jed_ne*wZr!6H0hKGIUz!C9@ZiUS8em9712I zRK8LheWkJgHAnf)0w>+t{2@Lv8B;&gl|CB&;*-3=r`!IgNAnb=-jw!8 z=gQva?A~U1%OWky<|E4%%gdI(@ zZ502?Uv~zH@{N(i-0HKCDI`;05r?WM1`daUW|cCpIVw@UYgqYow04<*YErGCLtp0#CYHQze!_cb~cO@FOJ zsHV+%tS@$Kpn7chXC38P`xg$YbhyX54u=Mr_9xE1w)U+juA?VzD<^OM=qNiHl%4n_ zJCKE(I9i=+J&&-cW4)CsHg@1-)~`JZr<1F|G<)eUR+1XozblN9SP%mDc$j0*w4LNi_&|O zg}gAxB#SfpKZ$>Mpw&^FIhZd0NitEgBx^WZt;lS;qa=GYU$-%UOsX^ol6>1HtNF~@ zw4%&nQm;O8zIGd>tiUN6FVw@^zGa9VK5!$=6Zxb(H+_ zqVzgSzK)WwqvY!-`8rCzj*_pVWbNiSnQm;O1_SgucPGa zDET@{zK)WwqvY!-`8rCzj*_pVOIKXrEi0}g zD{jjxZ;n^oQLdw8qpcD9Kf@xvVgCauD+hWzP_=sv4w?&ot+&*ME3Uf4hRSc4GoQqjEswmOGrpa zPEP*x=~H@odQMJGNpA9fh3Zw6^nQWFoSXE#w!)seDqK@@!`Zp1wzj#s8DSxJbaV_3 z4*nGjd2ViQ{-;5d$A5^A|G^<67QczezoE!KyU0JI$cXi?xyYNFn_Iu1?Z3~?PqX_k zv-i{N|9<|}NIv`zbM!CsbASAY_0JXZ&+GrqA{iklUrWjV+fnkT_GCed*sF`vgN@nV zy1H-Q04Q{G9!LZxb8pdTGUhz7I9BJp@I>k6y>F|S%=-`-Wz4@LwO^h0B^sdpYW4c4 znA~N%{+6oM(bh?4AZrWVLJ-@C$wDyKa>hak-|^}~s1OSMV%ReR)5UOcn#{%b(j04x zALK>pmm-u@OqU|nwA*K0YnlzeK2549`^v#|@74m7$rqm7S3iY`K3Mx4p|YM4XWHUO5k2XM-s{iJ zG;~X|y4{!}$fVZke@;pkwOMCDNXZZAHjRE&N@hk#$xa9)2*`}sLZEx-h`H?^M15> zr(c6Ow@(+s#F)<(BUCNVmST+a&XyA#w$D~le3{QzKSx`huVpyQILtZ|{*aQlI$G-} z8@DvfH*5<7tm6aoD(z+y9Vk5(^r}hQX!9@kyEu0)5BkJdt`3J(t*(y7jPtLKryO>! zPUd`B;HQhxR`9dcbcBPqS+)be*loqF+jB&imKy20iq90PS99#`_^BD4%q~vD}HxW|u1B17i zGt$C%7jry?;fe<3!YjrYt5x>0ze&kO@(3xp2<-`41MZtXuP;1DnexF|O6iirS?Whw zYTa2XWgWwL&PUn0*x72Wk|Tw2M>!@k+3KSmBc+u`xz@qink$l{l@oS(QZi;Y{w^ge zd&_A3Q%cqXBBbP7xaM@i=xi{Lza}L!A^c6xN6^$aK6oVml#&os_Kd7L#>bIOP-HDj>=HL!$S+sHID9$@uf34B3(_Rhc!~ z(^za%*?4aLV7=F-L;)#H!o;-*DVb*unZ*MLB?C;Lm!}}N+1H2iS9xHl&5h%$0kYF& zw#>du$v9iLvUYvg0K~N=@g*6XfhOcE>KNig79edrFZ(K96c%xSG5#EgVC-Us(Yij0 z^Q8xd=G-ixP6!z*Y|E46at=-IG$tIe_g80qd#BbxdA8=Z0Q5=EDnTw-cXvCaPIorO zO$ZadE3;3)Csc$96@sZ+0!u#PhaQ{FN0-BKZwgcB`Ci$q zIo{l@b|grWN9r%ES|A@auaS^_O=vPQ%b??g?A&w2`~gN2X~+bAPH8nbF;z&rYBf6A zV?Rz%Kdk3rch|ee^keoxA1O1EL8H76HPYQ;9FNL5f46aT`K#Sdau}$v$1%F>YLC$f zfJBq;cT<`igmhxQ{LVE6Enm;!+2l7Zwxdefcu0xMv&Cr_T~Lhu;p3As*d4LkRM#2%jTMnVrX zPUop*iwp-0yPu3?@m+ALh)c<+Wtjuye!9!)2q-4)bseEK0j0-1x);sH5O!AZ%{~C7 zHAdu-D+dgK90p)ZLAwV4Ql{WO#slHuf%@ek^PGTQF))@cVvluj6g7|>0K~=v<>A@y zq}x1<0igE*`>nO^L6M020Hi5sJe+_fd6ZFQ`}iAS83iRD+BP+?2vUK$SH4?qMcAYfD}a5M7vG~j(+fO%AU7&F)3BScLCntpyq7y z;OHZy$JUV7eL(Q8S8uxgBSQNaLokIdL=Isj128_t0P<3R(bS;mRi98lzrqYNqcLll zFMl(V`};hWMSaElz_((2x9#6XMY_CcbBS7V@gj09It^M@_N3IsqXYO;s=7rRg6~^H zICWhUPH_#>0pC2{w6!8HQQ}Q<0n!{@rR0O-P4J|k?j(TVLoQQ(m^BW9Mve&l`h!M} z-3@#$kJNysjw=+jW&b+bCx|#B2n-9NSPeSj3ZJG9c7sBCY2UGhg@ARz04~7vX~3suRY?03(7#?8{g=}!W$4|rW zo(0dFyq8LGM}eU*Wrnca`9KqfoDu^l!wZZ}`=C7@t$+MME-W+vU@5|_BW7w?{v|>a z7V*(8%qb(RTr3i&BFKx*`i)a;m9i&T9{e1N`2Pd%S!)@XLX1oyKiI=St;K|M*{9RIx@j^6Qc|PWW&(F?-n27anNa}Z*zU+2NH4IA?Ax?YFlcvO@E|z7=BAF^}mim}D zQTaSgm-vgYbD9LPC2M8cqkvSl2Vcx5zF1B~8pNdmZDTaEzG$C+ag0lMe&G4)L8{bw zsLVtfab-H(TRr35`D?eV&&C)TcITg8I%k9tXTGmA^EdmV-jQLtp5efgnJ|%=lw};r zlWIf!smCpU|fE-TA9!RjPM{6V^Ky;$I~bv(D;0lB%|NCfON9pL0mzwdOkUCA=O4CrBwcHjlu_2 zg+-3=!il&-Mv|gOyspfh(8n%CTqMryfjQihMFO2Ryj2B)yv5JrEuKi_iNqI6N@eD* ze|%$>LmXHvg^-d-OvM-qmE%j)rHoWDi!^v&u;Z1!kn-2jC`}qJL6%ad?o0YoQd%|) zydMCuoGdlh(6Hv!u;DdYaRNDKYTWmDleh%biqX(#C^d2^kM}9XCQ*0FF15RWV26PY z$|1-IPQwFq7Z3opE=wFP|Fl$*h+pv`8xrYK5gQ0es8T0MagRc-99OQ4$*!2d2fD>; z+!V5jqb^S^sZ4LKqERb12rO^l1q8&a=V7Y1B1~jF(0$g*Sj55J2f*k9zG??h!aYD# zlnL>X)k)1Y(IwU0osd3;nxU7Fk-(aXc=g)J%FrsU1>Txh?OMebT9ugU8&c{UnAP>X z)xH|l8Ok71YY+`(RFeGlb8I!Wu-?r-QBw z+R6kN@d54yy-`SL)|*OVcWr#Z4LERtVBodr2f;8j>k+#9Jr59^+!_?gUgnw8LLCMo z!}7*u1ZjM!!VYVZaBVNqQIFpWCOb|K%NJp6z6$!W>24K2`+|UKNoR(!))ug$0WNHEsYHWUWQ=xQcDIcIb zr_(hDQghjfhu0N%)QsWL0oHYjifjQ}*HJ^eN)SJH9}oo(NGsno+X`49RaZy=&;fwN zDgFqaI7qr7hP^x2rMJ)pa(51h0z>?<4Dp0OeVeXXT^&25y$5`Nv7Bz(sj_dRePDh- z-e#BbQ~;?ifFum$)m7?a4!JMgN)7PBmWOy=z}w7S`l05K6J8*?mi=+Hp1;UsF{C$$0F=?WXyM5&r?r(B4> zsy)T7J{c?M9;`8jy3N62^pgq5;7Z?4y1{@mWfXa+JRV}X)kR*@O^F?F9~;zU3K2@Q zj}{q^wX5?bv#0JG<U-53MyK~hT01%}vC=z>$03JMfFJ;nrbMl2mTZ7D0q~TOs_waPZRLt;HFWEFs z%|H%aA4(t43$rJl-yZI&H8BloOdJ<4@5aCbuEj%=UIM-bx8HGtgiC>tEJ3{7_MK6a zzEgk`Eznub*s292lz$GnC!odxR96GpwSds=_Sd^X?(>7pI45GVYY3C(XS*tGHK#F| zr_H)6lcy#Ovj@|ZLC+Jr%>zN9RUHFl1NstELbbD07@)(TO7vY|GE*66-U4au!Zz1z z96L}*cIxR&;L!xA?P{N0G=)=Wp$?BZ5&MbHSTJD`_c_3Z#MCw9L0L+HObtv z3+S^(Pha<>wCoU8-ZC6_yHAU}KbpEPv3VihZX7*q{64HSc55kmX&llGH01kwb326I zvehYRC8=scpJCxKd_s+Qa;y@{$J@~u)UnBEbrU*y18P_^wQ!XH5zhq(YXRy_0nb-m z6*CaW@Mw(YI)?Q+IBb2ZV%_%gz5EQMKwzWf&4y6SMpf-nEqTLzShx@o=pFy;l50oRz5A$fStO}p1lYJ);|-77+C^rLEWLM-fFTd#;k*x>7DOGs#{Y^9LJ;qzhQae@MTRy&f@lJyY zwIytMr4)?tC{k7sB@AeqvyXyR-r55Z=eK`x)}T0(G!zJ;=>xv&o~5>e&?fIQxL4f2 z+>ggUpl3Z$texacKHv?7(DWU&(pG4Zfk2u~@iGnQe21#Z%ctGTUoBfD>YBC~4(v%= z=l~$Bltv8|z&%)iVE(?#%uyirQPeQ-38R&RE67*}!YDXkU{&ir1@xH$P(i1B_&~m{ zpgRJ4);<5 z&T!d7aW$}`(Iq>A56zhYP4v3Q^6A{ zp+LcHSja~|pbry&Pc4)5EcW@5WE7KDt@joxk`ppD9Qe7MjOLLodLlAyNtq9vG2@Es{+-=M=_3#UoLjzy(T1K9=6L|VFU zGLR;dESji(WHyqUEZQusyfa*@4zwY=9EPfm*0_B`A=f;${@SddlN2}lU^d4c>_Clm z41KjeoU7BCq;+vT+xEEEXy)vAWwojzSu9!m%K3O}y6lkIh1+deS%8i&DsD*844<0=JS%}?5A3U3gZeQq~vxwq|jP$`yi{} z4ON2z5kejB8?-l99^*A$+zxsuM&__s(28ozxZAMzsLARHMd-8dQnD?!IA(JZ%aenc z&xMi*DY=k&?0q(C^*J7+RU;!pN|t`y`?+0$MULvG7~8D(V_EJ@CHUYolC;}4viv8D zMRMpHIj`DC(hrN|g>gk9c!hj|9!cZh@?m=}LCbETKvyr_FD}WsRIDgBUU(>VJMgkt zNl{KDGDCixl&x1u#|I%L%c&p9im@ktmy#okRi5m*MyTrfQgg`akaQQT8Acl(cj!N) zE`gY)rxCOmi`f;aTa+!0)W4jhD%N<_O3hhgrGZ_lX*X(ER>f5JDO|y%$f8W!Wruo8 zQ}AtQSJv|qSr{MK^0^n)MQa!myzbm_Se zE$j+|4_jp1(;rlgVkaZcED%z1q}z8XnYr}4l+3O2LrPwi{UIgeQh%3{IgYi?JgaYO zgvNfUG-Lcw%JVWeyvg}xe%+gbm(W(4D&c}oQCB;iK^u{x3ec9?r$y_ z^1i*fBI$8=|Ax6e`weL$zIU{KJEc zu_g%wIrB49`-A--Es!j&rgHW4hu~!`kR1`F@NM^pUal=rAde>r;S7YW(l6e{k4=2W zJP&R%<{9nQlGL^bqV?C75K?kxgf7ltj0pYm!$|Z91Lnb4Ueo2rX{H}cWC!C2 z6hBpe{!;$Z{#L~J6eW5Mch7={jW;8eF^`y{j9u1;#4V~7-uX2dr=Ekjqv92|z1Uvk z?GMSFhbw}icjVvVd`LmQT6%J$Qp$(fHVWHrmEkUNzp`w^$MoV=5wTc>;5Y9-kxeg( zJ#m%@53zku&AxVDA#Ok34ow zl6T}~VYh)iPdtj=6PbrwyrD%H16Qpf56gEWo6`Ya2-f4+yZf+jUg5=$oiRlf?AUDT zj}k)KlR^t4$z}~7UhsEY+PfqkZ5|1cOsoY*756^gGL4Q_A0`hi$t9b4sdvFU-ed1j zQnIyW9X~m~6;)Pnuw|t|s5!silfclV`D#)^bLo9ZMK|)ytK3zQ)fvUg^6D3Mxf-1v zxv%2MhVmXKlW2d{Dhsrr%6IJU6t(=K8oOY(^L36yr@lM7_D#`_TWs0PPLzBd))EWq z)y1qYidq8FoBX%^{<`|h(ef3W!Jt{W1Eikwm(QB-k1sSC31Ltfy!1UEA+lLusC>cbUkV_KAp_JZqa^$*w8K5!rJ^?Q&S?C+J=Jd0Wk3&&!k zX1U`gijw~Uf82n6HmF0{h#~?t$S~e4wlk`FKN><{^e{Q7%aD0IwqIJ1CEuyT!oKM4 zFsX4!eQb}`3>2l;f1Y<`sK;$&Apy9>`UE#l&xfP94W3|<${g1(Vt4o{oY+)?C2}Cr zem(6WnX-&kTvp=oq4E5;~(#FrJ@ zaiexeNBMii=6XAkW6j4K1>t0BhAi>WZu?`sR5FWZ+4zazlH-!Q@fH?xQIpf9n`QNh zkXNDcMN1qf#{G$w{qVf_=`_2ODg_cNr~IgyBm1qIJu(fqo%qtL;}Z)Yx%D(o!dwme zY5m)HYaiU`d2CM0BoRN&8^TlWh|Rzw<;+dlr{ z!bRwM;=1D2i@$PFcO|=b8&!MGE7>v>+p4OVB}pvUp*n<;;*3ZpY2WnOWhcJ7(+DK# zfN}qFMdY?~zZcx^FfIN5qyk0pU_M+f%i-$7V;!5KR_)ihWi@5G$u9BpNhhvTS3CO4 zF7p?@r_HDayWv(wODuxj-3|ir#yZDLV(xW=JNZYC9bC8aeJ`dt2@mV#3U)$u6uxo_ zruHYph4YiI0$Sco&4%in^d{>rmATvPCc7_eCVy+%tNZrp^Z6~93pxyB8+}^Di&V@5 zG7z%ohM}4VqeZ}mQ(zdEB&bcWR~0bqoZHxkLeao_yrC!@s`?Jr`dd_KH`{ekS15B$4AU zS=qhi{uT zsQfjDnt^j7T9?flSfc8rEozLSs(dZV(xOV5qR-7m)V2KHmw(>KI@$t3tNQ-f6wsM+_ak#d!1&KXQXnmL?##-IV+$F{|)yl9b z_5dLz(_*zzlZsO@w%y|szboBFp(##o-bU&wP7>61CqbMjr;VUm9KWmW)|B|o%{IJC zaa^o+Y*Gm<#&!%o33TapR80vKa|tBG1|>lfz=Za1*%I)o_RCI*i^=x0jrNlZiDS%; zLlVgYhK@a6$z7?AZ4Jq-my#PU9jk$oEAbsm*^-M@9bY>o=O;U6Hza2+I;JqCCP_NS z7^FsdJBOvDhBP_{UP|@5boK^H^~85}W=nNcb+&a%wN7?6Z%8#>biy#DYe~AQ7^EwB zyGo^`OK!yot)ekQE40~Q8FL^{G;ccZs(S0LM;=`hAEc2!N_RF%TT~)t`X<6C^LoC+@|P0b22v^$hQMaO%kh^AalWQ4H(e z^!8mI>oE~}x5$XJd%Kq!&2t|qhEff5sMPz^q*p@-<+KYUcdqB$)<@dW`@+DBH3M|D z*z3O6`v48h0RscOkyI(=PlNn=#QQX?k>z8&pRRhLvIn6b5ssDj3D9{<0FZH*`rdKL zBc=5QQuYT6_0tN0@VBDpx;zP#k%&q#aIgB#76VATyQdEoTw`VXsRn#l;m>Ony@g=C z4;(#dYNBZYeMh9-xcK-NO8JsdXzk#Dib1~dOp$x6I%4% z8y@sKMWsuX<3t`>!tz2-8G0S-!J5(YEV!R9E!6#V=zLdEURVCs7TRqt<=0Q%X7=?F zMLuVFtIV;b7)U2WO*Z(5by#zW02`*n;-kQ>HFSD7q!y`+d?b5|Op!z!U^pCwR1U-% z9?G&Fp6K({MOJ=sr6|rng7|a=Wp2b!4}eYg)@WFX?@IZcPSs{;J4Ij^kJT~YM#_Wp1Dk(c}ElZ$dgd~$pY$Mk&PcIW>|9U^w%4N!Sw8Fjk1}ZEno6&Il+&h1kqp(<6TMNez0;A$GOs{zW+FAuTu^q2 zda~j4h~4z4&-B=@NXgpE%3Aapo-N4g%%`5MGGJ?LBw!-as~XkMGV0xFXg&D-L8qD` zbl!bF6aCm;XIGvB?9&(Bo|nV3S4*?-quF1Rk}+y$FLGzkjKcXcf0@@So$r>Be}S(Mw7MisxhQcuB?evfXju&!Sq)xZ4LM%@^HQ=| za;Zt+m({%zea~h2&cuE%0wW(9BMv*9?ay+7y6UPhKLc_D|B?0F<@LPd^5gH7o_Bw%_f!2=9c*u zdoFlzjdE+bf4*0q+}a`vi%3iuTkB1i7j5!x|`93?yu)ai~2u^#R5i$5zRmmO>Byrx+>vP)N?5j$~kcd&^*ar&Ho z;#_v(@<%DzQQ!B()7P5S@WeaWnuf*5%i+}5_tY=?Pf5v6k;bR7s;6-~N3pGE38QC; zD}Po>cFrj~>%v9@+&x1Apk4RK*FEyz%H%&Z$UlGibA$Zz`npGMFHHOY8A-nGkzptd zo6shLmzxD`G})VlT^t*mMSY?STg5{vRqOF44JOI1)%8b)PtEAr%(&C8d*tgLxs~U? zN0P65!pGfj`k9^%DU-!t@J@R#reBC2o_sG{h@^z1V-6LQ3$k#pcb&q`ABVYH( z*FExek9^%DU-!t@J@R#reBC2o_sG{h@^z1V-6LQ3$k#pcb&q`ABVYH(Rwygh1S_v- zR$g=bH%RhzkIb<(D7rPIvNimFk0f9B$lU1%JY@$zA<5T0vg%o+@mbV&B>8`~M+W}K z9+`rI;{LsR2o{6`v*G3EY0g4`PxVR-|dkD|DX8C z6dzB%`^ZOnva|ddK3m?t4@96`v)KS0)_n9 zfA*0rksSZkMwu!(MNuT)b_7F zGCueZJ~EQu?|o!*N@2p^`^e0H^pRPKVPU`Xk&S>@tnlCa$kIOl^pQ;;oSyy8M;-!` zG$DLsjuaGjC=f~ln851OMR^zl#C`;rK$4yV-7beA-Gr_G@R55;ONFI;82#R2d%UyS zGGcmgaWAelu=MFI(U%^?Q*+b1wf~2`y9|r!-xt5XW-&vTL8nSd4oWwY64EiWN=vD9 z2vX9aFmy>OAgFW>-7tW3cOxn(Fy5nkpYz|peed&+bN=^rKRNSgUDrIEnf1NaXI|g; zSC)hjHHCx5Zn+<&QbTd|K3=@#^Hev_7tn+o&nGnRUp<5UVh&S zQ4CNWp0A5i0YpE~kE-fTt5jSBX)OHk-#(w-+?Eh{MFv6Kv4jvR;ydExJ@AY-9*5{_ z`1bOp1(b?2t~$xG%l`_J%S=70isPHg5g30{Iw`U_97m_ zkS+s@Je9*I#FPgrg)QMA^UshuWiJ`k0`bW3{Yei2LPq$^rz|SeAWSAOFah=HWS zH}Iklc?&8A5S|$LLW^ATHyjrWybE1CHgs)Wo}1I-+BA$q<;jhzJbb<)eUkK^H55AE z4M1>H`Qj)+V1|J=-F=ajIHKebA~;xB4uF84csT&I0L04i*$#l4*<_+JAeqeXO7b#Q z(64M9LK%P?jf13sFdYCyGT;Ze`!`{KL0bSDF2q)nSpgVrIY3{IFToD11>jD&xwCnO zjw?dd1AbSMiT+fQ$*`4VA^aau+-?1r>91aDPk2GmFZDNGQ8EYO*g!H~g<`^}EjXwl z%@(2J0lw&y$6z*&xC=rz4kt+gkC7RW!}oLO0)D~WlRK~hWq&(i|D+=zTQdT8k?<=! zz#0(#NEr+_j4Un)C7ZBxI^`F!daQn(ggng2a}s*b;-xRXGp#M69xtrP20C~n)S;Yc*o-YuEfbjv zOR)4xeypFM3y+Irc2X5JSI6d(aT6_=6W>zA`zm9D%TeL4;*t6BFmuO|6hKA} z=5vI~-cLm%EF*f7V|o&@*;0t!*{WkU;@;{3RHsjc$i0)S0QzLlyE3nn6@VL?p4VN% zhR-s~ty1v8C9Vfw<2&^ z3G+>+^UZ$d=d$LfR^>8#=imI9J4;YtUsvF;o%cv3f2A|mdOMeeFwfDu5Zgz7d{$sd zD--Wk;Fen8EmriqkIdR#$Y`HW5T0*q|2FjJ?>;jBt0Fzl!brj*Bm2VFb-(+_#ftBq z8Wkj|6sB+%WqQBI_L04D-!p9&N~UJK+%9@AR$O6Jtkn5FVmkp*mtQqq-1M{fc4#s3 zeQ`8lNvC&7w~9q8=lgcr;+~%+Xxh@n%90Oah2=)?KXH~$*Okty7=Ph>mFr#FFkQNe z^~e!M3lVVx5v3c`zx&9ki68t`-mm=WBhPS_mDLre{^=v5-j|K{mKFTzBfsM;Us5Tb z`qM`ad0)O`^rw&PQ+TznXz))T**x`QvdYKbePo{;Y#;g3=yxC4(hKux`EPyXCy{^e zBS(e_8vp4db9w*0k392Sw(n0L*~bMNL{>eo(0pRAPV`yJxKh8~M#s3^puW;X)dn$B zZYpjm4zIE_4u4o*X`W_u8we^00kK(RhJehp%BsS(s%nbr&sNoz*1&BP7+h;Cx{1IB zI%g08=)|D+9je06b?93C2d= zL`K*qa%x9yCQ)6oU|n$~FN`6pXM**3sK?KnmeeyACBQk1A3k-Ww z6=7Uy7ipBQYE(IcfXaYu*>x$Hj#?rYfH50H<^#9TAO|}A`IFjQipF%o#xb8JrnttL znZ^aWrV_n|3e~3RkjCl0#<|M+1&W4j*5_=fk$ye1{D5F|v z`&*LNT9}EAZke>Qr?+NQf=rqqn~Nz?Ihe5l*+~O=7Qx$b;Gtq0T~y39;x?*&2x~Sd z)c?Ch%!x|pl4(v7M6i{E%f_)R4v0r;okx`5;*2?7Hh9GsFy{tHE>Kq*I!x)o=fv&z zxWj+?ATW5SP7ahiA-siR7D1>9@*Y5*msIm;B5314zU)?HB7}VrWG%O9sRuZLpb+jh zocHZ&yX~$QtyiKtY2ckV%7M4D?aSeac!{3w$Qo#WLsW5YxY+N2Hl73sD+hSXtr8Rf z@tUt*QCr4pb1w%W>(F)>|&73@%B;)^SEi1&+uWsk;i zM@UP8v~dV#W{?Nv?m;r10z)NPO@MJ=_P}f!MsTdhcns#-7n9c4U)T45%P4^kyu^pF zqT9uy0p@ZLE!m758|AnJ`7{wk7GT<|@l-v4#i9|P8N68zHq%Ww5Y5X-&c7xOT92NW zKAu5Vg8L*3-+6$;48(Et!q0()bipqExmZFp2wj96CJ#xJ0)z)3<$wde*%A?BkViO( z4?wKa5kp+SmHmax4uH=E6#4+B(k+*9%&#^ASK^kr%pxdB7iBK11)NqUCSqZk^J#kS zNn;?~aCu6thb>?h2?KfI;Bx)y>&<2fsYP40rjb&_7xljJ#tH*dqh~w-n=inN8buoS zZ~IMA@BlQ6^Pcm|NeTewCJJ5l1iTV9^&Yo_m~dEk5{dz8G~YC>XTcMh=~1t8UdegyEnDcHahV3nD+ogG-72Unf; zH#6Pynh<-K{cloV`3=9Gm@WNudQR&CexwOvaS6j`+`(4DnRtz=Vz#+1st%g`aDUCN z?(8S1fehK0G%`&DJv@d!z;}f)=rrY9O%q78(8yyE%HsSz(QO}F;y$vSD({Afl#bqn z&ypX^OR4uTte%Mdm2WYR@uqPbFb8(0(9rc(Gu<}2)YX+Z`wK`@YoPU8&7dFLA zPk3EUV2vOH3iNUA9DjoCdV^dC?Nq;d9Q?nfkgV1;eftn|YM{~N@^$+L3gm%kmsT%eR zUkI}*U9s+Lu^nr6=8yPp-g7(L2Ke~sB@hTBVU$nS%mH2!F-QedYrSn{py1h0PS#pc zjA4*`0j1Gi{YxKN?E2ea6)FK&40o?xGdIrBx6-a?*POTV z-Ky{PN+}&|$veVd8Z>71_uko^ctgeW`XBqqye-LhpUn5ye%=_$mWyOmudCP^Ez;Rw zRQzinIc#U7B3y@EBTFXaDu&1A`aA7{2RSOG>3{mjrp=)Y#>WoR_6`*V%{cuZy&?HiuLUypW$1uRB_ zH0T(a%rU+{kMFw;S)RbEZ!GB`D9#vkBF}w zE=MA)R@CytJ=aNcC%`9G?wW=?zXF9p!hqadfzD9%arw0v1v=;U-+g5Ho(>H2b*+1} zc&i_kZ~g8gllu9>cetfl^8p0Ca%GC_LtH$4@%dJZNi|%PFZI9(= zbzy8DndRXprbA<8KW%_((pz{ONq7eOQ%HXH5EQ}t4cisb2ox9=Dnz^`o_*3f)inuummkr zf0)puftTr__QO~Op(&;CN&#J~tPmk1p%hr9zFk>|knyc|`EGiS%`o9vl3G1I&8I^O z!gJ@{Bo$h23n9Yu>yt-%*gkScwUBr8!0$eCw1c_LpFZ-;)ye7KedMLYtH*!($cDGV z27dREg_|bluzh5&r5HK3TFW3MAyKQuJq0hTBy-Ygt7MykGepXhPSFh$=kZ#bELF_f znN7~C7y;Y2v5MXrxo@oN?CvDFi`l;`4EDA!E*t-7UsApPQ@*qwS9}-NOj+;nc_NYE z?hmuP=i|>LrNo_TH*Wbj)qgen;M8!ko+i|Ijw|6ZhM{b5Y12@r6UM8&s4$Kq!}gK8 z@RJ&z_4T~Hcs3wxbNl(AG@dETkQ{rX>-Vd#_S^32I8L}un6ultPTF{wx=%af&AHEd zG@E$L`@fp?SbRlh;<+5#HRHLO6l?6Yo<%m}wOQC@d6RVzF$n7u!NK&z(JD#yuDT3h$? z_0D^=5vn1A?KzoF$#RTMcCRF%%gHaOA&G9iH^rRS?HS1cz5uL z9}la$9zJHS$5EE0d@UL*V0lwKM5*fXogt2nB};s;@_qd~LJ1X?Y>1%y>h7=aq#s&x zFyW|ZAwQ`_1?OC6z!TP~x+fxpm4~=%b%IiE| zD0o(}r9PLelkq;jP*QM3yJ|W5=TLl8S8YAVr{CB^S=OREz<1Kd}sY zxML2XHf;GGTOQJ}@bHSNbO$fxi)c6Qb7nfkp*r%@>gQdnmL$Z$v)IoW9rHG_s*=Mo zl-~J*JU=wkj8;pLmF>^>p1hF6D zNhWLSPBpzIR?jbcOtze2>c;lwp6iLK?cOw~Z)JJxG3RCaO);inO>)+2*jVJ~L$&8Z zB^%RRpT=p-x6~i`U-`|c`%k^EHG`$j!ZT+Jfw;*ToviSCBqk=-Y@RtpW^7yxyPEh) z9<9JQ-}PcU^E0!Wq`jkqDH;0ZPtnQk!^Ln9jf+L%S5GsDkp~fismqvy-WnuZ)zc$e z-vxRd*Di+rr?;QdTfQSn>3(qcdwdGglGWpD7sl}!TMGSJj(SS(lF#>mGWz>m&IlXR z<7a1|q88y)SNp9pv3=z9CVpYh0YBXzX?m14qSa*s{2zWi_?o^UKaw)U{NqQKXqAmD z-W_zvhsm5PlKcvM(+{KFT`~9!TO#*TN7&O2^Zioo)bSEWGuXBZW&L!uVvXMA3%TiN zW!M*eNFCF0J1Q=veS)w_9Iss8E`55bXZqEsr197d@sh!zf;4UNiQw_axl{+MuEeQ< zf}PJfeg<|L#${tw?&cpe98pebGeJkk)g*LIPuY>PYu3B9!k@-#c*~Lm?jc1Qd?Ds@xqg8%?mI3D`<&2Yy7#XIY^wF5iL*YA@Th*RkV~=SL zZdSYO*d%#R<%S(s3J>o+mF6A)+GJgKA{iRM6*go<+wvW6L16)Vh&^CkDQ*h*E)IK-AZ)=7L(1F3I)i@M^NgnQOUDIdOhj%Cv zmKf4Q89yx)c{>$3OA94U%e4fmYq~8H7A=$x(Nw{*o+>RgYE(28Exp)2a(WcQYD>Vo z7A7ba)AiOKg4Ub;lsDyDJFtCZwJ0{%*0z9Fj)chDd6;`O<*i)l`M18b5-zv$N+7wR za+Tz5{PL05K5`khk35^tXW5qVv`u(7TO>iw5YZ-f!AiU;F3~0@KH7G+)0SS_CZiiJ z%hJx6(HE3Ye``nX-Op;r33gtAGKQl7jTf4gcr+x;j>^+UPS=lqj9QW`8NYAhWw z@D82XFkRh_D2opLgfN3(g|N5|L@n>TKT40yDIYE=zNr}_^_nYyg|{dztdz^(RjBLaiM5P+@(*iq{rQ*BcY_Nrlet_ zr0&qA>Z_y@rKFtRrC6e*(9k8AmufS^?B;8P-r5wyC%qB;q7A%HwsVtKG!2V0p{=h7Tp<7Q?p4_wR(TIvrs zKCOL=Ei8u(=8HUlmj|*f%IySG-LMVZbsgNt7M9U<2lPWqXmug@5F0aiBtU)BRs(Jk zwC4*wO&Gd+Bf>FTBfnfj(gKIS`*$2U@Y@hKIgSuINR}F{b1(>o;LVGmv4!QI5>Q+> zO%8Y>qpXr{}g3YrmVk>81BmT0Z4WGz~lR$hR1LAExhEy#70bi5nL zZ3^WbBVsijA%jKT;Tig&JNn{GVm^(XAVt|U%VwlKpkhS#sm9e0^ zg1Wvb;oO4SB|PBKbL63y>7avxt8moQXyfL{F?ThCV}kRX)HlgbGTIBjAa{Gk_Km)XO==V~1#|TaBHw1mOeY9^t?p ze6-Qth;~T4zu`EwmYya`>$V#qRkFU@)0g$|5#A#mo+W)X^|9Qr2jYIZ0&(NdD3XYo z^%d5%RWXfYqgSox)|puV=L0d=@xxWbr6C8<8^q_73f9UzF8Sy#XjWQBvbu)`4Y!1S@HjJ2uE zqp2*|bT-9w4(s$=!RcIu={&vZe5>gKx9P%=>7vBxclp!rE2oP)rc1`AOV_6Vy^mbh zIF+gwh&>LDQ|1dVfb+y^QqEHc@3yANr9n7};WuL9#7i8>Y#bpOoTLy07k1JZ0CLy{ zw&?}7>&Sjavr5Dpni;d`(I8NX;0**9N_?HT`Dm69>P^O?R>*|1(D$O zwV4gpATr9J&BXaD`+--5maZu-UDsctuwKH(gsDQ8sF6!F1xvJ5OLUz}^y5nm>r0Hs zOH8=S%#_RjqL0kXxO9bdiA;Y{I2&idaS@wX#v`3~8+-kl$1Ff{-j;flNPk`lZ9%%f zC~SdfRtORfT@gX9h!(7fRjr73u1JipNUpC)VY9`!t1^_UvTUpOgjVGgSLO9r|5YE^ zQq?*LX1&7I`KV@Y8CzK9jTx>znjqkv7u_SdQ!uFmOsI7)3Sfc|<3UCRLB^eHCgW?^ zYO&eznmO*e1?Bofw)ICs>yH)JE%n!}tkZ*l&IValGM=yBR>a`I2ojP-rtqaWhzdGsJo` z)P3_+=w=vlGrV9kqG~hpU-yyiV%BY54BFI~20vHa&@!`epO4nTUGbn?St-@>bQ{T2 z-cSozyKgwJM81t=+kPvwovXN=r@x(VyBreF7Dhe`JeTXpHx!X z=iqMRQCcM{YA;=mq`2Fph1#g?kw9U?xhP`;?z>%~yWPm$ zo`T)ps@*8m>K$+hC^M_`*hUPZNz#(yWM!q8!Sg z+-;ExS=HZPv)*5K-`@z`-$d?j73^9t?%#uFZ;++`_ol>Gi)of7y=U# zo%#Je&-t&5Y%9%d`^!xsIMN3{^$%b+2e=*wc&`rdlMV<94+yIdh`J7lC;r!cWGbZt znqMKb&3oF&p}|F>)DL#Qs*IaR4`z>_fK2;0tH0e+`p#m2`Oa$doz3Gr`>XF9N#Ac5 ze&?+I&h@|3M{fRhlW8A9^&R--sJQo(NyBPEYU+~m`z+&ujE$8j`{6y|Lph~Gd4od* zn?uF_gFdpGF4dvTujdR4-{1q!B^RDZefg`Ddl`3WM`XoAWA<^XgaUHA&~Sh39qE=k;CZ4HM^$8|O_Y z=goK*D5{GV_KQ~Gi#8?SR;u&mzZaJOW6{j;53idyZ*s7+adUHVio%72ge1kp?qgB2 zw6v0ff~ty&hK7c=j*gOvCRKtOr1kHvnc{=KzP*`+g~g*skFcoO&d$!++1b_A)yvDv z-`_tpG!!eEV`5_dNi^r=GcuTes5u>~eE3-ftDDao zG^bIC9WC`89UWNF+~42-e^)gB6Kei<(Tu(LZ`Aycd1dVNe;1bjTQvXwAe#HQ9ICd~ z(_A`lZ=}19+ihfcuD{#J^gZ6%$O^#a+{_N9wBO7LV|%~(HcDuFGdE6=b1N@Ff4eBv zuG5n#X~vUaC|s21%QcgR9vh}8+otf|_a#-^+r^mjPR^Z@igEj$(wg=6J0BX3w|C0^ zQ-x)Fj$QlZ{rZDWuCEP;<4?Xeo~{>vZMrz#`PvNNaUY*3i1%cHN&AQ2gzlUOHv9x9cG*z;1zyB4zU$=8+9vIG<*NoMRWPT6wUE} z6V242eD<O*DMhWuZ2*qK~vC4T7MsCbuZD9EN;hm4^hb%0N zM0kv9|FLM^|0A03Jxc$~W%B@5Bi`}0*h-oeYB@^&FGVx9u)P2BpGC7Ezp2cZ8~;)? zGn2UevuGare~IRA&|a)))_GK0UG(kYPG66C#pkwohM<2E&9JDyie^WSpudV{BfftY z%`UX9*?$qu_BV*(xboS#5}QD#!<&rYo5;0)63sNEb`R1-C8Hlcv!jm4o|U8P#ENDy z3*5VLka7lKngAVuD=2atD_I{vXo&)8icp}T`rh9}v%BrP>=6D62>PIOu0+AgT>gjW zumLt~e+?c)U2{H%h0vf#F+e-HIDc9NA-Re|Ky?>Efb0~;33qm+yZ9rTJ7$BqEb2%f znC++bm|8u@0ZE@dsJ3Nb#_{wq!8IP-#lhIeeSJN#2uU>!fI$bJ5vlns!OcaWm@D5$ z)-7Pj5P7^ugFiAKS1*-~AHIR9Ka5CI?Met>?`)KTv4&O6F`k?f3q1MyIteS9FNOOM zW{`gu&3ypX!Aym4^)BJRi)J?(i|DYN=XHNX^A*U{9oyfcxfJK^1J6h1?x4QL#V3Mt ztZ2rp{T9tMz{}pdH(`mdWLm`Qy`~EqD>Ja7*$XS0Z6EIYD1Z2?Xf`Uk#yGFjj1|pU ze-q7Ae-q8uu%cNVAlfD;WK>3dx^}9B=Y0@Ku(=4mZ2@JL#{>jW$UGuuF5m61roSXP z47e&05ODgu{M9<&`42I6fPhdN?27>in>S@od5lS~Y%*UzGVleHUGgU!7Ye+K{uO85 zNBSTYo;4&n3kD##sC+>i2#(0Vab{)+2^=iaL=0Es5W4{Q**H-aAUQMmGY*FZfUuC0 zBnrNOlKY9F0DKfEX@R&3faGX^<$&-pp1(MI5Pkr_NKP`L2Wpl>NYId|^5;-ZQacw@ z8>K)?Lq~Zu6!+BPYhpk%+AeE6pqkk}7_RX!>4I0?*>5mIr`z1L$nsU>*Q95D314 z_!?qGGlvD62&5VQTQm<>JBXEIEi+8i1>tr8fdaw9UG8^qwq^B#F?v!hA0D)0lrIyE~`Z^c;jAN6yV%OV`4-%Lhjb!z-(f- z3lVFm2)d~^UTjd6MHe__oI@BfbV|NDH12tgt$J5nRz5&RgCnQ}kiz3ntUZyHzb!L0 z;3ajI*jyR*>%cb!_Igs}H57%z>h(I!Gurw-z;z$cEceF;@c8co`N{z2B1|v|s3wmT z>v>}#n*0zqK^KUNB6m_0HCM)3=Bk8;=!Caxao*JN$stkU2JwB$VK_?3nYG4j%7C~F zi~$W?wE!oMkWl8=N%_e6u-8s!WSoc?&n-|V44iRE%0GoPGedMlLZF&p88b)%KyJVz z%sG;?YSR_1lf&L6D-qbogvUj6x)R+s!bd-?#<1h$C;YTxY8 zn`f6UpUw&k>-^s1nLxNX2F9%`;5RH>%6e zUCT?=&!rX1r%%nD=*hSCF0g%{XGWO6Y@PckBA4-fuANw+t5KnOZGi=?OtfeLmL|LZ zEDWG6x)oN4q2|oTy`OJM_%^VvC~CS0u2iJ8UGS>6P@l6f#`|4z>bqjxcaF3LZwLz$ zw+mCn-sc&;_wIa0^S)46CByH1QNhpm<+R00q3=Ue6ZE|EKcyDe)fL}XEPicY9Nt^p zDpu02V$rny4mJJ0qpqZXx@6I<S1(n%F#^v}>NvC^8<(nZ=2%MnI1 zMsYnVr7Ni)w(CBm>V5Dbe8159;k#Jb#P)|`?_#7%+0VMN2K%y+h_bi6WuSO@{&v|M zVfmO!IbnVIOZ)N-+A?Cgk5|PDNh6DT#XeG}eKa=um_YcE_WUC=T@F1_*%|F8HlI%x zqMzoCK5@)oKJki2az>W(iGLQD$$M&$qmf!T`?H+e__NgcXLG90Erb>F#ubw66;w|u zRO&0HLn}6WD>UgU)4V?m7!@_!f7IZrG^($RU$0>7tF)l2vRto}}ui8r_!3!qVnv#>R~B%v6f%LWSyTx9ZOw)s{%$b~zYOYb=DN&5I#ZZZ+xoRd#(< zj;fWSPb#}3D$Ti!yv3{C&JiSw;LjQa9sqKpK^7nax>%i&Sep;4$sViCDn{gp*X2hd zit3H%%l(lZb+Z)pc~9!5Ss@|C##iBqsfjf?ZuNyB4cUSX8EZARM763rRRnZK?^TWJ zFf#}|tZhE1O9=s(&{%E>@#q0=p+Js+^fbN3T(`#bL@a7{#-ipGCy~*Ksu50<(O`WQ+PGo_tGE{-T-l&>6@&u~M)d(KD3EJ0gaZZPK!I{b zNGxieRdvQP-&^GnkF+;iJ1BAo1eP<4+O<%Zw9xOiWC}uVNVKNq1FUMmZ`7O*GGkHm zfiFop_zHXOXd1|k{*9V{RJAZ%JSKE$VPmf5Kw}AN>svtxTQ+!;8RUvE+5xmxbG~WObeRZn%48A1JD~@yuXZ{txH}JTw`1hhkkEtXqGkX&GfEo{WT80o$ZKT4U@OX zl2$}R$AlY-z@dUD%IG#6#76@>GB5b4Av|#B8`Gci7khXpVfeT2$+?q`RQC0(l z4C}Z0`mmN6kGa3yq2DmQzpnv-<;-Fwh>`wRV^P&9uuhjA&^QznCFq61Q5?YF4}Fj^ z0JwqzFG9f^075U_s4``sZR8mRK^lTYizT6PCvP%dJ$OEmGo0nyx#V0JM@ z?;`f^Bd=wH>~P4oFT&8#-`Esk8jUbl2Oc&e9;*XZa|jy}Kl_1k+4MI?>Hq`zi#%V% zVfvfqbimpM!Hza}^PA{69+KdJ{7Od$`Xc-;(J7?}2@{ta2alO7KvtKqWQCqAB zQ{J~Hr4_sFiKiz7Cw%87@ij-G@Sg0VUiNgXu75%0kCxIDrU($}gM3e$L z>SNMR#tJZrwP<<>>p}Yuf}|VeV0UygGGr854)O-fkXV4eH4|we*e`Hns08+ZwgxAj z>M_5$+i}=?&D>nZjIgBpvikgb>BO2^=1w$X?{Yq!b?7E4f^x5sQD)Y)aly(1!Qx_C zH;1^~3;Y!Y5;8;V(h=Lm^RvZGDPy(ln#-K1H&)dSUkEj%l3>MccRG%gI0%n5SMtX$P0y)z|tqt&^#DLI=TeW01*W(G;^5 zN4nyDdsCVc67pmugJQkkVW!5f0~s^$??<5UCBq5yJD1Ve!DHKtx}xbxclG7axGr{-5m=}=PXkSpe~8)lepH-_{(jgT6W z%`3ppmy*`27MpmBqn$($s=eK#u>G?aVXK*QgyzVfq(-eD_S?;Nd3|tmQYL#9~I%sJBq z(46TwIUjs%-klkVAb^8p^d0U_EjnZeJA(+EvW=$wV`KkQ@qIARp_>Z@-a-LN4OVy- zV9Dg6hIv;=S(1l8f)U+*v3?q7jLvMJv(@JHyGb=fKQG-_6{^UAUr1?NMK$U|I=^#BHTxuezzl{~d%8>;U3$zFBQ z@BC@d++rlwY{?%n>5rh(eC?@^sm#A*>%5#J`?T=OZ95iZ57=@oz*KZ#Sl2OM%RYWv z_yx$yEXw>{G%wu?CHW(om*pcUc+A@WDw=6RIC7R*)fr@>1aiEOh^DHZtu1bi;+3rn zSvH&HjI`rxW(b%Saa_^X-qJ2m&yWhC)!Wv^ie|HpRJ|Sj52kXNYPFx%`u^&dxApc- z>fH9`JJJlknl<@dVnPV@SyhwZR=@qSjcBISOF~xr>$fd>6M4)#(-A+c2QwreV<@?+ zToCQHRKnIoXM3wdrT-?HD;+(E)suIZK1Ym+InmMVJN^&RO!hoh&_U>_QRfq;`b7Hb zvwsuK5?vd)UK-MllBf22D|5}S{)lGZzOP89pC0zRZ9Bj4;4%aWppYGR%et|dQo}Z)dbCtE67zHg~Ybc&+z0t9*U6V9$7qw35 z3-+>3b9Vn^o$j$-tCZn`!4Q7l`n|q7pr)_@H2R^%ktk6261l%BAIX-be%B7;} z^*Zsw-=cZC>9=T>ymjtSIZ?pvShWx;KJreXEw)=emO{j-@uaiQvFR7C1ZOi2d&5CI zuCT<@4)s*yYG`iy;dBRkVLD4YSC_=|Al`|F=l!B560RMxRE>wI`@)iLjamkcN0kT< zN%xNrlNygp?W!eD@}EvLdgOSWNSB{AeKnL}|UBpvRE+CIV2O~I_ z2=pfNu75y>$l5OvS#{@9528amTC=^J4hzlqc0#2qbV*){$P*F7hbhS$k?!D%mfR-| z*WgaLk|WabOF2HmAS#yPV~xT$+xSTH!_=!x9+f&NL{T>Fuc?M>I#-I~qn#_F>6S#g z!gI( zTl}^6OKe}i$x4r4mlahh411kWIGe!Y;aOdhGm`j_IC5pbriF2RFR_{>=JwNCRo-_a zPVwiId?6SbCG$HUqrB;@@0jPRS_wVB(T^3)!Uk%0);|V~v|C$cr>NUGy-6E9To+EH zdGM6Z>oJ%ws+JkR0vnw_vMN>5V9=*=G3|^In^eVq3y&ew} zJwA1w{h9eFtSz2xGn1noCfvx*F$=ZoG z81`-F#w%gfkx8d)9kW6xP5 z$ylXIyXF%sFIR@Ai34s@t|dUAk3-V@lsd{rAvjlM#5VSB#m^=T>yObx>l;z!Q@nX}>6JL{B0I-8v^SzDY<4 zfAxy=K7QW*lioIgG!@Myc$j0FYOBzdFdSX5m3zZa=e~wfVPci527iWKwo~e;+|glS zG_AcBd*T-?etD;LsjF9J^uE;HP46MYlaj&IapTIP(#F&$rmqqw8rgQrUi#@jBr`7U z5OOz;&v2;WO`Ce|cKmsd*3oVwae8chr}E>afupl=`P{Ml!xjdo_L#KUNWqg@hBPNP zj1qEguVA-+$q(T*Wc>N4%ERVchBJCUZ6WvQq*IFw5$x z^zOkSBy~CN(`g4o;?wB65i1O_%Pq2`CfHwO4S81HGj)gWyMF0wd|YRJIdsocG?LZ@ ztM><c4bLRF=8vjvsFTr+=J2w;(=b)ltM;bN%5=kZ z&e$P4{yD)a;rh6fs_)T+@YLN|mx>e89Y=$anI+P;@*zpvXVvww2bmtU;~8Juew;5j zS9!E_g&l?UsJ_j~%{Z4lqHLG{cZSHE9u+_>&NER5;< zp8tz_ON){meUNoP6cyC5!s>eS1IxH zQ2pg7qJ}8qFEWm)DAIIFQfNyvdCQgE$g2V^ZfB_Lx|G)~Tbd9pRP>Zo2`zQmEwt&8 zbnUWb=oW_62*yL%QlOQ2H;rmEvR@SFo*0)5~FG2Q&udF}DQZ_(M_N9Pq zAiZo5R5o~5Cgh7uXoJkFJeja4nQ&K`2osq|d6_6~nP{j?%&v6o7wNbX>G%Zc*S^wk zETt3Fq!R_Ck@V6@hf>MyQYq$UCHb(k~s~MZ}TK`qa^cO zCG$-r3*;pWxh0FPOTN31c)u!9+#pesCs7(D@xfK1%tWGGUg9IS#HZ^LpD)BKR>dp( z#j7gBtJB46g2ihc#Ovh6>#vJ9T!=NUiZ%6%HCKqC(#2YW#abQ2+H}R*CB!<2#X4t2 zyV^y&OGJATM0DK>m^emn(s6sDbg-0rN22w>S@$ zf`j`Vf|eb?o63VeH^6n`AR)B6vghDt)YXj1&@E`h_H2+4H4abr;9f=2{+B?0+aO71 z=r{S0c@_;%ILVJFT+8eS@`gjl!PuwSA#Z+=BYEhjJoKUgW;v-*p&a=GiZ(z)mB}?l zIB=*|HsElI^zsxiE(%~VMsm!Z9g(xj18hXs6b(F)*K#u4e( zx(FV**AecIivQI=s!%z2Cpka^mPEjTbC9RY$f`?nhNm|dCr=VW6s`5v7J^tqQj$kr zT^r_QeQnyPBfm#5S)whh9%RU>Z$A~Fr9R3~s-wC#q`Nj|R*F81(h{D7K#TP4?gNa} z!`iHoCK;rD7UOz;`U-QpcIq!lECQZ0P~u`H1FoaSwHb7+#>hRRC*<7p7Y)BW4G9wB z2!bC3@=K0jw};Q zg-j(UPNn2erB+U*bxi$5G#?=%^9@;TL5}ReyGMcWqA@oGD0>Il_Xb_(Xag6L2UW_3 zGLu1Kwm|~6ldl>Bu>(VnfIv35F{{i>h2Bi1)l8M!Om)aiP2x;#{!CrvOnt{p!`MvY z+Dy~YOfzg2MKRmLI@>BZ+omx47tw5G@>$X-kHnbAaQcoi&cSRDeTY%=rn;)%glVY} zCMX|We5t2`(!7VB4mq0U$H#f)XUKy;Q?5Qe(=j(YHaE96H-9v@0GnT=m|tR@UlyES zQJ7!Vn_shSs_D%d$yV?wgxXV zjNbFiWr)mC!U)H#pz;=TrEYU~4i@+W<|ZjD_?Q<#p+y|UMX3HF%z6>meGxBo5g)lo zP_Rf?wMf*tNIbqsvc5=qyhw(-L{7PMg>C6Cq8axggwg^yUN{U165BL6wt_0Vn4|Ud zZ{9E*xzrzx#=TLw@FgVpV$K{B5)`sGE#QJ#W)EHFKrY`dSmvx+=IUI=`d^;)W!~du zKHL>JSK&RkiU|_4U;U$EzB+Ynqg6T5N0DLTfsTYr0ry zY`v!MzGe`*W{6xv6s#Flt^GwbA6u#Ho7~4DZTAJu#o=pvBlnP+%(%<)`j$5urxhQV zDi4~=qs{N3tsRl8PRHy2`-SBVzx9n5|0tU0Hyr1!9bOnI!q*>DT3VT{kHA-%+}D|f zObPwQDK7~u$Ags$pkpDyan_shY+J8|w%#aiCFpM@T5loUw~|7)l95{}1zV|ATWOtJ z>El}&>sy(}TUof<*_7Kk|0tRtY{!vq#kw!Zyx6=(V#<`bY5if-rfGCkWa!s!c(Gqd zR<^a${^lp4ozIFp75Y1s);m@1JJq2(HOQUXf}Ogmo%+t5hVh-o^_`~Uoo3u!6qXvZ z?Y90^G=EaGmJJOr-&apzUUjUorx>ueG1I}A5O;3cV=PbqANKA#DysEw{QjQJ&}ooT zdZZ*(I%H@>5m0I};K7^G`>M$dhp+f#R(@AvoDWIWS$gyLqSk&)=}ElaoN^M%hu`e*4fe)YJck-3yJ<%9KwVI z`H&bgNT}L>ie?AoP9*Yil65EJ!ir>2akO#3=4RHEDYE5D9<5bB<2D}O_9dC^%WB)C zM%!c#+vL966j9rh>DyH0+gDn*sYkYHmbYmSw&}3H(vyF^%JlUb-`5{SvkgAevwpHI z5^Sqpokv7l){>j%o*=tRR{gAEKCU@F~1KX<4e)s;!uKe=ugM(cK>^(*DJtd~S zhkSdFWcHNR_Ee1aR2}xzeD~C&_TcGz8s&SMt$SL(iDtUJdn1;;A+~ql*>2_8J|*8b zFxoeC*f;XsH;&pjN#8du-#2UBHy_!zSl+ih*tfzyuqHov#&lrAcko>1z*gJHb#q8VLSK8lVyib+3;EkBBDJ&H$*=KQ0;gQEa!NBx7NWTxZye8(STj#Jc*Q;m+( z9FEg{k29iKk8?(jbC-|v4vzD&PYTFS3V#*NbSFtnQ*Hoo^#}@J0027e zg&ulnBIx^rN&em8PoVrOQ~n8*e*)#7$>mu$D4FrBI}T&UtOo(_%1@yD=j8HFplrTw zTNGd&7noONH0HVo7~*o0s;cULP9cv zg4)8u+G1jNrKIHKXTN?&#L)h{V;zBD$mc)|JGFg%_}ee zFe^XI>i1du{jC3KzWjbRewfW4X6uJR{xI7=%-0`g=dWh>uV(L0v;Q~q2cZ1hmw%a3 zKKlDP{`)!k`#Jre=InnO)PFlTDBv8ITDBmm;nnfQ8(M7z$sc`5evylpEqvb`NO9YA zvaRsL|G$88YWq7;(U`N7!=3e+-un9Ua{!C^p8;j^u0XC9=J_D*VdME={-uoh5aIom z`A`@Z%R-nWnaRRyS;owTH}`p07v3sLvn+-ytC}oEsOz-PIM+5Cd=^ivEdR{Q&Uonq zhjChFAltvSpj`RyD=5o7H{~)bs=UGS#r~fblsQ;NiZam!Ww{>;%2{mLB@?)eT#v5Z zW(fO-1?5NJZN|-_>OU2fQ)+_H1?Ai5g7P)z1NnbmP`>@Wpv>Oc+Hn2jhUV{q@-?^f zCpENfO!=o@yZE+Fclu;F&vpmZtj_jEjq=a-CmpuV4rYBhQHKjrR;Z(u^nBFum+~#t z39^;Ae)|;=;rsT(w}SEuES`#Q1?8tqe<&!6d0g;1^rXF(@x7p|fhqt=_bI(yk9Xby zgc&ewxjql7-6S0O3~};~J|Dr|WRl#EEj=LY|2{UD7EH}%Aeau4Ai@28LHX&g1?5&Gx}ba;Pu{rkVq}>5OJh2_5r$_%vk ze6OnieL*=7)5lsX_Tldf%2H7MDXzaPDBpw3qaYVN7AY=ZkTNP0SAp1Jt^njus&Z9sgKRR^ZVpZ-x;Sh56oJxOU~JO_sM1a}Zrn z)_Yo6^=m;{_gg_(M8e>0*CL10QKv3ZadazzK4$#y3(C(FKT@>aUlyD=>Uq&qoOnPm ze)Eq7<$^0+$ln!|T^k6v7=K?-&heIuJ08qa2_r~-;AT>ONZ z#f(h#!ueiM9{G=g^4zzAa4?wzhW%Mh5D*hAg1OX^oCB$0InolijeFb`BCxf`CE<206KRym%7!vk+D zzJul`)-7hr1<+&zr*dp7J~#OFbf@DqjOazDdM4{D^lsOfpEeo6#gG`6X91=HJVFwn zhY3mu1F!&SSQ3ct;vOS0nCT(R^n~mKf!ei;T{oCTQa@%6}ot@7u$ zi~%fq@RPMRi!LU8A8-x86(R=~XR%0003$vRLt~43FicEzMA_S|0Uc3pajT*?_2W`7 zOtQRq2**%#r!~UB(1l|ZU{GaP2^G9VZ;FPZu!aTjlLJU2IIb=xmoEI0E{STvtE;eJK)~eg ztThStllg_f1y!>N64L}&kQNDMtGapnp=F?&UDrwwB+1TS)*3SQde$J=s{r0(1WZzd z%;2~|xS-8U0q3wckg$+tCKQG^J>)trl$}0Q;J_OSK*dQMPhPmjst^^fyq1hHx=Vsd zjID>Y>eC(;CU0v-2=@&fw!Lr!$KiU-qv!)c0v`N+LP#LG6!44oqXk|{y^O3^@gPSM zNBO~jfxn4jfHG&kS)_1fH-U3e0;)-`Fk#qyxZXSJp&VRTJVrp3ZlIVzxN&9l6Z>!t z#jr4XOL>9E3h0_LV}v0rLLn+B&Jw??OBYBEp&Fa+k+KHzc^xN#5} zZTtp8AN9H7%@T9m%Oi|iiU1S=P9USQ_`wDkL>Ya(M1e)RAQ3%;0T!a05uGlOAiWeF z#uD=Y*EA9}_ARGO!lHo*LkG4o5**;zVebCv7##j^C=kr9mN-cHE86B^ND z5RrJT<3dYJ;v%J@*jC@X90Oo5Yz=fZmOkFS^7$>USBZC_?Jyh|SGYLKI|?fO5CNnO3JQa41(SsAf&6@qyRz!$4&+O+Z38%lnGq zgxI?p^e_0s50N+J@+?FecqAbUX|(~m>EBwnOJ2SaU%U+h}fr%mcO*3&FzR;~a{KLR$PZs<=$jlfvtoMHEy;du#cO)kSQ9s7Pj^ zyc-imw}gr-4vPry74ydx2OAf+WPK|rzi%z3#{X7O7G^5hF#T3g#`Z1wrSn@sIc=%r zCTppxQ>l}5DOO;q)H|65qN@!&6Q#h%(b^u_8itx>#;nDrff{z}W!5KfgM-jG9^m>cc+(AJ ze*u3v0T0#GaKhJk+X;^htc(qWCsb=(O+uHut0q;dVyY`Ar66wEnwLpz5~M1UORLhG ztCQ@ivm+|>t1H+iD$@5VQx>ZdcmU=kFgzO$g@J@_z%R4l3)D-H3jy|3!rO#2I__0< zpVY*V)(&Xaj>OeY#A(z`RK2d&Ubt5~JfU53qFsfrv3^hEz)Z8zsjR8GsKrc!ogUkQE6z&T(bOA^?%3~(a+&@~sLK9Gw9gS`*j-A7yyZeY#< zElv*7v0a};3}tYxC(;VfN)cD_(3PwIoSmX1Al=5 zmjI0G?O;Y5aLm@sq6plihtLB7@k1a>L9jwb=nyqPMA#qi4PI9S2my=;1_-Mn@QJ$X zqgEHGbsuhRpKTB-0FR{iMG%}Kx1X8@Xr%_)C*dsgAe02W)#u?&-S2w^xJ=)UF$+XU zRS+un-XiRYva7$g(XD&h2SIurb;3p2`;>BfS=}Jeq>ifxpRVKr1=O7kC-tdApt%F6 zWDe)*^I%W}D<-O7N1gFf;D&F{UJK}84&ewJTEAOvlrRh_7{0YJ9L>`k$uJTpH3HEc ziBoy^vUY@`Z)B4ooXJ}I+N_IM&0x+Iz=sB?5BkAy3$c>Fy1u z>{T!zLobDaQq)s8iXbQbv`DV~EqaWIMc@X~Hz)y)=>~qz1{keDj=rg)sj>qa;HY+n zeRSsBr4>R8aB|IJy3Pg$H{kWmMla5iaLh$|4>AIv5+MeZ3-osC9q0xK=+XP0f*T`q zaeH&nO^=K=uwkQeqk8u9L~YC>`c?w(Z-N}OL$^qp$)`b~vx#_-1vb<|3k@LGvoN&$ znTlgN)^0wEVN@73aHC)ck}pv{%A zp80UgRg93;$kf&Np2|ej0&kZ+Gg6Ot1-u|X|7LUYz5F;2hlVQ0Lbm+Em&(=Lsk)fb zPq93}=@)Q<`8R!29{0`Rw`K?Eou{IuDzK4Yey~^A z=2Xu57x$^MDW~P=h~+nl(~yGc5m&g!ofUG;mG`BcwbU422r+i0A;%_j6a0{Ev$Z(y z9=yIWjJ{z^uI+9$Z=5jDVr+bz4ausF#1@6%)+1{-;Y7r!?TZTA9LC!ey>O0#?TSDM zD=ZG8i%z{yKze#n1Q=&6$OO`jhUq@*E8AnfU+rAKB+$INHXCay3IZWf~QIq^hY4NgHWlr@Nl_&9;y(t;!~`25iH%TA-kNrq6< z^|905$M6i|#?Du8H)@PuxLOGdK!OKTtgyv%7k{pqw$M{=21V!jSMaLdlWFZ^*{NFK z$!rroIVMOg`NCQXpORBU83)nWAVxs|aw|e4yn>(*lIRzZc`pxo26?Qz(GM5pBH6X; zyeJy~rw017;5R7(YFpEQ?OdHPLJipg-onWdHnBlI zZ3(6k^`VA;)$fQfyQb1H$fBI7ock0t)G@@WUZ~&wUd1dXU2BL7Uc4K3Q6gZt^g@dc z{^-5}HV&u@Yq<5SeX2Q_P9{<7$YzQECa1+Q_u62VTCpYj$e!6~p+Rq&1#KeJrYD=~ zAZc&3v(nV6p3aMHP)eui)`IxxIF$`a#Kt+zt^BKDwYRc}YR?rWC1~GSSEGw4JW1zM?C^LIZX8f~9C2ek~~9 zYCF*)u$G|2&$-Y9eSW# z1eK^HN$af{uiFmc`J7ZR5Y!c(FNtJ zo_n(FM_M*&Pkb55)b&{9@v6wTcU6>h`9!`Ilv8;JbuM-94r*jCmT6kmv+ro!mrpHK zvhJ1Q)3#H)Ts{b=)aKK9xt!|IU~iz!J?ePyt)R?aeV`_E7nG$EZ%f`* zb^owgWnSDHNnjS*Z&+zOuOlc6ZsKdwtjB>2{9?;}oaWu=x8BSZVnmG#ZZyz2K$JrK;+mBggXEKw2hrkW zu~y#fUQZ5mC?u#JTKVuaJ=w90mY}_8xZD17SC5kW6D>Ux8I&Zar)FGAwkZlsCO&5Wk zwjJW>uY7PR^KHUbPMFY~K(AWxj?v;Ey~v))J*RO_&kK`AFuO4Y0�=P%48H_ZU%y z%b83}npWiO(0dYd={fm1<#6c#eU~D!jkyVQJo8iiO>}>>SldXir2QdFi?~T`Wqi z_F8zp3*pLRNVY-)k$s{!&ljN!aiew|k%h~)U-TL%;q6b~7Dc2k8QjE|@3th1N!VlK z61$?I6B1cc!M$N(5~DHH_@*@1VA1SJpxjtbWO!*QJM*(R%?F#2<b6@>nG}zY#9!C#8GLrx4wO9GjPg6%<0OGl>(UZMBlx+I?k3T?m>QIx%- zUhJDoH!bd~P+z(9N~q2>bQ@QZey5~GN;Nr*HCExer%L;|u<=_HM}3xep&cr;GZBT< zci64qJ_@`U6172}I6^6%40wwP8z%dV(kN4m?RR!&sf}pzDnHm7uEuW%35#rv`P#b{ zzPmeaB(@&X=S_Ak$u7t^h&Hyr@cHhC;EWZzdxFWY%SzU`5=!|Pbmc`Ot)ux~$&pxLYrj+?Z+eNfqKY+;AOzCE?U zJ5fDnA#LA#GJ!5Avo9uCWpBjI1b;lJ*Ic!7=L??2d_3N8L5JI$Q!51G@PhdY?X!6K z_|NuUht0Q5o(0zj&C`tNwTRKShlWl*zsC2{Mk&!|DKCDp*Y2n@6xD7zLW+Mz5H*3b8j zM=+`F3(2Fu7|0;U`s;K{^QRgt9Gtx7XdUo+6E?}qPNsO`9cmq-w_LEdXCR_a8;GZy zy!o61F1&j|X5{pNLx+1lTivGJ%w{`chHmjDXLYBQj%(~eO(BfV@o6wBarga~)723p z$DtXHyP+>Pp#Bm!M*>af3 zsOyyH#d&rbF}>=z2t@rqm7NC)->yky*Ozd5-N+|-g)jW$S<*+rnpplO3CAlR7xWM! z)QLjSrd^UIF@jKWZpkHBljLsf9p^edJxSStkFvJ0QYn)21x@!B-rXIP{LtR?fQ{t= zwAuH$q~3a&5?g|Tq*RAuv&#J|O14r#tWsYCrS8TzA7?k;t(F41nuko9b@YQCLt7e1 zTAnNfKIN9Kg|+DCu&C=xi`ujp4MrP;OIM6F^W;c(CAXLp1XwIcd;7OoQ72emmXWyD zY9mZxB`K4j*lL%PWJWFKz#VTN-rC9E>L{7u)FdPGsnsQ(+!3`aL%i1N7M|jMz0DTV z=Be-RrQDWwtIg+>%*RXCE3C~wD9g7*w$oFFysPbFLtDr~O)yj#}hKvhlkz36nC3O)~FtWRk*Vl5J()Ysq|&lu2QeNxdwS zb}F5|Af3@AotYz@6)v6aES;k-oqJz8k6SvQTDkx#UHC<+s7tCiN2(-9s?=7hOiQX< zQmTSlsuC(y^+mFJP_m{*vNlDsE=aOoUlMU&vVmK&ky`R2RI+JOqPa<;B}bw)T%yfc zqFrC2gIl7LK%#3wyt_-hr$oFrUcApsyx&~>ld|}LusCY)y7&-*`0%dS$fVe4lh{~} z*m$_ugtOSBve=Zc*z|R=nN!&80&K1e_PGQ$9}ipbf-RcEmV{x;*I_FJu+;_8wJy>1 z645U~q8qlNn_8kf6rlM<2B zc#$(N5tO;exv~f#A_8F$0SQGg_JpBR!kEp%Sh>R35yChI!npFncs#-xVqQgDp0||m zx($H0b@3$Wd5`Bq2<$uwy_<+~n^FKJ5t4rHlq=fIN`#9ZmsOPb0zeMqesXP0ZAHYF zFdyA8r9v*H+q2*e{^l$4{5SggNg{~oBCwY6QJ=1+dJzO;{E~`Zlz3PS2N`)h`K^`Y z-0+ysVsb})SO^1eoO$x|dvdmYVrP%zIP`9>J z5EUbhrI|JFF@3zGI*o~hi?R>|d8|I{`J7g0KXG5TJ~?Y1?BV4sR`@UTaBz$-+!X!nR$=|i3Z zw@@A`d_@edgi#&zYQqtB#L(L(E-LpUhKl?kG3>DveFTp-RIC^x5^B}x_wXo7RUPa+ zqZ!8I8{A&YtLfy9$YK(vX~XZyKZ4th&~y1^MZ{oGfDhT>J#BExe(d~>v2^rL8&%J= zfDj_)L81&c|S23|(BZ$wJf8@(q$N>w#^Em;yx5kCw*MU2)nkORG1SOBsn zdF%vx?5fP{8O-e4%^Y~o97fC>rOq6e&YU#QoDR*LEzY3!X3o(ogJiQ1#=kBoW8ImV zm(tlj^H@~D-~$Fk`&3qf@#u2Z%csWHN_8q3&=;4cGz=)3~H5(Fi)^c_7GL)|}5LOLMlc6v~bhWlrJSigQC>a-SaxF+mFG#8`NEt3j z+b_uYEXYPK+)Z1MEBoISl*tUl85eFV&cl{;1^Y0F?e%1np!`HnQW;1EdFMXX>J-R6 z5ixv1zNsguyTreu!{@eS9JyqYwq#niWY)4|KD=bHwDf-|DAySo85(M#FtlB#bvB_7 z4-I4^bna>oT~u8$DV=_*<9%86iJY642%}d3YWdEvXVCCU@X|`i{z@p;Y8ct-|FNKK znpC$E!04sDWWdkpts|vkC9-l?WyQO0#AhE**mXs3c;4U8D_7bpZ{PF-)_MWidLiTb zKPf1q%<}iwa$TqWHw{u5SJLd)AYv=w!D|-{SHR4{bUPJ2ALILg1xk*@!as546Ys`= z^gk^qt8VtYn)B1Hv`MR6K&f>2taV131`U~;91dh{nio`<`fYlB<=xtm-umYSWzH@1 z?~oCO+5P~_a~kW*1LKWp%gwTYFZ=^rL_QZrypefG71%#7D1T-0{mL9=b2%S*gLC`B zJ3NAXqC14DM4@Ye5z1c*^tMo&S&Z8kWu9Nk|N4I`D68#C8SP3t?8^A=%0}5rDLm(H z{mRC-!aQZeQLoNf|0Qq_N!*Jh;oQOJ+q?I_DJWy_>yqz3VcLJnx34F&udnu>1?76% zM^XFt>Gp`fg_&(Pu=cph?MdkDZecrYCGP)aLHR}0!An&7fn)iBQ|p2A$brl9Ulo+= zk=ED;O1(%+;^&IJ_6pc`n`Aqd4*#g2ynK{+aP$t_@%7d|G4YOW=@LkmvFk2L@5 zg0jp>iP}l2(Mg%ZNxAPyMU+$FFPU^8w5#*;0Os9=}rypfb zo77I5jZRw}PFr6c*F`zkk{i~vI(1+_Zy!1BUOu(!IXLabKIt{Oq#CJ9zb2g}U zHe_@*>~J>Xdo~(%HkN)iUVb*wdNw(7Hnr?B*?L-CemZ-;JHv$f%!itnK`p4E7L8C# z4ya{c)Jha;H6689j#_U;eHlS*ETc9LP+QpNNb>V-rt`0Sua?PC8ALeW1JIa%?W@uG zXF7ViZ@&7MUsxC!m|2-w*;qL^Iaq|aZgX?<^YaS{35mgA4~2ydU@%ijNi{jS`}glF zDk`d~s%mR%KYjWX?Whfn3>9o2UrttpG(JKTYiNtAWVoS~osGS{y^HfpPft&OfB)d% z;J0tzMn^}-#l^+P$0sHxCMPGSq@-kIWaQ>#*XBi?Ro_1>lS5|7?U|{bXlfkmXs@`s zw3L@OH8r)gw6wRk|BI9wO{#yx)M!fm2TlDOrA8n8rm2^fmVWcpKVa%_hyOaLM%(J& zNc9h%dg}*I{q67vQoa2Hss48OXI1@Ir25;rKdI`yzfslSPX9)!e?0h0R{iVAzqi## ze{ZXg|K3)A`_BKwt55$YUVZl8@@mviUrnb_SMzetuK!kzHVL;vW&H=VucrIA`09hs ze}k{Sc4?m7IPGO8>%Y}k`~UlVwe<5fPPDK7e;I%d{D;0;0=&(zSrqsuU!7cYAMLB@ z-XEaooe$1hXWXzk4rjf{Ef44XnDP!k2k~tl&WFix94&;aSspD$8|57>#XD>sEhqVM z9IvEASst%uI7~atIMRLh)n^^8_4I%A)d%!$>rb3%{-LjS1n&5)2m0mym9HMV>gQ0y z#~(&$4*S=9HIfiz$2Cp&M_*0!-B+(8eQ@5p6X=t8QXtU2+Wuen)nSBx<*T1v`0lH5 zd^ioS;;YK0lBWGjzFPI0uV%)&mGsS5zi0e|uV(*D@~TgQ=9=txU;PN>CVpu@)9YXH z)#l)3w6A8fg%C{ZOOTw;3KqS7q+cPiY=pN`ZU69BUtJxB_SKJYrMdo{0cdS6`N#j| zs~=xL`|3x;RxnRI4g>)CmwYul21gReU6btUOQOmAU%vV}?Fkm`f9tDXpnbLY?|n55 zRKFkgcfNY<3CSOPHP6i{(Lo3y%b$I98bE0GCtrQ*&%U}1?W-R>tt|i5S3mydt4Te< zH$V7lYJE(<-}`EFdI|F1`)ZCq`f4sJMA+|qwIPIn3nh{CL3jm7G=H1mbuDsH_y=FT z%5r!_X!0OVKqUByjR{3S(jdl_CbX}XhJiddWzcJY25y%w)-C=rD6ASFvQEP2(E+m4 z2c+B7KiTnr5v|aLH?JOX0#3wooBv$ZIn~*z1^z$Xw7kq$-v#Z zgIbi)>~~eEF@%+EGI?XJ>B5WDqm{$eL13J6WGSJwd!3Qab4Wo_y{1C-xIs2l z?JZ>37Z6PM&g+qQen=9=AVHR->(wWXSfys#H(=n}Ym}HO!mp_M46oa7DUOC*_B*|% zO7aqqWVSe}oV{CH$hy@@XIksX+y%TJ@9LgJvbW;ckl-Diqt3C(9VeG8 z(tPor|A4FIVbEj-Cu$j|GA5e}2RL)N6EFe+M%}NGIY*{q2q;2`6v2!>04#78>I0y< zfItBb6B4+dL@b~P5-WoJZXQ!n9_L{g1TcWT52J$#ebOV}%>zWZZjN|h=>k+Fgd+x^ zqBVpl2@>e`98@GS4s+I9cGr=$KzE-p(5BkJtsZTv)7;AGO+C33blogT{9azHcoriA zkn-EvWw@(Fy?i|C3&HXrL*k=pvmm{5XOuH4G6F-;8vZB@BT5B(qTI97*Pa+j{MZ*R z#08>ly}G(HXjWcTNzmX}}n z?%BIXraC!}I%TN`En#|G*CpXVc;Z^a1<;hb6obhcE(`-fdjE5-Z{M}K<>ISMNK`YhGs}C)sdB8e# ztJoLt#tio+icq34?Y2YgxKiisNWTG!U=$NDR1q?LKulU0e6|P9lUoTSfeXgZ)n(Ct zdW;0@=L_lZMJ`kTvB2Axj8Hj*HJ4$ip&!A~sATzYs6~ab9C_Hg2mnLCFA5WaO^Lza z`@-?iDoEz-!y`?%Lt;Na_~q3gauz@+?DZA@V7epXGfd2Dx^PS+7GsRpqMtWwALcD4 z0LvO5O`~rLM4-2d<`ux)tH7CUdAqatR@KK$3>Qm+MdKBdyN6m>U36IGK{(;dsIZrs z^vr;uE+*wHaM>ChiHIP33D>?GJd6_=iTUR4A&3bBSPBSD+WkQiuwD@&Zwy2kf%)kD z-jTpBVPSTZF*W}BFDs*5#@;58MW1CD-^C7lZvZ@3e;sWHlp48fzkox-+yh1+&ZBXo zxSDTKF98;MtbTed&RIaXEnc7?;++ZnG3E1lf!L=k08to*6&EIx;v1$hSN;QV+X((k zA4VGzTY&y;bxZ;{{`BP-W=u*z)FcttVm}C0eQ=R|f72(4 zn=!sjI-V#1i=^X&Y;1~LRmz9O53z>t@dZ-|v);G0r>Huns%L$8fR{37|Ndd@d*Z71 zaKSWvjkJfAsftuEH-XeA8mWfIY1UNfG=6EgH&RYyQrSw(``C33oXYZ(ROnWa_PHRIW{cGi>> zH3sCp>B##km>;p0*NvCoESG;=mH*5%e}pRUl&Sy}N<#&tR|yv2#1-7rDDc87z(f0L z)+7S_yw&f%`jJ3kk4E7)U!5I56_`&aRCImfgN0F&Xlz>7aXz&ss)*yHNRzy%5U-e9 zvsjR+7~8B^u)286r+BoZ7o1kCvzES2!%&Ya z4KyyryH~m`r*VTmF)ados;Nmuk`PN;mM&FRZdX>^T&8ab+(3ZOGc|9nz_0cBkJ^E6{zJk>>urKtGj$OJ5n;3|#L6Sx|^*lj@2Ob~W)4HJzRC9{k!*tiYgI z?P#DzRb170w)WhWTGmHQWKH+!5M1ZfZ)MSzB|B;a#`a&|>{(;i6629UXd;S)h+>i{c#qKkQ>$mvHh zVQY)7auC_9>D&%uYl@F(qpfL@Kh-0oZ=;$8yZKuTglid2LyoHJF(&FWQb7h?0L`;C zzr8C0F3*D7yx@cpz!?Kx*X`n%O^&hym~{cRQ}|`Kk06O>>PbUoO=sH-`{fWocH#0>O&;XfkVozT^{&*nDHyIvDQA4%pVh?b(4BweU%Qd*_W2 zx9%Pfc7RGTk~l09)a`wq3*aC@JzwyQp*J#Ov^v}W1_B@@X^Bb&)yBGfr`q##;dn@p zQ~(qu1DSL|fq1w@?RY}Yc&zM8mNPwO?TK<1Z7Z6QxV^DsRe*;b;6u5<JeYP^+Nr2NDZpJ>vyV)0GFpHDuVGsl2 z!5}#s&Es*O$?NK(_W({eP_Yi=dQis+G#q!&5TO~X&ca8RnMWa?9uO^l!k(w)n2jT~ zk0PDEs?$yD3{F_Uug!uCh-d@Xh&`u8YL2qz>M<1F6#T)|JTbB^(!1da?V>*Vs=d>> zQ=7kMp<$vuiHrUKu&$y(cowv7yWu<=>$(7ifi9L~*j(Tv+R-qM)miz~wTh)^14yjv zZ2abGtXCeVSpy<+)koKU#OE}-gWF*75@Ppa+sf(Yw7h|d`5~i1(65(3}RgCnN zx#nw8iHn++3$|M8EeWr?d*Bh%lV$8cU$BSsI>^7#Fq{B?=>!->!KdoRsyAmoO@oek zwUo%s#Jy!`;&fE`^h6yzB5x(|L4L4~Mnz6%P8V<%?{Ov%>CPC43|UPy=)tod#R!YT zwBGJm_QKT#i>JoNoRPSXA^0;$k37^`9K-fyt8I#R9#p;C?5OP$CkS&vL{Qg6&GbBo ze%i0A_t@}jg47pD%Z>QdN>WjfeCB0BPVJ@oDZy8<#ENiA-C!lU`EACpgF0V^(XWPR zEqkB0yaJ%`D){;<_&tTG;~+@C%jRX0g~;Z1(t-hzvjP6rUP94*CyO2BeB@3doXqXu zK&OLWbO=LtsQYm5NiTBbunwR@eicOO;v+zs*3f3F3)k3^AA8XJhu6dN!IxOf$QhBah8yETLmySmRd+qj_H5=?w<(4VxepM<4D!d&%;$)G1e zr}Q)cAi$Y3+%9i^)p6t);1n1Mb1bYX5!I5&t~qrMh6V%ZWT+w=;<~ zbeNwgKYy?^l>4|fQTxPxGo#WGlQl92USc{{#g47UpZ2!)4RoVta_K79zTotPf55F_MUD3Bl)h2E6BAai{? z1552vZ|T>k5(>5B;~xp@E*hm2N?);Rx+z2BAdGB6YWzZ6wqvN-%X?rmfAcOwl>T>L z{Z)dFPFbl9SGxo$OZj1;=-z+$>dU$vmp#J^n(=~zZc6;-tBZSjyP&tk$^4zS#jkJt z>Z?l>Z*F^8H(zC8yC_XS_}y2hmV7!S$-O0ir`UYp;WuBctR$m?_lWyIzeIt3>Uyb) z+GB5?VLthx=Spm2&dRFV4vVE~k0nx6`dLS8cY7a)O7X%CqG;IFS%=IAd)Z@B%QVdL zo9&s6c;q7nw2CqLw4Sv_*l8+TvD<6dj2M(_J8W=|s6I_K*wc2}YUX=PJ5R$quCj;8 zuj`II9roB*Wg}eIo7}KsZi-;~vYH-ETE){q&Pcq^mJF)odZFKZb#Q+wpZ;3~>6p3K z%V&HBQICCIPDPx_^BcxlwH%GcTtM*}y+gnHRD%h%3H-(%LZzvuw-mb`je7cT@|$F) zr%`nz3*?o5^VP8}*#q5GW`(VcR~qu~aR^zIj!bWUi5&A0vaFPPUcFTL%~xlyZGQ9B zST)RbfkZXdA2H~J*FKUPQExVVv=p{!uXJ@r`|6phZ@yaC_?xfZjr#7ZZ!&)K)lB@~ zeD#_3cVBJ(-B-VEc5#?_&rC#Xb$bGUy6VC)$`wd_11S^edq3XUrqVlR||ai z)mz_v^||0TUyb@S9aZmo!t&wV_3U8AX_fAhi)s_1MHD0pyM1&U?W;*M*w2+#mA}4+ z&yewp;YDV-8)d1~zmTrLv+whSiOph5Wz>^|^m%Qw&f%)~)m_f(^PV%C!#D7&rReGN z>CK)awDYT>-t6i5fM{d^(9xavAbzkh<+=S!)^mCO(N1A?+Yla~5b z;PbM(UAZz#)*M~U7SbPN!#Ynnlu^c=*B|`UZ2rokdMSTTe~4`MJk8!=vG8VpDDV0_ z9cD}sjObGsJ?p|%Qj8)+o0tOEbPn*l9 zaG2QwiwaAzq9M{mUDJR~WJE31%t|-d;PuEPNnkdn$$3W-%t!!pQ}_s)_|q*BRx5Rs)=x~39?{{QJ(M7B1=npy*%a$$%{ zx&cqNe1EKJOkPAThuylS5|vuzoA5k4%vJ5}Sd>!jX6bvEJu^wjl~Es}$O2rRFHi7e z)tj-x3xkK2^{xsjv_IHSh$#Iccr$M7xn*SW?Cuw%N=l9Xr*BJAQ;Y&V~iQfjYK zy{Q@^U9c-$m)WpX3!U1_qiMLJBM=f*W68bsawuA7FZOlq2I;)hT(;Cv&q%;tY5wKy zxW`QBWqG;XtyjSmx)A)=2+aLC_X{}^n4F_Ng!TmlSE-+nKZtI;QG)cAkA6ZJ81|87 zf7Vw_OYB1E3l9d~LQpCGDMns&Gt_oF@PJ$oML84N!jm@>{4A(3alGh_(1WZH_pUov ziDSG)u;$r=wFa+ozI2wizeVs`tH)Uyp8KeU36?vl%67i4Bt5>Bfg>C0S za=hVMZcO*5=R0u;b1|9$%i+^8y&rdW-nnNizrzzuapx`BBuOy7c2T1} zsBGo^RT`nY3RM0fsKQhl4HNn7kbwllYiZrMrk<{`gUPq|GLxCtZe$A<10` zu)9auYQlPIpO-v+%G}1Va(M1RZdpH}h8-&3sbs^x++>bs%Qkc(@L<;_Z^>jW35~VugytI*_3eg53#49gNgv+%0pe51SaLG_o)8$dEW)|f>mH($OzcuC#aHF@ zI&t@qBVl#d?s#D9ie2V<)SAlH)=(jlZmyLJLi?b~y@7Tg8k+EhfcIpKF5bTMUi5}V zK5}9%lH%9brjN`U4$ea55v)KBsI_0G02?8)&uuTTSqpY zS#eHnO>5U4h*Z1LIolAvJN$eLwcQZmyr>s=)UA-do=j}Cs_?33sJt$r@ZFhkRNds! z5{l>@o$Iv4yHmuK^COoC*S(#9vkktqqd5iXquzS^t@871!}$#-^y7<;#+&h1ZgNX7h<)VF zVY*UMrmFXmm-QpRRvb@?1a;v@p_13agA(~MAMa3KxdWBFc%ey5I75`XsY|R$63W0w zAi}RN3Dazn4UZL1k^CCdbWfP--e42vT+@U5VG7V@+V&=;T}mbH=3SO%<-t@H{pM(~ zX0;k-wQ#8@|7MNB5Y49MV4J1^p>l14QXOtS7YynC{^qCpA$pS1^NKA7&J-H9(u3|T z#`-BHDbfKZEoSCqW`okQ7p0NwEzpG)Yx7#GNtg|H%QMN=u}7_TCAIdpt&^UuFBWQF zrnJr!w>n*}a~^E{Jm2bylB|0LZCkw5=5AZ(!QJ-%v3J)|Q7!tz|M%>n+aRO_rArJ# zx*J8wAp}%XVveMe(k-ZTI7lNU(jnd5-Q9z94bOPIan8Bte($sHdDgRj&u{VhW7htA z&&*zX&Aj*PvwXMds*)UsM6=KH2n(;~Omtrz7Z6a;oL=1=BrD(+w0_PKOZAeS8eXk5OyLcSzfzSK*;%tF3gO}^rud?mH~w^O;QdAaI#xtapG+Bms7FS&XPxdtV< z#(Q#2)N;)jaxLq!t^KlX6|(KgvK>LPowl-Fy0YC;vONs4y#%s->oTbRewl#^nZab4 zp&*%ITbU7EnNca3F%Fq=44H{>>B)NOsVwQ~57INv(zDN{=ai)9?@2FEOD|$bFRe>0 z_e-r*NUbJItp!P~KbP82lG?l{wM8w3#E{xvm;Bx@xlD;yg$Ku#VXy@pW%K>K$Tgl6%$ z4+F&M_z0iBy(aBRdDcJ`pTgSRBQX7l)(fF?_=vL5gP!rR$YT`9&fm)*?XA;YQS9fV zZ_rx?Jm${xV4`be5pG~Y^wN+La|C1cjrDSQdtEbva$ABo==!qh!Mm7HUa`k=6!<)L zl*Pk7yeWZv15jQPPY!fkJrE<<0p2!%3R7T+RQBp?sTLYs5(~z94)2p>>6i2dZ>scX z-UeAr`(=eOi;o5su)fDZ5}QyJI|Xf!=BMcu1(8d2N7$&Xcd(Q+2>gQ*J=r zD3JcufR3ZL3c^eB&{Nyxt!{kG*7ATTKZXJhrlGoefvLJ?hgzwMMmca-uX0;`<2%h#jN{tt$z+n?Y}$7!Lm4Je48Cfk6*DP3sgd>0wP?I!~_ZVZ{9* z*@Ygb4h==l!6KZI(Wn7q!pE3$u#b;`+hU%42n~6?p|?hXZh7HK@xx)>s(13-<2tV4 z(?NwTM_%k{u^(Z7s(fdqtN}C9sDMLK8?KRS5gJr#IFm+X1`qEpYcP3hdP#ex>}f}p zx+lJ;;4<`J|sjWq$W-L8SqvBVr9E~P%^v^~HqqK2*uq!G@OZZ1)jC4p#+#3Mh zAVYV26-epXNC=}2yS#3NkvgZ|`>=&EK5iI_d)dR4bcjg>M8gd?=sAU>qCDI;KyF9vT468S zj`s@QBc1BwWb$L9Bom_Do&pBYdvwsg4v;<1gVi1VLGU+slSgx>2`6-H?6GU9W%!0NL{ z_wDo>JG2#|2E;@4dkgh%1JFL@*XO<;mmNj*jt!S3Lah79nmUD5IYk&3@ z)*SbL1fcEbn2J0&{ARW>p|_(9dFjT*`PCJ;$2;`&_bsQ29o4zK_2sm@B=!hB7PKN3V5tk*MGHEO z3%Y{~dW#EB_80WA77fT24Vf07HX11pK36K57jyL#$TO69f+5E}PtBxb_~`ld!QKOD zZFjZ4mhOD>B` zuKP=FSj+BY%Ws&LJ$RQrWtP1(mc5Oaee6wrjG^LWCMK?nJK@I4IGE-d>U%~5Pd8@X zT4^2(7+Y-`%b^xU#mt0NRs;-IBJ5WpeO96(R-#i^Vv1H`8&~26SK=2}682XAEuDkU0*4VocV1L%s| zk94I3K5w~btbkmU_M1mP*dreLqEu$3tZ1#gajjx-t#Wbg+x}V=)_OJBdJWThE$@1r z%zC}XdV}$Lqy2i5&w6vjdQ0khYtedJ<9hqxddK2=XTo}E!V6T1h<!%>A_N@x$?4ck&o9nuUYYb2B0@rQa4wNHrEZ zG|hL!?3eKgp7c4`Up|c3I(iVei=%de@}{oBJbm(u8glzO_IEn+@AS;yZ}5G;Df^v4 z6ZM_Z@(C?oYw>{;ngbhJ{T(s#U2*1J3BFxP*{p_a5`@smj`^oZE;x?C?!3^90-6e+v_^-iS)srgYn; zn%W^-+S54L)BksUweP-Z7^xp?%AxeXE0gYwQC!`N5CA+S=}k?15(2 z9%bYnEN$FtF)2eYN$r zQ}KbW+xDv}8yz8sBs56-5r zQPbq8nLqEVU6&lr8cojDa`#sMq^~~Tkv-qlJl``p-*-4a@I60_JU>c1KQ2B$X*xe0 zIzL--``+Z5e-U8+U9-Lju>ToiUj*0}!1YCdZN8RWvY5G+Q?b9gmRpU*zMfZ4_G0}@ zGt=kw{C3{8^{?GB>>CCB8s)38rnROYohxegj3mri@0s6Exd^Z?0_-M%(d`h&_9WVa z<|dKj?YHg($#mHA%@UN~L;c2|k(Z}Sb0}N{*cSozG)Q$=jq@PS!wn5wUj*0}0ro|J zeGy<^1lSh=_CVBEY@~urC7aivar~z`h8uF9Pg~0Q(}qz6h`{0_=+b`y#;pe=ESo__qQ!8o~a@ zFrXc5Ru(Sw2;CDB5Rkop|DmX;jI^|(q9R(oR#Q{c)zw9-*T%-iS}zP3-l_g1uOZDE zcN3pl+5KW`YwPIf=;Gqy?d=^95D*d)^6%8^tgNi!oP_-{)w2qv-LDE`-tv=%54W{7 zQM$TEMn*#jL|t9oPx!jGw|DgKGxnRA_{~iIW~Tl=|LCrNYhR-g>_6Dob8~b5;IDt$ z*XUQYeT|+A{`wyX_Jx4mlAqER$^EP~Ze$zL5z9~b*sJMlTGvOkzDlD|klvFd_nu9! zwIHJ}O(jVoUZF5^;Ir0O^NH5N&qKKebpbSrMOmm*A5@fV&o#ei*YB(--C62RQvCR! zvTSc{`0Ic;Qt!}cHsY60UIs&WfiTien#arvaMwm4F2^1n~i1Ncy_ZK z*~q?Cu{-!;tMYL1^VYZ1{k5$s0Gk6@jX`dKtifT)Stt0D5WI49$uWDLsH&E2I zaj^{LziJB{lj*a(KjjnCU6PUzlgXY|5Zl7QEqY_;X25?bV2gq~44e5*{~}-`DumDi zHr1!%9|HEqe=lHD{VHH@{8@lqOy|C2DD>Y7*slOCzqJ6r_&*b{qtODk5FbCB@CE;0 z6R^7pQMTL({~};-UcIGC2VI%=!AUSAc!ncMQGph)t^T@z4gXUC`_WGUd)fQelNmfU zIY!dtza(I*{SdGzd~V165U`*AQNU)cC2?(r(%j(xRlt6Xf_q%vfAyCHY&DN7XaSqu zq6U9bSCZuH_X75Vp8|F<94%n)piiU(i3id%RbVeeB{)+pO<^EYdoNR~BU7Webs*>U z-e&{C&st3igZVLgS*FULwTD^=sO9KNhC6cXi`ynP zUmuiD6XrTLDNcSz?=oE8$iaAt7O+KrFJO~mJnsVjRKUiE%q@!lQNX@?TTirmhJf*3 z1?-4v0^2_d*j=~(MZm^rL<`ste=lGYN*cZYjet$?9MkLf0`?1vIy@;d>$y^gXLEnxG~Vciaeo)>+_SGB`AD-U|*fDqt6rA8wZcqDiC#>6IfXNjANlB%@&~%(KcAig zx~ehf<2Qa4upgF0g^OV-_0_br>Ftz!*0mBX5${|kvxGiJZickE4@cWozY{DwG*mOwu?@yj*^#Hyb@FN6%S*H}Kj5o)px(u%#3j&uJ` z%wKK7W35wA95Ee6?9$~s?Zw_KOx)5T<&2%(vK;Vwt9)N@TKr_Urb=fuGDTo^+hwmU zvtpZryb`I-fkUFj3t>e-S>Pm)y7MGZ;LsbxLd@d|OD*wrF#wMib;*ZFOJgxSyjqkA z;VC~q4Vfwyrxi1tXnQTPgn=V2E@c2C;h!NFKz=i7+kQjk?t!W!cgKMh8oPy5%2Fue16BwTX^inlI2ggG**R#G*0yuzU z01ZI<#Q=D00HsF)^dy9wIIdiW#JqU`b|@%d0K3!;A+84Kr|~%DfUPu}JAMF;3Zw_F zcVimkDjLB=;0VY93vjFF*?B_ikkm=(?IP~1&?+!Mhsg->?hA8)&*UMJqazNRV zZ>0&0mcoyIIiS_?2_p`Ol?aN<`S7A0Y;WjIG{9}(9Cb)+oCch`yW+ZoPgICNaqy#~ z4F=#Akpesbf+I~y9^|=Q%?sM)HxsRf6QLb!slPec(TG4bI7TIoHW4y#!~SLIlJ9{= z5Jsro8y5H;f7tXukZT@n7W*|XJa_=d9U~Mv%5Nhs2cPtFWrw?dH-<97L--H8u??X7 zVkkHXGB{S9C`~SmKiWhTjzNh1?0DFxx%;iM?F)#!Z(yS><`K-pH}tt2Kv*5Rui+R- z9(KO(c>h&+m7U*tw{vuO*k)50hC7rN_uUqS>$%vwdn*{nzJOKUI~Bi>RYy=q%mxRJ zpA`k;^$&l2-&l|p^C%r>n(V_4&j+-FEwh3t$EuB;;fv=FtMhXtGJ}!eI_nlkMr7zP z$^m?0m^wI+n{d4+NB#z^5s}gnV}23KCQx>F09yqdn~p#?r&PIfTT?OK!suDSQM(10Ra3|4KN>R*bOp$G>UZs;4o1F+8whK+&;aq#)o z9>wQ{N8_r1h9rcBc_1f6j0%6uvup2+{bMky0p4k>$J`)W%e$3y8+LBDhy{p%JAtbK zlrK7R8io)XjMND=bI&mLFbixRc`$Tf*dF}>QE25!ZoRV~wV!Hz${P(hKqk!)Hv~R0 zWJcm-A{y^U5eK|zi;ha(dr`w{fnbC*MObhHaq$BdT|ST=jZY%SNn)8n%#_dY6`nPj zy=b|XXu_Q+KAQaCI9WwNTQbv(brm6pm&iF9_oysIcQi#*AVr$eitTj@2U{Z7YKm!0 zs`=}11ML)uRFsx^s&-kbt#+C{n}=m9LiYHrd`!yK*JkVro!bi z63sJ`UjG!ZpT?J^No6D}Y5x$gzX=!=zfLb*O{>z*LJQc_q*?C;vOWc5bslGRXX>;b zXFNa7ET_yKMhn;h+I^#$?RcNZD09#PcFaIF>M(ogR{^`rJO{3wvGS{cUAUTq$ow4m ztAHJ2o;whb8`+u*3g*38&CS8f`=XGCSDvS9p0^y6OF;GIGF39sSXzg`7mC;~4BB7( zDRU`LzR(4RQ{(57P~|f@<>&C{4{GPLjG+Z=L1(tWyjy}_@3FtWt(e6V`&FRLhR^AX z;K^69SW9929C4ij8T^clfKRX4vd9z*(9h?qP?<@teR-r)sG(@A+Lo`WW69TD_ypfy zhdmcYm6vP;KGf1?gclX4LzFXM#!lL1PC6EXI=?6y;~0P}@W?VF&x8etew3c`iH`nS zp&@&be0io~d6u$b;itW#RP|znwEa#A47(e`i~#8oMK)uwkia7IHQ2j0Sh!PZbRaCY zT>C1*EdsN2oTn`6q;v!m@;X-M5}kd_LUCevSz1atLcP48p*)VKL{Fz=U7!e;N;_Ur zJ8KMvO^5bhN@MH*>S_SD8p4dq3!w`I8K+}o!z+>sD?Y7NbjQMa6)Oh=D@WTZGcYSK zfNvw}-v*p2Cm748(71NPwlo74zm58Ac$fJIGueepLlzBPqe71JTgS zdmRur4h%?xT~>k6aes?T0gTAqu2dH-H^I;(HCmr0SVs%kWmj}-^w3L^D`3)3!K)P^^r7Gz_L>`L@_HP0i5o3?L$14n zc}}qRJRl3=+ieS&&UnMlK4f%E9~X}P3Wsn;RpSS_s_Hgqj(hND)kR8I^~*Oh=GhaT zR^M`l5oUoX8ux~c6E9Xe%lbl)cin>l0p3u7m9zoqt&C1_wFD&flDhR6)s1fy0mH1= z2&MXwS1@0Tx(5UeXhHlY0wm1?!@~i`tR@zrx8WT1hzb}Azj~FeI^75j>;MD^a3&4F z1|V#7*0cux-zv)J+yP?rTdEMx;0|0P&?f1w!!Ynn8>{@AfUN{HDFH3x-`d98yPTbS zggQQ|cf|O1SjNKCIa*lrtQkpa!{S;p6+7G4+lyh4x;Ri~9kSihl}HM?;SR7NfvX1o zH#oo(Ci``QMk3CZI8yZ4Y-3e{5tDRW=PtcW*Ipk4Uq zS+5wlA=r7X;RC${p*__=h3|OLT0fkyG2gNu zfjQup4d7RIA+mu6y|E$2p=iv(7}mjOoH=C`gAa#$FaXF6v3lNkfYu#kst)hkc*&9n zW>J5IQzc57Y$zz@V!MN*b^?WTOoa%hf@NUbvNM?Xa1$*u?rMdu=Tci z-j0@!ZIgzsu=6wEyCRUKyC4&?K)yMOT6byNqRH8|)VAp8y&MX#i8Y%mwqFbB(|85D zOgA0cIfvHT>8iU^*IMaBmbW#ReK!}PQkL&Ln3E-30l8L2VJk5WMY}F_FPK45W6y*2 zi9nG#{Jil9Y48kl5tFm~{B+CR0 zkpn|;T6au%+(de@BOQB{CtRsQosnL|sLftWmR9tBkIQfd(rc^xS?1B7NsdU6fqf9agJ#A}jR7uP0-X zywo6Rb&P0yOQS5LacPTuYrcYL0Rs*)>#sjw-VxJ>Q9eYj4Ue2T13VKReFTsR+9kQ+ zJ_4XWGOAZqf9Z1f_XgCK(+40mXS_1 zwgrq-45U+mgasX1>LP=4U^rEvZc9z_qz5&knz}|SBVqLQ<<%$ zBITTnih49B6G9{GigE4nyxcoR>5H25fUBIMB?*8|>MUA(lm*FWZ19P}ol$X-!a5Ofw^9>$- z(4&gH=|PHZ@T7o6bL+`BmopS5wHDH#mim{~`IRf_DxYM+*o;=MW~yasd@<)7e{8WB z8hgJ8)xj^0VbXg|+}cHllF2joibQ?A&Z9kx(L&3q#(16LnK(fw6oEj&a!;~i8;=X6 zo%z6Ln1iUptJj9Om*I&A;ZN@F*@azJLEwau8DV~3V6Sg%);oK>zcEpD?lfFHJ00vV zDZ&MNwXhg9bB@g|2Ek^?`zc_*n^z>@Z}f3$=bvZN>AbUawVqq@?*ew1FqWH+5`R-b zAjkbyG!`sHuJ3hQ=GqSd8gxl+t@^tU zg+IPfm1VBmebg$9%~+r!Ni4maEE0=x_rYzqxI2&JnNtcLD`x2KD)Ku8z3Wu`DPZ$( z_wl{*dimgvywOhqn_Jbv`Elp%H$gm_zY5r)#%Fy!V#0fcTF>4}?>{!6T2NEheecby zZI(9iazt6RlIO8`@j{V~wPXRAx(@wWk*-abG$+@3@u=@GM&O3$hY`@X}s<$q}Oyat>UFQbFq+3hf9OAO_!*3 zp-s0ebLHb6MOooJ@rRm~c0+y7&+JA_itpHuS~uy*joBaY2s_T)#&C6 zI3H<}Ah;0gD{?%V5c%!(8g>%u^+s_dyVGVB_H~OWdE56IPJu+CE_-|5U0n{Q&h1XA zuT}Cs`!drc>L$Hl@>um3$p^704F2kng17G2rwI_$r4q3<*3dV^770*#e(^c^P!IC; zc+A@+;-hAvp4TnnvBmi%di_Jan8)LAAC*Y7W`ug*(v8D6{z3H9L{k0t!2q^@Ko z)K}Dk>ioH}h=k-s5HJ}f}9KbrJQNkfELSfD;bG+wjc8U7|;+%L{G3KRp&B~5IjJrCOhh6fM%n>midT+ctl zCU8od-?fB=y{(9%Ka>5MAm01V^Zk5#=TL#7{kvx&yU$q+F%=#~yi-fQXT&Dzt)O1? z@^O}}5eFfrB5d&S!-4`Mt~D=3z5VY>6}v{~5`NDwRE=BBk;86Zyn7X;w3-Ap5H_ zxO=8@M&RSHhyq3i9y5hU9*@I|Y#BK0%#?&d)#$-{H}4giJ@_T2FJ|*Y+U>oShdPvM ziK!pbr8!p~g;73E;VMj0wp*1>q#W==3)pyQ0hxGthcwMS(EwjOUOV1TEG@U z3)l{50ejVUO{e3UW~uA@9J_`^y=?`Qa^)szjLRPTU9^Dx6fI!a+*>zviq>jaeD@_d zd*K;9m14_-qVVuS3pTWX{TMA^C!z&xL9~Fa{jMOzW!~&jx!gdGeQ37b2CX60*nPBs zZH*SNhoW>Q62girY38iooJh|QIRrNFY?6k>j=ZUyz{W=l*u-c7 zn>e%@b8za-r65tvTZb-$_Q+#8>X}{TsM_hTNbk}}L&6tt>u9VHGJF}bB;~txj3JZ$ zkEq2jk%zr!*T@Jk3=%?J>nic!)JWyCJXNE1_!=h|Vg9xS_Ys|@dNZ;5^RO?k=cU+S z$vpNiHxbkeW6II3U%!42*N-&f^bKtx+xRX~N^RU99No@%dPlZPNab$sk&UIj4PM{r zEdSP(PP?M<`0er9`|lmQcKUZdUMDvdZ_4XxR-pW(aD$4%MgeeBuAX6Ru z{r<|3)TB3+yoSVrekBohcU-c}o(b*`b#SeJO$^pDd+79Kps46;n6Q);(MaFOH;$qj z&bFs-%l&709ZHH_ntnmuxIZ!UgzqzZ=Ay%UD)c+BUb#)E?Xu-maJFA;2BAgv6U9wu z@f_CZ$HKkaB4!A4H|qXBC}208gi@v4oqDn9pw|~ODWgRUTAElIB`iV_)|w;B#Ge|9IL<|M4j4C2B{K)MX|2<y*}X5h_gAey zKAt%EmRx<^)zuLKM)afYy(Yxmw!7Kq=dsiE$VKbsTJAE~+Co=!NXgg#dM=Z7^GfP)=Ls3 zNvTP_y2Ra zfn4maY}~kPe7$T!mh8t5vIu9{#OJb~lw^}QWRtJTrku*8&da2=%cK{`WW>p2ddYmY zkjYY#$>xyBxhj*pE}hpe{iQ-WKUw-~kaU5qbfKC#iFvU#cUcBzU2 zsmeI1Z(dSW7E;w}QZ+(SwG2{q1XA_8k`3dMjrEdES(42kBwL&%Th%1nge2P;Bs&Ns zJ9j0z#wEJzC3>BTZnF`iEavsZZU`= z2}HMdMZS-V?9_|wW{K>55ZQMYIe0E|s3dZ9Pvn?Dtld=@HIE&kXko;ZXx$EBEf>MCs2-2|Kr zY||>l!rnTEf~jb}8s||)y2>pC$cQ6zr6c;f3V799W!j*}RI7qKxJOp5n+Nd-{d+rg za17n>qgz^@L@pSJLsU;REWnbaH=V9mNXwJE1Y}TuoNn05j^oMG3>Ek5B|XEW6Ar-1 z=rtAdq36NiTzJe(;c?3)h8_;yW>l5r@6!>(;_>!vawlMSQPphrlJ!&Nqwr)$s0!Lq z3RQaChI|u{d`Gm0#$4Em{PgPkR&nccjic}q+l-SMg8YYhCUAU*3u&P1IQ1YR# z@-M2k4MR6*ptx|YxG?wIj*s6M4ZNBNb8FV34O4$8+^>?2M~X8N`{+%5x|)XNpz0%- zjW7|6u;=N<;9X!OS}z(mRLeq7{Uv69(=aTUQ;magz^dVmAD#9)d3Wk4wE#VW50%6& zrrHs9cp>V;2%a~%ro)+b6qr%K6@Kl2@S(VgOSzV#Vs?*MYKGG7JYDuYI70_@)IDxe zc+lf`&>g<1R{o9&ZjGZ%G+%EgWxa7;hgK?^qb`+#B!0oaiQ< z=wX~d_3}*gNl)~vPYf7M4BAZ$(2Q3LgN$&HHE)m;3BK#lmPD%Gder9;K9(C!@-aTB ze9uz|;mO1Ad3$(_9Rae1g3NG`5ixl)?^gkPU~*$&a&vET3v&udI^_^#GM|x^k zeQM8WYTs_^zbP*~q+#j@L%lGC+M7Bb&|giN7%*KxUGV){}?G6HRaPO?vQ0%-v6&6DXP!Y@8Ds zoD*K06WN~=#hMo*n-^!Am*Ab3l$n>(n3p!5m$9Fh^_iE8_~B726wNC(&MOVh%ec<* zS^4qVs<{2cJ$)3pN&N!(Gcq^3{+?AQTXYW~|K6$tMUj%I4#b+{$ z&ovf}j2DgV7fsM&bi|@r>Y{nk;)}*bi@`<9#YL;rD2UGD@hmuxeePLS5=Uw|M zvsR$7R%pCdWWQGIvsM!EqCmzxnag~VW>q!9%pu1t)`#R(<8WMrfl~yD1mV~N?||q| z3>eX>EPUOCcJ)sL?EUpFtPNB**+vf&ny23AliBFk*cdS07_{FQ^4S=U*ceIO7%kcu zYup&m*=QPE0r`_O-Na%HnORrfuq>ZJMQR+K+Gm z`z4M8GLZr~qot}PjEv(&4U6%FaBFNXY_6b{ZPvGNy8lVQ-npl_!(+0;i$Q&?FbF+2ruo3Uv7DorP{=_qdK zDE@y}z&`%mbeuJGoV|3MWBoc7d)@HkQ8e~pJl4rqa>rcFlR}e|B8QV=-;2o1M`^$50#jsfCL#4>f=ELNeGUneY@vh9jSCL^|_@Jg?wh*rM zq-DyvvcYIpBB8W+mY4I!l{rq+)K?b)HUCo9PN&ep`c9V^Hs@})6uISYj~sLMZm$yG z#%`aAEazUonx^I6fR;)2-k`3-#@^uFi+~zWv$>Y64C&1slt^GAS4TOD^xWhH-BA~tqs4oKQi-6jj=OUoK2&gXt>WhH-BA~tqsO=1Cch)=O7RL*Z zI;vuA;sYa>gl}ziy$N}eNbFK6%~$3Wmau!s6~D4;cigu{WtXuQxvIXkHSmSVAlurd zTJNCjO%3fn#@qOH0^XC6>v8slicuSuxyZ4Z5W~_gmpZ%Ra^LNQ1Con?`XZpd2&gXt z>WhH-BA~tqs4oKQi-7tfpuPyG4_;mb)cb z`S}F}1!V;UG=zlYB_$Q)e$22jiAC%3$3QO(r-|9L>2((+MMH2Uo1aA$3* ztE%e!9Kd3kcE=zyoqmJEls@f2z`Ojv8Bk-l{~rjbnXcUAGEMcz=ddVRS&W4@vM$Bh z4w@~+J1%A{B{=V|EPZsxVp~Rdk(nVOvT5ps|`BW7g<+J#x$u zx6A)NXa5!5iWZaWL8jlL|IZ233N~!qFY-$>S=O!oTY)+UEl~TT1!{%g2-IvG83pC? zjNGy}Y#4(6OMzMzv|-%LkNp>c`cs82TA;r9i4R5Zd_dSd<&MpDIPFDlbvWb4oO3uE z#J71k7b?qjH2*=<>S!U#BVd7egHf+FsICJDxQzteao=ozZIyRfCqkSL4K8gCQx6yfflIw`SS=Z<^GyLO+tjS z=cc7YQy0VWoR;Tv{t{Tt63HbKyybFxjh_N_B?2u_tK!OVgO~j1y#A6voq751 z0=1Esvf)1kYD0RoKy5<|mxJQ*=D9=ul0dxy^16H6t4?(FBZ>W|K>eJ779X2d<=+d` zT$qk%fm-JG0yQJX^FF#i6{rOvbDMAeC{Xj=))O11CuIItfjWVX(EeWp>N|fFsBdGo zq6KQrr==z7+lFgx@&*N8>%wUMAW+X^2K`>3wq)@n|D8ased~_`HJq{*@jHRqoSuLi zOA3)Bvs~q}j~>v* zX*a;S!_WIgv<<-5ogN`G_>Dl#Nm{_|!~0u-`WR0cEl`^ppatqNtb6=uftuTs0xeMA zjzSC6P5|1lo&uWOe=AVO!ZDS`{vl9{RsRsEIWf%90`-u=NR+ob0a~DbdCmPapP&RS zP`myVs3WUIufj*E)2s8tkpC)Bm!Jje67qD!Pk}n^r$F8HQ=sPjAy6M-@Q!>pr|SMG zQ0x6opw__6;euve`ny2QeS=O1i&LxyC(#=%P`kavQ9DC2o45~>Z@nxQOlTksb)UZ$ z2DT`=PscY1S@uk7cZi~P1o^Qn z?>V5bUaR2JN>%4yYObM`LJQO{MV6p+;^J~>23ib4A^bz2z68?vd7x_10yXmwfjTYn zcLKGt7)BzGQ^Al`5n7;*bUI{$My0&`Mh++cRiLgnfeC~{uS^3sL-7c?fzDzmAzGjg zg$AjBm*~LbP$&Zlgn{mF0`+|oPxfwT1P_Fc1j2@c&&mIHetH_x3)f==FsY^inra*Y zK42mASALq`r(Xs``6oY(L-2#2_QU@qgR^rL3(Ze|Gy+I*>@XYvN-aAK6W|*14I~nR zCFbM9Z-8QygH+S`2&g!B9z1)H4vmz?ybp)jBOy@0tFzet5|a3-15AhnjM(#vB87aS z3%~*Jso*dM75^tV?!FX(8OA>xYV)5CH3K2qp|%~ykl=pv3hhwy10_SgMHiv`B zfpo!wV4gHVx}x5`XTl&@f|Kw*C}FWGEFw%S!u{rmsX!9cz#D{isGHK?wD1FMhi^L4 z-;#~!_2A&dE;!Hf2dqa0=QTqo)BVr8!{&$exeQ!qqo6F^A^bz$*r6z>pcwp)gKLaB z(PzgnfoKy6#1Dk}yu_!4E)<%L!@$-m+1Q);8 zJ<{<%Bo1|iQLngOzYhqKyt|1T^6Wmqd>>FjxM2g>oGV_NIB!{}F`xPZB`VH*(eL$+ zA`J)Mt4+TR0<0wO>r0y%mH2!xM0}v+3t~2b5yR{*WdwP!z}=&x%hf%g2&iT^goqo$ z2-kbD;$`$I0udE4qxo*`koYVd%7uR5+#MX_j!Zs;RC7Zf`vKo&z&sL=hy+4U7w}{` zGUipB3{#YsS(Fs6d4SmuiW(OUURVE8pb1Uj18`8GZ+w}dH2yH`={JE6kP-j5#S!he zXn=(qtCt&#YZ{o5i-`1&iC}y;RT9Ir5(AwE?gQ9rDj>(oyRCE^E;L9@3JQl3xQ9aT z`@dg0LWna(Jqb1Q&M@}P2<-e7r0y;KfUpCu$^|Xl2X^fpj~lJ899cuL6FEjdalMYa ztdQ95A9XF@MbFCLKucoT>rWOykk4AzvVtBLM0=>cWwx0ur(wx)V#rm5kj1!-qQyw3Q% znEv88C2TeIeQR12W#%V=%-5+IB*y+Imel@#+hE`A5^td@?L)~iTTXR z^f^@Fvv20-YRary1%ry#jBjO`bun43Wm(heS?Qyxna3Gfty%rr*@Fr?ovS|al-WhE zvnP+UrvtP{1VWqGvS(iBEXU-;@Z`K&&6vo{K~m-pwB}@JfBwLhdl-{jrjXlho{PxL z1*r0pT64!%bNkrxaANb^6!I31bMQ{`NT|{XUZgiuej#)E0u%W1ZZ(f$><3zQ_?3 zERfQHi?@A|jxA7lVJ`bQUlA=(mzyY`$K6) zya!a;EWpRq!lL2@$W$rJYOKgYM+YvbV6-Z+f%Hm+FA`4LuN1W-*I-1`;9&_23jkTWL56Ox2)p9=@X}A-WpRb2@tN!$v{~LxJm|U_>EsqZ(uui+ib49ED#Mzfd{d zWW-U579Wh9?#rFI_qCqOv8R zGTj@bMS!fxXY~W1cR9dN4YF~U0PPUwYS1tPc6AzZgX9NM%_U}YGY>)=3h=TPQ;pX| z?A6c<)iOGlvt-pK4AkBt(7vNo#~V}^p90b$E8CXoUNKSlD|bkgdB)-npDgtm!NehD!pjkLjauLqTLT zzy^F2adx#>Z=?sBpwsm#&M<6en9FI?3VuCP1q@#W09%x4}k?4f*{T`P`mDdZvb5G24^Y2sKbt8b`XaI z!pZ#!*8s$U*MDS$s0sl_Lgg>lI;N>z=X5)l;yNt?!S(e{BuCfoI&5Fp?})lMM!m_R z1-$1A@@BL`kyRKIomos4sep7Ak^;uao!+9p7qC)?&6c) z<2D!r0AhCo>|!>T;NXr$?Nwygq7sBTzL$NX`BOS@*~QD%sqcPeAJn~bl(i~K9i-`i zaCLhmD3y6rRkC&iSR{~e#u7qdjBwBss5e*oXJqpbmi5VDyB1d9LN0XExDK4YR93w*u zkV)T$NbjDQYyfu}q%i}}qb2Q8$eEk(Q{Ab#lt*;VP5etpNGg{bDT?f|cR z4ZTPfg+*y~JiwVZg%pHbR$7UYhVZ+t4_W>&@Hsfkaq?z4C)TP^<254dJm12aLgrdT zfVRo?NX+8yZ?JVs7z6SdBOOGabIrkOaUV^QKUkL*n(&_NMUHK}3|iU}ev9_Gujeg% zBU<<3TAHJE6J>(rl>o=zV6`IFQ^8Z5rl7?bs2g8*9=rno3=(`p!Z};|L;!!qx#Z31 za^1PhBB(l?DH!GXO8me~kw^z!!dgw)nq^y8Z4h#nAHvNAxo6Tvx3&FC77RBV$hQRQ zSYt6{A*xY8(n#;Uhck3EmG`T5HgUGZrphF$?4_=QGE>g-RlBp3yTTTr(Tc~s-lB;9 z3e8y$y~{=q=hn*yTan>=I#WB5c6(XFJ=k=E&~C_N^TF}SF2CrqRn?@y`N2~;&@uNw z;G_R$b40%03Jo04n(!cfyK{xOMc)!2;vV#5hp1E@3Qaj1ogeVsT8&ohUzmWUSuHwP z0A{BFet+}eA3|Cn8W?aXD(mvHAKb6Br+m?@-4O;DS%y+(8p!o-cf7`IX>H5#MZ z_v6F6k;0>Q;x>>+5SDKAB^r|Paa7Rxw5944IdW<=zH_<(>)itTKW=b`oQ-y!>25;M z3fc%~-Av#QexGf+VaT<8L39dJY`-8UF}!WhT6EVV;#O;ll$7VtL@uxru83$LNlskL`adsCD@ z%EW8$nGa^`Rr%29?Eg)mb}A%cRI5n-0`==jRm*c{9Mj057IHbBW}S*4pvY2-rGVtW zZ^S2Ml(2Op-wZEh#Bf$`!l_yV-7Gm`8h?N!}NF6h#@tyiS|BDaB8$Fi8` z3ruwIg9^hd2Q~R~|La~7- zu?)YVx8Bad2z&vvX#9V%cb8F7FMPlMhZ$f<0VNbE5$O_XP)DUix`!6&R#HN`8|g;6 zLmHH3DCzF*?i|jrdaa8f-bo@*pj!;?ohT2EK{ovkCO&6u6RQl(xZLZDXWh*i8* zq2uEw#A}ci$^22@`N5H`UV274LZBYDI-3o&qCPP!s72-5Q2x5az3kE~#Ai}EOm?Wv z7e9Gd&qYnQ8X-`(j0+Vna-PlCTpH>Z529Xh#hUgj>U}$Omrgv_AJ)tGc4YB(Tjj&J4MLz+eIHa~ zH0?$6{Y2a)NZEEiQt$gIcgXO>$JLCC1mP9If@k)d<>WhdgO%Xt4!dUi>PNfX!p|N1 z+l5sT0<~hIs`6<{lRuG1Y5< z8e>S@m7qxz^_%qzZ0jC3k@*?0Aa_H5<)-v>RrGAA@Jqt79i0c3Z?SZ2S?_lBcyehg zA_VGJWV&y>o+4}E1{}V6K-lYDOgV=aUePok&8larh# z#SIkp9S2HuIlH~YO{_oLPaNoSXMrW&M|}Rcz^=#Z!Syd)F$!g# zc)9QIFwlBP3aM!lUM zK(cOZWuG~+HB{coo2S5XsxpU~UEVCX^*-c{>LT-S`46jn)8zYVqY{x-`K4P{^08{0 zp%K-SD4RC*9njst^5R7fGwt5ksh0f6Z=P1$_E*Fjr(5CQ55KKD?(!*KZbjx@97I^3Uz^63gL5suE0QJaLFWA+CCoCF8*8&O!G5=#*$(4zABXOeB_K zXH~^`x_P3k$}CuROkf&kDT#EvAs6BjlcD8dPVZeKXd+uhgr#<#-Www| zr;y=q>Wg{v%1WB{iX#=_MnwT?beu>x70F@?{nN@y^1hAy&{Zk!KPtnm zCpD!AjGf?TKdv;Z+|+|x$WQL;9Lr5!nx41tl^(#$zIpkX!O~-=nGcR@p?A$)u4JYw znYnACC)+yP`DS;X+M1FFD!NKKMBz!6HIFO54^RxACw)%c;)A_c{3&kX7W-*iB;5z& zoQZ5Yn~z9{fLgD(W}IDdt@C}?^Z0Ft7*4OUZjUjG$ ziLA1Mg4X15rU#4Q;u&U+D~NzvvXty-Eg*iQ|H=7ie57@0;++kXNV@UasoL`H$tJ6E zd*9sz8^Z1QZI+|+X&n;V`r)V@57_Q3UhTVPmMK_(jYIGQ@{g2~346k27mML>AAfK~ z@5g)XAp~k2gg`yjju5CLq!aC!3la`BtS{G_N$f`>qmN33_c!0y>P~J?{rGn580SLn zz>AZ3V#5jFJ&bc$JdQs70Y2DIey+bNIo&f@{^?6mqN9*m;(5>!{P+>+r(MOEi$&PM zX>YB;VZn6&rj1kPEV+|RcOpEa?CMfJ-s!SD=IYX`^a@l5y;Fx&QtIJHKl_p!Bu8EO zuFi+P4tzif4ufPT*J0FTqBTLNtLm`DVs0JO1@zV7vQy$xy-0jqf9E0-Pp&L6gV$WZQi`G+8ML!g1$iZl+pDRmJX^;-B zrzNSNONGC5GkU3KQNe)xGOUP+#+ZwFqoMpQ_rMs}W0G1%;|lv%jqC>vx+;xNj9<~o zy?UZr$0I=XsHt(dsNrcU#nXdVZb(g#+#G~J9rgrqovD&n4niW=#7EpDToWl0)2U<0`(AY%LmJ9(}|asjP(}U!d0@uoDMMP2iV60(hnstYF}ZVPGMq) zMmD&yfW(IIy#|TeC}B{J{PAgEkjn zdlFV$0#&=|z4jFT%v8Dd>c{Qrag6Ei?H-}+S#q%%C89|6?YYRoc?+UfJM9IzL527o z#}pmK_<7j^Z_wgiyQp@g8oeQRcyr9tQOTZHp)FWFL0vk~k(Sl*JvE>fS!@)yvwq;= zcXqKPy3Qu!fM)H^Nk}J5^+gTU%QnX9))KMk_nn<#sZL^b;$d&P1o%4ff22S7(MJ*u z{~;hg^F>ToRowPK>^^dHyMy=$RbzLY_;BtId;TAj7uiDtLemSRgZN#p6kT)t60>3w z)2dyQ#$96$UBmuegK-iAxm|rV61|-gT@#2qSP~r<5^Y%BFcQfY#_lG5$wsm6dR56f zVclHdF#tK+&WbGyrHx=TAHOD4LDHzbQLx(l$R@=1Df8KrXgd$Po&GF5xhjiu5Y zdQ$wQzQpw;q6!&R=);`tU6=AD!;6XSU*%%R>`2Ji3sh5+Hlo8pxXTV{RfI867l3;m$JflKR0QJFEPpfV{^>fPAT&f=455 z1Bw#UAVboi@>7aO6+qR&LAg4VQL)# zKqj(u)M$YCt)NRKkNCj&Z-I$vuGDB_vy}=g6v{%}h?|qpSaBr`7iInMq3pwW%O68| zPXqHyU%fO}VoCxQZ<5j%jyPM%r#Ij8oCIZgs7&o*e+huP5~Myn9gFiA!$b!$jf_wB z0#ykD^U_AsO2-Qv$3!)e%S_zZc3hiENpn#~6a-b$o+`y!-D=Cjg@+zOp`>?y=)|Mk zbz^sS`$DRe?=i7-;^if+)Q~n|&g51oH93^*%%-H+EjR}Ah;+)Fw0*A}Pdb|L<5uU2 z+K_<@iVrkZd_3T>dcB&$>dIi@k8$>y$>m4!*yd_gPnGKyN6;$O$FZSyo1-<8E*Aie zt``6@Tj+=h?wlZjqlm`Bpn7~Ba{s0}{)qEHz;rXz85`oV>!AkAQ@8D%KG;-R5t&*` znmF=s>p$vYW8pcuODN2P9@B5rK0noJe02y&a&*_Ar@-J_)cT%Zz0P}i2Icw@=Jhwjo>`nT{qTNO>EtHPV0B{)Jt0b zBY~QF`2**&h0wC4!m^d_@_WK1h900y*&OR#kgTcO8T=8lf1dlfi6#qNi`Da1u*nd{ z=`>r*;?qJmOo@56nML)ZMXw{*e^a0i*IkXUUXAozjfz-}PG5~FTa9g5jT>5x__X3h z=4Pk6BI^m_6Ipc7br%`YQ^=nRI9*nX(0rVJOPP5^rAx=%(=Epo#4h3XZwS=umFeqM zW$V=~>or5`-FyB4Ci77%o^?$(mJ zX)me?gmo=tN>3Ux7A>yQb~MsnW?bKFyn0vvN5q=zk+A@)*-OawLEzTk3DlQM+wi09 zE7TnT(GC*L4v=dHB)o&HxPzj%gKD#b(4o;H%~2$`4>--3j*L_Dw_q(>8(p8<($%&+ z7dxiz1P@Nd1+4wZcP9vPC)`FHYyB&M`goTdyhlNVFrxP;x%M6k?@=kj_a5o(QQPd% zcF6El z{+&RbXe9-JE`xOGXv;<-()xD6iBq@1FajGmP((P0$PX>`VEO!;Z- zeib)a~4sCRW_b9L->brN}X znsIejesvDJx){E?T)u*vIjw`yYyV|716%=hJ^XY8#zw0$Xp zez#244(J9lWin*)3=ipta+S+JY>KZPGK>^z!9tmgju^*E42O$N){mGbir@HA=NXmH zPSn^P?`^Ihv&_`Fg6}XJpRmp~`4T-b-8gx?&>Bi3n{Rx|w$vHJWwEuf!`$cmi@SZ3 zjnB-?{xn20j@bN9yUE6ne&6q<_#a+xvhj{c)_3i3qq|8zV!5$p++klcx)UL87^I>l znY}3@pXt@wOS1Yiq*6rVMN6{>bCkXsPPUik3>RoN`jWmW%Y`Q5TVyw%nj2J>o6on$ zzbVh3thU`>o9rkrn67mOVUmee6wWq!-(gVitSFj?1wVX~AXZtt*bzm<;#g7kTrGJtI>4Vx9a2VnMSxDx#ahnkF!?2Y&B}Q?2?tWH`#a{D#J!$6QR*Y zQ7d)MMsX+S`o`BDA%@M80fp+dSp5e5M2DLCL!Fm~bnJ#aX*b#UO*RhW9or4G?Mxv% zZiPKN+YNHYN~Hk5Zhc9-7wkRpj;K0QkWus|8^6iMXMp!l>d+(#U7c>S@tbV?CL6!W z#&5Fmn{3>up40dy8^6iMZ?f^5Z2Tr0zsbgLvhka2{3aW}$;NN8@tbV?CL6!W#&5Fm zn{50h8^6iMZ?f^5Z2Tr0zsbgLvhka2eD+_u+c(+xO*Vd$jo)PBH`(}2Hva!ZHV*m= zZJeBpjPk()s)vYCl2cHS{yth-8fL`!*!g*RMR<6mo`VG8BZ2y}ktiG(d zx#?GMysxkCFTwGNiHZNf9RI&lj&J;Fn?G&qr)~eVou9V*)As(j{XgyCZ+7^n{oaWG z#p@q(@!!9=$;NN8aUt4ScYFo?S&zHAnX{fG)+@7Kcl&7O%sw2JklAn5-%&I>+`Q4o zzh4}!Z`T6Aj5~G6M8-SyXf(My4Om zar!&IYvU$=*2X{Myq5xD&=)#`{-HKb?+oNUF6Hx>Rt8#jG{#d_ySF9d{ zHlF{hHttpTyi9eBBo(2JBXCrkE{hGei@}&r#YuGh?=4oZweb_8?7CmIaj##s@!DUt z@h87&ad9@?;W0LQl3rWaBs=IwX?TyswIM?j;?z zR8MRM>pcchKu(2{ocC}kD)cxsR7%Pfrb2KWheIelm|Ej;+9m}Yza9MAeAI4&uLoGfo&Hf&mf0LRPiPZX}f@j4=NVu&*ptyYU3lrIT% zy9Ypt0LRS%^Dq#$CIC4J6d(n}MS$Z;poajYhZNW>cR#V7;PBP~P?LbqG@-Y5kZ^kd z4*{4gwt(FX3w99zviY?+PDO!2&;uaqLF2UnEGAu>ZB$8RCb zaRsz}D%2Grm&8W^A~Y+YCKRX%BJnokO!|n5>k3zfeble;23Wh^0buD?fF82C`(}Xn z%%SqZphz7s!fAcU{mF>NJ-Qk60N})B1K6{H;!p`Pv+>-|7Q+>p&=)(Br6Ue4L;zL?BD=Royi{ z4m|a2le)&o(G9NgaqLs5D>y{g7I2Hg+f5(jVFU2@^1eE<6@*6ATDjuy;P~1=AMk`e z`Us%;2&G^3VH}NMiT)&0=LEt9bJBTaMETO~ps))g@NvKBM`60rQSYq7&K={FqkqOu0=<_)c@zw)JB{Rp0T1<{6f>YUTr}RDPu_HicQLg6Pf?f-5tq?;^onmL7FaYA_>ugW{J_^>pme@oaXnGQ#kEX`YMx2?czh}zErft zN4-|AB{XhSFos1K7mi%ZkYEWZmX&apm7|+wVV53lm=Pns=KnH!az8-$TJWS2LBq24E&J)oR3iqOW1^Q%hpzAIEE->~08MU;HSGG|4BYk5?$#q{ey&t=MK4*jL}=qBUua4O4NF9;OZdG?Xgf-z?w5`(mF&`& zD%h7MuVwR9W%k<@%lnmT-Y*LgDrI3P)3qsn=Ts!1 zl$$Y>TjZ1$wwF$cU4`G=;!Wgh*b9fYqyLG?BRCQey;>h$w)29Z<|V zU^oX*AQu2RtwqS=5ju_BSYf=KjnA-}7$};e1)GGhlwa30iC;9ugagSTK>|mf1 zZ5&w-fVL3GfDp-hK0haE!r%uoXaXUpja0!vxatJ-juem%7x*9;*kKQ)g&R`6Y?}+PU?0R_Pfyz<8QVO>IxSRTaULC#8!%^MC^l{f z(ag8Fnsy_a&hysJmQLuyU?3v|mf#Pp^oJ7pJB<0qEci7n=QMm6%h?vKGD0ZatUzRl zb+{lB76kyW5J-s*jF0MWVE`fnkQe}ok!b*G2teZkidWYHu7fq4*Pi5dgX_BCSUq5h z9x$W_*SH5Qucvjm2WJzCcM12x-z<+>Y{e`DhFbw4m2KdiIvR>TbW%SeO#ogJkn$st z!W@7d+@H*WL33Ya=&adHpa$QdqZQKEI z$M(h1abL0N*zhLid%*4GYnR-_AK`jW`C?DMh@U(@ez%%C9nn19PWp|>a0)C1uvY5` zDj%lAjgMT6Gc2F&h=&HoPxuB*b6k$bqm2Ie2Egh8A}dZ|*3E!tX1-$2Q724O#zF0W z411!_Uj&S0qwnSn|Ny?c+(03C8wx{8?EVVjYfs9YE3P&lPL!~F5ybmi!!c# zR$tSWm=3&b>3Q(ypj=0%vY*`ItgcDS%?6 zHQBkdPDYy}`J46(NRywIVg-?AnYU1lw_*m%t)HzJ2?L*dy0NRxMd{2gI!>)JZ43Tb zz0JB+^9j26X$w23iN2?rY6eNAt8LVDJoZ+7d;;(i{tmBj{!TY^=Na6Lks=fy?n;g8 z!L+j$89rM)RZa()dlaH&z`=p_50_kE5jziD*@%E7XeNHE4N(el6v`YH(8 z%ev5<}jWV6whQS9}cDY2AE?4c=7{KdOow-dSJ|Ki#zrzboWB9 zTvg11GFCR@2#(%q9O;?a8g?JWh67D&bqFX{qd1Tr;?77&0QoMv&vlOz1ZTXy@09tK zYm)5;X;o?ZTC<2IlC$6Hjo&Xx{!>b(>`c z@%{`Xo4EkIhs+@16Un4TQS7*)WlyIb@2&zaGkds$}J`QsNFhOyxVl}8e06NK6Hvt%)z)?SrB|8 zuLSmwMf9*>PA^ZXqL)pssC0xRtWvH(0nb~p&jRcq)ZzuWin$a!92-jBbpEdRJi#w~ z2*_mkjWxC0QIe^p3PoHfXOS=%UdN%le?ftU=XiwypBVjY(%2}M=eiW#uq*=$e)JGK zy9j9(lc|dtz;I;T9` zkj+M$;V<)zNRkfy*8(JvMa{KAj(hN0SMCKp4fP)2a6jOwe{ zlWu`0;v5=Hy-!aTQo5gA9L&SJYd-++gCQV1x!`(^D-xFWJI+9SA*K$#lAbJDZhd#` z@@fj1*DSUNe2)`lf7iwvjbw$n?c?r<@aI#H5Zpx-%@aA%GOjCZ4@U73U+W0f2 zw=#}-g!0B-It1?!+IXe*XUQqKcb2DCBO1Yzg4f!3dZlh`wd}`f&!@UvbFm0*oL4{D zE1g@9AS8 z|9&<|_}OWl&vS~RMB_X6N~UJz8y9+xHQq+>FKHm*>} zi({;1oj}K8?~D@SER$9@vV2FfxWdHU)f;FNmx!NJ#?~k=>1vCtO_3InLZ@tE z_CqC!f}m0aIv9e`#na9GQX8 z#vh;~v~k(sYi)ef8=;MV4Y=0E+t3i&_*cJcZ9LKYS{wJi*2bOC5ZZXZ=e0Jj;*HS8 z``xd#aV|83Hg4&9t&QV(BeZdR=WA_z7mU!x4;-(x@n$cCHqLH;t&Jyx5!(2H?X@;; z;f2t~53H`W@i*XWZQSBo8z=QbXycaV*V_0lDnc7CHM!Qtdp!}^c({?6m7!cbs(hA$ zyuMtip@NC0e4aIjuIizo(rZ+OqKH8)Z4M)4JWqwvGAm7ED8hSQmz^j&PWvsC#xl1oaPd9RDG+} zj+@*4x9Gy6ln10zuO+Jz!^DmKsBit{b$x?xw$P;bd$UTn0H8qw$BZ(EB6F5lj~#j%fQ<}9NR zi8q#GjvY<4Jo@_Lo{52d=-A-ULTQo7YZJ5B(8;4C_HhO=HP7?v8O~$M-uNvecwqI{ zBAs&ANpbb=7L}>lZ)qk0m`e7THj|fAOEqu(RGiOMX3C$M);pe?c~pnYV(ZN}J_r=@ zk#vXyPjhK8!Qc8{$dJoIN-1G3e_(nBs(kz`X7+yf)$7FNLE3Up3WkE9C#+VN? z>Y9y?v{_E|IPIPu-M7Ph`t=2u9d1a%!N=RAQ({3IeaZQ+vLr7PBxouIQB{5I=Zz)+kxtl*+xgGE7czg~*B0oXB zm9T?3cs@IwVB4HCxD$XgGymY~d7GrVQ+WA>z`ewe1zHLFbQ2fLX(V>Nity-zG}zv% zbgj-{!Bj_{jbqeXa(lM!gd@GO%gw6d>TjA&_f8&vO06gVBpQ@>5y^RV$`SwR&?e?`6MT3+``i%m zdk-9zJ7w=CIw@=?UKJeGUVSbF;MXZ5PGU8cf&}W+Wb054N>MHAG~MdZsLIe&>)w5> z!;~w-8mQBque;@5hJ##haHk%xr0h0(z45Dh{Dm?C?RqnddLsPt*mZ{EFFf~3Xu2Eg z6MgGR<)}yxUeqBqP>^JkQN83RZg`j*OC{Hk!qz|?_K@2BWobwQohm$=rli5Uv4JtQ zf@z__FQvYLk}L7N0ST+IR!%VbZLebhFm6higF~d_0_;6}7v?mG>)mHqmO<*BT^8?v3BZza}Ed_?mU1 zNu*OyTkJIpWm{xPZgAM^9iO(C&bZGcf^phBF$=FZD%%p>!;|nu6(6*Jxd=-UXusTT zOOqo@vlJC~Y0s1k%Ssi66t(B5e$E|eAL@Ipw$Uzc++L`fRYcV>KHL74o%E|*N2FFq znQ?rHdx!hSj>@>Ks*;Z0kdB%QrkaJ0*u9S0lDKd9Vs{^OHdux<3WyO(cQ%uRv{-iD za_MZf%&$uoBfAidtm&-k5aXB-!;b0f4$JRq66)or?O^`_uSWkdKoT^lEiU!q$FSwg zKKECnxv=ou`gaFn<2B+Uo#MK=;!`BaBlukmsp1Zd673JW77mDqwIw#pyOv7=SHdLL zlDgKy0@s@)j(8>9CM1ZIyS9yqH}NG8(Yp6Yi1!2}U8K4XjU^8py7&AgcjLOZbGtWd zBsV&{*Cr%aH@cTEB$u#y7D#&L7^Ps5PejitXk^w#)GSI6~M=1N!8^pmrnG4 z-Ho<6q)rl5_hKYh)5SW#T6KVm4%= zFZv>}`ol>2Lm6d5`1^yz`U6yD{f%XP9s0ffWxeA1J#zcqYGhqH`<*6aKW+3oT*%sC z4cL;%*)R@R@yl6?4SZ0Qdv82o<{)Q^xC0(1XP7&nUn8g2IiNiur?oMlc_F8PHK;}+ zufjM8<(F3y8&pu0mp2}ib&!|wAC!z66w8$tt&tb*loyy7e6b-9xfpzgHN;1vz{@zq z%|FDEn)nie`xve3P=K5S&+VAjU65Vi>01R3bA<)>p#ZHQgHkuc#inNsD8?oVj59-~ zrLU>$faV0l2&w$>1r9L{_>x_GK|hDMVmgbm`=2%eYSqbMKQ_r(; z&OZ^FXIGf#xc0v1xjg5&Bj$NL-%)XDQQHFPGF^XM0w0TL;7GXF4@O4HPu-`UmA$7) zIXerPL3~;U;$Q_)OaU3|T>bhfTyx~|vS_|bwS>Y^0kqBQlQ4CkV((4w5eqP*^+ zg7u=J=b}=?A~bzbxolCTWl?o#QEllO{nkKT(j;7ZOTDDgwZK30PISuk87GJ%N$Hun z%8T?MTXA)~Pt&i2wC^NLi|UWP)YK;T)Mmp4QQVq)oxUJCHUFzNZf(76F+2GM5q)=ooh2buy(i8FY`Dws(^pvvf78a} zmsS&wRufUzk_gw5sn@=6uB8aAr7EnY>8_<)uVr|yWk#%JrLSd|t>v_=6?|Koc%~|lZdCoY{b)LQ1OwnyW80%~6TAe$mEv&@*;0%6BkfJ6OXz*vmV& zj(2dtySPNVcr?4Wxpwae@8T=&66oy`+Uyc}{iKbX?V_5Qqu^*G>#d(Bm|RY6%T#V| z9c~*~nejr8aKyG-Hn(Y%qH3Lw?#)<)c0Lv%M=_^+%DO(F8lxlJ zmWsz#ddJo_$2MNawvopl;Tgwvf1!=r8nYa^791Ir<7g+|iON&aJ>FjAQ09BQD(q#6 zlyPJTvo&Hl30OV}JU$5mp9T}1hR~dba-CkY;EJc=dZ!UKr;%Q#QIUVAjoZa{+xiQi zxEE}?s@ZyKsCzx%TeLdTlRVNdIC)oomI6D=9X`ujK1199E&!hw5}g;(oELMQe-%D2 zQ9LizJ1_fhwDIS5IYbw!iD!CxXX!R)f?j9dTn_q)cD`O0!sHii85iy47ag#R&f$w6 z%NOu2gbxnB>>;}B{g>MK^CQFuJXw-QEkU-Kk`5VOXF`!DEytG&itt4}_>v8L*$ciB z317{Cua(2s|1E9YY1QmPFX*I-V{euQ-du1+l5hn-Mm&-6{s08uX4K#LRU0>6*?G`} z(8gtQ_5V&AH+5g$d&KX^rU%dYRU6ma8vyUqNJTPw-DWa8pzTW)jb!^>8~=o5IH)5T z!(0Ag@?8wa`rx0n@rn=2eR)R5%u_#W;~>QOVTQRTKJ35L#!sKD^n4Ni%xrSTzBZ7p z`1Sg(qj7?7B`WeS206-K#N@xn^7HdUl;od3e~yZZLX_lj zad8O=3CYRHsi~=%nVEUHxs?U+Csi`=nl}euUyu0-Piaa1nv|bwYEFfQHr3a+w6wIf zwe|M){$)e{-v{K=)6+9Q?I(YH_P^-k2#EZD1LTXpZ|RpU|Gt$!ZuOU~{c-Dm+@C7) zjh`y=&7Ugrt)D9L?Vl?0ou4Z5-9J|3dw;6P_y49MKloEce)t#p`0wBPy&V6qum3ko z^7Hfai+{Dte>M1jJ2W`p3Y|oxFsa_@>^8k>YhiMu7w$vRIFX_+&3<>E7*4bnrNDwH zUip%|E>3OxOe>qM+E$$Q|8h*8(w6v~Jo@tdWPg3SySDb~3V=#GIq zJGWK6)55S_bMV)n0{v}F&P+R8{ISDtT&UlKXWBESry?yOCYvFnB({x;^*QDKL%;tp zCVvjxr`jsE_l1$0@qK9H^f@Q1O#fb?+mTemkN$&${L3+%!r}N5Hth^%KACYRGCi5~ zrpZ5<^XJ++nGY6bK3xb?G(BC6(#tKD5oWnO7*I63JRH$0xICJ$ z*}goU@nV6WEJT{YPggPu;Ab1<+wk)p7*6f39pIVwx}SGEI*e@i6JJ{*Fmmf)my_+( z)U-Zj^Z_C!=i&~=HirDOn0yBtZpk`Dz7<(J63=9EHShBhwY56zatohDmIAc8GR@&S^?*nzMSh9NW#P6Bw~u`OQB1Dda7QUxl+k<^b4vRa?$r!$ zafqyT#j9mKjFoC@iMjaQTrI*%XGBbX2VH=|71tf`4`cG%zsKZi?&4~1Ur(TzQ>?kG z(5NB#R@ckom_ZuRX$zf^{$Wf`YYt?uN&e)8d!JTUQ7QB-TT$G>!b7riRMP)8CbvYy zf9&ps}oMn{iKF_T38}Nwz=7*%M&P8VX(++#YbON@#^2m~XGo*%Lje|P>v zOs+MH$qIj!l)}FPNHG2!?@k%9$p3RpPIq#OZ6FcL^EBY?2ZOu5Ndut!O^BGB6N1VX zg;aPSFoxblfy&B#6!bI)fTcY%dRGdNlOeuosB%6wa%&U6kOGzS=a{?-(gVG`(ZQ4ekYCKTkv34Vee#6MEGe$vZM>C*h?@D z+7&d{I|IN!6m|f5o2SA|rXuVzG;NmU^vx|a zNKo}^%8*~;DkHkwZB9@W$A@Y!GgfCPJ=g&$5(&iZN~!A*;Q`{pMZ&@bW=KJMB0-p% z0I)g84+6vi0ME=plsf=QT|qX|Bm@ad6Ui^h0wi@yp8^S_X-%c%IY5p4M)SHPM?b-gKQh3!#r(pFwts-K!s(Kz z10Y1RLe+$#7P`m_o1+3;m504_ZN1?@UDw+?nA+YT7}!xuAIjwnisV4yGKX3MK0(kN zjc6>iyr8^0NTIeCAY7-&LqHORFL(w6-yHhT+(&~J=*{hye5Ky=oN6u6IAeYuxCK*0b>%>WPp33V4a0?~KlUdQB+Ut{vr-(vD;fWN#m zawD4ZtwOIYL`)9$J}&bI_4req_+Q85905*+(4LHsTs;Bfcb!2=AQ(*`vSQ#W47gHm z#%&GIk40ZfH?G+rYz@|G}-nJ`2~ZjZ>w!>=>)&em{ZgQ%pB zD%9KnZYdOkIshI7IE)f$7ad{r5o(eZ8qpkT*9Mf;2aX3v+K(dD;v&g%dw^Jh`2Zl+ z4uBjGs38)STp1_i8Rgp+C4z1k93AXiW{E|ojJP%K2Im4Lad{GZ+pb37K40xc2=odk) zJ7BJ!&-_^lxWwAtZ79)YQHDcNHMH@YVUFaw@sj9>ALhSBXcp%Ih%qobYcacfY6c=o zW|%#+WnZ6;kGngyLA2RRCSEBS=|&Z-xSj96a(H2OXUoW z%5+U)NDxo@d*yWNvkYhA%!l3?a3cCN@ar_~vt-w*O#iV=7U4|kwRErc34 ztrbjS6b_0OVpJEp7#1!Q7hv5ly3Lny%P+H?x9Dzck&1Fr7)BBCc@YI>G6`nEDRD8i zeX%A_@sx5g?Kr%c`HdgFUm*+MS9W{v$MiK@%yDR)q0Zm3uWy~mEP#d#}-2Q{J3{YHQ)HC@nx&TD$}qgrt1Lp zRa6Km5@M{%GSbS*2g|-bD%bV|&;$crD^)mGpkx3Ty5@he zcVA&m_4&g0*GfWfK@<=vp$Q@)D7~YibdVmJQRzicY0?Z$LAprqNbe%OhTb9cjvz=8 zkY2_3#(VZWd*+_m&pWf{Idq+@Bv-B+q+Q8>eb)CEb5I-9Q}qb9UKMLlkrP#u5mlRH z2C&IOiV~1SSdcs%Uwkj`r4jD*2l4|4u$!&3PkWX?6pG-X(88x0dbN>#*LG7scV*r1~_@Eu1MnPcykgb$bp7* z#6jW{kX-yAUXQ1{B9+LW;X${{83uuE!2R$CxcO6vfez?=i)T;!6LQEa#x|`D4+Y{n zlI@PmCC+jl%}M0|dkKU&91>+#$)ka6ZG)&wf_Od7USihP1Nce;F?C_&C2huMZLb-d zeIx*P+l~*tZ6?9VuRS0c9!QHsJWc=Q<7t8V9fhuFqvqJUo{t+nY-kAYeA}K_x4L9g z4|!+XM(=n1Cc4D>aOL;@r}?zXWekiEA`H+i2?`K{R}uCsfY*9(?bkD4$0(f>4Je!; z;SOz3ly4bX(v+N36z|ld zOHt=rI7+S>KX$15~nl9vJGmV3`S@6CVTq6rw+4hJd@#m; z@=zoradR@3U%~Xsuoml16q@_Q~dA z;AZ@2g}fIMf6{<`{~8q13|fhWCwg=*o6}H4)~U$J{7$5u{iG z!h~7cA^vufyb5Vt{dR3jh7fdD9!(PZMm;;@-1UhAU2%0A_eqR#KJK8>e`cO}Yu=T2 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 z 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%0A&~r?nPsa5cO7r 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%0APHCn4JjR;~k_9iw(joQ`L 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%0D#n-~z$Amt+%fqd2KWmG&dnfB(O|u@NzUzUSW6IB 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

7&TX-ZW<0t{(NPqo_u#bQT}6-cO{*(Vdd%tWjOP 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

(#$Oe5sw6G6E#VL-3YC<(?; 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º*6V*Q1 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≤!_6_^^|>sr0cow(GCshL;J3`PZoeW6fFOdL8wTmF_>Ru`Q zl=74Xxl*H}ThqRxM32!eAOx#WtLvHqT)UKAkKD`_u;XSQt`goY;zPFop z`{8F}(KUa?Q4>%z>HL*Is9-agB^~mv*@>nZg(wU)x_L3Z8SQ5%daFPK!Ard7b*wW2 z1w+kP=Hw{kf+#Or9)sf^DhZD1w%`hf;`s=Uz*-3CbFj+=&GK4^qVb4UTa2b!NJ2tL zvA=bYetTvf@?7{^oBTHl@+<(Dn`$HC#-U@>&DogEfO+ zkPB&mzP~cZd8H)eA@QA!9*50GC>Qpf(>92!Tu8_1JI^dO&+7Ng!|(jq*}T}oc+Xm2 zn@0->w<>bBibQ9K+6w1+w~7~XQPXovMwd&p3hNEE%9KAAIce?RYLz#CEKe?y%-p6} z9;l=wlBnCJ5*?`OBN7j5gW3kFm$#kcw`tZt(p(i;C=tf`DS|rNrpHsSo6Pfel=U4p zi-9ekj;*M%lBfxbs40=C*-sJkRS}C`5zBHBt7H*tACdRwA|I4QYo;g)Qd?p)z)jd;n-WUqqOZX6ab8f!^T4@uu@$dj@F;|s{wRn+`lFB);LA;KQ3 zBTsVXo+70lod9GC8>wm+pU=|XHPRr`>K)tlu4 zM90zFS{~O{?!_dI#Dfa%#8G$346jP=3P(@0B3(tx+mfLkC-;x6er`e? z+>4eg-UQKY4%(D>l?eyH%lpr4<;E~DE>`;`Q|ycOa^bJm=WU=59*4+6KsWN%6)Xo zBdo;zJwN*~8$3byqeh$nqJVyyilA3o_gx1^==VklW!?yg0MT`aC2w#LQ4DP6Q5s(b zo)j#(8>J^}in9nGY~W422V(FTypjez#{!W7K%|GB{|i2t)r;KNi#lDNVbkkH-{@=j z;=l#0_nE<{oZV>ENsz`K5)aIqh1#2WQkgE^izdK}(%6eUUG4e*k`Jb9o?xa%>S*;o z-ktDOL-^oP792Ho99b`m5eepg0gg#ctx2X$FRe9Ye^<4DiiyACgWD-)OHx2|%<3+C zUQ7bhES;kQlYJ7CN@|cvj}-Ob-08hpRCuAX&+9>TpS5Xb-8rVi>94+846wiCgZJ#T zCw;Xh4CZje7BzF)6iFhK^DLC|Ly<4Y=L%dAj8<#R;1>~ox%d}+Fy+#t zr%No&vp*>oeypjU^nvB&br3{Y1frD(kskjRHeEbsyJd9d_3N&kWmW;I-4 zGki;?txn3eaJ;4|FF&xYIY@vkdv3Qt*sga$K1tlDPQo|$T3}8<;GHn?@?Y@5Yf#xW zVcB;=>#8E@D_nkhJpFI`)0fWHR?f53mv%??Mp3!@eV(R*3tfE>xc9I5;KmIjw{^qy zS-kzVZ5Q=3@H+3)bv{akf!yBlR#Y!LNGR63r`qd(#RsRXZv|Gq#n%q-*Y5FyEm=?- z@A4S)wabrzLz>l$-x+UK39tM6Z7LT31s{C2(}ZlEkGq{gxqZQE8bJN#T-r42>}{+4 z_JzS_ZtS*3x_LM5U-7}~d)>(UI#`yUVwakBg9}j&^|Z}BWsE!6wtd6Qb7S|H{=5%9 zxLLPajpIQZ}9Bb8Lj!@r~k)3SnS-EHiE$&y3Xf->FGrs#{J(o-tFZt9K zjQ`4XwzK4OM>wfa5RpV_W>*xoV!mcqX;x1h^V{y^siXA1Bo53sJ{@H_18D-@XvC7` zxkI1DqiD6d%kxHZ-lz21V)i%12e|wv&v%8K=3_x11WhHl<-fRD|!8@SPIw z;F>-PbL{>6^t`i!@9HSr10$0ZMWXZdlOM2v*|&IgxgzwEcS`t92`_>OFPc$hi@n_M zl<=JrzEi??O88C*-znicC48rZ@09SJ624QycS`t93EwHh2 z-x?yu%=optCR+YKD#FT7OSKHV-rG6YJ2^SIySw}P`XZVeh?a0nOiV&TLQ+yvYHI4I zPoHvfataIb>%Jsh)GEO1rB2Eurh~=j_2rJBs&EaB8!fFLrlxKA`HhW@-@biAbcH)Q zI=Z{Nhlhv%L|XVCUE$wz;eYK4|061lSU_}z|0ycGv9a;{uJE6W3je++y#Kp7_}w59 z!vC1NmM|h4{D*V%KMnl9ojWB=BG*{|amjAzWxW;_i(F09of7`PP6-G9f6@{r`E>rP zC4BSeTf!v&z9oE4>anBeLi{IN!cG9bfSuq!ZV68zTEg}09576C@xRs*KE#CEG0*>- zmhjG@A8K|6h5?p0elwya?DW@L!mvMV3BUhaOBmIU$y5+sReTL6_b;`CRe!aFsr_DN z{$Wd)VHwMPP>A@M+HWmkCAf#z4w4!Z!EB zI9@*tV)pq#2R zAqA-&070iNa-%)KnC90}l|IRPwhLlO_rzp&2IhxVmgoFx33Hb#4SL~EE*f2oGmd{M z{hDEyyh+EQSB{7!VvhG&KIsGilVt=jv;_{Fnn;oFEz*NnnmygFlaQWxoL8X89(ob} zT-3GyhC{D~LdnG5x0L#$`t}f+BT1wDe!O5EJ0Fss(HW4rxT+JbxA?x7Q5We}_7XWg z^f2~05$Lw_gUS1JP!HcSh;g8%zog($<#uTROVucY5PcxX*%M6)tEiT}@jZdD{roe$ zj~FaH2hlm2NZbQgv2wbP6AEI1^qo~ECYDf~6V)AKxjOT>=Ixi&S6DJ(R_V_zzp%c) zz=AP&lwZ>%YLE1At&U!f2!qfSwNHKgubb&0Z{A z^l$t`l^^t)Ifcziccy$x3}MVYO5JHVCoY#laj8pjgXZGR&nq^Wk3GJ%Ds+aQQ$GdY zqfY|hi~_NFU>*ikhvDcKi+I?bE%)9O2k`pIRHqGg-N&RN`LWyGaWFwffP#tBn1F51VCSky}-?G94OwX9svB` za>DZRKn!bOu!jv;{=Nw_5KL-M#^E=t0+uEHl@o?speK!+SeJQ(Gov1Zk=Kzu)9e6` zJ8e;Pp(q}n3RV7KYXI?}=j}MqL);G@fUogT!SGRq{ZJQ%1oT z0PuCX7)=0PH-!@tG|N;K(7A|5=brv026gj@pRr}pFY0L8T-QCdU!m_f<- zLA_MgXonBhR9$rC?}OfhveazAgKn)Tka7Gl2oQ2%1RRPFk6;6%by#Du$=0G;mQ`Y= z#olXngh(-mq@Mylc3S$YI=iV^^@s!dI-Lh{!|}Vco^ycQi=iuyP|m^7*fyjaF#s&8MKOG#gz^ZmDvnC#P{YQwSL$fnW%ifC_aMkqmfWC7~R3-w%V_g6ego& zhD_rh=x2*|iRc@{b}0S8i-3m`R+zdUyu|~EiyiqdW13hIUFHYfaZnP@z-JNw@{dp| zg0O|0$XMmDH5ACXKfsDKDq9>tvj}qoHZ3A7Iyg-xeh9%x0h~erQT|>|Af` zGCDoR(&OCn$S>i<&+1Ag0^pGPu=W%E^e2AK44lMx4-?lt>BnhBLDkwqIT0 z7cldbieG4$(J50rF>?_0bG&^9tEAa*O@_%}hNOCyic^*vm%6lR#w)ZG`TPtH(-bII z_B-`#@!G7Hv~RT~VG2*OpPFV{Kgs#99c8?oiE8|Lq$`7yE5~Iz#|_QPZaNG9Dhtk@ zpQC@36Ofo2lxX9bpY7e9t!tWVRht{Fo)_z68hT|Bo*(^2GAr&XFa1frQ*0iKQ;tt! zj$&=jr`r6&>3lKKe6#L6%kBJf^@7So{o>j@3);M@>4L_q0&r}B99o`lV!l6GVP|4t z_q5hG)BM(;{M6dQVXmUlAdS9lzk%tzeD$K)>7sd4^$9LmX?MYb`j>U5F9|qbLJ9KP zx$-uzz8vNkZU^N|I~5)|eZ6ohICjcE-TrcU^%dZpcb!;N_M{luxj34ucxCzv>P+$d zo*cBg0*vcoY>g7NCndX2ig4>ni0VG!YZN}2DS5_S>U~)lSC;Bu2I(miAS@4=E`4E|Gf7)UO;;{iS3a^{w%T1TPgs$= zUjCS_LdCfvT(sgWs0PRDD1ckcLQ8#V(coF~nM#s?%ae-zBLm4r?8|47@t{YPf zS`j~qB+`J71)vxaO?s?mumF&%7}5E)D(nH!6njaAv|= zHHJL^7{!Q9fN0i$hsB7G2TBS6;PQY_0YJDTkrkx}-~wI!p+_?qP@Oabr4a~1D+XQq zfjnp0Vq+R)cRM^VtSEG={C_rQ;&(Wh#Zq_x=m0?6;$MwnXkl8sU8hHG_vN}>ya`O&NF~r2CDmac(m^EMon0RoT9^jY^l_8wsnmoz&8F)k= zz-$`|qA|=`ty$mL)7uee&{gl!f$Gt2n%s}p-kyW=JyryCGSfoFqeILlB$vZ}W^n+WWI(s>nRTAIgK?^7P$nZY8;?8A~>x zZ3fZHLoswg&Yc5SqM*wHz%ynCORm89=1W)QEq$4(50A zP^gFN03F9@obqU3{it|o4Sn*oo>muT(G)dS+8dd%W=vfb-YO%M0YnH}I$$=Q0(gu% zb80p|I5$KF=LNaALhXCT5n*g2|HKIlp#9uLKliu*?~Jz$U>rj|rD!q_qXt!Ajtm3w zV9kldwz{??tB#b}Q{;F8~$D zEY`Yy>(&~=IGkx|SlVEn4ZUuEp9~1cuzJMY_Yh|FP`7@~bw0Um98F*dg?XT{#^p^s zA~_tG7y}~J?gh&ODPgh7(jb4-nWPZFdi}C*A9U+xYR47&!p*gbW<23^87K|1zwU@J z050aPwMs7^)vUg1SkaH0&^KOFKt&+q<=dj=D~X}zdws+8Ue5-D9$Jr=5H~+c@0jNySgS8J<)|OBzJCjf6;zYV77!7}FYseI8J+VAM z{;G9hse8rP4ATNqm>2=&G?3D?Anu2_w;K1X^nu|ZD!{@A+@mtqqeJRSIt+L$BC zv>&t&)Tx_(Fy8)%9s9w|e@w}A%;J8GY<0}hbWHT+nCJFbaqn1w|74!-MA-c#!0bf4 z=|r>OMEdqbVdq4i|MWH8sgnCCm)WUW(W!|h?a0#z^|6@gWReIWw0;Tk=j3d-7~-cY6*X}|J4$1via2#4!8c*66Ux5 z)e>GP@3`F*EBIMS2;bxnUPy!Q%9-vgzz@?ZR^+a_tgd#(J*3OH!wlzGK@m0J~QvwNFiJCiyPUD z$`>LY*Q>>@S-;)50>uQ}o4lxY^cV^u;s0z2`#w?LR?1f{(r!ys-Wks(m-(dBHB2F$ zz+$mH+BHHYpCKIj;cqQryS@3gB-I1$M%SDBCr&Tdx?`E%_7{FE)9g>-bw?&vKRH0O zgc)?&lcC3kh*gAe42;;r$?t|ZuT-w9i&h7Uw3_^gHO|bZD=Zu^c-0D*N&|=3w9%*b zESB3sNyJh$FF&k5u<>V*#yy&9Ga)Vu{aJZwzdzUDjzXf%)3NdSqa42l?}h2!%3PB_ zi4NT5%BANZ*7C~1bocwtEef*$5QV(B*?T|u3(G=2l5E8;h7a@WdsLalulupci`cj2 z>ts2`>A^3AABvHew1zYD$nhgz9vAaI*712EN?^o-)%Fv2)w%)2WVJ+$#2sA9L5MRe z&xo>~WfP8&DC_(qN^`#WU3$I5FH(c+mq+WE8m-W)sDZS`;UciEA z2`~6Wy=HmO0*{o$TS2shdCyNQ`=8~QN5~;s!sUaLKcgetm@$8~gh>#&MkYJqM{lH< z+E_+1$+aH#60<^Bl@!D*0u)*I$XS(@Rr^LqxsVK4RiH+FBgz7JS*)sB4i&>HBK&Kt zYI^>@L#lFg6l_p~IEFzr$*Fg2>Lxju15>OAnQR&sRSkXWN;MF6&G-Drxa02!MA+vV zy4#e0wS>=U?LB{M3FDY(zx%Bv{CpU1`d3SM(W8WcL(g}I*HO=(#IH&(fGQhbGmx&G zW5s}J9MKZCS^L!ze#-i*C48yyTT7Vtx0Y~^&##uSed({3aE;h+En(wFzqN#)lV2HU z#eHEi$xidDosI;1GYT_KEF1vn8>ELs9f;l9?lc_ z9^NS&j>BQuaNgcy(Rho@L)(NzRe$&ynVsi-+pE_u?>k5wEG_3Ag?tz`BkSNf4t+9F zZ_~?p&STpqh}Uq^EWyre*Px)IiHJj3tp3pLl-;$&HEwMrW=bX z2Yxq`rMM>eyR9mIckQEzrd#Ocxeh=XA^^l?Rsyr=g5XTP0uZ)h1q@qVFbYKQo=UMw zWPy6nrY)TlbkMu^(;|w9cs5qppbwOG>7MdrCia&>UqRC)bc4>%`2B-^ZQs&ATAt+S z?CtpRmn&gZa!da+wKTwW7`e6n~+pTy+kZMRcPD!=Mk#R(@&Pn1U z8ixwS1oRN2)=0de>h_h~h)}EYP{JjS4xzvyQxhlUy3J}ag06^g_t_89w#y$NPyTy*&J7c~-v#*tBJ$w5?toRT>Kk`}jKv=2C9wy2QFh*y%*lr4K;VT4wi}-|Nup;szNHo+E zJB0X@8c*=a8~U*5OeK~riH!I+G0!5h7$}yd^w5M8`cM2=E4DD+CywClN9WL;Y{|*t zD`kYiaz$hGM*?yWMlG?%eR#w@ybP4;RRY_3#u)q{3T(^ZU(Fc z*Mo^Fr$sSE>oz+YZFs6RPT^nd#^$w-OyRr@`^rwPrv=9VLbWx_*y8qAyL!HHYHe3x zC81+;Z^_KKyJS`DV=4-Fn3JGm7O`d7$Gb)%c~WEitC@+!&t=7? zy1lPXT?OBDyyEJBd~0?OiC7^_7bckYhx>4|S=0@OW~st#*GmmOFImSLA~?B^;7{%c z{tm5h`Xf)dpW+X{#v3u%zv$N`dJ9kLi*N6cdf{ZnBTjfwZNPhW^y9{cBID@$iGy^kCmC9a#v&cjL!sGQpUGSm zCFIm|Vk&LrUZj|$TPBVOou1@`J~36GiW$u^+|EsY8R@k37u2FGX z)R1VV9O^lijo^u3oDJ{ zxifpc7GlfRu%y{w*7F+TBuhKESnS+h_HNyhEA-=lM%ihlgV9ln)!=^8!spZTCK*C& z&z#srh|!*J$L93Sv*by%G=um2yN4&h#AR6NMH_L<`_NZGE5zZ;ErRzo5l3V-R$Ar< z8S@{zuE}dmbeBCDgf}kNyPv)T>$R^7H#U7OKNDOZUGQ z5AYg)sHzJ;Om%oNo^tU0_wwQ`wGuZi8pIp+;)$Nm|Ti4$Y z@?yKUGtQ`1UT`ps6w<-+9bAUw>74=_llEg1PB&PLoPf>uK^=YnmODpT&stPd^I1G5 zY$j`pqoKDo`mif8*=9Lcvvp{Re*|CCouBZLpXQzc}$86OlIOw!r4G`NP90{0pY6I?dN?cnskqH`q zo&rA|-BW}nstqI_hMC8qNfRhYp^Xh>jaSwKu5vZn{X$_RE`=f&i5nmA;cz+8e4uZeTsY2FlU4kKvhCidg8ZNB!iiEpZsKV3Yeq*;)- zipxMyIIm7aflnilQpHnJ+e}hN zNm7?fQjbRR6;x7xUBX~k!mw7tC|$xhP~x?%go%WNDWk+2VhOWdar0qui&}BZbaAUd z@wc|()|%orLgKd9#qCbS?B~TCdc+({#oi@|z4sJzG81!F5_1s}b7d5B!xD=jcSYT& zL{TlG9(kgk5u#qsqTU9gKC+^|T%vw7qW)0PfOS~lFf6DR7Mu`q&QI%d1&3-^dIDeNQ z8|uMk1$lhZb?_EaTq|92;`N$Apv<6Kib|TtQHF&TRTUV0J6i_G`+jzY)(&^GR{5FF zb|+zEgmrNq4nP_iWgQ>N-Y3K18SoHQ>rv$EZu7(&a_o5x^TyT-LAy$2S@}>s&e3;} zkiOj>ar|Bl*rhLA0VT+uVOuX*N6!&wk4FQLuby%aVRH9bJ$MIjCVQZ&Xt^(W1T)LM z8dkXQ7*Fv-kGa6WA4<_Vh&~ZM&*vcA<(}S{F}ZINy@}|)a$EYN2NZs2c#7)E-A_S*gemW(^!B%Ot(;sN8TL4^9eDfD z4`VAon2_EwtFUIKP!7Vm-vNI+h$>bhI0=;BmF@qc8Ms&5_xu^Wiyeo9Z_p}7q2Hhj zBHSPA_yP+Jo}KE;RzlKDQ{a+$a5>`qBBXp3UvL)~FT-KIk6l8@>!jsA8^ z*yeOZTMNPh>|;d2Ie-_>7#6QoIC(A0fE8AflN&BmB0`+v2xsH)Jj2mw9bu~k9tUBy zLiuQ+d?UyFGRFMN#sXT$0!PMz7RG}2#zJt%L&?X(n8rVFkB3W+M<|a+8jeTVjYoR{ zyF|ugGsfe}#^YPZ6Gq14T+|$cRJ}$Z@9%qXJ(CqC>vuNyD>-=~%cSV$GV%?o#+B$f zOXKODG2%gv!&#}UIRf!gR(pp#Swucr%ryC1En!Xc-UQnKDkVdelguO45J#F8I+*~K z(NcEZP|a#3$S&(kikXn)^Zdj#hRwb2F+}c>H!?A@hZ?n;{^~V77Wtbk;d!m;5xME1 z$SK}zoV5HYNk`9axe0!z4=U#B5-t<3)%yD*C#1-nTb%Ps=ke z{&ZeKW&XEX!iF!I4a7(doV7f8y?>A==?gpvqI^0ds4|naAtzKOpXB>P7CrYoWmyk*F?)CbF_vKpEh&`TO^3?9uQ(5+U;svyR zb23*ymH%!_*mX5&em{d52Mx0dariZ_4=sw&dl|$^51F+ zPkOIUW4*p%S13lin^}ppHw~NjRZ;TmDLk*+v{x7RHE*b!|1_gliMyF6!>AfFut zDJ9U-?hAT5Io>@*sXZmty?<&6+X=JmX|h-l;_hjSSb+NVwJ7)XSoUA>?*BV2VFydR zeVc<>lr7?1GJ78^5&GyY>+dZc+qwDnr^;mQ1Gdy=BlG(OGQOXOAEk(J3Bjn&jQcP%>2QDfx(|e@b~ZEfBfgmA0imwz<;~^ z0}B4L2nNQ#hl1DF*Z=H-f$<+Q_)jc&>kkzC$KZc;@V}(Nz@7hhIQaCx#lhJB)xrO( zgY!y9P1o`(7eB2P)b6jY75;xt2mAj&qJt?vI-Kj^>EGAEl>fC3c3?pM(5t2SO&#nA zqVrwz|JOPg0q9^M9zISI6V|_`gF{KM)|}e^g$`aod*eslBGx->qO1gTu+d-F!T)VT zxWkJ>C6(~yvyAI0e@O?wJlDa8UYrsCQU~AtNalj}pt((Tp@ZRAUC7ma#9z|E5|C?Z zv0e8J+=;%)ijy7xOC4MS2Xt@=z9@dvW!C|Zzodgrul$D&R{m!leC@Ist2hDkU)RCR zaMYusR9CNm(81l_)X)BF9b5pl_-7qV0yXHyAa{=r8bG8)NIcp9t08<0`tkkNztF)? zI#P)l)r$U;4(@q1_92DX+G-1n&!)4a?wEB$TTx$>zn@dHqV*3Q{Hx;`PcgKKK@nf! zRaHgyPrbG7PMy+{=CD&S!|*?Ja7;U~0j_gn<)bGWSUon`g``cj1`~X7ijM!#!6iut z#1rhCzZ$P(K9nDqg^^1}7mMs!-Kd1)KKZ*2W|1@bsp3w=xhbBKCbSGnG7C@iydAYb z>?Qp-9sEgE&V=q7+^948051nsjXmUWur)TzY57B771LqnrnByeB#?Ih_} z%oUFAhU3cV`Nzw&ha*|qNeaolm&MJ*Iw6;Igz)H@H_`5k~cM2S0p*%TNrZ+-S zsPO&8C}B~zy1xDL?sEJBQk*=Zhqm&RT8Tc3R<{_az3*|}!cWzL4dc;UcT1#oeLF8z5SiBnlIQMg}s6y!d1m- z$8*ttjo^agMC0OeSs|>8Y{c+g-h2gdWg&QG!BOO1F$VV*3fJA%Y(5JX2;=7z=g3gfE1Xd7Dzy&{qr25)G8Qh{GL9z@%Pz>l&BlJ`X-0K(; zK8izfa885E`7FxHNm8Q-YFTk5F##zHpvGm36{$csU(5DqpiU}Ow{Hl=xK{rdUi?B( zv?R{hYvApWP%E6t7{4=2&>Vntk*+&WahO7b`46yOcrY9uwB`0#XpAyxj$@cmtg$d0 zN{Xj{y6oKn3YD{c14Z}*jN0P=LZB)_y`(@yn9u`?$Uqif(1D|HRb+!5>MG`Ph%bVM zz>oep=+-*~V`tD0hYwM>!L04j6CaQn<^z<$9|~|oxDCD)Q9%qspfeK5ZzMv1dy0hgn@}c;M-PO`p-dhCPBAj zqnQ0Zu=3&-hw%?E$<9G5HUU`5h>*{ z(45z@4xt}gEhzDE41Gb=zK-|d-gsCLD#!=ysg^KHppoDQV#44KVsP&cfW+0TvIsup zAU;fYL_uexplA>m`VyQ0@|ZJzmDTMo9N?N@J|wXV3`g)+^jvHTj3)*WYT}(^VDL;%3iJDqtb{Sdt0|qaG1vUx^!F}EwX_D!2qaUxvrC-09 zHgGpXb0R~VFkQ(s{rloaHNrHCducjxnWoj58aFakZo>RyGmNV<%+#~&-)Au{XOj7+ zLvqs9{Zk!pW}^hMv7A|1Qqq|&_p)UDGd(A=gO9Rvjk5LMXZV?B21sXx#^uCS=e%dm zxk8x5F_BoXdK9To6MN5Cm7RUv3Fyms5vwwulM0)v!4#x4$ z_5GCVMwr+3KCgpNyGc5yMc`BCQQpAK{OYp26!pxauG}wi`4iRo*^>DM6M4m5`QHT! z=0736-3*=e&tIr6SSQS1x|tRAsbE8(aMv_<>*lALuI#<)!jtNp1JnFp{yC=tMNqcv zv!hR7wp`qrBI3ymy!e8niK455#bQTAuB&<1h+70O_SE_G8Gqxp9b zmmCegWdtq8>+@dOd$w}tfL8{&MX7t`8BCSQlJ@(61s(u1BO$kt2ra0luN}mUen&n4CPvn= z!XZqYmUDvjBHlIQHFa~;5N3FN5;^#`E(C1?3C=|@F@P`k)C7F3k9gBaCTmG&1z{Y} znaWC zbmb65_2Dr}V7+dCtbrBN0G0)@T2?3}HZm3{(+Ubv-X5Av=p; zK_3wQ2^fDC#0viy?FG7n1g#LMUk+`6B0WMU5wv+AR!(zlv@wFYsIF56#Ds3M$crbp z0$sL(K!{ykiQ5y%!MBhgF+I@RK>kcAATnfQtTKc%5V7Mt zNU?z+gxiCU^vM~36Ir$|oD6ug52n1vLQYQfE2g68+#m?;r8j- z;Z2Ad0n?}0ZwB_oDtE*v_eD4jPOkULZs^PkRSuYiTqc8n0*44vDyb8POezeSLm_to z5zGLIqwL?MfUM?%=rLes*bs_lWak|O4-R(J=y;L`qIE%>YJPQIANhgjdPR6JQMn3V zcQgjKHfjX;twH>Qns;I$Jv<}Iy`U?zUs+wEE#yG=Ne2At#`YaYm_tY6?7l{ML0W1@ zqFaY<7Xix#VL;a;kxY0Ik24{M)ThfbCWkA{wH3_EzbEvU%1r=sc`(^u7uQDGsdAtG3B4`#THZT=9C9EebBvW-|h+~o_h7vY&Z)nh(pDO`iD9pw!w zPd}Y@OZ+l;s;}sRAhd!cGEMC+4o01zl=40ZPKR#ABOJP2DDyord;@P!CSS8v$|O#b z(rMQSt7{XtZLGELTmti*f`;tdBXWn5B}WNU`tU#rmA{;o`Ns5O5zLrY-&5;roDjq3 zpsSo;8rJ5}Q(chtxzvSkk@vp^3x1!J^5RZH-1-)ZPKYOkBd!+(UAJzIo=5|me1 zbRm?z^{W9O23Q@x#l)q+o&YT3W$={vx8N}O$;ipUcx+={KIl-;9FGB#!?*19pfSre znmlv`R~xJ#WJv&8V}K)k`-TeSXQtmQ@9{&7T)OUXP9~rFUgfO6W!0jCKa8!d6xvux zdC=f?w#x4e$#UujK0vpWfwX)^Fjy5Ug%)Y3mxom zp@U5?bg<@y4wk>r!FMloFu{cmjx#ye!RDVz^SVlVR!fz;f2H?l#_1eo7k*CC$w<-3 z$B!?`p+7cxfAm@B80Xn>dGc|X&vEt4v3C1$J^jf;yptxK6MU(Yw&asB?~|^XlRRwO zNgw@b)}_-gI;S6=o{lD;I(wf^%$z#3oqnUoqN8MB6N3318T_YR@lU

Sqk*EK9ixR)^_*8 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

v8ME{Y9RT)0hr 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

A2@PCRbrt?H1**C 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


V53X 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

fYJhHR%e}jHB?r@CQP?X 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

^y{I3T4s%qar|GV*|?NK%#} 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�F3&y3uOwCp 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

HbcIWM8W!*CZ^l4 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 z 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

ripvZ~S03_MDPxc_xJH)hCQ0f6@<@g+5_g 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

Sl$P%v^7gz9?{;JdvH5q8@j)hV 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

pF?3{gr8S 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%0AuRCre4z7vsZrWi-NDA2>1<3kN}aA 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 }EEVK@rrI92wge|^3vIUGsK0M_Fxy1%} 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�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 Lu#dD)B= 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

R^>GDTbqrHJ)s4PY)08i*Wy{rJ|g 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

T?_f`d0}JccA9VUn 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 z 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 E2aP=qI{*Lx diff --git a/assets/r2r.png b/assets/r2r.png deleted file mode 100644 index 2bfda75f9cfc493351250135131eb19c0e939d27..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1248884 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%0AF@Dd`OTtIHF@VZ@Rd7Wo2U=YsDm>L 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 g6Z1reYFX@MiU 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

MXe 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

#$ z1upq->%EG6uH{7`L4V?Pd9zBE~0$8z*typC$u9%?pDnDX&7j3tyTH(3RoLT2oD4Wa^x*D-jC zMhF+R87WSY@+e;_A6N&}vLENbIM0;@bcCZS+*I5todl`a`T%C_1!V2}n`Xr}qFv=I05R7j*frk2J-ZITeBq|nNebqvF-}|pEH{7_7 z(;R?vjHf6QM{C=XN$}0P-o>R76zmQS7R!mG6MJ(*xNF%G#&XA33Zxqx)@4>d!QTWy zMutjZ+oK!7627`c8Jzgi&Wq1_h15u|ugXH^<@_A=D{-ATb_}H;=0niFH!7iPx5u(JN^i-$;-JvHz`5{atf5dE9pQIxue{hR)Ej?i)VZA=m zwquGha+F8;Zgz?`qRu>0i-x!>sr4U~`egeT$^fijE9@?E*y z+)S%=`6P1zbLCI|t;#RTTO;4d#73SHeua4w zH`z>~@t~5pg=7`JFLTGz3T=z0%RTeViSqPQ$M`OlBbX_VRmN5~qY;ux4QXtoGg z`ctkF;?$o(7~y$s>uR_z%R6`7JUzo#Znbb22aj%wYWxJ^ITa3x?qsGy0E4~34ZdCY z26HywalB^}=7$Aiy5ylxJ}sf0-8Mxg$O+q-Ij$j^L;22fw9NgWo}|^ni{r;Ft-a(( z-pCU_f6gIKM-ZKhg?MFci@Yy-p{uezm>YlNK8Q)ach<1lfEFK_dB4&R2S(YPI|LBGPd`^?!6c!zFD_coaxHjbsgp^jg(@U8R4JqL{P zsXeDl+W=-9VGH=e_w*b%P2QY7z^Oicc|XTfx+T-7<^+Wx+9BEn8` zi%xQ5puuElW2){iC?f2HnLjF6I@CL?e7h#_M@8`V@orNYZdbWg+H1#LL@ntJHuerz zt={VJrA1m55%jU?^0o03CSCa8tHWzL;rQj~I9%;GPEkH)h{%Ox$E1!gFSu}~{OkYr zm&;GT?Is3;N0~UG1If;@UF_7}Vu!@~caN9<_&@)L^7Q>D%K1$GPOVLs!)x_!(n%&4 zmpEq5>lxntYi}zTzx*n$XJFtNMFbNe1$Dq=Z>3K9I)%nF(uu%j+@6pE4xdvx9$^;# zodC&)FaReT{BW+pU~}g~Ty-0`VN zn=NgXhwpx<{QkfBV7d2OkE8j|PG5GL97DtWgvYTmu*?D*gIDy->%=GJ z^V|RA7t7n;#;(OFt`V4G(%$2fnK`JZ9XLJ641f~>{72s)5km(&tdrP8B46Dp;L-%g zFs?rMSoy{scb5C^yr&#~`Y7@Wo@>u9H@@o)?7(?#S=i079WB4zfd(JzwG8GUTylm% zMT73Ed8mlM5W92VbW+-d2*PY(u3>@2t(O~^eUck7MI2(n6|$?$RryJYYiSeEmxOz4 zbolM!#_?n2$P?bne1eI`8IED(SjmenWpZ(jiFa5vvruMsF)8olh+7w&SOJZXy-*H4b-4W1U;RzF{q`@Er!Xt8tKR#%h9UwJ6YemtCm}$G0>z^88k3iX zXRdgpsKwF_|HiZp-whiwz?M4f#wy z!}MALG@DBbER%G|YmPg%eDQjm@aEETdE}n^%18g~!{s~oe5V{a#EA&(5Ix2Q>oHt*HU8iU;`WF^I3mF=7R{;W8zJPbB0oV7|}oX}CMILu+X3qDmBfvuPMtL=b2| zYDd&anC8}tqjNgrM?N+AsdA${8|)mA5vuL%-L4-gCu$i5J8@JQGNvvy-RE>M58MrV znv^x1RS|){CXlr9Nu$l63)$93_A5Mv#bsiTOP`}3<%tOMFnXHnon~=dppWsYn=dWD z`H%ljIdBne=PYdyJ0-J%B>`D+U=fkUT^F2Hj@q)HkoYVWyk?x~@=fJIp8(|puVffp z%V6Jt`ec$eI*Z)UI8;>ZU{OMF0ee&t0i?lQBXII5WhG^ScrAyLAQ(91O;?hju!gDi zHMH@h77$1%0?DfsZWxyKm2VV0se@HSu;0M;d;F-6@mn)KIPR`xmY%>vzss?)eN<_q z4-uS1?e$Q?xI6W}Z$41|=2Q2S2k$+^HBKxBu_)of#R@AVE^Mz*?|bBK)^sSDwVpM3 zB#zgwM^w8z)19JGa>L6yKPMtU#=-(e)UyD$z_Iw# z;c=N|9JRuj;5(0%ucLtAUGz(g2MC=7q+G*5A8rk0QJOyZPalnR+ILyCzlMyip(yJ@ zk^Qs!+AotGqz^obck?q9>C54xdnn`!W!Pn!AzWwzR}v~EKmn|e>1$!CStr~g%mK(x zjk$&xx}Lo$GEZE_Zv6F)CFbfLZWF!Z*X9>;Vz;ho^$p8#xKRp#vpi1Y;j8rQLJ?sB zk6HM)3+2n#z3M=D_uH>P0eCmv8F=Ejg)o*i#JD2|M9NP~A_lDSOna?+_-EF`Te7+; zPFD9h6cJ`wxb%7zGh~&_^)=%rS-iBA8a#aEYuTA}(YQ-!^20na6Y-A{Lg>Q+TxA*l z=_grUD4)t;M{rIu%KlR!J<*jeMx?FG`n-}CIyQQ?Kcp#brittF00YRx*AW~GZhfn~AwEB0Q;4IEjJ<}B z;sVQ%d4y_>>1|spUdD_<|D8_AoXcC==+WSLh$3v%&Yj zfOyJe9wLk~g5Lp*b%OXotDGS3DzHTn!Op&l2o??i3?sjNyK1lUh43Uja^zQ8oaO`` zmBAP&WGvd^GtIS5AWmR6+%=CIL8>Bx2I)}&US$O4K~`AA-#~`8CU%$4-|;~C_-DUc z4sjCCI%A5XmJbjx`xHExpMqA)ujO_(w7>h78_Un~&Q2ZST7-j)S0-5iRR+2QnLb}1 z(5P^yoJX4>SBB|c@e9&qCFvjy{U=yDRI9YJC!k@2di>jWJy}koIPvnA94O}eT^tk}`>X;6NJ$u% zhO-a-qlUB`DfcfZBAjbZI7sLiC<+~XG zBOB#>?)F>a=t38qS2;WX2wneq7Ny_!o41tfUV8&aQBn?>kYH>?gyt==CaW;pGk0)W zd+3#Te`6o=M5j@$e_d+%7Fp#;HyG&RFp9dsT_J=|+#0&a1+s*erjFqQyI670B3h?# z;N&hG;|=FB>Ej5_3E)j9C&YudAJ{<$jyi|=io@S~y8Qe9`_IcApT7qUdOGGO7#uRm zTNM!)Y%|JtkQ7#C*Z(A4|dDQWESYr1?ik8-HGpY5+QP}3ns)7n{0v1TIhV`{a# ztHIZNP!VBRXG8Jh`YDuF_y|g-A#jW z`ydmQd-4_fl#%$uO(qJWh=6^ID62(h*-Za;JEl8=bYGfGTTW2-(@|0^VLSbeI!n*Vc9MCdCZXqM6b z)e{jYX2_8BRXr5}d7|F(b@FVUc7RhqIqigY07ZoP*{QOB@9uKZ#TS&Heeb)&zNcsAg z?<$9$KEiI?C5{Q@dIrk+5(_b&hA?s>f^7z`@}c5Nm6Mv+gA)?S_+j2##)r1Z)6iOl z<2n3}w<{y|PA03{FjAaroe(PJR~+(9wl#l)@HY6Np8Z^!Tbb%Gh^_O}b^JLi7~6Of;3SqUzh4)pO{HlR0Ct1jd@hLFy13VG!iG68&>%C@=tz(4 zl5RYtC5wrCeQN85!EiiP!n*o04lXWNSulikm468?NjTabx04Z6M3`c6$Sa(@rosNu zhH0mt6@?1>TfQL3uB9x_h(jcB288zKys!G{M-G$Cs0JNkFY{l=_J<# z&@G@WqNoTjto>cY9+m_1s4o0^ozD#XPrCvg^~4==g~eajuVxu!OkZcMdZ;}1y<=sSg&=nudkTWrU`U!*60N{&l@HcYRL*hTxI=Li z5L85{%FCcMDa37Gt<_b!DOu^m>4!P}I4I4j2z&ua`XY>?hAeXRT65NTVG3> zbWtwT$0kEuxSg?ls)RtOP3oRi7yAIR`JO;&pzAdo99biM(CDt|K|;aPlo5mpT{Uqv z@kUCfxPw0@G9VPnmTtm&^@(LM_=N2}!f(;9p5Ro3Z-3)Z`P6L>mIohMD#w@R3e`Xq z5!Sf!WS#37TE0igX$!>)d}kT=yTM^ESM*(Y-fX$$Eti+qzUJ~m*OBr^narZE2_;hB z(29X?s$6)ba|F5yZ|II7cd&k}NArb0ehrlccI*|mSb{0O0TQ224ZwHQKZ+grHM|Bl zjkTq&+yl+<{ck-l5bo+F?8`SYN*x)z#I=m|=xUI4==e}=0UOsc%Bjv!} znewKezNB1s37ZBe3naPn1>DvfRS^MH_6w|wY@Zrt*c5+oZ?IvNbbJ(Ncr$b z?&So-jq*!>|D|lYcu`qCc?^EiCbPrbJh#sG+8&kFmeJPs^@NG~R9O=5Kp4#T7Jmi{z5!Z;g!!WOdhOfExF8+g)6<o?eustItd-!@am2hJZi2{AX zgw=Rk{K#?s@WhdsGB8yMHN3B3DjZ>T6HoVze+S1W0lFd;YyW2eYgBkxJ_fk3M}|N= z2;af=acDMdd-~=`l?c1XRQ3IJj(rFc$N`Kpb`DQNcWP|sfb1NDNO>>m!4kUgX!Mz{ zO(DS(v8GWdvMyLfX^R>(^~HGkYW6d6rp0kO^3N3hbm7j%J-Gcj6A@>FY==g`VdFyhz8qggxyH|!0*;oIrA;W}Nov@M-y zlcm$ao|AiPOSTC-p0;qfF%o!!!u7sGK2$HK zKv;gNgCy|Pd#Eh3b7z6c98W!X{Nz$uV}1JSm+dP*|0{1Rm%ZXzCP-QM9h`{J zks11+&XEF1mr@5-!v}NEK5WeUFf~jTVY`6ov?O6kT$f1YNqhIkiyz$x-~g%eBGzC^ z<=er>-vL;-=hyBwT$MyePzGkgQ$++%MX=}P4jfOLaPoZ%{wzIttbF)`pDdsF$QL+z z+~ZeKL}1W(JQIx^vx+*qlZ3u1BKRs1zNV?MB47M`nt!$J>=%@#I=?OCfJMqo;;diO zpj{<|EOKIZAniodG=tS$^I$>|;Q$K;uYc_|?}=4F;Py32|Ib*%gzx z%1J6eB&kZOvQ++sRHd?1IkC&G6gEb73@D%-A<%{v#Aq~2Q9`(M=6p2B@4Wl&wsiD3Wn&xW zD5oGGR~v4UAXj4z5e7gF_!I^nbJ2|c!Z23K!nbu6&^!)UG5zDOe6@Y}cR$&__T?wr zIqrO1<7@MxvyN?CgB}+gTtCvzgFCWlRz0Wi7{6w`U&|+qGGkp=+z6lhP1rF-;0n&g zrYw?c(-yKYf!p_WErNvr+_W(^Rg$l{CAe(UNTQYwYfMxAa{pOZM6lmd9%ADji{pl> zh~T<>p^vmr ze)RX+lTSPwMT9eFFXmWKl@TuTuxFF}{3^DT5WwVuC+$-?u>O?`=_;9#6J_iRYGbMU zL(_l-7b1S3DJq z;d43yUBunsuY4TFO^V9B_-lB@hidAeVErA*s(lJcnAvwz@$-QANf-=;2Dc7ih_nsc z3#Y)^yG-Hh33tWCOXmJ*_JT665kBkycX*GOwRU!!X_<`Moi^|!Qx0#`$g@#rv8lvL zer5hQf^#S$NZi1n9BCp;I(nR~vS11z?nyd9r)J8EkSoed&zIDT*e*m0^Or@Rh9 z;3lY>6w11%a^*`$-23R4JQ3j_?>^p4d_iAZbT8-F@ArS;P3$Xn3-y zpC{uAIxF9;oHpba|8{mci7D?RM!tRX*o}y66!X4Q0imvB;9aOY;|2RL$0~58k0J8q zJcWQAjI{e;e#*18!QW^yM=PPsIw`(_)W0F}d$TWgy*U7-}dF z%+eLPvV7vUFK1)PP5OmAT!BNF*IY4bz-Fw`mB7f2;TJe$RsT~F!A)C>zRD5PA4d`4 zkADB#?KF2od%yG=8y#+LsEFWrq&6tvUH&MNWrN3gpFrO}Dx5v9nIeK4pv&aB!sD=x zH#|q+A3zC#jbM~m-}r;CXg~6!Z*BWfE?v8Din@iKoPxkR!#aW&jw#Y6EIb&>P{)`N zRJNOixT5??Ayq!eDH*zXl7NCl`9LKEWQY?Paw-B0$YvV#nX*|o$f)jcy|U{#dW%U% zpqx+_x_vTi>@*`Y*)(81Hhl+wGS=tq6w2ED15QiLPR0|)iwR$(2 z);xkFWlTC>9G0QOVZ~^b)3`E2gomG;aP|Zv@Fr|i!v+5Q)y#2C{fW12RA3+_I}b@X zY@^TAP_I!g6Nd^7ozMXlU?6-ya31e&KXYXNq4tV5m?feFx|a6s)z<6IX!HK zD|i4ldS)mGK{+_k2*`5Gy(mq23NUTme3T{nVHIJfiU_7RJ3)e9nW&xTC?Tj!(Aggx z_VHd95`{3{HJ$(&a>+l}1$ZrueKzSljU(@T>nZ4+Q?-m34rOOAHI~;Ex{@7RB zCqDD_c6M#CJgC0eC<9J{!0r$F6TsPLvonNq31w zwAJ;)?VtU#Pq&A^b+*0b&9}E-{H6Eu-Nyw^)MQf^#ews@E1rAybo1cXOu+bK+@}FmUfOm^*;+QN7h;+RF<+#+2tQ$yOPad4d092 z-SE5pmBu`-mc#B8FTUTLck?845i!bSy)G%oW^cH%jr<`oRnNUINc5-!J(%m2Y~)eU zSN>iv{go+hJS4dNxgHTWj`D^fN4dtB!h{KfmRa0z4|@l819>{}qYiiAn5GkSY5*Ls z#nER4WMnREPd~*u@=5d*c8dFY?kQbYfsKsyxV)3E0{6Uw?Z@T8RS*oGjOZzx?pY60 zXa-p9!LJ>Gc%Co2cH^1SvODh2wEr6Qb))6pU9UHquHdTXZ!XPC2YSpeZk>qmeCs5O zA}-+gN~A&avKvgb!@8x2@O&Bjy-dgO_$GVM>g->v?)yb5>mHrqUY*-~2wwS)q7T^k zJFe>9oIcEr3yBVpQ~I7r{tcdF;7@>q@VH5;9ULsqZ7%QQ>voRe=IfvXe2H`?Up2h; zRma+Y{onrWcIO*TFtSAJU_T3CPA@i@h^}+b<-%?4i9h&8`|NLhzCHSxZ=>@J5(ssvI`;4 zm~6W!?xunDzyMFnpL`*SfI4{fQ8B|h*vBaxuFSXq;w0Jr+l|!a<)g$BXWf&2EZA+a zAeMnCi>xlRx;X0n&MF|(*KR%B1!%v3a|PIV;A#^B8FxiK6YUBsDNuH$sN_U@W-Nnd z*l}l@qG(efpnWJLASh%(y`NugXP#lx^|{k5vMjdS@3^BKy!}oT5Ku(m_+HDUJUNLI zg&(nO(LT3Gzqp7ZhFNymFB;(kVT%V3wo9ka@Rh@6JIVf*s_NK}*gh)5ilm$^w6-g_wjVZvkd-6;BqAlf~S}WFnHe>$e4?o|2 z>tBDUJ^IZj+Ue65+G!LK)I++o#;G1C)RZEEGQpw-=}H-)WJdW3s@Nq@C8cDGv7M)_ zmzOLn-|l_ER{9*U40|Aq-^v*kln5(T`JVrN%dej$aM!VJ&=4(KZZs%qh^Gc4~a(B_u^ge3J2H~=@J3XYzEDs zuI-RVLw-tb;9Usn#9cf26|pl#1Y^K6u=pCYCgbnny6Z`XJL0ZD++hG1 z0j#oIWmBf;D|qL-U~g|yUpur zgNZw#XD1?Ld}iNLN`5&2z|9D7YEy=N)Po0K9pAba^#sSz~6_YW8_24)~Sm;6m z38y3SY5?EA(-RTw+p6OMjsjX?{1*eelXtiZUli7^GceT`RoZb10}Ua`Os>q=W+WaE z+Sh7q+tt@WBbz`luL8k8Hi$0MA8)CUKp6<7)Rx6D7nTSh#Us6g6I)#lRTkJ^$bS6i zKKk|cxsN~6p7_pLzO=NzU8J9Pb6igNUL`G+S?TNDA}vcQj(~n2n=Ls8pRg5nhTMcz z2_dH-K*o_{Y}Qbxci(rcz46VjZm)dp{cZmdH)6m}_=a`v28iPjHb7R8g(Vf8ac?ls z@Kh)n5jm2d!zf_Zu?39MfxN+O`Jr2hkCH;_Y?X~NZu;ItS+*-B_+H99D*YU#OXGt% z!8_-_xPmXcCAQJ>yIHo#xGwU=xPSfPdOOQWUe7*#hRxlR?WymaZ|BZ%pE$>OuU&+h zK}}t8g!U#ILymbbZE@lTlzLD22Kd%}$ag-QrcQN<^#vay5fBX}IaaKk(vH&Z^Y$cDH3MBc3^c90@@q`lfADi>0`!yK=8S z5qC1|+^7DPwP6%%6C%!a{5GD*K4DJD77%U^3)zPpE+SW`FtzFPM_b$i3p7I0Ei+2L@Hb2%bsdODV6!(CiAXCC{HiJ+kEpk9UoAf8iE?GhY^_LS3uyb+&_&k+Eemk#=Qk}c~^uY@%xJPD4Y`)Ify-SdJ z=jCXvNkq}C4a$J!EoV4aeq7$#-yVMWeEZ19A8rplehP&vPC`I2>@@wLq5%k1JXbIg;J0DbQl%9b$%{$-fght~po<+EJJ5^<{e#dQ&@Y~6Ha;+`@m`;x4@u9HhGH8S z_9#d2PV?C#kLn-yh>%v(PLS*kHOb(4I49_zN9uozlfcXuTK22S`HgYK++QdKH+9kNMFlU|56&!GQxu+NK{kFkx)V$J*-G zpKZ@R^mO~uAAOm7=bml{_|oYe?|y50&D-8UJQGsBmRRDeCs&ASVVn$OY9evj37JRL zr~D8&HPD{L0Bp^iM{~F;r~XlRYy)Gawr=CJ%IyMmPGryz3Mbnc$P`ilYZIa`IX;H^4TGU>t)Ym%8ur*1%P>3sYt+uxf0O$YXZ+>C+3kREK(YdI>1a(CH@+z?k^ z7n#P>9-K%cFD`&{=$ab|CpZz|b~X$ClVANC?JaM8bvt+j%zO#smqqf&iMC&-c`||- zxKUv_{Es3+Y~4(hSuF8Ou5}h*m-l%;Az}i5_OT%CF~pZQ*|y+rNx#NsCQqc(9QenV z+18;lA9-;}C?bzM6wUR? znqWhYfVN2^?Ua#=Y=%H*j>6dt+_fn`z1!1;{qxUlwuip*X!}Dp zejoY9W9|I;HP((?2uJRa#~cfcjac${Jg`-5+prGEK}T}xt+u?fDD_kecLACIkVfj{ zsY~K%d$r<58s*-vEO=bNXZ6F)57xD!q+^@#3k+H5kJojWrF4viU9!ecoG`k{rC{{Q zk4`Im>Es%5g&FCuh)BTIQzqNamrlYC6eDb47=D3DQbvp+ombZ3Bv@}Ria=!u?7{e5 z2*6K3aK^2_o>D@vDIz;O+J3!Y-|qt6VNO9ZY?1%?;xE@S;I9pqE)Q_R z_+fN~zFt3uM;hiJ1N7!>86V=|cjxg80k{o|LH34o7M}oXsT*N%79Q9XcloITx7Io@ ztxG%rq@Cd&5^Z=r1v6-hvQo-!!l^0$;7>0~x8Ts=Pfs@dgSFu)=p0iA6u89Uk-vr4 zFen_jbX(FMpfw+p7tpkBY}dSIVg`!x&3`MW!G(EvIs>vAT(%gyaoB&1z_k4-faQ_9 zVfX~^z|#?4ttX1F++4Yh zaRvM9?ZG$P-u}bC^V99lm+|gD$opGDY%H`8-wPQ_+SfP$0P*Zvq>S0B6^)JJeBJ8i ziOL8(jv>-kU_v$>#p6p&zwaO3$Fr*$91kcR+B~*}lqnU4y9-NC zAfKDB@D9mQ@YI1{W9#-Bh9y2}J#curz2}87 zR>n4N8lg?M$u16AftHOY?(n{J5hYOu{pPePU7%JWbd53DI-bl2h^uScNKa;^hyZ<- z3s_i^ewHjGEB!E3!_T~Z!P#x$OcEGtG6=w}QZDB)~smkp|?|se-3;Qso2tA$Vv1 zP^R0`IPlIKW?S*q9|Pf4Vv8h#9t?2~vEC3GH}NUP27)Wycj7ZI$K| z#X#y`B`+$2Fe$T_!1!Zw$8yNL{q7h;yHW1D#rIcu@4Vf2JBnw%ccQ#yo@{8VEVkX1 z5#~iGy4={#Jdy%t4vP}Y*|Q7nBOm!n`^=Y~XeZfVzr=e6t(A6W^#TfMY?4D%t}*1j zv`kq&5n+XQ#X)53Hstv@cgX$4_ub##^tuzA#Iea30a)Qh_KfxUOSx!{p zBNU3EEZ1XsdHm~iEV6d7%{ssq?|xynw)aQr@64rh?JOrAeCzSE?b*}o?d#uw54;Be z$teftxYkqL)!&P^`W4>?juG-&0oGcTe$$QjMPz{bvdL|jFLCygInjs)?8$OljDwut zC60Vt18`lclu=wi;GJZijMkLr>W2v+Z7J>`H@2H#C?1MSI?PSCBC9>jtQn1f&gifk zKqPkuK5_uEFbHFO*~6Wbi5ZlP{47~*iO(|I;RxJFz9Xi4Aii=dzwo21hKzhFcK*9F ze5Y>?HRzv)>~v4_+8I;6t78`T3p3&#-Hn)nuV<*cPOSn4`LTu!b6lyMfV|S!-S-ARH$|J8~)aL(|VRNxWOQN7sK{Jlz6S9T`JZqRrv}A@0p3dJ&;_^KM4|Bw`k}E8m0z zw>v&%q5~M=zD#HCNo{380G!h}J5v4PaI)YqWW>|8)I6T>1tvyL9F8A7z;W%X?PVu! zYg=n)SomFP|Nh^4SNofMebyGwuy)I00Sh)+vRv4g&dD#fviaxC#5XnshGuLheOau` zeAP*q^5tX&M|}KR9wwL`@gHhM5h4p(xJ-Vk?0YydNGA15I=kz6M)!*mx%!&N-+ zr5G5>jW3um6_ASKoAa-^LagZ3i_4ziefF-M*ryz3?Spzhpv8YGo$8(so*2wpjIFjuL`O3%Iih;6k*=4GQN*Iks*Y zV4B!CHReUx4fA@5Z5AxKeIsQNpKEQNaFAB#tRJ(W9KnMP(kz~1vF7R3_UseSv~w5E zw}Xcdw>$2+v+X~D62bx6mMaZBZh&PIER_Kc@#L{ae7Z?FJDmnWf3=Salh=@Mp0B z`e0P*CyOBP#Ko&@bSIp6XtRaL4gVJ5`vRv?s8HfpmVTL|9BdM{#R|UHMR@1s249@G zIO8$Ju328(IGZmsxZ;#*askG?EYA3|=87I^sxMHCmt)!mo8M_&CU*Wa#A$>K&dvSi z(S6}%xw`~+F`4Gtuihm<2ZNWqYBrHGRHedNGid}ZNY#7hDtI>9c z7msrPZx&4aAu zyTX=?v2jR?e>(BY2mAgRKRV6TIHb3fwQODT+P0DnChGYtCv<%9*M6gY^^0F^Cr_S7 z8R1g9z)1<-k$REExJyxr@k<>xbzJPAt+}uiMHTx?{2~Pjv_q163M9hsv|RyqFO{TR}t{o7p8Bs9T)z50X^UoW;*&>z+He1)$&{{q|Fy< z^oc(pP@dCKvKbo!aISf^8UZWs8f2N;gya zvo2~8GOx_UrApi&w!b26@&dW(^$%0{#egxYM`({H;gUEpiQ{L$1f^vga?oRvtiw(7 zwH~V66Qtoo`R%^P0`?Tb{4^%U83n;^S^uPHktM#rFSJi`c5hVzr6K6V2{K;!0BmR@y+-N)^m=*u@5%F&;J(>lur7`z)_*ICSz)yy%zzlKSFC!a$Da$agn#g)nVJ4}fqz^EksbmMijR0@5egdJ6)=;=mpW zdb(LZVFE>Q6t?#90m9wKx7+u<>_Gd4pMO((`TZ;KfTQy{ z+2%6+$Oi3V-=V`?#j@5G_eIi*EcuEo_*S+qm5nGK>Cr%Am>j#p@-9gvKPfx-#zs2$ zGG8}*`V9C{QSlFe5s81s^bt0(jh=XQrb;@g700jTsGov19ThAe9kVVYXDO$$1;i49 zYMfuNy8(PPldjbP3iX@*XaI_zCu1>ean$udAtXeGeFI*ihb$2`c&FIZc#gRQ?=P>X zh#~^8nWNgEtPbY7cA?Sbqfhfa>Pe7}J3*H6drHDZPJmQVZi$z}>N*W-`M&nik3ZBt z_NgzlXE`ZmmA>&Jjb#nuw`r4}0%NaSnb-uO!z_7Np=rly$afrEZf}3xvG&vNer>yr z>zWWOl%+itiFN~DojamO10GF{H{_d2j_E&$i@`6`EOS^vx&#qC-ZA<|g+Ke$Li_OV ze6xM~$<_9@H{IFZ^rilH4c zw05zbWUh1a)P;76>w28?sPtF!8fkJa?p(*d2lnz<9v_)2&C*uyb;1FP(vx94BVG}V zAID|hky0pa%9?ojExh{k*W&^&vg*TBh_hQPlY|2r8&g5$?r;g8r7-^)g5=+$=GHWU zgip*~<8h|eSJ9cvNs*pDnaV=bX#q~GYRdE;T z*DAnOlipCoUNo67ITAVg=shVQa7Q1zE60Ij1n}*G|VkUgy&xm(-+zE$MRyNv;o{4 zo|=sQ>51X)ocAQZcaD3NEDI02B7(yXp@)xw%(Se=Whs4v+jzsr7)Wmal{5>XuB&y*b zPVLZb-f)CPRFx1!6WdtYPmsZ!A#IwN4mk@sO6@0)Hb=XU+U_p~de`Wy*#$3)Z zxPHa&9}`notXTAX>YLBBU;iinrhWRuf7~u{+r=r5Ze>>L0%InrU}FBsMlTCB*kf@~ zeuk&v#f-aIKVnXsT(D+lUjA9oRUCscoq1hIM%&9m5Gf;@fG$OjYJo^a1dla!1JhFo zTyx&H?6K|(d~vn$bbZKB$&O(&MFckjSS<1ShM6KlI18+Z zt-I0iq({^9$&svxkK&sTe1KDK(=?E+B_{4crF?OWr8_PgtUPbAKz;GiQ|$t$WRQD1 za{KXi;%={G;2IP76a*HFa$4KAQ;qfN-xbF4&Y6IFlvDY$9K#4lECUG_=TtJdz-b82 zJ$s%n_nty2;gR;xpF9rhxUPjYoplxreY`%U79px_ti!YMm4z6iC_-JNB>4Llu3)hp$pOyZo?GoH$WkRSpX{~7FoW0rq+8#3bRXm6I|`#^GmmE&~X zY)C~3f%dx`MFf-)SSa7mv*g!CC=?w%vJYj1#dh0mhudHH;U8-6|LOO&6ZhRs8}8Ie z19V!EE*vLxR;FIy3IwS86-DLFJ|m$e8*Gu;q}tlk&$SQztKV#&`P66liu5dBOR)%! zveqSJ@B*7Ro@VXhY+YkhiU(uSEs6=`Bc57V!=daDV3->*#aS}e2Xw^mhW=?^R6tSDY^Q(b58MAME0*txK@fFAZuaA!IR?IDxJ2 zs);IBnvFs@$dP%98jMwNdILc(X^!GpA6;d#PCV}r1 zV@BMpftr>;7d;1lal~}s%Fo|2!cUDnwbxS_VNbK8PN23GY^w>)b5&^aPLYSH_28QnI%Wczg#b z@3XHsnOys2a85Wm2QV1h=2V2s z@WA=7W2Gn|m?wR{e5j{L7<7zsUVM71{lQ26gz>=R`C5OQW1=s^TaSSz12#!GW*sJ} z*HG^h6hSDPr{wHob7*;my318;R?T8Nbaa2a=e`r|fmhzcNfx(pQr7-1_4ZC1x(KjON1w$_;OmAMd4e=PtG9o;%Nx_Pnp2T5T6jZL|v)INia) zJjSv88p?DkAb1q^P)sOA1o~GM6Tqtiru&LC|Q{xyjrkN(L!w^|d6cFk$U~DG`#|(^Z+p5vAOO8dmYuzm(tdR!<=;VY}-gX+hLY zr5(OXGko>VE8nQk&Taz9d{ptw845@8L`UX(2(=OMH)&MitPNs@rHH6)$@c(l72Z33&LMB`GJU9|h2H#F z&^*rHG>%7?QN*!W%A|Z5eXk(CLq~UEIgA^&6|A3Z%S1N2JC=D0!2iIjTiHQYwvnwU z2ScDIlY}t>izhgNi?$tTtY6Y?@S(vs9zWkc{HZ6}!%tppr;*+BTPr9caR0ng)@fNJ zo!7r?GVj}<{VZ`x;y#teh+kP`qxir^yNhcszTb`FpL#u4H0)z+e=et^q#|EQs`K=cs=Dle!)_37(m(y2`KcOq{p}k5UwV z@E0DqMdFMna9Fmi3)v9xr#%XQ88Rw=MJZVj8M@Nf+OB+;(YNO%PaoyZG_S?;ndgzgMh7$r^_i(<)aNlN!q*Y&) z#Q3Ey?HW4w5qp^I??UO|4fh>tfA#%uZ1)`6;G`4Y%giy;*h#R3%x}@YEw|}?Gk8*) zGVgeWNnZJDVu(7U@kk0oh%=O&UocDqqZEMds0_P>#3*x06ma_MHzke(CmyIU`j-aRuOJhg|g{p@9wZ@aT$l4f|cNw+&}>QBk1 z0n@bCaZA${9aWu*us3i}PiWtr)z!+iH?~`$a}IP)!rKXZ@$@kTfY<78^1hrSyXE>` zae!*`)qX{zyy5(gon>>Wg zhPh$BOx-{S_JBv)p{0J1FO?UzFSSDl7dT%3_V!==mw&U}|H@;)c^@y3JT7oXE169z z>&fMw7&8erkyp@ggg=u>NBn>+umY3&cy*g*q|3-pC?3O1Ygocv5bDEL{lsTj5IA5l zmaP(EiDrgax2DIlD7=BP!O8)ay1})`sR)}|a#|dFQofG)VgcrkeO*@PMqGQaP8{hC^>x^sxs@%A+ z=VE}02nQ&?N2`0RCrhP`kMOdB@WXGtr~QM!|2Nw`cfy0M3&is!1dHPf9^t;UuPyIq z!<}=M!#Z$gaxbrYofTDPuAFJtlR6dNKNqX12N#+EkV&bVvG^Q5WyMTv%1bT1%E>Ia zdVcQYYKGcGunvWj>pUtUh&T0aAVo^C__4fLRaSk&kbmUA(>5!wNi1il zF|YtB3Sl%>bIc7;71bNm0_igSl|X?=t2F=*({!S)^CIJ1zEWvoFhZ2Oc=mWUnBU`c9$F z=wH&s5Eei1^4ZN=AHyt}o0qx@w(^n&(=TKD>^6fRX~XbS`doY+;WK#CQY>SL<`FJI z@vn1wkfk=P(w8ko+w{9`ml^L*r7zehI054VtN`0UB)^JI!l%9zsQjCwbv%021oxk^ z#OpK6wA~w)IPjV8)Rfpa-FPiief-`KRd(WVOtDCnfki{Op7<#rgg1VgZkEfg@V#J$B0}(V*(*yq786ML zSKjlGlU$meh=3x3UoEq)&wbE`_}X@%9buvW_B&d8|4%*Ge&*-j-jtg@cE(lApzNlXD+=8n?_B&ii?X96{OO_B)QWJMKE(?!NbqcIVx< zwUy(C;SZ-G`B^%Z6$KCq;JxLJ%QomsR^$<8^r1t>(>GY)!JCvF0=ls;gt67$1oJN) zm7c2CaSfMs2E&1=9JCCk*^7iW?Z*=iSNaEM;%x^n42Ef zRyWv~V-t#(*9Da6&YxQaW;0_dl@iw2n9|;0{C^49izqH!;@XB){6kqG_kM$4zUMA* zNZmxP91?91R$skBnPdRB&d-`M3Z?qfA4eR0*V-2oW*K-uf!}`BKhtC9u}HmKlQ=*M zE?m%8c^WwSyy{mfuHwZ!H{u^=)a~#G`3yI3GFvlqns$;NpX?t7Y3lt-C9QX*^A%(h zWKl%G?cV7=(y34BX$YQDzl<=S!2OEj$JAb|C?aI9 zlY&R)BqFr%LmAynRAJJ0q5Zd~A?)MYE8}W|oN^eaMbf-8C6odgCaT!I!gSAy9=AWq zum^)zSpJii3Ra_sQaAv8QjXU)x-gyai#Uruv zd6V>Zq)A!uNi_UBY>^p|pB*s?+l6Y18uBaEfQdakwz-az$}QNE8zJf#{N9Fm@X1vsBvuh2Ck=Y!i|<(bLfX>O%6_V3rJdrVm;d*}Uu$1}___AvNtDkihy9mT zrk?p)@~n3h97_313}~15I1e#btK4z0wfm2)v|m6G;lX?MwFAiF<<*P1?k9z$T-ziJ zZ!EL&0BwkETl9VwP+MNxpsY+*lrjAiatqa$BM%FbfppU1Mmlx(; zRa_F2J{mHs%@pmX9gi;S%EvHG;`oVec?nawp>TJ+_)_oMvoi0*F~bFfeT50crMa42 zvGp66_;sJ#)Hc24!)FfZlM>y`bQ@kH9@Ux;~O$xVHA4By>)seWTx z_A7YRnM2cXwPu+9t#jtG6Kuse5A>O zgs|ydD@Ws)LMFXw3zk6_j)7BN8b0&mt2w4NUw$xA^Go9uzGiUIW@T|LiU{}JccA@O z|IIJA@BhJVWfV8g5K z-{1b;-}#01);GSKMJMkD^_mNK!UFTAixteaSGdw)(J*+O7ag`TkV&u=l121<2b}OO zu!AC^T{s~Pot89?I?SLDPZpB3t%ETw&*}>Df_+&<1c)79$hlgl5`yrVaYP9LcN!h^ zXnF(G=UtCxEKkUwjO;KsZRw*7Dk0?SM;08m&R*c?-qY>O$#d=Ex%GDF$l-S4cJ8*k z<2JtTJOqD~E%V1@@uXV1-YO*yS(6Myg;5yNglD=3F%w(5iLVf3RidG>7LIW81=J$f zWw^ZKhn`P<=Q*xzIMp6~^gHeG$DV2@pF7K9I*I@+u&hUM23+txS+a<0Jq-U?5Van9 zuK;;fCcjk8v7_+LjgfsQq#QkdtljgnyW49Yd?iOZFSgJA!5_7ce)#wK8lFY<)qQM0 zv$(@1()RK?U&OCvQPn;}{QkK}BOT#Nmmm3WSe17-x1^wq=97Ult-zza94cY(w?O>dBRwDREA&y$7t$RO^SU3Kqu z3@RhI0Iwp#K33!Ru^@ba1>+_9tHX!bL^`z6jvwb*hPS+-z4yI8)?WF#SLf>@7YQTt zBTwiZZ6ISW!e=H#`O}SMBhT$D@VNku7h3H{QeT%=+rwY@a{E`m_QCe;N1tpLR7Bvo z(seRDiyRC^1iuE|WFgxHRu}b@0XM6&pdUX0{u5DhV*a(LXhxDTGrRq>h+U49rBYU1 zReb81GHA5QWj&Rv!hJtf8xSCI@W8U?lo!+Tr(%I0sEy@M-_c&LF&2-raF4%~5U@!n zjA@n$54`x56UsG{1M}f;2v?Ot-bfvJ&@LrcUKJ0899*JTWHH$$99{zBMoW~AaNF+3 z0_*HcTwv`7#lMX_t@G7!jTEXYNIt=5J7%HW7wIT9PJO~?s8!P1PlK-)Au%0Jn1a-0 z$xW-fjOCcM=aFU-Uwj$RGC{W)m6gq>^38r{_z00-yUje_w~4hmTFe}>aws0nLwC9C zAUY|#Vs6MgE6Of3olCR+C-MTuDKE_Ss@Y$G?@Dr%KTGW+9VPR&17SNyh=}|W=GUE$ zEmU4pzE}9<*bPH;7`dL|2%8S{Pi$ZvKfcx8_KthoU;mZ&v?F&SWuCFjhGCB6XOq@< zP7DZhA9Fm0NeL|`?GCr{$CJ*(enJ7~i4976&B$i;(F9n}#-o*Y*$szvl;ZL=J(BI% zf&Qo?EWW9T5JP)0due3+lr9p^6v2DpbYru|H8)M_Q>bI-9Ginud<=SsS~u%+PEZ+da&PB zuVaPxh0i{e2oG|)!I2|eqJe$l_CqKk9Kb$?BEs=@_!x?(oX`O4F*2P@;%0m;E@)g< z`2ccU>`)E@GkyWrpFW{S>DDRc1GU@kk*u9+PkEg?w+cZ68k0d&Ln|b3;9nFL0u4FoD z6weh-0RogXMvrPXK!2)!=B_c2^I2yRnXdq(auXs;6X9K}pK-SD&J)P>-TMx-AN%p! z+j~CnvUc>C?S}klygB>?SWiVLo*)bKOTN;V;1^Lf4gs&_%eaKPvixo;yV<_q6H2HQ zPt@3Ef;SXhl&P>?@#wUt&jGiarZ$(F%XAq7MnGXB+d43L4^?33veMoB&1o;@$6xVB zYM~9hBYkL4#)$E1mv!Xy{Q6@1{VzP#KKCc5+OwB7P(-K`5!Prk%A!@ffSh}^;x^as zsX#AJR+vv8U@pO|hp*F7%vt8NJoxqiS2X5ulFQCfuoJGE}$t6nO+PNL(-H}J7|m-SLHeI zB^7xLdIlO>zvIgqW0Fe%=D6&e6+*_nYr+NA_`I(ZvgG5k)w!n6O;iv_JWfGKx*+z;h_7@>&r7ErX>o zPwBSLbj*MnG3^$36nj)G^Mr$EPOrCZ)(C)0!m)yF_!N}&GjIQ=Bs17 zUiz!2{L_z#yma2*G&K~w+U!lIoF#a^Sr-CRUme5s>TO2E^K|sr$t?A5Ihgu~oKAsv zh$zL_0WaXyi&ki+31*0|?~oSPOgs@`FB7zrsJ*heqC9&cx)rtu2Rb+5?}Wu^NW*`v zzANvYJ+R&i`Yv;TYD;_Ht1;YA*4FN*;TuZuX9{SHMU~%MiU`l6YHukbJP)SzBrlzp zRi7~3L{Y}D`6iOQsGz(1yFI%wfc6ZBk}PuVqA0M8eny%sPzakLP~~V`O|)@zB8+#; zlKHLhxaVmJCm`wUWQcG-_%b`+`}vy31)CK%j@=hMabmgs!~guRw0CjTep_5+B1Zip;<^}%vO^8lv& zWFdgCY=~hmF)MPRZ$EcFuC1-MqfGu?bn*!0pZ`m5Z@>6g-W@q=Ot>8t_(hm!DDoaG^X4x5^Q@`oRBkYfFsbB`a|jb)nK|<)ap5EEil;9*C%gXXV7lI9KUd zI^*j@d8#skUo^t;g2|?#^<8+9CK<#9EiBqmPTQILAVDeW4&!~P9tW8#J-E8VQ$Myj zmT`^E{j=XW$#L_vrGp3B(c6x<+fYJSKFU=U9w(7@1s)L2HVX8{6!MTXtN9*fxkH4+ zK!%{5mXt4XiQ)%H%I()I3(!^zMR0@#SFaTDDBu-ND)5-iRln3@vHbL@bL~4%KHVPs z_7m;dXHVzI{CuIe&H^M0^44iKCS7oW1p5H%!A&La`yLyphbZ%b!w1_TzKXo#u6x?c z?tP%$|ML6WefQtnj^BA(JN@Ki?SsGmZ`yDCiw~jvz+K5}2Wca9cjy)in(MR**0yMm zZW6gLtdw|mr-uJ$DwIBJBw^45>X3<`^#0kEXmEUTOkRfTb*SYDO z*%3yp?U(#LNyab5O_7Z!Dsp>utv&h3qwRyg_8aY?KYpa0<1~abr!R7BX^SGl1!Pnu zgd9uF#^1Oeq?8e8lhOc>l#M)H9+i*cT&F2uLn8EC-`M6;>|uKFw)REA}gj( zU13+hS!F00A#tZ=d9Al`CL!c+4JoI@5f zIzuMGv-Fd&pz5H5rb%?1g&uxH!mEyV!${OldUrwCsIDYw7tqzcGdg#n8U4uazN#d+ z@R{vZv%do0l{EP7EjjE3z={}ZQ|^IV`E^6kp`~L9|_5F<7)KuUl?DatQD`6O8wJ6Ctt|cVzxU@5RN#JZD3PpyF zRB*lSsS5=Yx-*7I>k?nls*TX|?tvhb5w=i7P$?nG2=qml#}WU+hl-vD1y#@1#_35y zDy}-tu??p2N<>aXaKqm*iQ|w^O`>ZULCh$In#1j5pu=%DUku22RRuu$?z$ezaaP3z zK@t|0lo7m_*AKQQ9(ua{;itdWzVpNd-tqN*9~)K&4>LyC&pU$?a}FIwVeQ00PCMY# zgS&5!^1%vUe`mv1R8 z2l46GcvpKxgGw_=P53a@kFrwzA2frT&9%=7=_k-=h*PK8h>agDsyA{gY%`-jLe~&wS1h3m@B(7+IW58w^k6OFi~0zEj4ZDUw8@<0=Z0X=QAm zW&f=V`7T?8exF(KZ8s`xp+MD5ybjn`;&(sZy)}|m)jqG3k9r8_Ca+zz^dgI zHS^L-Ic2N!gD{Q0JkVfU-cNhmM~asnT5dn|iX-jk-}}0D0;QNG6#5p?HtIubO55cK zdtmg+hIJOc#yndXS>wDHlIdSLVTLw-fm3YGFb_F-@JJ>eDOel{7*v$^ z#rVA*#$L1+BdhN@jx^uSx|`0Ng3sFKO((7d&o}FN>Z@b8UcEg}l4r?A+n)t=$5bAs zZlkCE-R`NM=ClKLM;;b=2k?&A>w4^qqtL!b*)4!w9OxW{#}hWE zAr1ev#<{**2iz{ix4hp?4p41r?^kOO*Uj5n`}13K%5-EG`Msrxa9v@!5@5CvFp0WW zM==5WbMJiVysYTFZ?X@lsmAl}bzX4Y@6LHo@&Vd2oZK^i-9<%U?GSpnFq&yujmu;v zwz1-}6ER$Ow};zsI~V*lK}P|B$>U`vR{NF?ut4Bf+-rOl%K|V9j=%CBysQ11S6IATV&Px|MTEnA(a!pGHVuCGEiY@o`geb+-R0Sd?GlT5>nsj% zk25|m16kq}g-q04Bu5EhiN)zfl@YRV4HAfux-1m9Xd+QQ&hoL-76$pF#7V$U!s8JG z|K`dQ+vyHmQwc#%XE7SN#`d1zz=cZOBa_&G5-UUeN_HqBtk`LqERh1>h2Cw-wJ2{m z5#chM>1$7)Yv-Rl+15^;Z)+sk&!YWNu46cI>?leI95e}hzWlL#;+P_|2t0|=&g!R` zVu+Ye;3T5=7xK!OX~Mw5LXK4S3&6r?rNi$mLi?2+3$*)b{4T(vU|`$uaRF-+8TB6H z#~y!%(-GEDNI1`t!xuPGnB_?pSlyhI?0nq_dD{D_b2nYx_&!3XattM(`(OEeY*^ey zK1YfKNcFza?ek~a$A9M&?H~Q`zs48wXF1AvUlw#O@+HdFGI>LHHbJ9^0ExZqmF?&i zwS9^!c&2UCxY0LCL~zbQ z=W(G>fJ&X;j?3yE14qMcqYfa)0;6$hzsQ%$A=ZaV2riJ@|Eq|w!iL@vzGywj$tFkG zV0z=59&A7LQ}1oBdHrjU1-{y)%_`e2@E6TR>x^EBi0O6_)x)$1_XR?`kXvqE7hQx~ zmup;C^VGBLL;w1>+Gl?M^X=r*XZUi|Bd=Nb%-E{d2h+8T-E_j9>TiPUIq2Ku^$XSt6QrR5o&`(1;HpC zP*+hV(FRw(7>9+1B8Afc06+jqL_t)3#py{#*;IixsxXWFfCWz2^wV+l{xfvS59z@Q z{lhlAj2m|HC5z$mRt*o@b6O6zEKQ%#ZIzKq5rMv4B?T9!0W!S{uN!0*6yP+x9`FPw zafA^Syte5br(0Ne$c$W_)oFK2e!>Rfy*$%81%!8pa5JDdhJPL`5K-YvegX%HJ*=V= z*nbLdVVL8YLuA8_I+pgUnJKMTz?kgnNv{Ck9T1vKk7J6)Ud+JJKaF0kT6JMb*1OWp z@b3zr;vO&=gU(70g#WQh_Dtgji{hya$88uu%C=uEdt1*U(|{oS5s^ER>{O_Xu+0fjLlNP!+Hoo)IEJvyl%b9T#|K^6#I*gY43JX^qy>`- zATt#aP;4kg1mDfXnVYv(LTrxl-kDd@W0I%$#I-KujGc~ z_EE0v2t_B6CeT*yeAtcli&+GPxW%^4m2po!eX2e3$dm1BUw<0+B~D7@<@LQcDMhwkXMxv$QfH2q}hs;#G+HX zitqbcx5SrRcaXp*O#xojKZ}?+=5;4l@{b`8*`t{`&DW<)xHn)3ioeGV5z70I7)#{X zCyEHPxx6#sLu?{EVg5LCn4>_x;uS0HXa4d7?fX%3+PBYsr7&B4mqDDXdf@XmN+Xwf zviVNrf}Ir^Sc4kNrL06rmkRJ*o;t>D8cRy5*s?9kBb6}SLKFvpD|sOw`4CzJDwFr7 zazmVSDb7?N@R|0>&!Z4? za;=@?+Qv)Bipnl3fSOE&VCCg9A1)|1DR~JOd2`Yha=f3uX6dqX!^`b9zFdDT8^#}C z!}!&&IEoCPYDbT9av;hzNp1O3d2$ETgO?RcfP64xGtriIbA^U@J1@c$VTmI=YIi6WWq3zyT+nz^{m~Ja0(t}C;kf9`Lx*f~75l)o6Pn}tBJh|S`Q*40qR2War z2smYltXR|(yUMtONXtGWL1^ld-~1?>gRh3g7z=h3{kAI0z~pqU&}q(v!?X*&FKhs& zG0NnQ@#vqnQASS>LiBR3kr9=$v_G+A zu^(QiKZL+7#~OqWIkED^>?1EmedCM~hjAq$_VML6veH@pc~}zlxT)K6R2_`ak$&#i z6&iL1bqc3}q&K|Aq{`}?0JG6uDm~YgxvCcPdGreIbO)i?|Eft?T#9LUI_lJPNYmncIkI+DIz?N zs=TF$@I08-le~0ZSWJFyvJdbz{Q`QO=g+jkyImOeBp(v@3@5FVqup`w+aYw^!f2*t zHO|G48I1mPB86|@4O~y}JW;=kesA1ttX~T=2L`6M@(TPub4$VX=NzX+{jAnoFd$>ZIHg5u!a$7D_;d$fBQ2-khq| zq_O9VUo)46@?ZUTr0Yz{n|s1$qQiY`qm&zJI*V3L?Y(2wKer|gUuHqZQXl0@xmWQ; z(Xam9Uu+M)>h89T+-z^6h;e|)Ig8D1R{3?FssJw7+Gpp9G6I-@K{$yd7u|W_fpQw* zg%FwVgL9PE&9U$&ZH72#sRu4)=1#q(ZD>;;QeZew)uG(%PZpQNUpR)`#HZ}LnGbZ1 zX05==iqO!>2CthOo;0$`@$%<631Jl_gnjrIjvj3L@4u6i0gkriLnvxkKFgteTfR^s z(lViWcsu?16l)USA+b7Op_%&)@3OPVk*MC^>5=R5Y>5Sv`cjjXRK5(`=J-jmxL}g6 zD6vDJ{C4AJ-{F*Ni$(WMamd0jh)l7w;7VT0;B}*Wo3`SYJ!6PBEMSf6B$`ZQ{{N&20EquwhN+^O|BOxR3*##HXHx_=j3MI|tG-J``3 zzbJH<6?+ONeggyFA&np1qV1r*v^R`)>4R)}r>lvw(aj2-S2C!Kuo49XPCsBJ-cxbd zCu>KKu+hY62zT9etiAJ{Z*T8;&pX@kd$^c=V~s^iTDLMGjr^o3c3O)ZV>E&27I}{# zYPh}vMd<{$G7~xlp=kE0Yp2e(PyFu3+DAY1vG&yC&$e|pT~J0igMEP)&N>UA9z(r> z{BF{D&o;KH^whaFk8Os31!Pt;oxO<*P5npM>zZB+;llGIC~1gP*f;e!`Ck0#{6KEg zgrLMa60($(=r;iowYDcBm_M%WRa9~ z^2WZ?w0Yt-Y+g;KlWzIp289X*<4$zjw2R~3eXZhwU*(RIQ0nVkSWVlsZ}+qm?IVB|D|yGM%mw|UPC-%fqJ=x*LZoe%pQxCm8y@Uw zRj02ooj~2BMrA@bW|fNV{t0N&G)X*-D{%N8TyuOKO)TNBDSOt%G{GKjW$|hzX^qA) zg_`wM9r@_hl+9su$yWy%o|KBjbvrmnvM1-0Ue=Kc8r&cjkA0r#Qy!um z(&WovV5$$4mM}QuEyqW>V_jZYIi!sZzj9iFw{tkgvYh5aWv($XQ2F5WnYH%iFF(q) zSr^)4kDbZ285g*|A^k8rihjwy3cM#FjQ66OV7c0Xd~!kpxxoS4^wIozHN#LwxGeEe zL@0h1FG)~Egs$qZrC5{2@zCG>VPLrvzssNg#Uf9_r*2zg#}t;t4SqQlB8pk@877N{ ziNAXyX1F5*q^7k;T>UD41v!lZ0`a+?fg=0PJj$l|5i|*IzvFWI8BRp_3qNu%N;h7s z2i0mSB(EyJ{Py$;Cuqy`CysNYh(HJCdopzSgL@0@@=Z0&6>w#RXOZ&T*Fj40mN;4B zyD-@(fXY{YEcPg0RYZs&XEF&L2m)1I8A4mh7ug`gre99~ z=2Qd~Kam{LDD0k~ad}}}+i2Yut!c~P zSVFl)o*(w4ExuMiOvnDNx8K7x4X;7z75_o#WHY&lhtIu_2oo*CD7pEipcI1q?T<@# zEQ`nI(^ic4U)yw8!C-j_(Vu6ywG*LZVuYKS0nqKxG>e2@Xc>wK1`9Tlbbq|_A41`= zzw#RSvn|>;E~AKGoARr8>owy@ZGa;$*0ptrT?nwnizU3JoUNq{I_Y~hse7-$vG2-< z6!bNr0Hj+U>DT2UeOPdSlrZs@oK*iMUkkrgK)=C>c`A{pieLj<>WT>V;Sy%wwSG~8 zxrTA!Nc+}fXWOSg^Kkph*Pdukvi5Nfe5X}14>c%KQMkwz?_S6E(lFWt*h)0OmT@rt z{U{eCFv=0>y^h>Lz(pZ<}8=b@mPXsuWgEH!o8}Q*DVZw;3a?o97R?ZQCZEk`OF`PuvK6hgfcADE1`bzipAg>o+oVXJ2_afwa zv|W#eX+7-)YqPzoA@gg-Up3)8;#%nEP#T zT2L>394AdWOnzyYEcWbr+g_`qcxh1m(xBp{^zzCC=qA`QAAa9Nq8AZ#cLUh73j=7+ zaOiLmVRu~oj66rUFq&yujmrcyG4*47g%@7CktvQ0$_S9h%pbXnmkCzpk_#NA&oOdq z7qT&R?8st!)0^&U|NZ~?_c;;Z5}Su^9kYn&MVsW2?#M+mA3`)CvC}CP=9S6ofT(~1 z_BZ~bFm^A_DVY7JyveVu1iGPN20dTJgGj zdSQ)o(Rnbvvp}vBcq3+>BGC1|DfSvbw3w8;tPf#l(*QoYl;N7Jg!$#k0r|t?{0cle zf!w_8ww3lPzx{l3`kdQ@l zzvkm*C=XnyiJb5#9jA8OFoq3%D|Gt;UlTohrk#E2blYM9{^}2~F|Icr?kA38!_S~}@9MS20wJgT7*trh>b3Zad zpS3vXovq11g>+gv?Z}EAXh;}8+7V{$^37e+Ix&ImFy$sPxaM$i^~ib7z!6q{?VV=e z8t=CeKX0>AU&gR<^BV_o-Il-Bk`*q3(5i8p2RS z*w4=2VcO_Hu4Z`kt6z>1!jH5ce9I5C{oL{G;;+gB-c@L}KA^)$lMV}w9K_&H7&iG= z5EL6982U$XNqMI=Fx2PP`HSsypZ-ky&42lu?eT9s(Ka}`^&&BUnaULhWzQN)w8)Ygnh;M@pR~4A7 zyRn&7N(i+v;wx1eY}@SlLV9ZIR`A zHn8>|jv~Se@8pA=fN+@p=}m9Gt^Ly9ct^YaZseMA=@#z~6_av$6=S#sk7n}K#Cxeq zt8n*sl@V?%7i`@$5M+-q;__vGI-KIAN$eOh zj&VGr62MSGu)u*;(3#k)gdkq<$XEN->do+6!=%Rn)-=O}c8eAqJybeCI;X{Vf+M&N zXQh~_h=ir=%LncAiKopDWyD0Sk(5`t|e^&?5<;e>+!;%l{q&xUWF z9zML;e&Pf7wfDXMmF?Iu4pe8ZyTD0r;R*HUdnzXYsZdNK+fTYE@n%kpd;udLA_5ZV zxSDs}Ht)uqZa{r_EDrI$zlwoa*1dkhVK#R0YqX6~Xz3^=gsPLVaqY;RH#uoL zZr;IO%@8`ULL78u7>1pG0)pKHXO9&!0AkFrh62GipIB?3_{gPikC2-Heuls# ztsV^?8KZ091W>sZr(e-;Fo#`Xe6?TMm@a<~d`ZpE#6Q6<<|uur`{O|*DvCuBL6#{q zlrQk`z^Q1y|In?xSf3IGkCc&+=#P(m27gj&=B{I$LJ?k?j~+dMOf&ytKJA>-s~NVH zZ$Rt)JatpT+uI%wj=i_3>O&1JQH z_6y%^pI4EJ6E@C6*99c?G<>9GkPYKQ%0kViK6RH|QIb>wZ3a@vnFkq5IT-_!`!UA5 zcXKMjkG=Wc_O>^CU)#6swMneGAcQI!oZ+N{lb&$EeDfry9Gp4tywbj}`bVd#nfppE zr0BNKRLKVQc^>;-<=ouEa(-36aBYVQgqC&W8cMM>g6Vw1uPi z)Uj(s6_z?9-@Kowo2m~Zfe4URcU0)iXL!Z*x|+m0zK#KaEW0Vr4xfn!=GZ1NT@NhF zJVsbaSEV0$58n*yNInnfuEN*pB5WsyE5NS^=ww|HJ_4>6KhJrj_}C_C3O zqq_HmA?-Ee_e``i@P+VBsktWk*Nogr$IbdIw{2`U{nISxZX^=V+>aXsc~|a{@eHmb zpZO=SS4%qqxrS53bIOB%?oGOBp5}GSyqFw-yYO@eTakz1pYncpuEGqs-Ep`4-$f2k zDH*|Bt8%WH{h#le%UBl~&-$@_Umu&?Qbf3>(99!mDI&~yakH+M@(XM}FyFgWHN<(| zz0Tf9Zz6Pe&U?Om0NOL0eEM8vM~;D|0~l$9(M-!)Fgx+mZzRpY=_2nGPPZ^wtRrT> zU-dK5wBtVD<_3$SF8Urny43ExW2OC1|MRc5JMLl9eFvKA7oKY?hdH7GcyGfucU}nJ02$bfiVagvLJ10CZ{eM^0x(jDk5xe zuEJNA*4Os6PkiVL?H~VdzuBHUx!%rSVzSI+e2q!{I=ECs*kHE7`VFbo=C_=+v6=$^ z|Lnc#x24B*pI3JtdO%|&CIS$^0i;Ay;vk8VEK$^KTbASuR-8Dp5-0hR#A{_(D=Q!J zk7OlY863xwhiI@OiLzu_l0}FTNdW{W3?$~U8;zdsd~crTx8FMF+|%cF0}YT|F}v=4 z&s)Q;UAuPe8s4g1RUyuSvLCtyBUNQ;06pRA)|qcV=(`EpVo~?XBwZl*f}P-e$qmA# ze3fjm^92ZZ7_BfF<=xIVA75xc^T`jk|L7NghL8(ng8LA;%h4oD;e(SmDAPV^>&#Wk z*GUX#9C**ONS!Miyt=^2CMG|e1kcVo-p>EX2NyWq32FE|ix7JoOhhojs_~s&O%m#4 zIb}3YL{CIGK+a22gAL_*Yj(5FI`pndyj2~piJ_ST+%c^d)xwb z!vse^>b-l7-_kw_JPsj&IGmjFXnuJN)3V@bUizTJvKX7BPH<6@*2p6#aYHV&DMj#~ zKPQt?Zz+$xO%zWEw+!7qdg&4;st{+1>rJ+q1e%|xoTxH897*jW>>8`Bo``Vn^k)0x zKR{9EpMR!3{~QzSRD=sCBV6R(Pv+ROu(`*~or@ljo*bDgpPEd9PSSVMML&%+2Zo=@ zhUH%&0q`dQg9{V|AD|HkKq+f|!B_10B4S2ye?X50ji(03lcIq+fA?n)RIR;xT-xK;n>K5pY<8!yz@{`q|Ir>%y@Ts zNfdKHiCGtzXnp3fC);oQlV5LNedMvW!35$K$GfVCa1L2;k}r$my!(WB6t`eTCg*ua z4wQ{i`B)=*iI`w7f9-<-xPy=L6dM49VJ$3>Pd+sMhTlZA$%=dMv)|~8VS!J%2&eLa zyr;bs2CTGrDCAHEDh60-s0S(rSWeMzqJrQ6oWLd5R8sZyn(fS~Qd8|j$ zrOM(O4%heGb*v(ecS5f&p^Sk1-hbb*_Va)9yV?WqMxk#VB{fefaCiZn3oXm5Uv+a15mcy*Ql*(oGQ?4Vf$>MKd9WiC7f&ynbe^U?!vux6NGIf)Zimw^0C>Ph{UZ<9 z>r@2#0#8LCe%ebQgmD+Y$_3U(uh7B~n3D63Fcne6c-I1?vF(d}%X`}^o3JdXh8H;O zw@gL%WFBQyc-CuK@!M2PL)h#-r#(=1RQ{c(%_EWU$~4CHN*bZU?( zrAMWwt%Hm#(4SHWZH3FU2T3pr29Mw=*XS4TJ%EeHrlyM^Eo{s3Y(6v zcs$)>M2zVS^V-=vejD1{+^8GGZG#ce~R8Fp!UR_1)w2^PwjrGA1y;$O~OQy3_5CKl5Ds{9~`NV9dSu zw0jrffnQc$(d7vmyNtnF0HH^I@t?i%~pv_n!QfK@4tNLBFB4fO%Ly_$Jnjcq(P*lX?geZ*INTr z!D6XUJ;ug5;GdzF8Om6`FWO#WY>OOYzw*lKEUaH>x7~V-Q(}(iGb#X;c&wuznb1*( zm_^rES9vml8rWu8+MFT%HvZERv z^K4EXe|s9je*5ZUFVha}xBKq9v7JH*J_;VlORmEs$$U>+X5h&8hkPWi{Im`5`URD5 zs_iy4!UUi6DPa#R_UFmlxU35wkQo0AsS;K3?#cWU*Z-FMp!?VaRrnQ!|G z=gznD7q;3(6k^Zw?Xaypfm7MtMvkll$+CRI_^Ni_RP5UvmGf2x5{^IL^(8Cv>>@I2 zA3ns*dx&G6fK0DwpGVt}lSa(b0Ph@6no<)U%*ZMXkKp~cYEl74c0x&yVOw6%Lg*_@ z_sb$`MIC;j$Hd1`MxhI%* zM{!d4j46)-_y+l3KM~;@#Mo~(+M_zLZ#EsX(wpo^XNIT6Iij_;{qOzx0X z5y4NY6C8PW)|d+b{JL(<8!i^+ao4kq}u7ndqo5D)2Aux>#d zL|~b2SaAonASS14z&nbsH^zBG7q;j95LXcaK4zz;XD(7;?h=`w^MjS+0+~E)yDROH zhn{Hv2t|Y^o_wuc;$!_16ApeHM-hQ9m2Ex}>!bN{MFdHebSJ!>Og#KyLwcQXVMe)- z(#wrp?k3Ta*X~pEQ-L6n&h@-W*Im2HBl8vHy(aYC;k&}b%G!dvU*_8nee^rpfA-6N zlerakz9UPG$)+S}L>H}jyv9Jklr6|S4MC(%hPl(I?q$Wz1o;Af*;NRM`*w(KWdN0v zRmz9E3N^wgPnJjST@IHl7s>~|shCh(&zKPbL2;2x5*E9YiXxUy-k|}Tbn26-A{h-l zj9^lZv`C+67k2hzhm8HRm$;JQLc7Ry4BJd9*{QFwFnIjNlWpPD@ixcepn0q-KA4ys zCcCm2XsW@VBu#nBsE8nqvy2p8#aL+6Df!{9XWM}V7Cjw2IN8)?J*g`IK}k(9|NJ=F z?!=LGM@6IsCj!Ceq^HNX%kE7T5%^nMqiq3xhq5vLJn$D$%2-|^|4!mE32wWyD6dgA z*u1dczWDG{?N|TtAG7NZB@QMr&+ja@OB0F+J1iVIFp^YB^QlQ6?c{-k%1`3QF!97o zI*PqQm5ID`hws2l*Py~3uyIsDF-bXzjok?t`6WsPh9^U`(35ru9DO3tFhQlO!gP=Z zZp&+I#9DqCI0_#aWRY?nJ@{F*R6tM}!TC;~RaW}enD|{~XP3|V+G2b6d+u#N@*^K_ z55E6hS=_erE2jr2kL22sq&Vbvs3T)~v_YTsy0_V}>y~b74-a);8hLXSv3j-c7W?89tkW&nBvk5$>8LX`@w-xHt8j1%eZaCgf(3aeI^9|hBep5Sj z(+%y$TTY>bz;0$1Yo$7El*)QGN@+9Xv+brkux#N3ZxyW1n(%2e6apE->4b?$XgR7oPedU*($P0vA(jA(W(30#ffH&A7xZ*0CID zudrU+#w@!fsJ&ceuM!s~h3k)A8r~hRPUYk>lgaDCSy&4qG>B@DwS*1v55rxC@iLE& zqrcO40F^o*P7qF#)^iy-CU_*b6Hvk{7L)PtDl_Fj8-_6v0fvq8147;XG28_fyJK4g zC04un@H7O6nM>GnItakal=~X1G3&_oUAM2cpJB1^BOkkq6A?I(L;2>IX-^*T)D{=m zybd8)<#EOvE+*LKSTB)P7c(dy8a8P14V(s=Y=_eqDwH-X^iv0nH&m+gJ*R)_3vk1G zw1_JXlZ4*7_Q-LI>FF;wly&PQIK@jpT%8&84+2$XB%&E6Wcnka6`t2%hqB5_;BfGk zr%{fgVVQ%;mIS%68do@eQB)v&-m!q=ks)3cqz>C`>z;fy96UTKU8K$g-fZEPfA}Y* zl)JPR&y>&P&w6Nn^CY=qPe=j+e;5Cvd`dc=@{;Q%OgC|fDlBfFWIsQY`bhXlBeWR6 zlNUeIiccAB`hkadE`mu?ym*Ow3_Zj$eA*C{9Gf=Sji#+|6&;1EB1RNOIDi*Wx#}ip z3W*$(|1QAoa_9Q~zNg)AqSnHCdz~H6kA3B-_VA<6w@1JDN;`Mn6Kgh66r;`LNc~;L zOFOiwzW0!SPfEy+Ur?&d=OVUB2FWsh#akE3@X0@(m{LTrZ7p};ler=|Zs<&zme--* z?%&@Ac7Bli;!|RPsgf9#K`f!LP#TS(9&GP>{|Uy$^pDHZLnPV(64A93)m-SZRdgw&v<3VW4GooXWeJSZZRLWMHIV)3QL_UXTPp*{5ItL-%7uk2z6 zXPwyR_k(@CeYLyZZFe_mN;hSA@a2V7UbA_e_I!@-!etZ@_E1)zYwy1ARQu?M-q}9z z-jkeiun|AMKOzj4Io^>5UIYqNKU!v) z0j9^90ujFp>mp9OPg*-D<*IOb4CMh&mV(*iSfPVRdE+e;x{;XBN1E7OoTeJLB@_`B z;0u#4DG$F3lM#S6&Y;AOGQu9pEz8t9&X(XClgOPH18(t+`Y#hfo@>5jjAUOCpIUpCwLr3>Xd;sBh81JP9Z z;hP*KgqKl{`ob5VYma>Cx%SkH7uq?L0=9^=iR^3;(L)m)zxh3B>HD^MNqc9O`0M3u znM+$e@Ca_G)Up5;W$GmPxq*SQ{PF6PMHC~phIy5+3wX{rVWWpF1lMu0LBtLxtV=6V zDU75GLZn5ygz;U*_JsKyu%xZTGvNU5595pUi}=&0orM z@Gc=zkSgcm+;{Ad2E_RKPvDWR_zYnLcXz?rhEMtw@Z~=G7w(EzaFy)k(A}pvdN|FB z`PP5OXCWr7v#lcbARM>&Y~`->mrhO~OvYB=1(J zH(~ntz$l%rqoPm3PQz5HN2fiRFYVJZ+~<@gGdLN?^x~dMViM*}X8lkWsx3dv19A5} zryZI~dlEs1)9-40oQ(JFY9I5fmtcQSafJGE1-1wHYT;8DuRGrk4p3YfdL2=0S5LxH z`}Qq4+lW4QY+bmnh;Vg@IRtV2M1(`^cvFtI(ow#tgsuU2+%e3KTtn|`ZgplOeG|UZ zDbH-e0GjDfIu7oq!{Vkv=>EfZ2X0dvr`W^w((Yh0@4@ZId2f{CKfu&P4Ij4)EEX~$ zvdG6$Hc0T1v%sivotfa1>}>zppZjS05B|{|%c;j} zpj2DJ1uM$5jJ(XrsC@l^mRjCYosU8UGYepYUxk4z`D0SJe{MOfLDcSSKRDPqpW{?|u$N zgl8T*(|+}T|K0ZKPe0W*2So%=MA#wCEt2Wl`>I&@0WA+|5I;#qeYiVmIyMZSJDG!L zA5f2B$`%%Yx0^(ZkaQm=V9btA60g!2-tbvP1pP|ZP#QoM{8JHObz!G*)qH#Z12?t* z;y?X`cKfaD$UVu{i@i&fBMaZ`jLBqM76V8jNWdolk|^cwggFyH3)!8=1h{S%@Lbe? z{q=Lm<|>PJ>{wFi0ELBJjt^Ic=H0E&Eok6~0nugBZ2uA`0K9m%ZJxc@wwMHRL1djp!}Xg^ zwng6a>>Alm{;WStOoGdNfG~d!05pnUnUSTO&{u6h4}X(yX8Pp+Hm4Doz7zaQoX(I* zcz9O}j^eazcqMr)@&FpiPZSYgNbR)8&CZ)mCcoXqvqX7pT-wM2z}ng>JGZGLq~l;l zrG;e`pPUd^=C^?J7)_bSqT}4&a(m&K*W0iB%Ad5qeE8+|Iu+vl_7chn8;yez>a-Aq z-U(ago2p!RJI&MG%2O{*Ga&g@FDN%lzP;8X+^5pKNkIHw_eZ~MNFf0+A{Z)ginw5HyeBPSSBd7uamM?fWbAi9{0 zj7TVOF7#2}$*VGLpON-mS=S$YxKpo!OQo0vln>5wYRn(CfBoD4Dp#6pq11DRyRgr? ztCI=QC?hZ-zk@uvC{T(BkV*R1JLyX26a4!s zALN7s+ej6fXn*2|U4{)$`ow{OnM6&SV}2;FDliiR-dy9Cj);7^SZO)qn_Z10vpB!n z&T~4lDRP|7njNF!Anm^>-i7e5(}^imT*$$fF&a+3Zj11a8|S zTZFi=+rBx(RQblSrA>z?BDez?J*jq#w(HhY%k4-0%3bZpe*8UcR7pibv>LZr|#9SwW~!Pb|4 zlGlj$JuPrbwQcVLN8P&!tdfDtybFB4Dbr`!!T#{WFSajy;mP*QGcUJSPhX^6WjqJG zSL0lwo!w#Olc8FayeKAkU|mqjtCSH48p_kMDcP1$rX9uAl&kLIbLCCC2X_c3(C}hd zIfmcv*WaB-@_7snvYzjewWnB!44y29xb-ub0Bdz*2B)>&qBp0kRq~yyz207H{I1#}U4{RiI_<&ggkIDl3;8GzWCwCy9(r;B9bqrdGTPFw6dQlfjF^3EV zkZ^FgTV7mq;PeUz(+W@g)dIMR)pIbxg=jiwh~dG^NfaOcMkB{bTMpoIPGKKDsZ@3X#R8AhXNb~n zKDpQ)c;^l6$A0MEcF&!j+QfGR-vCP}l-W)lpbg<^3iFgrno70vNtY(4@)Ak4Z8E`1 zFP6z4%EA0x(a4u0jBQO_o5CVH`B&!B-iXu3@s>>PrsEpDvGfWKd`L+ca>RR=utiR^ zT0jZGg?zuQmQXgGp@qA~+d z%LjVFlXlJeOdQK5d0>o5GZMRHmHH>MLL?aiRwV?lpWJi6B`%o1Xy2v`*_COa+0zgx zRS)4HtySdnI0{j%J@SR8+n;^*$@c8a7rA1OaUL?x@QyM2BBvqn4N7#|+OaYMe8ErN z6iuBN${jd!SdTO;Wjw7SucwB22Bme|Ufo#2nVo$&wvUq09`JjPDR~x}Cv#j3RHayP zdfIvOBOS7~`(uq!3Bx(E_~Rq*kPe?U<;f)@P`@dDUG?jBLN2|N?tZ_3*9)_Ks= z>i&+wuVgx$FdfI0;J@9&#{BAh?e8hhAQM+B-m8UAVZ82qJ2*gb*<)U%T3jI|OYPgY zrRx+20AL}gacbwz|(TzO-DZ%2pu#!`CoP~(nac3g)11RT*>%#QN5`c9`j zvk3!erazSUtvVeRHw{Af@87et@>;Nk!|{^t4(~*7#!!rcZJZMpKPNk!hGkNb^q2TJ zT4plB<)#H@D%Uu!dwq3|qbl!i|K0!aciM>?`D|QdF`1q1?p9~{B)dP{vDVYVlh`8H zHk63W!99_aq9+jj2OJ^1C@c+7cUzcSk%@Eo7)xf-&5$2MO+b(#(ZCLN{IYlw6yg{L z4g+jlqpvRU_z^YWllMfa>17ijq`vrd1S*ppd;~A>Rh|@`gms3`ML6b1c9?LU<3xl- zjuhTwGG=aPrJa9eul>fa{$cwUzwtSCg4T%$o6HWXh~OllI|le(=XvXj2qE-{pU^vm zCCA0m5pTF+$B()v0~tBL(gs9QqG6T@^CQ(c5}GSw-Ad1RewFYM+V+IXBsNEvHSJj)Ru zA47O+oDiAMggOo<=-n{`pu3)SI1Y0AJd;PSoMV#G)ijUZTy4itLRh`=1QSdw!VeQe z5S_{1pml;hi}lEoGv<0$^0CyU1J;p|qNB_}=n=tLlp(7-O!~%(( z5gNh(NEwm~FF^0xNvT@*bO#EP+~n8Ex^<3W-PqX3E*g)6UxYuV<4$&2eBAq|LEx?x z6%qD!Sd{TDO)eE(I9P4xUfXHE_UnJ%KK;-$?X?XQ5q6hRNZ4qXC@&Wzos6#q3hYB3 zEjcH&blW269=8nSYY6N8NWt~ku)F6u@%YKR!Y81DvqGzgM)oks6uUpM_@6F`;KFlg zg+}4F!~FxXa0F-sCt&>fi6X)Tz0&RzrI2n%hLocyA|PkRSz+RF5k(>EwbuZw(!O_P zgf&k?U}x5S_ukQd>Sunez4yKMlMs`~$ZKYeiSJ@Fk{`~<;X0MW91V{=1}>Dkz~O?G zji8kYTHIx8e5Nviq0JBm|LitEkZfn&rMQDa%fo;A+4ejC{QqsIpMI%rp1Ii0up{p* zJ3+Uih`G7_!2nB7%w`i%h_;sT9J*^t=iQD1qE? z!!eEkKH1)R*DdY#JKoXmy8F&{5@m$BTvszB4!$h(rK7hroTzj`p>pWHGtQF0P1{Jr zJLjx^dKVQxY#XhYw1vX=b}e?mIgqplpR(RB= zQ|XLyQTb?_$CDCNMtJ`D*V+@0ztEoNuJc!3xxlp!T=8(hwwiGWcpCvu~4f!A_MrXAR@(D8pn56+UF)M!so5Ds1r?SO*24?THerZxg_km>>F?f-jMAv2M;MA?Io4&lw_AlL zxWqRVZ-ijVe;jKB5oS(uW*{*<5MJC?DJ8^ZBt}){dz#ZWuKqLLmL;`ptQk)`bV5RxRpWC)agww+IX!L1ltCtZdvy@b{oYy zm-}p6UGNpZNYZu?f+N2(e+cSzduF(drG1g-%0&7;3F{^Sq(FGjc7QDa!-${u&hP;y z3Jht_RIsppVi)hAU?C6o$w!o*u**#u5jix^$&2~3t*N|L7%*X2@vwhGm}EDTN(bh} z$7AUuyX4U;7+h3~l7va*uihqGr&W+8@}xXylID;=PqUna1A}Nt>fmLXRVo&drfN;u zBgli*SFcGEUV%5N@p|2?@QIuTK!QmaqT;kHjK@1=MSR#tyNFELo=T{Fsq#fZ?xWf1k*~DRe)h5U-1BES9bvC+FvQwKabfR(WndO`H)(@CafZ==gr)u7A#J2F zZLei1?;~fDMG93GRaSaPrQw|~!X*FtVb>ha@6mq6n+i{Aoi!jTYhmvY`VH)fSKRsu z&3{S^06FASBafpM5!`LQ3Qt$Kis6=1OYNtA;(_*qKX51CEhr+OSnZWakuh^^{@|Sp zv??O(xmZsB?Fj=}K$ju>*OhPz6TD+bdrk|Z&r(6a1?0#WvV5RI9ZDiD>;?w-Y8%bf zU?_LP?E4(2do5Fxv(4OKR7CJpvM3@X9q@ollNYcm9611)V=S0~2Xvb+75Ww!f7r+= z7mnB3!twUy$IrJ<{qd9Si5K{$!G8n1Ik}H_PX0sw_E2u|vH;ZRkyGXfq$y>PSK0&h zEcrsLlNSm0BrcU-y>jY^Z+{*imyyB@d=(dU|m{VlHHfo8vl*g>z>l&4O}FXhXo z)M2IHM3#5HLrhT9gL4I0ig*fzSM5k&C>oOPB#hpoG;9d( zbs=RDKgyjPEx-pA@3*aU@MDG3@>aPXZJv{_%+C&|NS!-|2oqstxgMlgJCi@|$cV zCFmnKrt?jb>#@`;RJS7Sbz`aXWLWnCJhH4(XK5cj@Z4BA002M$NklNDX*FV$W1%&?y{Y8DTJ|%5GN%43Z%Y zSs&BiIP- z-CkI_D~R9pPhxj+rehO$HS9x8n2z~PaVy(ZliqxCJ3&zjaa5SHUGoD+L0s-HJw5#^j(LgdnEWUcx?%iuJs-o{E)KFIo%tJw+73_Fr{J4N zF765NZtdxH_qD#|gC=8-2_z{mf_fV{5meTJ#xWPK0DD>FZ(onjZzZ8je^2pbLO!QL zM$QQ_8Tnnee1kbaaiyI0U^*;r8ielOza3`fwO|W}V;0>V-fzV; z$_&JOCrlVSQ6IjD^j}8B+uaK;54(H8J9)i3{JwjSxBu~f`sH@#ecsW!!3WeflP+lO z&#m&2S|5Jn4qNPFSGN~`Dy%Y8c7I1U(u^x_DRQ!S7yvp-oUl8v3hnxK<`d7qKG@Ye zAEM$5PCc~yFTPm$Ed(`~s}%L~b1z?HLjt9Qfd9l-S_aoF?5Kz!Mvva~2+0L^eKXmz z!=0E;JTI}u&z&=En~&m)EA0<|=X32J{lhA@hyP4rtDI)B& zTiEgP$sc~O{q0};2_{20K5@;-G#162m(N716R1T+O?;am4_`|zFge-dwF}878DI1Y z1{PI!*s1v93oo_jo_Ri<CZ*3wgzpAi4>QQbO@j9n?Oyr=6s9st{V}VSHyXMSn82&w{v*i+%gZ&XX*p{O&*ft@iYno@`rD zMA&Puv5>NbOl`9Yz0EuKV8b)7XmI}2$wsF#m5WSl%ItyRLu(ngaxyZ5^^o5XSoOP5 zL{8wLytcej4(1|m+I#X*{_r20gZMsa>(xC@x~qWTE=ea!RX$k8L;oltka4d=UT1;z zILFDHIJw&1ar=$!o_p_V_uYS2yX&5Jz{=v|kU0F~U)~~U)-UUDO)^^s)= zcuiTUjDXV5fhWTFMhT&$x)unP<60a9Jp5y_97TlD?koMsb0+@>dCQ&I<~eTZfiNm$ zU7u2u*~?~5TJ5mdnbzi+WZywWf`yz*oQCj~FEL^L)o0tY&z$D&^Rw-Bc3_^ru$$8n zDXO0vHulJr?_K_+25&fM2b}~G9juhwzOvJNFH`y^;SVs1q&Ed_9F#ZIPGvuY$ zd3`j6EtV35_!iCzFAs8xsbA^R^!6rhgXGnOe?i5IAJRVT(E|>>d)w9DeSG5E^pe5^ zo*~8fYwtNM$u89KCr-g0N-i0l^q;hkAW2)ihYWHWSn})}X~;uWurbBa17;UB9@UktEc23R~^~* zM%Js(kFt+-j?tatLYCB#Po$K`dM8ipGki~R4xb4_V3#Lhy9~wZ5B!;9AfJg@0Ibgk z(Ck8T5aTELk;Q7r$}Tbj(#Dyuff(Vk=4~XNCF-)u2%ZKOXcKVGgHo;w21EF%S>XcX1E?5i2uBCQ}CnpbkSwBIa8x z)}hQ3F#L30#fc;Q61ZCh2v8uxnGS=`z^M_>lzrv6w=s+|up^t46>G2K2RTB7a_s#& za*GZiyY?5_5C7oZ?GrzIPdj;oy~-ASH1)~0Bs3t))+hTQlnA^wV5EqE{B$0rFSdRu z<9;6yC;bs_=~DLh`F@V#0R5Y%7 zIgwq2Yy7ni=j0Q{9CJJlNODaJI8~2Q5y4Xt>`zly*wz00i+k;N{?%jc;m7HdQFORO zK9mzr?Xx=bksCcj<3l~aJ{U-sLLaM#r#m_F+h>Qp?dTfcMfU4z6y5+W-~Yke+DE_V zJK7z$aWcXp%3rj-izMKw4+kh|*e*x$!E!YoNDiRYc3ZsFfRUCg<0;vTb@;)5h6!K% zG2RSQ#Rp%3aX~-jjw4rMkeKP1^Q7D354f!6vGOxYCosA&2}BkUNUvGkB9pu1ZI!X# z8Yh!=rS<)bo4Mw1^E~4?cAdEZd>KQsI1*&+xFye?+7> zloyo_XdI%Hpq%5j|B&3?Hw2N)kq5l?u+J^8bHc((d*S6v?Xf3bZGZl`r`oeGU2JD_ z9Rufb(cf92)Z0ufPfrl2F&py4pPW&wVt~;-usA%%3qu`1s2mQ{Y=x9X=2|QR z>wxm+*gNu95mF7(mf=p{VKn(CI!w|jYyFbw$Zr7B-A%eX?W>MY}l2tzGB6g+}X!XwuJGwm+wI*o@A z;h6NFvvL^fmg#U7r#}em;1G(-?QA`*Mj59d9ONDZQ7WRlj&WJ zw^yRcrX}-eR|1*}OM5f;^)c@h$jF)T?#Ol6BHg`SD1eve1J8+!T8j_ESc4}3X5g?L zoMpswM9?ho*?u-|m|iv`Alu+s{(4R%T0MfEGjNpm_1_5&D0gML6!iB5kXGP2%(b(xoo?G(7u$*TH5QRhz-)F) zY_U+rr1Kn$fBP%~sfcjELfZZ&6No#<+rxkMwf4XLufN@%dg?qoK1&gSd7ie-Xq~7` z43#26cK5-DP}511e(2WENz<_*jh+oX4~31P5;O^iN1Rh%DSqe&1qm56df?l%B0^)Q z)jT_6N)dtk&KI}ZNsik5;QMcB|M}nhIgWg1aeWP%Spf4hI6DQo&cPItwq=orazbD& zL*EPRimk;UqahD>V9-M(Go7>&l{og&&m{elC})`rIQdQj58VJ zzsOPJTTITeyP2cZ*V)m$i~@o?%ja16%@LWT;H0vX$;y(bJ!0PL3{*r|VYjna8jMT? zd|Y59ck*DiL9z+(nQfHmObRDI{d1Hks-6mpZ5L)CvM9@dlnH;LfE>f5`nu$ zofLG2P;@=6yyRa#f+&+(E@}hoL*ei)rI0!53wx!&wcP&Ar@!9**{^?=oml7FS+6gl zOg2#Vaq`oh`8g^|+9Y{+XF^MRPg@#IVgjc3BgUx^UceNQzDK^q8xZRmJm4$f;n#pN zZ;K)VsCrvw0x8G-Hq6vTg zK1v8n?bM02_8s@#*}k7E8NT~_KF}699@fU)JA^$=WS1*DJPI}Ksq&M$;&he|d>RN3 ze_ZTKyFFg~Q@-|lsETB1jda)MHyyq=j>X(u7_yB>+->$X$*w9c)7ouf9XL^H=u6 z?cy~^Jndk_cLH6E>pRgrg<_e0z`nGfh~Qd6b_BBM;chPVj#NUp<<{fvo%i0>?)#2A zIQ`%qD2Lq8mXC1pqyP`fp3*J%$l^ z=csaFNF^wprmZO3<;$58Sohe)?zb zZy)^d%_t$zhcL$4OMAl7lnX5+lC+|PU|U2gDnLdVVMrN!7IZBD$jz?rv_V|=u#I9M zN>N_XpaO!*2*%0+pSXrGzB8tenbl{eU<}-QljlYP6i@`E!7lW`l9nCjr9ly9B zyVz+UqO9Dbo%i&XbU(@&{*iYqX*(;0{DNxWxA^q}H*i`LM*Q@(ogZQwa0bETPcOJ3 z&p~3ijLu`<91lH*^x~m&1TGJC$0RKsJZ6Zur_FS`i`LSqLZ{cA`Q4E!heGfHS265! z&DELLw%ZrK_zb5bJkg$b@}>6bnN7YoY)kEFCHW9cW`x|*ED?SyY6W3xtB4I2lsQ`-YV@Fi4ouIQg4iyLL?b7YMCr}zkrPy z|79e^e||8RwT}gqUm-f&g!jlA(#;sgF<#ms%LlvVVWtfhE@tYTn1kO)_D7&qX3C6N z@I-_?$ATv~5#c0C>wYih2?_hDQojJGD9)9%s_7{Ko zTzlq46ey6*ZLaRvB!d^|`?hGGxBZSo&h~6<(2lWnsmHPyKe8!(RQJSP*+7PYlzd6c z7f1qV1C3z$m`7k7*D7a|rq|I?y(F;s)}bg2d?FV^z~S(MKj1{rf(m5v(A^zE#9cN* z;*i81N*O9)RL;dtMljmULNYqIdBxv%4~Rl!dCdHkpB;7@AiSR9i7+ECq8htQ_w8?e z)((r=!Ep5^|2^B8D1 zx-ecL^5yN+82D0V{HNG#o88T2usz`Vd&Gh9n4uS1e~&=QqTEb* zO*^j^J`I1}{Wfrb;z~PzM6q2x1xxMQx8!Uit}7y3T}qCGxUPtBBx|l3kOA;jp}sW$ zQ2|M)-o;r7#i<3k+b&MsNjNcWi4 zP!WOeJ>oIRFflYMGK(7RcGdCAV5YLvF|^uo?XJv;`XyPYe(jb);{il@gw1cM-1pISCai1BW*;ofLfKWsVQu zINwgNd-%qaC-GvJh>8fTu6TXx0g4EVEJV$-Siir;7dVOtPk-ff`v?E?zu->S7utp= zA~4zFe2dpIFz4hHbtZ?LpOPPbyo|^*X&m}FximKBVeGnEotXqqv@RS23S}bbNywnl z1OFx!5u8<+BX4u;$Z~#bm6?*&h0V5(AU$x;di&*H`pNeG_um5ocDXQD;QfZ~iq33A zQjm{6CZZC8Wmazm)l(2^5y5gV*t(zC1&5kwdGw24ZlC$H&t-z;J@0vd`|WRJVQ;Oi zA6sQo&E5A*IA(FcT)6PY)En|Hck9zo84j1@c7Y&rR22ofNPA=_mNP*V)Z9gmJb#_t zlRP`@SlRLzaSCCc>ljvUJjQhl$J^rCawh+B>VOg?KXbe;c`tEUv z3sFxdP4|)A-Qh$8*{O2DJ`2f9oKPXc9B++sg*0Vns=VQm2R?U2*05 zl1ILDrv1u4{d9Zu>#w#mn~NwRaB>JRb#yIhz$fQ-B~4>CbUVp1Za zhEY!lTVbMk8D#`_;;(Ze0{_?#XtUPZZMWReKKhXlwD14^kG30cIfZ~yAE-C`J09uJ zLZB0(wg6!aVJe?F1<1r=S|ZA)l)fa=2{vG(xIlYn`%U`p`f}oWfrXO!EC@mXvbLXz zSohP}M)EMZe(w3x?V;cMqxR`f{c*ea^6TyN#hrGBwe&4yZp#x9m<3k}!Mln}5yAK+ zuSAbLNMY#p1>Vv9+ugf_K&ZeMFdPq`h{@9Hog1mP!UZsRpln{=w1#^w_=5M~~7^ffH*53V|yW2hY-O+C3I)*tEMA$+| z7MK{eQzij(J*o;}|lf9#p|#fM*QkALYR3JK@hnX{L&ThrsIw}5eHZ|?kM8Cz`TD#!fdic*s4 zkZ}5S--Js?-r9M3Hb?Em;Lj^2a!ej4C&6l*Q1R2A3|SYSroRVHz*jk6zCCQ@R%nbf zg(IG%E4^1Up#h-&o}@2@1daiHP}zz}rF3a@8{XTR^20q9Pyd)H|4G~(qzJDvHkpxl zXdfQOo>YaA5`vN;JA_??A>JmQt_TI$1>_=%2*}8B>ecb33+;|mEA2;r^v?F9KY1Sm zR%ChE_JEwxKY43_0)PN{la$L0wE-L(Z`j3hTjtNPPxAm`Zhu<>mYDQWW z3>YOZHIw|^cRWD@V;d9zWj~!Gd5geTc}u6sRof;GnQwWB72HIxRn77bu<$$v=ALm1 zD923eI|z*Zy!7=2)sz9@@|OV07<|$nw^r;THQ8APcySGEN?)d6*uRAa2^AfA+@Vd& z$vU*NIT~Nm#U1*1fy-n}GKP2AizZ4VbyYw6(ymMvIWcD9i=ms2NH=yA_VU)-$Gmo- z249yO0t^gD*$Z4=S{{{x1t7h{+xQB0k{s;tAnt4prX5$bQ7$+@Dfj?Ig!$!DypOf7 zeEIqI(4T#=efcZTx94AAcRN?(M2QR7EtE(_>5k`j1(gCm(4|F3> zLzw)st<2bcEwGJ51WU?%-XeGGbJPBue?Ey#h*Qoye6m@aMl_{*8>*!I{|PT~ohhDXs|y z{kF@t4`jiSo{9+bT#>fGxbT3o_Vk%Wl?DJiKsn%mO$(kv=eJiny8*fK5Cc70LzA?{ zU4c<3Qcg&20o?f>C47ijFXa#AJFnSO77bOV>=UZ59NW6uC9Y%OiY@xRO~$i3T-#_Xsn(MihHhZ=mfGnj9{5*^B~zBV z4=U1p1E|md-+0XXJhH==Bq5yMIp_Cf!SV{KYUi;Jo!_W^52UFSA5+m1Lng&{%J|KM4&qMzedly9L{e15r5gYu;JvCIZMK}3i+yHTXNQe^j=d{4rT z@-YEmE{5tf;XCkls2r6~bD`<)a!JkMG`jyd@3Yb^sERpocO3Ce*n(l2q#mC@Mf@mZ zv_Wi-0{MpemlR!F5_^N){2mw?t zn^A;8m=F2SAal&c88}ABu3I_>x-675=zE0ZPsnGFJN=$f9Md4z-ETJsC@%Z_ql)e7 z$)(0#9qivy2-}nEiU@C^aNiC^gvpNOEs%0O>f6YHbfi~k(Q9CPL}&3f(s2~3>6B-Z z3eYV7QIj_ynS`kYuJItI!Wa@wCpZumT>NC%G^FQPMSll^jr;qPmI_wW7HwtAeS6<7USa$h?!81*~%BEG{$pTXBe2m5G16hC8_ z5gv$(jmb85&iV=Lrv33m>H*UryLD|gvR>MkGN z#&rV5h4+0a`h%~ui|qE?=A+!j6_331L%k?ZvXBt{2&VkAA#=|;R7W*?_!wgQm#gqiX@IhrfDbtCg7rz z?kpq(M!V$-oC^&2Il<|1?Jqq4VteVOS2%|DwcuS}TjPoYr5QP50@rIBZoTD}cJkzL z)=15~9CZ4JML8B|U3|>~7Q}hXyE}IK!miUC9ur;4C`4o8?x;6T7?M9HKk&uB@|-(IWrg{3F$BA;F{_!N4$u6t z-pV^<1O9BGz_3I9S5{XzO~L6GU@#d>cfp9C$OhA`&h94-=pexy6K(o<$4G=pf=5(c z{x&aiMGF&E-rEgpGKuP>pm}maHM^ieu*c=ZTimm)$$}-wcA?d@GSLtEc@|?b`%0eo z_n3g&Uu{o4x6%He-~3E_=#gjItJIH6$QD<}Ga<_~C~-;=!MahoHOGpI?vbCK=1CZS ze8-rjkz?!^J`B#p8SIm<$X$5-=2i9n#oO0>sY~#LfJCAh;LyL`~i;t|B)a5 zf%e`9-)(`A59E)!v&*hvQP4*vgl#7Hw|T4h z<9x1thB6>ISu7dIl(x`FfL=u-e))?Bwvv-_4ZkuR|Kk57zwsq(dXPhV>1&!d+ue`yJL8V zqoev(o|4$psyFQu7SmOH?a?}n_ld7CS#Ld=pXX{T0G3f8aN%m*XYo=yb!@SH-}l|x ze(vYr#|~2Rv%H%&!FFiDqnd5UkR$7eh*3jZOUw;kI+d*<39}`{$T5JJp4^PJpu%5mXGSx|q5W0){dn zL?ZF;~}{CFB5gA||8s8brGReMYYhK2&fSHBLBw;r0IY_Q2beY*lezV$6v zU~H!xS6TP-Wn$Y)yIJX4BRamKCrGS+luViwrQ6^o&TnpNI_eCG1rkD z+tV0e%y;+{<___TKOH700PXMYUul@81u#6~vkx8UF_Q5@SNKNSt}@vd&oTDprWTF5^^K0Qi}Zki;1Kcbf^8Jz3=^?;%(Y z1xNhl6Xibu)<7x0_)#;d>3pl=VVk4fcb$m9DG2mU$Kcrtb#j?_@4R)T{nRJ!ZSQ~I zjVNqxE7IU1cOvACkn!O5O$D%j_G8%v-U3bp!pJ9W$FA)M(Od}1X)Pi&J1#2I&mC|* z(SeKn+VKnB1PN0NCvTA>;^}QU@EB|}rxI}ZsU47#he#yi0G!dt@H|Qeo~q#K4f z+p@Hq4|5E9l_-21Q}D4&dYBOb778YV>9UqvKk_WCSba27+v~OR8~FxB)%!sz!4;)W zVnvsdIM#=J!&w&x6I|WlTblG7ta*dOv?b3X?ctWi9&MJ_>L{r0vGCNFWfa-xJn_VW zQNGN*JRLnF(8iybuml<3l3+tAwC5$IxOwx|?b`l@NNhglvda!kSy-mMN z*{Z|_qM?|cn`aWD@)4fmEf!7QLuSThLfNJTs`^v1Ux_V=HUc=zgI+e5(>p~N@ujEg#uW&eiuUd4 zR2C+4eiXm(ANV>6J!wCLW-{Qq{Ts^xiYB9+ql)gTsata2zNKe-a$OPOszP!!z*|*B znAO=Fo!a$~x03_;=s5!6q;?z6syylxH?!k~jmWe#56>LIX1i>*%4o zhxas|an|{$B+&4Vrv~0c?0&rUb7;S%oieL~4 zZfTn5N&%0r=lhsNJ&rKsDuI9bTc2;g_A8&^K5TZCvzW5M?9L9mJN$6po98$~GR&d( zr0Vo415Ehe2XE~5RHTIL-qk;`W2a(Xz+TmRNg>?NAl|1d<+2He~B3| zam-WxOnbA7QQ2WW4q8_hcGz`2*KRnz&_4Nz54B(T`A?t-AR8~Xg=KOBBl1xqPM)wz z!UuOUk-Xuj!N1bi&BM&r0c99hSWs~C*Svc&!KL#X9P53dz53Fb_S`cswewt?aO=%C zH&0Bs>%QAjs$oKRnetm;cj7!pfwFTsq6YtWSrA|3sL3UcR`$5~MHU9>4QMaGI=E+Ghda*bYCyCFU<9d%vmvW5z@#EfG2@J+bc+=``lZ!EUR38Vw zaB{GxE>b?0xs&ij+;;+ubi-=iufFsu6IBNs>CaUpymz>cV#x_|XEP2Y=>JNcH{tLOIEiS>o{>!12Ud-2>ZcZ+g8!@(L0McdG0 zognWZa5C1UjB4qSOx(W1XBQ9nvrg(x)(Jag2EG_)WbixWPJo_LYlOq0g#te_g(Gz< zamMwg;z^Boa0wSn0LyQ12P)y%eDj!-1=DxdnZ_VHesyMn#06j$?qG23%BMaeGfn`r zsVWn>%Y?7d4lOS2GTF?LxW`x|U)gVW-E~v@_{YDyee7c&=4u)4n3g{N^GKRA-O|+= z+-cT3umf;kFbToRO^6c+w$Y|XF~L5^Jefv47JbAqa;JJ5@`l_z{Lo*t-~P4VYOg%~ z64&4Cwu=|JV;28yICQX0T#}4IZ zyEKoG<@yc;Zh_s{DuxNGGKN&8f3|MZJM4RGxM}f6Pfj?>MZ>8m1W*7~h+e^Br*D4F zpWAOwJoZ}q{GY$rzWnHG?d6xYkO$imF|fOgd~S2K%QmMF?a@i5Js{b=q(z$G$%z`y%M)6w*I2R-B-JY6C{G)6`k zMW$Nh^0qpecB&PD{k?$l$Px>viz*>3usBG7Dt0T>(=`@VSJ&d*=1Sv}_AnLYJ zQFKx-d0YQd2Z?W{svLOZ)IP`fP5hoDgGJ^V8Jvy*=?|lzs=^S8H`YnRj43lTNn@}Y zR9F)(z1AO<%rsV)@KxqvWVvIGpfVt78$gKvytV3`82Q1W(as7^-+?s>7wI8m{s)g~ zAn52ao^)hCz|}nvCQro|TKcMwQjz&6M<^yhyh`vnGWuqZ>M)0GiY&V?OJ00zf^i-IVn-AF+3$M!qr z4=#DYD>(8FIbxBh{G@-uqwmy}Y1PIs2u$AVod_Zuj5y|K$7pfEhpT5s5MU1Yv5#8DwZ`~pb#9aQT)XYWQu~P?y1RYkgLkqxj`F>V%E(oCi!I%V z^uULZLmUTNDh;L#t$c(lV^QEx5dmX87@Z(wL|5{8JQd+!lVj`ow(zQj&?@aR)~FR- z6lIbqKfV)A`r2iHX_HYui~S}E)gW9z31Ml)HVGi;Ffa0S7uxrLS4VJ(Z?;9?RH~Tc zDjY^K?eQlz+Hd{Nm)n=WcD9}0;B+$5+d&q$_E5kFho423$%qWlYY%?j@Grb9O~~^mI)Q)FKS_LG(@xB~OZypE8dQJSMf0%GjThkg0=unIf`V%QPJG5;HdorU6xai{n=9Y1ju)FVuCdt?Gf28^)vavOQP&6cAnf9nZF z{z#zrRUKo`wX)vDqKCcVH*w|7Tc_W4?kF?H9+-nTgFjCOoP(bYQ(TAV8(7-9OxSf<;%nN64^&PZOr`joA}z)ZqAfa&hxeHoq} z4&dZqRk(Tp80^0N0L}+1Jo9@>ckNJia)5~$W?H%;f=BGX>wy#Pzx=QNR(sb6?q!kT zHFkP?H)QQ}p65fj{w7oCJ|@JI%uJxU8-y=Z7e9BIXz;{?EWY#A z$2^3<1EEYNGg-OC#K0nHXAv{Gl#9t#-r8+UpL_Osb^v`XlgxMBbw_*WJ$JP=7Hpku z$g#MgY50NGf!##slZp>MhwXjg#%Uct&hy#q$6%lMz%P?*PJ$R7Su7stHSfYPANEdg zEV4*->HNj^C;#%x?N|SgKVng3qwSzou)$=MiU^zJbC=1LO+MVW{7H>w^5Z81c4?}h(K~Dkuq5^}l2aIds$|Ho&T^2J7Uilue9IFzR@5SuiU=h) z-tD|Z-j_LTV2w$wQ^?7OzU!X$AO7vX+TQVw6=ZCK$&{^3l$%QEl;@^zI!R-AJIRwU z($mXahXj6{9dUtyfQpg;sf?^GarMCt6Dm&9EH19L(=42S_Rk+~&ph=4M~^PGyWV+Q zyY=>)avb`}Q>#q2qFlpi4T~$w94X1-06AJ-=2{2j(p@O-s;~eKwl1}OPC+<0&+a95 zft*JHK(Uk=b4(bmvXHyRX$W4&Fz1n)nM|VWlx1Yvi6mvf49mqTNnZLT3*^bb2#vw; zW+-$^GbPH$Ty_jIA>}m=%AJ#CE6|?fH!1h*d{GX?g^|Ot#g8=l7hMGhW&kBk!mS(p z^)j#BK(bt(AGAwnUyod@tgKRRSuErZ(>W%d6#IR5>hM-k!G)b&${{SG4tNrT_uAGX zK*2ld>I9fsM!SS~3+)`c-#`7i$J?*`#$U8&x##$TCx$R7y36S%<~K*Mlb2d3OflD_ z7AT6nP;cIlp-3wZ{|43*Fk!;?&Z!B1tes8e3!op;$<3H?Lv*1FOuh|P7px23ASn?C zzeA)h`H|xgToG%rzG4_fcynSsn^r_{QO(5)6%iI_H!LG3dR0VF-%2rb64f?#l?CHv zln<6U#(WK(gBx#LZQu2Q``Zuw;K$lK-+5Q$$+XCUi4TwYfv!B}qvuHg%>YQ6PRvGT z@|ITylS|zD(uq8$L`)=^GAt|^$({78i1756zS@5GH-Ec5{^*nK+-o~5M$ffP{I`&M zPeD)-VH5dMDZy4c6UdTDA*U^Lwo_XDCk@M96JLM2T?_PSl#zPpmAqJlp3;yV#?W7+ zR~^f#6ZqK_t;lR9sbO_HwuT}So+=_7^9lww_MJE;@7d|SzR>Qy|F-sl?|x6a?}0np z`f*O1;FK5_3g*1C!2~d}TYJfjcJonTS)3xxF4f5|?bAMeh75qDpxL8;nrA_^pE{yK zk?ooNSqUkL7{|p>IAq-l)=CCD20oWOi`0J-mX6R;c2AEf;pmU%jktsXd2l9y|y59_)M6Mu8-C za_}327Do=n860C6JcxhD9T-~>I5A>e!9*?z5k3z;(qXqUYV(k*1-2M3(-$mqtn#AQ z$>7Iuf`^k_SWsQ#^n>*%QLVL~{%h}QANuee^xY`9QHs_{cLBR7DB>&xj}#GHezdKm zB~>0}pfuViAv;mlQQkSZfB{>L*>FcVWCxFO>9}&p0WWfDUEsfRP5wrT2vh(wt+8%d z&!ULHG7R#$j{=U$L5}YdTe|tPtudV)#>Affk?UOCDU0!#ciUKxW;abqF$<|rjx&gB z{R^)Ly3D8H6UAZF7(osh_|_E>^iS{;%e+$kR82i9>5?MYyZMzIx*fk58GefX)!z!giyR18#p zXvg#PG7ou`M;nlg`+f6BboKe*GP5KcWtb`qoW`rXBn@!|uINwS+3Rd-C5)4K+S7mb z{-JOuE}`ZuJu3=4qJtXvg|AVKPh9UbpID!cvysg#}$#9f;&sAM6%lS; z=d_g%+}wWfWB0Uo-0Zm3Q@rRWB?uD*0ke_}!vo8AsC!93qLqh%4^e2sX&aYEc;izS zV6YkkoQObQhcbeS2>m;6)ZUD^0A9f341clercbQ^UeMtQY>I+?p-OuCIlfq=4aunu zAhEwrc|waP3`P-wZ~crzR7Qv*!b*Gf)%o_jzxS2)&}Uz47dH7$WqiKjFajb~cvLyS zyh=hI$&s4MVrZ2*`=VT>fSkw!$FjQT;gMzGcqxYgz>MQ;G`Q!s<6O~jqJ7VI-Q7;C zG9TdycAUbXs?8eLhFP~9G9)2i(f}^yBs?b1HjaLKRXqSmzVja$1&_}Bz#^g|+t33e z_Mz*wvlrXTTnpy+%FQ<)Yq#($c|{h9LaG@ezr&c9_@a{4zCm3-zGK&|DakKy7x~49 zpAXiIkEPd-Ys(M+1;&gyC5zLvk{5(-2c91|@a1v-MNvySAgMnI91J*2!}?WCi3t&g zw=%Go?_|b|xP5Yh2Z{)uj36JE{jOy0LO$d~NxtLu=$Fo-y!7>#H`=3Leztw}>nMk^ zp<)w!=tuBIv57Q2)e#BF)4$nBBHwBjU5ZaqOqchhnRHLuJB(S-tg`}?-?~Mdn_x$gDRgcrj4)3m&0Fb1;>PWBYO`AC* zUiXv!Zm)tE16P|lc2C+yarB&#Kf_g&oE12VJH#8g#Wk4t&A{8kul814t+Ur^O#ccZ zUuZ2{+w+lun}c&&9!4P7E#GnuT&b-)nz%tqDc@0v_fBOZl4G9h=3Br4iYLAEP)u*0 z0?X~&x9n`Mt}7zEd8rx2xUPsWV#WXOEHm2iQ68?|SvUx|=2mBv&b3;mQ=Zv`N#cwI z^qc&o3Ctv{1Dx(2-m~x&j31nb)2YEL{vC(u2?Jnuc4F6kXqN(Cq^oEFtng9HcW}G= z&eiryzx-3}ul)4K+vdj09EH0WMTG1=W9!AJ!v&A2`&WjyU%#Y1G86V~c3y0vRItD# z%qkz%3+zC57Q+R{U3X=$aOTIVyC#;?sf(8ff|(CVx|LENAd>LR3P52cu$Soq>MLFI%3SrKC_z}oEN(@da3k!lQ;t`BKy|#I%tx9t~eP}lNU9q1eGlGF=f>Hd4P^u-TEg=XB8`KE#A4^2^qlCC$`CQo zD=0*y451-GP7?Fq@htQsk(uQ4SX7T}6yVjDPq(MO{&ai(xfj~&ub*o-a53q7-g95O z>+W~3Fw4FuX2LRoi)<+a&IyGyW-DAwG~c5;A#Z$ zE%Nqw%{~E^MFz^zNk4ZAD+lZA$3Z&~Zvmx{k}=X7Jd!q4@b*bH(vAowF8CImkmKz{ zu>%KXuy$PG?aZ3-c!Y^;h+2>SRhD%5>2HEfD3j~Nk?&6MxfrP3$wIHR*g*k9v`i&3 zVa0B1c?^;6*4ezcY0grQGdYN#CFd?CraPg(>Vj#wDBxsQWm!7dElv0q$F4v6_>1iy z{)+-rwH!-h0~3x1NYn z!W_E*qg+C~v>C;iqP*Lam*Q0zXQuiy&@0V3E|_{>ib(JRUZqnR+Jb>GFvI?f#nAL$ zmLoMPu>b%-07*naRIB|M4>YH#BtI_9x*%n~&3~mk`L4EE6*L#8kTUA7yz*##6qMYO z$q6!ZOPv4h{x|c&0aV%75z>6SGTiBYT{XX9w z{>x`kNO-P2@x-}yj(c0SSx7rzF^Q&#c6l>9@rU(S7?Q&y$L<|PN3;9 z%Dcw5Owcp*Zp3$NB>&CYWZN8aoVW;Z`J)K5y%kbxX5IKTwJY zlpcx*>;)YZ5op8MiMh(DN^5ARo;tPEe)PxgYM=bc_j01h7C4Z7+B+5UYJfsogAxLj zD{T-h3_;aqmJmQEg3uKa;-?}4eV${tI!Q!2p)D-2{Z+OlzTPR1WX4?EPOxZ1MM__s zi~$~D^F)N9zES7gVVe^Xls9Dbs~74@C-4GG_GlOB#~GuTw6s(?&_CkdC(qvIv8WoY&Eovmp5i*FubhkD z{r9c62kyVA-Eae^+(De}blPp(1fHNs-iRJ*BxoS2y9tQb5Twg^!dri|M2yVW@TmOb zxAFqtm|m-4pXT?e-#un_j#YmZ5r*u5No+pA4hTo}Ch|G7YlIsAfP6YewC_ud;H7@+ z4e(~wE?ei!!eeJo|+gZk6Ih6|K!An$=4QSe-T~rZ)5T%31 zHef6lmQ%`V@ROuTgZCj5Iqp6LN^dvjIN9zVmpdmyu5L}*(*#UJlWtG!Jjzsvzwo#N zVVQ7s-)nly%WE~Gm`9Tj>MH~$A6H0yl)x;QA@B<5XT|D%*BGrw&-?AbaR}jrgW46= z^*YysI!mlxS7L34pZO-P?d4lBMaN+z@vDFlZQVJY)*JE%{WP3)H;M>{D)E5*2>3Ue z_B7lqceV4E(=`irmftM0XTeST^>NL#JWRt~cYo_R(97t}Q7}lja@`~LK|pu&&Nt(P z`?~d;!~u#Y~Dx+20`D9!7N2ycOT-{Pn<+VK%ZSMMxn zajt}5gy|b&nQrf9Her%DBYFKU`>2|Pb@bZZ!+RE}9beQGy%5U%kxSat596tK^c)=O-$*ngd+cNQ`CUwN&)dg(%2y7^?g;qKeo!SPkT zzg=8oVnLjK1)5MEeuAF2={SRGrU)d*`9QBlX+ETxSa!nM(+P~b&*HLCCry!;n0VJ@ zLohiz>EyPnz%1V6xL)lNgMS8^lv9)uM2IXp;Ur_Dh~UI2i8?9egooydN6)nX`yc#4 z`}}9W&SXz1BJ8poW`mibZFs5@!WK_`#Frw1BJL!O{AOu5_j`(~f8ci3>UM%=PrZexe94pS5C&Wxy2QK)E|1zQ`C*4X7O!Tw>4v5Di+}6K z+K+zXyMg39ZB9itFYDPXa)K^t|r(dpDeW?z!il8{WC+-gjlW>RP_l z?(q&XoBCckHCs+$xUhH%nU}99YTW7X&Pxpt#*tBOrUvs*|+pRbrT)M7*Wb_j+S-dkZ_N&T}2VNh_X663sJBx@)?W~=+1Ge@MP}f zEEGZq=_7+GVY$RL;PLEBeTE1SQu`tRY(Fesu4s%fw5`0n?|AvMzy5xC=*dInxF?3F zI78AFX(KT}0RBP@5kgG&)7TKUNJ4*PpW9}V%l@SUZb3<8VU3ZWmb1eYm=4g;^iRSC zzDD?4U8(K3!>b@96_KfX{MkW8S`85tl^BB2pX8`?#j@3!e z0a@vdEO#(gGIaLR1a~c4>(XNY1QKcYlOC&_vhl+Qzt1OZzEuwM-Px1JFhtc!+vYNj}ByHJkqkO8xEAqhgN@tiLq~SsLY&PDKEWvto-B?b$ z7^OG?hS8evlNYz)fs<0oUnQc30gA&Anc+p6`iNUk{P>biei`3)QM#UQ&D9GM_|sW*ytY&^M4(+kLyaT7a^1}zZ40@ZA%b&AGYH1?pfNwlwMEdzcgZr1R||_rwshfZ{&E{nZ zb#+(63$VOs#+E5f;=sVOjo~5IdbT{?T^WKc8JcOmD{rlVV5=EcB0@(^OK-=bsBYm} zSb)WyAj?wSWNHXtT{-c`sK#*1*6;uoe56ZxyLGm3Dt$Ej$&t%xWMx}9 zesrNc^2k%=yWjm0C(P`}$lMcTSU}`dFi+#i={3mKJpLt~X&U^*7@^~1KHCuatF-Hn zJjxq#YjPI}Hw~fv;g(~|3*Z*p@U(ubKaFEm=0<&i@}kb89A#=1GR)Ge&`!AHCT|UU zcmu`QT_dNtGR2s^gR%VDOUKF=fAhxjzB?}i#&=!D#ZV7XHebq|LlWo@=&q1Y>!i{v z&5<$r0(gC2B#_IVL%Ix4TVR}`+oI2bLyq&LvA>c2lo@a1k=(<();_!ZlCBFMq+o;0 z^E5o@y@N!CYr0emSkgX7uOR|c^6DL7Mf z{M#tYEmv+U_uhJCx$&wUgfWL$#F(A;GS}vS_a>(yy!qBi+Ux+Q`AuqB(nBZNHd272{peK?^soVv{WAVnDT_yKWn*Lo#RDk?IbN_qte z?lv9)JgB@;mvyYutVF<0{xm)UwSCVrb-c*@Zk2I&nNw8`9y(E8czJ(${KW(1mBVvo z2Hg!`;eYKw zFoe5B_=JYuMY)zeO@W1saspMxvwXAk*_X=USKcfK*^xGN-6iFgPuyE}-f=xUJjeq@ z0iW7da}Yg(Gs^)Ni&3Ijih7#~?!3+WQjX7^9k{X^ojgbVmbVH)7gu9UutrpM@vEYO zG&x3>*S@GZqC|F)2Q7&jIbnFg_GuLbUI&bpipVSu6-!xAk|yE<0>qoI&X>Rbvmcc2 zeCr7oRan4f*S9+|JR)@-zAV6Z4H4-2^D@t))*o^c;&Z>Sk&jr5>MW_|g|XSpN9G z_&im}?$|+h$XXcdDH#3X!jrt}vn^__3#)+O5T*myZBcwGyeN;WF+vBRGC8~t`%`U$ zXsZT?#>?@2N6MaOUM#QfdA&UM^otz-K2vVI`Lgo4FFe5K8!j!wQ=I&9;#iqEc7mNc z@RO={$Cxswet3jqE61le31MoSHbKcz{z=0C%J9$v3998(&T5Eo!V?wHT3&Ja<&fVk z%vw3ADxMaEa_FK46K?t_o(zXS19jD~EYI8iYW=v2+(ky?hjK~+X^_z<$wZH=JDF$; zC?xEzmWKp{h~Q|8n^nn%^pn0$P6o=t$&=*GNf6}ar#Y5bG-l14;sVExb-!O4`64cc z2u709)zN{2FQOOvtFJS`Bc2+dHNUfM69_9&jLS6R~8#Q`NKY3gAq?d;438DxM_=iVrN{V1WrS6 zXV*P<-&j8LnU9p)Zo2{5pbpbcl4+>7zWu946Ua^~tgz=W{r!ic5#tu z32y$RH!mGkv8KYZ^(Cv3p~3R(!;h7}|EsT-{jVP{Gn|NUN<#$V7La9)5a#JGRX#6q zd#tVsI>?5P{Dh$TSfEX6j8HGiM0{k_@+E<3x|>I<(jn zSNNC(sBnaE+K}CZATijWq+SWqIEKh}R4=E!W5lskP8>d74!w1_964~ToH~vn6~u0R*&3OsqQ__V(zx>qvevzrgD$r&M6Jj$Y&iQc$QygaIY}k&r#ISXzxFS0(zD2 zjISP zKJ61w@aJ31j3F92`0b`uzE?gl1U>NA&rN8smv1;Pj+K2FAUyWyzVh%-UgLCx6ZElF ziO$T0&l|CWlLZTv>WE6JSkBocDJ!jO$_Nh+t1$xQ(hb}yi%;&dZX!aEp@|1Y?@HZ8 zwu$Y46K|vKt_I(Gk+Zlha>FxqZCKBNdlUE;9XzMS!&3lS+=eWAGG4{6_D8i%G{|tE zdGc(fY0m_b!8(5zXwHon1_@*PPE+dqhUMl*@iJ0BT^EakwlO}JM1a%0YKSn(e3bEa zm=m;y7cfK^Ecbn2XZh!U^!~E@YR2C|j_#&;WigjIp7r7acCSs*c4LSTA{1s2JC{R1 zaw39mZ(g{)^BI9oNJ5zmx4gDbDNdc+4hRoUOKlmYMS}-RWgLl+?RpwQmTd^H^G_GH z>Y}(3DO^&7SM~G&4Vvi4!G8h+go6iWn1d{rE3TR>+qcv9z-=Er?A(K_>d6Tp$wff# zs$u!@56Kq-z$ynG}8;J6bScau9qf~rfR=vQYK&;eAuHGPwbMnVncmn4zD;Lsy( zd8wP5wj|$u$M;Bd!(!B{8#wXhL0a=QlBTI+yPh%V2TcSRAr z6_@Fd6CWK8T{Yv5miP@?!zJw*OA=Sh(9$FeenMwQcfS#WGTifvGdOC3)CaVrE^Fa& zgFkZv`p?KC?^!M;vg*7Tg##*Q4_6%_op&`N;Mj9i~Kf00m;?&@)5;uVf{EcqEMF^z|?ouqG2om{2N;;K1R6a?(|pr18fz z-KEp~Q`aIJC3j~8BB$`60^a{2xb_LVme`N@t!j6xm6Cow}f#jR0gCD%OY(a5XPW}B7Bv~3*D zxAN{F7pynu6UJLd{CKjOHzrmXhIp@VN(HAfV!V0xO}op@*G!ikd{%6PQ!4m~0^@=l z-~!g3m73xSG7Zs13N9Z*B+dX@=p+2v!gI z^c5*|%YWaKtmk%FMlX`&GAcm^a5qR$=L%1Ho=R@sxx@`jPC*Fq_$%=NN}MQdko;HS zsz~iK>wHxjmHG-&8BAEfG47+x94VG@t{TeV7lq>;^6eO^f$t)pSy&mI;1rCJ^6K7W z<(Z$qUS4|raM?GrSWYf`0u_dz43~bE!Ot<^#3+IJHgm5<=1-mWB4mnMg7TEkj+Wk> z2)~!%UhP?Z`1|-~N%YpBE~4jeDK>wKXCv;@AkP3G%e}X{(&u-P{qnID{P~1Smi@qm zUcHoSEITh$5%*RR=ao|6F82$}+vGNfw{yMCyad^5eRafn^mu=TK^^u4X!;C)}anM+{8;%D1cAx!uoiDD9 zw4I*5jxnj^pt*tbL7dQ2C6=f{EmzWUr#cJ)P-_G-1iade0-8X}xKN8eFM zswXp@3vO1{YOiMBQPO@DkU4%`G(>nCHFePt;cYPQmz;Eye!NG~*#`@HoHHTlVS0BQ z8~eLWyD&-IBzwc^>tT%yOh2r%o96GHo8hUceGRSoG?+ShRROS;zms`+YFt$e@J_Dc z6u$}@br{tMfdv)wL zt#pf3C6QOk!PAB3stl+cS8kAm+#}G1E-#C6+oy)gNAAC|{K=nuxmg7w#G4zLT@QIAftv=;j+ydm5PO-Q+7UkH9nd3AH+Q=l|l${*s zcy&%%KtA(*ca%i~uF8ioRmqi8GRRx`m}dcBW!JWCe43%jEcKAOO_`Dq>b<1RQgmem zM|cviZkZz!YC&)Y@Zglso_`$;}Po`L%5*fF3WlWp&Xk>%ZD^Bv}*lm zSpAF%ZB#f3SJ}k3Qx|9F(Q&%iO}hklG}I`?{7ggYMoklU%8s*L1ITr@UlCUM0*xxz z(r#>%)H6!+Wxi#6d~T?G`$x}~Kc|fxIL@aqRD{E$B^E5-Nkar_>yapr`~B71_uE%L zChFRITg}`i5u8pz zn4DG9QXb1me`!oDqeN9+=#Sw~_#wR&Pop_FyF%6CG?-+NpD3;g)`&t`Q^D$@%iibr zl&}8v*UC%Jzg12iUZRie3=xn;4G|VR9RrE0G7*uhb&2e@TGh1#pO%t&4VMBks^#hA z-yjnU;T4$9ksb~{59N08T^{>QW1lPnVj-s?!YBjO7`)zw=G-02S6#8Q+;H>dT~Jiv&{dXHSNypeT>CaO9XoAC-O!9*1Pw9(53B*H&s72zCpg?FJ*C zl@oL2$lfDmFFV#=d+7}fI1ZNMM^15S35I@b_w&v|C5V(A7hzPYkMZerg{ADW#UtWe%+`=B(S^w+{;akNYf?gW>w zK@1zl%a{J}{&MR*SCpOL_B5Q;<&)I_gS?kmfN{i-{@jeSITb-`3R-&#Z26FR$6`-K zu=`fF{ATeAD=6+~J$_`hJpI&L<)I(G!t*FQ#xXuXHZ*x-rjl{hU5}Ka-W0_}3;Pjy zDitm~Xe8z_#BC8}H7iX@XT5q)96fiUYMTKK{aPQa?X|ml@Lit5wyVW8|Jrj6C@|t* zi*yLjwOL$Mf~?Wimn_b%>q-~ajgWD#PwS+02V%7 zLYFpf!-T~%1dlw4OCtn_hiZs`ocf31>L{moj1MoCsmWD7FSD)u&hOn>?t0%Y7SR@1 zgi}_LC)$wpD%Kby*q$OhwX~Kj{Wf{U_=U;WO2#( z6MyXQ7cawr#L%dG*&z=nL%?yr(>CbQ|2cO5K?3!Ir>BCEYmL@7tid6t=5yoh`}_#or!vnMb@&~RS4 z+|KyQC+fIs5xcoL_~VDTYK%pmGKpJ>Hh=kJlTOFRGiBo^Sz-Xgc{u!`lVE{g`l@nnnbt00)~?nz10fMzbVvlu*Y_F(&vgjm zlLDE>lPyv>@^(t70GrnSSN?fAUoIb^qsEIUFcdgZ@e5h~ju|8983x$=;OTy0fa%RV zOjM?r+tF_nEghhe6;dxO#>zCXs=CvBlT!5ZZa|Ly-S@J?u)>0n*&r&=7bxY;W;C=R(myj&Z&M~0PT-18X~-n+Pr9p@HUwD zOHR5;Ki;G0?1Ke8&Y2MOFugmDjs4xGU6>?plD%Q|MY=`?rXSXsP4jop&G6LJ^%c+f z22&@mgp;;ihRM@Bd5Nq$YpdV)?Gb=I34wL1>~5T%9OP)i@$x_Y&;M1q>w`D)GR|?! zV=fl(qRw&amZ0UAJoKy!NNA1fW^9?<@m340iL$7q$km%A>aVxz4hc{Zmr1gK(9;ydy@_92T$8~n zm@*|^d#<`8R3ikQD>(_FDvs+*e^sQYqzJx_!Lm6M?ymeQN|#V_3p3)1AhA~I(#i4i zgKs`l{?niSeK~Syq0G#`{La$C7!35|MTaSOMbMl?v+#;(P? z?$}-a^}qg7x%1Ae;p0(G)j(#{d9E|AB``SQZ!PnNI$!-H9fzvb4e z%AI$hgxt9;yTMgpp$}t06Iqx-KG`ufF*$)=mlB(Am%naBvYzNr>#Qyy(^jIyWzRpm zZ_@rqlsZFOlRwKXQ&OnP|ISl`kgc~ur zJArYAN~~2aXlR!{T}&3f899VVD3aD_rCeBS<+IJC&IBM2>P3Y)hi+qdFkXKA#H-~$ z{KbRijf3v48RF8Ij)pxFQs%3o)kmvkYqCvXD$0YK92I8X*jhbOs_Ukava%V_6{g(*Y|* zqoCcF?3L?^1;!FXhMcV3Z z8SFL1(c*2tJs5F8cl_oN97#Y-Z7(WLZMQ4Pko~+3>gXH$%QwFIjq=Q+uax5l*xjxn z0w-`RAZrWAorVZY$PACH4b+|NIRs`DC$^y2t_zQXdMf`&^YsPZ3~k9)qf7cDBxx*I(GnCx2cp zZ|r%q96NZjEU{p)$as>S-D&eA24{9fT2LB=!T=7N)U%x5I{KsCr1r&;XCSQ~RA&V7!xnB|mCN{?LFU%BWc zz4D`$!(=06?$khedCyGw>5ul7#~^V7uPc}sGXiu^_bz*%Xj2ZiEXSs}#PXHlTkuMGKA}rLqYf6ds-7;L=sI3#*`S_nNnu0eLGFO)a= zT+u9T{krRSlyQumJaxrBB+^To$QD_do=5kigUc}SCL$sA$FR^?y`Hw!1H+N1z|^F5 zk+Q;ys^00H;&G_(_UhrmFW)M(&;CoOH4>_?#wSU~!%#(gveqoIg!#Td?58W7OXh-( z5Fj*|DuQHg{&h}kAa^nX8%bLkEroFL0}x1l`WMwrwl=;93mxL%uXh4QXz5BqoQ5#+ zK86aNob)orA32erE=iS4%alaKE3;Kfm1Fh)wf1BI2}t!H^7`Ah6tHkIT!X6 z4aQlS2)>Lpz%DOLmp#uNEZ_ak56a_@KV1$pp3E~ZUSR!Qg9N_|?|7>r!XoWunSp01 zh6osa`HtjRm}i?IE5q{S*JrH@X|_!IA*d^V0us0u)PpzihHIlCf*_Fq z>&BZLUAVMeR6_*X7!WZ;fR`E~_<4pgzL79VXET8T-ZqYu`tbXAmEZWxZS*mGC?+Sl zQBKRsaOitzop_L$8KxO_V-f>O+JND`INf;kcg~Do!t&l1d2Quy=>SeOL3lnBM7%b8 zw!xfS;0p==_99-+D}2|{7@->O)a*3ElehiyUEldh%=~bbex%ATK+*uuYPFD#HfEPN z&q-#FKen%Y?|Y1`Z_e}i4tBjSGEXlH{Am^sZTwU=Kre3RW44LNrG1-F@W7`xYaZA~#++S#G{|XSwE*@p1+I;4tYWJ46J( zMF>X;B2F0qf8$97mK5^}MB?n%#Z>u4dh*SQGxC+)8Oo?N5(5yP>1xck@1h93D{csD z&&mj*LoDHllFr=FSWmaXuUks2M};cLcv`f9@|#%=ch3;P zIhc%32L+6CAl}hVQNO1!GCgp7u{`_If%5dr2g;i#>fC#tc0RK*T4vDSsGG26!4fI( zGac=YjV$4kSLFe>lSfO;B;PXn*Tya3LM1;Nid4%)yqA1e2Nc*EguCA-)~zq&!lSK0 z&KR=^%h$oLr=>=nnWA;c&+0i-+0K@@m$si>eTgjFnXa?Nn|8DESDYR4E%FxTO!!R} z@vq1(==Tg+Ul6|jL@75Jw6UtiHI}Aq7fJv~>@VNWB^~K08$o@@YTR1H#`fX+1iew( zRiG@V_`0XfZ!^DH#3-sI>dP~68~n|?G5;2Rp-=ma3%$-x3pL->O_kp+vpo1A(!O}B zYooku1$Qz0o#()r>SgQPy85L`d$qcWfL%01*qVdyY7EuGbgylL@xF8q4YLc}!f|C+PH3*>1%S}1{N)X~(x2Dr&fOUz_&J6c zBA_{lvN+fpuYJX=wLnN>>Z5X4UPy-!Dovw|1Yl)uqCD}?%jG})hyTn1%8_!C&r^8h zv?n6WqL^AF9cpzJzHyVf?b6JO8f0gO3~>~PtIJ=WR|@hQw`}PPTNeTTN^ym#zUJ

f!sI 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%0DuOW}UD=l7}HW;edB#~VJ=KJM7H+*K6# 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

5aE8qzhM8(z(k^=}r6>meeRABS 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�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

c1!blhV6x4Zi|}04;{_@ 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%0AKwMA`h($ZckT3Gg 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

q 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: MIT

-R2R Answer Engine +R2R Answer Engine

Build, scale, and manage user-facing Retrieval-Augmented Generation applications in production.

From 06c5c1e768ac7831b44a3e1249800776c8f8aeeb Mon Sep 17 00:00:00 2001 From: emrgnt-cmplxty <68796651+emrgnt-cmplxty@users.noreply.github.com> Date: Fri, 23 Aug 2024 07:47:32 -0700 Subject: [PATCH 58/74] Feature/rm print cruft rebase (#953) * refresh should not be gated by auth * rm print cruft * black and sort * merge * rm --- py/core/main/api/routes/retrieval/base.py | 17 ----------------- py/core/providers/database/document.py | 1 - py/core/providers/database/user.py | 6 ------ py/sdk/auth.py | 1 - 4 files changed, 25 deletions(-) diff --git a/py/core/main/api/routes/retrieval/base.py b/py/core/main/api/routes/retrieval/base.py index 44c5eeca9..87dbb789d 100644 --- a/py/core/main/api/routes/retrieval/base.py +++ b/py/core/main/api/routes/retrieval/base.py @@ -73,14 +73,6 @@ async def search_app( Allowed operators include `eq`, `neq`, `gt`, `gte`, `lt`, `lte`, `like`, `ilike`, `in`, and `nin`. """ - print("auth_user = ", auth_user) - print("initial vector_search_settings = ", vector_search_settings) - - print(f"Received query: {query}") - print(f"Received vector_search_settings: {vector_search_settings}") - print(f"Received kg_search_settings: {kg_search_settings}") - print(f"Auth user: {auth_user}") - user_groups = set(auth_user.group_ids) selected_groups = set(vector_search_settings.selected_group_ids) allowed_groups = user_groups.intersection(selected_groups) @@ -89,10 +81,6 @@ async def search_app( "User does not have access to the specified group(s): " f"{selected_groups - allowed_groups}" ) - print( - "initial vector_search_settings filters = ", - vector_search_settings.filters, - ) filters = { "$or": [ @@ -105,11 +93,6 @@ async def search_app( filters = {"$and": [filters, vector_search_settings.filters]} vector_search_settings.filters = filters - print("final vector_search_settings = ", vector_search_settings) - print( - "final vector_search_settings filters = ", - vector_search_settings.filters, - ) results = await self.engine.asearch( query=query, vector_search_settings=vector_search_settings, diff --git a/py/core/providers/database/document.py b/py/core/providers/database/document.py index 4c578b699..d10089a55 100644 --- a/py/core/providers/database/document.py +++ b/py/core/providers/database/document.py @@ -102,7 +102,6 @@ def get_documents_overview( """ results = self.execute_query(query, params).fetchall() - print("results = ", results) documents = [ DocumentInfo( id=row[0], diff --git a/py/core/providers/database/user.py b/py/core/providers/database/user.py index 92a0a6a97..40e1c2dd5 100644 --- a/py/core/providers/database/user.py +++ b/py/core/providers/database/user.py @@ -195,7 +195,6 @@ def update_user(self, user: UserResponse) -> UserResponse: ) def delete_user(self, user_id: UUID) -> None: - print("A") # Get the groups the user belongs to group_query = f""" SELECT group_ids FROM {self._get_table_name('users')} @@ -205,13 +204,11 @@ def delete_user(self, user_id: UUID) -> None: group_query, {"user_id": user_id} ).fetchone() - print("B") if not group_result: raise R2RException(status_code=404, message="User not found") user_groups = group_result[0] - print("C") # Remove user from all groups they belong to if user_groups: group_update_query = f""" @@ -224,7 +221,6 @@ def delete_user(self, user_id: UUID) -> None: {"user_id": user_id, "group_ids": user_groups}, ) - print("D") # Remove user from documents doc_update_query = f""" UPDATE {self._get_table_name('document_info')} @@ -233,7 +229,6 @@ def delete_user(self, user_id: UUID) -> None: """ self.execute_query(doc_update_query, {"user_id": user_id}) - print("E") # Delete the user delete_query = f""" DELETE FROM {self._get_table_name('users')} @@ -241,7 +236,6 @@ def delete_user(self, user_id: UUID) -> None: RETURNING user_id """ - print("F") result = self.execute_query( delete_query, {"user_id": user_id} ).fetchone() diff --git a/py/sdk/auth.py b/py/sdk/auth.py index 6a63f0f48..be1ff9d0a 100644 --- a/py/sdk/auth.py +++ b/py/sdk/auth.py @@ -102,7 +102,6 @@ async def update_user( "profile_picture": profile_picture, } data = {k: v for k, v in data.items() if v is not None} - print("data = ", data) return await client._make_request("PUT", "user", json=data) @staticmethod From a128921172ae2a5945f2c8a846f5c51b8c6147ad Mon Sep 17 00:00:00 2001 From: emrgnt-cmplxty Date: Fri, 23 Aug 2024 08:05:40 -0700 Subject: [PATCH 59/74] update api return type --- py/core/main/api/routes/management/base.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/py/core/main/api/routes/management/base.py b/py/core/main/api/routes/management/base.py index 7a1ebded8..d2fd42677 100644 --- a/py/core/main/api/routes/management/base.py +++ b/py/core/main/api/routes/management/base.py @@ -367,10 +367,9 @@ async def add_user_to_group_app( ) user_uuid = UUID(user_id) group_uuid = UUID(group_id) - result = await self.engine.aadd_user_to_group( + return await self.engine.aadd_user_to_group( user_uuid, group_uuid ) - return {"result": result} @self.router.post("/remove_user_from_group") @self.base_endpoint From 6435dcfd2eca29045baecaf4914a89adacd99978 Mon Sep 17 00:00:00 2001 From: Nolan Tremelling <34580718+NolanTrem@users.noreply.github.com> Date: Fri, 23 Aug 2024 09:27:38 -0700 Subject: [PATCH 60/74] Update Actions (#954) --- .github/workflows/ci.yml | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 082a5b97f..3d5837b43 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,22 +2,23 @@ name: CI on: push: - branches: - - main - - '**/feature/*' + paths: + - 'py/**' pull_request: - branches: - - main + paths: + - 'py/**' jobs: pre-commit: - runs-on: [ self-hosted, Linux ] + continue-on-error: true + runs-on: arc-runner-set steps: - name: Checkout code uses: actions/checkout@v3 - name: Run pre-commit + working-directory: ./py run: | python3 -m venv venv source venv/bin/activate @@ -39,7 +40,8 @@ jobs: swap-storage: true pytest: - runs-on: [ self-hosted, Linux ] + continue-on-error: true + runs-on: arc-runner-set timeout-minutes: 15 env: @@ -62,12 +64,12 @@ jobs: curl -i http://localhost:11434 - name: Run pytest + working-directory: ./py run: | python3 -m venv venv source venv/bin/activate poetry install pip install pytest - pip install pytest poetry run pytest tests/ -k "not redis and not sentence_transformer" deactivate rm -rf venv From 5654f7dba6ec10964ee305f28514c4d7626adccb Mon Sep 17 00:00:00 2001 From: Nolan Tremelling <34580718+NolanTrem@users.noreply.github.com> Date: Fri, 23 Aug 2024 10:42:20 -0700 Subject: [PATCH 61/74] Update Github Actions (#956) * Update Actions * Update actions --- .github/workflows/build-main.yml | 26 +--- .github/workflows/build-mainv2.yml | 85 ------------ .github/workflows/build-release.yml | 43 ------ .../integration-test-workflow-debian.yml | 3 +- .../integration-test-workflow-windows.yml | 122 ------------------ .github/workflows/links.yml | 39 ------ .github/workflows/publish-to-pypi.yml | 4 +- .github/workflows/{ci.yml => py-ci-cd.yml} | 4 +- .github/workflows/r2r-js-sdk-ci.yml | 6 +- .../r2r-js-sdk-integration-tests.yml | 8 +- go/cli/rag_operations.go | 6 +- go/cli/server_operations.go | 2 +- .../tests/integration/management_test.go | 2 +- js/sdk/__tests__/r2rClient.test.ts | 4 +- js/sdk/src/r2rClient.ts | 2 +- py/cli/commands/server.py | 1 - py/compose.yaml | 12 +- py/core/main/api/routes/management/base.py | 4 +- 18 files changed, 36 insertions(+), 337 deletions(-) delete mode 100644 .github/workflows/build-mainv2.yml delete mode 100644 .github/workflows/build-release.yml delete mode 100644 .github/workflows/integration-test-workflow-windows.yml delete mode 100644 .github/workflows/links.yml rename .github/workflows/{ci.yml => py-ci-cd.yml} (97%) diff --git a/.github/workflows/build-main.yml b/.github/workflows/build-main.yml index a52f332a2..9d714cdbb 100644 --- a/.github/workflows/build-main.yml +++ b/.github/workflows/build-main.yml @@ -34,8 +34,8 @@ jobs: - name: Docker Auth uses: docker/login-action@v3 with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_TOKEN }} + username: ${{ secrets.RAGTORICHES_DOCKER_UNAME }} + password: ${{ secrets.RAGTORICHES_DOCKER_TOKEN }} - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 @@ -57,20 +57,17 @@ jobs: uses: docker/metadata-action@v5 with: images: | - emrgntcmplxty/r2r + ragtoriches/prod us-east1-docker.pkg.dev/alert-rush-397022/sciphi-r2r/r2r tags: | type=raw,value=${{ steps.version.outputs.RELEASE_VERSION }} type=raw,value=latest - tags_unstructured: | - type=raw,value=${{ steps.version.outputs.RELEASE_VERSION }} - type=raw,value=latest-unstructured - name: Build and Push Docker Image uses: docker/build-push-action@v5 with: context: . - file: ./Dockerfile + file: ./py/Dockerfile push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} @@ -80,17 +77,8 @@ jobs: uses: docker/build-push-action@v5 with: context: . - file: ./Dockerfile.unstructured + file: ./py/Dockerfile.unstructured push: true - tags: ${{ steps.meta.outputs.tags_unstructured }} - labels: ${{ steps.meta.outputs.labels_unstructured }} + tags: ${{ steps.meta.outputs.tags }}-unstructured + labels: ${{ steps.meta.outputs.labels }}-unstructured platforms: linux/amd64,linux/arm64 - - - name: Trigger Dependent Repositories - if: success() - run: | - curl -X POST \ - -H "Accept: application/vnd.github.v3+json" \ - -H "Authorization: token ${{ secrets.PERSONAL_ACCESS_TOKEN }}" \ - https://api.github.com/repos/SciPhi-AI/R2R-basic-rag-template/dispatches \ - -d '{"event_type": "rebuild", "client_payload": {"r2r_tag": "${{ steps.version.outputs.RELEASE_VERSION }}"}}' diff --git a/.github/workflows/build-mainv2.yml b/.github/workflows/build-mainv2.yml deleted file mode 100644 index ab02f156f..000000000 --- a/.github/workflows/build-mainv2.yml +++ /dev/null @@ -1,85 +0,0 @@ -name: Build and Publish ragtoriches/prod - -on: - workflow_dispatch: - inputs: - version: - description: 'Version to publish (leave empty to use default versioning)' - required: false - type: string - -jobs: - build-and-publish: - runs-on: ubuntu-latest - permissions: - packages: write - contents: read - actions: write - steps: - - name: Checkout Repository - uses: actions/checkout@v4 - - - name: Docker Auth - uses: docker/login-action@v3 - with: - username: ${{ secrets.RAGTORICHES_DOCKER_UNAME }} - password: ${{ secrets.RAGTORICHES_DOCKER_TOKEN }} - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - - - name: Determine version to use - id: version - run: | - if [ -n "${{ github.event.inputs.version }}" ]; then - echo "RELEASE_VERSION=${{ github.event.inputs.version }}" >> $GITHUB_OUTPUT - else - echo "RELEASE_VERSION=main" >> $GITHUB_OUTPUT - fi - - - name: Generate Cache Buster - id: cache-buster - run: echo "CACHE_BUSTER=$(date +%s)" >> $GITHUB_OUTPUT - - - name: Extract metadata (tags, labels) for Docker - id: meta - uses: docker/metadata-action@v5 - with: - images: ragtoriches/prod - tags: | - type=raw,value=${{ steps.version.outputs.RELEASE_VERSION }} - type=raw,value=latest - tags_unstructured: | - type=raw,value=${{ steps.version.outputs.RELEASE_VERSION }} - type=raw,value=latest-unstructured - labels: | - type=raw,value=latest - labels_unstructured: | - type=raw,value=latest-unstructured - - - name: Build and Push Docker Image (Standard) - uses: docker/build-push-action@v5 - with: - context: . - file: ./py/Dockerfile - push: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - platforms: linux/amd64,linux/arm64 - build-args: | - CACHE_BUST=${{ steps.cache-buster.outputs.CACHE_BUSTER }} - - - name: Build and Push Docker Image (Unstructured) - uses: docker/build-push-action@v5 - with: - context: . - file: ./py/Dockerfile.unstructured - push: true - tags: ${{ steps.meta.outputs.tags_unstructured }} - labels: ${{ steps.meta.outputs.labels_unstructured }} - platforms: linux/amd64,linux/arm64 - build-args: | - CACHE_BUST=${{ steps.cache-buster.outputs.CACHE_BUSTER }} diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml deleted file mode 100644 index 996f7334e..000000000 --- a/.github/workflows/build-release.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: Links - -on: - push: - branches: - - main - pull_request: - branches: - - main - schedule: - - cron: "00 18 * * *" - -jobs: - linkChecker: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - - name: Link Checker - id: lychee - uses: lycheeverse/lychee-action@v1 - continue-on-error: true - with: - args: "--output ./docs/lychee/out.md --config ./docs/.lycheerc" - - - name: Get Lychee Exit Code - id: get-exit-code - run: echo "lychee_exit_code=$?" >> $GITHUB_ENV - - - name: Create Custom Report - if: failure() - run: | - echo "Lychee doesn't play nice with relative imports for .mdx files. Add a link to the .lycheeignore if needed!" > ./docs/lychee/custom_report.md - echo "" >> ./docs/lychee/custom_report.md - cat ./docs/lychee/out.md >> ./docs/lychee/custom_report.md - - - name: Create Issue From File - if: failure() - uses: peter-evans/create-issue-from-file@v4 - with: - title: Link Checker Report - content-filepath: ./docs/lychee/custom_report.md - labels: report, automated issue diff --git a/.github/workflows/integration-test-workflow-debian.yml b/.github/workflows/integration-test-workflow-debian.yml index c7a9226b5..9f9419e95 100644 --- a/.github/workflows/integration-test-workflow-debian.yml +++ b/.github/workflows/integration-test-workflow-debian.yml @@ -52,7 +52,7 @@ jobs: uses: docker/build-push-action@v5 with: context: . - file: ./Dockerfile + file: ./py/Dockerfile push: true tags: ragtoriches/dev:latest platforms: linux/amd64 @@ -60,6 +60,7 @@ jobs: pull: true - name: Run cloud LLM integration tests in Docker + working-directory: ./py run: | python3 -m venv venv source venv/bin/activate diff --git a/.github/workflows/integration-test-workflow-windows.yml b/.github/workflows/integration-test-workflow-windows.yml deleted file mode 100644 index f0b29f6a0..000000000 --- a/.github/workflows/integration-test-workflow-windows.yml +++ /dev/null @@ -1,122 +0,0 @@ -name: Windows R2R Docker Build and Integration Test (Windows Server 2022 Datacenter x64) - -on: - workflow_dispatch: - -jobs: - build-and-test: - runs-on: [self-hosted, Windows] - - steps: - - uses: actions/checkout@v3 - - - name: Set up Python virtual environment - run: | - python -m venv %USERPROFILE%\r2r_venv - echo %USERPROFILE%\r2r_venv\Scripts >> %GITHUB_PATH% - shell: cmd - - - name: Activate virtual environment and install R2R - run: | - call %USERPROFILE%\r2r_venv\Scripts\activate.bat - pip install --upgrade pip - pip install --upgrade r2r - shell: cmd - - - name: Build R2R Docker image - run: | - docker build -t emrgntcmplxty/r2r:${{ github.sha }} . - shell: cmd - - - name: Build R2R Docker image with args - run: | - docker build ^ - --build-arg GITHUB_SHA=${{ github.sha }} ^ - --build-arg GITHUB_REF=${{ github.ref }} ^ - -t emrgntcmplxty/r2r:${{ github.sha }} . - shell: cmd - - - name: Pull pgvector image - run: docker pull pgvector/pgvector:pg16 - shell: cmd - - - name: Create Docker network - run: docker network create r2r-network - shell: cmd - - - name: Start Postgres - run: | - docker run -d --name postgres --network r2r-network ^ - -e POSTGRES_USER=postgres ^ - -e POSTGRES_PASSWORD=postgres ^ - -e POSTGRES_DB=postgres ^ - pgvector/pgvector:pg16 - shell: cmd - - - name: Start R2R - run: | - docker run -d --name r2r --network r2r-network ^ - -e PYTHONUNBUFFERED=1 ^ - -e OPENAI_API_KEY=${{ secrets.OPENAI_API_KEY }} ^ - -e POSTGRES_USER=postgres ^ - -e POSTGRES_PASSWORD=postgres ^ - -e POSTGRES_HOST=postgres ^ - -e POSTGRES_PORT=5432 ^ - -e POSTGRES_DBNAME=postgres ^ - -e POSTGRES_VECS_COLLECTION=vecs ^ - -p 8000:8000 ^ - emrgntcmplxty/r2r:${{ github.sha }} - - timeout /t 10 - shell: cmd - - - name: Run integration tests - run: | - echo R2R Version - r2r version - - echo Ingest Data - r2r ingest-sample-files - - echo Get Documents Overview - r2r documents-overview - - echo Get Document Chunks - r2r document-chunks 93123a68-d668-51de-8291-92162730dc87 - - echo Delete Documents - r2r delete --keys=document_id --values=b736292c-11e6-5453-9686-055da3edb866 - - echo Vector Search - r2r search --query="What was Uber's profit in 2020?" - - echo Hybrid Search - r2r search --query="What is a fierce nerd?" --use-hybrid-search - - echo Basic RAG - r2r rag --query="What was Uber's profit in 2020?" - - echo RAG with Hybrid Search - r2r rag --query="Who is John Snow?" --use-hybrid-search - - echo Streaming RAG - r2r rag --query="What was Lyft's profit in 2020?" --stream - - echo Users Overview - r2r users-overview - - echo Logging - r2r logs - - echo Analytics - r2r analytics --filters "{\"search_latencies\": \"search_latency\"}" --analysis-types "{\"search_latencies\": [\"basic_statistics\", \"search_latency\"]}" - shell: cmd - - - name: Clean up - if: always() - run: | - docker stop r2r postgres - docker rm r2r postgres - docker network rm r2r-network - docker system prune -af --volumes - shell: cmd diff --git a/.github/workflows/links.yml b/.github/workflows/links.yml deleted file mode 100644 index 75ec1758f..000000000 --- a/.github/workflows/links.yml +++ /dev/null @@ -1,39 +0,0 @@ -name: Links - -on: - repository_dispatch: - workflow_dispatch: - schedule: - - cron: "00 18 * * *" - -jobs: - linkChecker: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - - name: Link Checker - id: lychee - uses: lycheeverse/lychee-action@v1 - continue-on-error: true - with: - args: "--output ./docs/lychee/out.md --config ./docs/.lycheerc" - - - name: Get Lychee Exit Code - id: get-exit-code - run: echo "lychee_exit_code=$?" >> $GITHUB_ENV - - - name: Create Custom Report - if: failure() - run: | - echo "Lychee doesn't play nice with relative imports for .mdx files. Add a link to the .lycheeignore if needed!" > ./docs/lychee/custom_report.md - echo "" >> ./docs/lychee/custom_report.md - cat ./docs/lychee/out.md >> ./docs/lychee/custom_report.md - - - name: Create Issue From File - if: failure() - uses: peter-evans/create-issue-from-file@v4 - with: - title: Link Checker Report - content-filepath: ./docs/lychee/custom_report.md - labels: report, automated issue diff --git a/.github/workflows/publish-to-pypi.yml b/.github/workflows/publish-to-pypi.yml index 79ac0c839..c60343733 100644 --- a/.github/workflows/publish-to-pypi.yml +++ b/.github/workflows/publish-to-pypi.yml @@ -4,7 +4,7 @@ on: push: tags: - "*" - workflow_dispatch: # This line adds manual trigger support + workflow_dispatch: jobs: publish: @@ -19,9 +19,11 @@ jobs: python-version: 3.9 - name: Install poetry + working-directory: ./py run: pip install poetry - name: Build and publish + working-directory: ./py run: | poetry build poetry publish --username __token__ --password ${{ secrets.PYPI_API_TOKEN }} diff --git a/.github/workflows/ci.yml b/.github/workflows/py-ci-cd.yml similarity index 97% rename from .github/workflows/ci.yml rename to .github/workflows/py-ci-cd.yml index 3d5837b43..2c40e8801 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/py-ci-cd.yml @@ -11,7 +11,7 @@ on: jobs: pre-commit: continue-on-error: true - runs-on: arc-runner-set + runs-on: ubuntu-latest steps: - name: Checkout code @@ -41,7 +41,7 @@ jobs: pytest: continue-on-error: true - runs-on: arc-runner-set + runs-on: ubuntu-latest timeout-minutes: 15 env: diff --git a/.github/workflows/r2r-js-sdk-ci.yml b/.github/workflows/r2r-js-sdk-ci.yml index 474f90df6..e89897f6a 100644 --- a/.github/workflows/r2r-js-sdk-ci.yml +++ b/.github/workflows/r2r-js-sdk-ci.yml @@ -4,11 +4,11 @@ on: push: branches: [main] paths: - - 'r2r_js_sdk/**' + - 'js/sdk/**' pull_request: branches: [main] paths: - - 'r2r_js_sdk/**' + - 'js/sdk/**' jobs: build-and-test: @@ -16,7 +16,7 @@ jobs: defaults: run: - working-directory: r2r_js_sdk + working-directory: ./js/sdk steps: - uses: actions/checkout@v2 diff --git a/.github/workflows/r2r-js-sdk-integration-tests.yml b/.github/workflows/r2r-js-sdk-integration-tests.yml index 1ee8ade29..3af53ac0d 100644 --- a/.github/workflows/r2r-js-sdk-integration-tests.yml +++ b/.github/workflows/r2r-js-sdk-integration-tests.yml @@ -4,11 +4,11 @@ on: push: branches: [main] paths: - - 'r2r_js_sdk/**' + - 'js/sdk/**' pull_request: branches: [main] paths: - - 'r2r_js_sdk/**' + - 'js/sdk/**' jobs: test: @@ -16,7 +16,7 @@ jobs: defaults: run: - working-directory: r2r_js_sdk + working-directory: ./js/sdk steps: - uses: actions/checkout@v2 @@ -54,7 +54,7 @@ jobs: - name: Check if R2R server is running run: | - curl http://localhost:8000/health || echo "Server not responding" + curl http://localhost:8000/v2/health || echo "Server not responding" - name: Display R2R server logs if server not responding if: failure() diff --git a/go/cli/rag_operations.go b/go/cli/rag_operations.go index 3c81d5721..afa44255c 100644 --- a/go/cli/rag_operations.go +++ b/go/cli/rag_operations.go @@ -22,7 +22,7 @@ var inspectKnowledgeGraphCmd = &cobra.Command{ Use: "inspect-knowledge-graph", Short: "Print relationships from the knowledge graph", Run: withTimer(func(cmd *cobra.Command, args []string) { - client := sdk.NewClient("http://localhost:8000/v1", sdk.LogConfig{Verbose: true}) + client := sdk.NewClient("http://localhost:8000/v2", sdk.LogConfig{Verbose: true}) limit, _ := cmd.Flags().GetInt("limit") // printDescriptions, _ := cmd.Flags().GetBool("print-descriptions") @@ -39,7 +39,7 @@ var ragCmd = &cobra.Command{ Use: "rag", Short: "Perform a RAG query", Run: withTimer(func(cmd *cobra.Command, args []string) { - client := sdk.NewClient("http://localhost:8000/v1", sdk.LogConfig{Verbose: true}) + client := sdk.NewClient("http://localhost:8000/v2", sdk.LogConfig{Verbose: true}) query, _ := cmd.Flags().GetString("query") useVectorSearch, _ := cmd.Flags().GetBool("use-vector-search") filtersStr, _ := cmd.Flags().GetString("filters") @@ -99,7 +99,7 @@ var searchCmd = &cobra.Command{ Use: "search", Short: "Perform a search query", Run: withTimer(func(cmd *cobra.Command, args []string) { - client := sdk.NewClient("http://localhost:8000/v1", sdk.LogConfig{Verbose: true}) + client := sdk.NewClient("http://localhost:8000/v2", sdk.LogConfig{Verbose: true}) query, _ := cmd.Flags().GetString("query") useVectorSearch, _ := cmd.Flags().GetBool("use-vector-search") filtersStr, _ := cmd.Flags().GetString("filters") diff --git a/go/cli/server_operations.go b/go/cli/server_operations.go index 4010d3c8d..09719ccba 100644 --- a/go/cli/server_operations.go +++ b/go/cli/server_operations.go @@ -75,7 +75,7 @@ var healthCmd = &cobra.Command{ Use: "health", Short: "Check the health of the server", Run: withTimer(func(cmd *cobra.Command, args []string) { - client := sdk.NewClient("http://localhost:8000/v1", sdk.LogConfig{Verbose: true}) + client := sdk.NewClient("http://localhost:8000/v2", sdk.LogConfig{Verbose: true}) response, err := client.Health() if err != nil { fmt.Printf("Error checking health: %v\n", err) diff --git a/go/sdk/internal/tests/integration/management_test.go b/go/sdk/internal/tests/integration/management_test.go index 55dae6586..8e5709732 100644 --- a/go/sdk/internal/tests/integration/management_test.go +++ b/go/sdk/internal/tests/integration/management_test.go @@ -13,7 +13,7 @@ func TestServerStatsIntegration(t *testing.T) { LogWriter: os.Stderr, // or any io.Writer } - client := sdk.NewClient("http://localhost:8000/v1", logConfig) + client := sdk.NewClient("http://localhost:8000/v2", logConfig) // Call Health health, err := client.Health() diff --git a/js/sdk/__tests__/r2rClient.test.ts b/js/sdk/__tests__/r2rClient.test.ts index 38624504f..37de1f12c 100644 --- a/js/sdk/__tests__/r2rClient.test.ts +++ b/js/sdk/__tests__/r2rClient.test.ts @@ -11,7 +11,7 @@ describe("R2RClient", () => { mockAxiosInstance = { post: jest.fn(), request: jest.fn(), - defaults: { baseURL: "http://0.0.0.0:8000/v1" }, + defaults: { baseURL: "http://0.0.0.0:8000/v2" }, }; (axios.create as jest.Mock).mockReturnValue(mockAxiosInstance); @@ -22,7 +22,7 @@ describe("R2RClient", () => { describe("Mocked Tests", () => { test("should correctly set the baseURL with prefix", () => { expect((client as any).axiosInstance.defaults.baseURL).toBe( - "http://0.0.0.0:8000/v1", + "http://0.0.0.0:8000/v2", ); }); diff --git a/js/sdk/src/r2rClient.ts b/js/sdk/src/r2rClient.ts index 34dd2e141..be5f26cc5 100644 --- a/js/sdk/src/r2rClient.ts +++ b/js/sdk/src/r2rClient.ts @@ -57,7 +57,7 @@ export class r2rClient { private accessToken: string | null; private refreshToken: string | null; - constructor(baseURL: string, prefix: string = "/v1") { + constructor(baseURL: string, prefix: string = "/v2") { this.baseUrl = `${baseURL}${prefix}`; this.accessToken = null; this.refreshToken = null; diff --git a/py/cli/commands/server.py b/py/cli/commands/server.py index 5355b4e8f..946c3bc98 100644 --- a/py/cli/commands/server.py +++ b/py/cli/commands/server.py @@ -73,7 +73,6 @@ def logs(client, run_type_filter, max_runs): help="Remove containers for services not defined in the Compose file", ) @click.option("--project-name", default="r2r", help="Project name for Docker") -@click.pass_context def docker_down(volumes, remove_orphans, project_name): """Bring down the Docker Compose setup and attempt to remove the network if necessary.""" result = bring_down_docker_compose(project_name, volumes, remove_orphans) diff --git a/py/compose.yaml b/py/compose.yaml index b4a4e7c46..5e8d518e5 100644 --- a/py/compose.yaml +++ b/py/compose.yaml @@ -21,7 +21,7 @@ networks: services: r2r: - image: ${R2R_IMAGE:-emrgntcmplxty/r2r:main} + image: ${R2R_IMAGE:-ragtoriches/r2r:prod} build: context: . args: @@ -40,8 +40,8 @@ services: # Postgres - POSTGRES_USER=${POSTGRES_USER:-postgres} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-postgres} - - POSTGRES_HOST=postgres - - POSTGRES_PORT=5432 + - POSTGRES_HOST=${POSTGRES_HOST:-postgres} + - POSTGRES_PORT=${POSTGRES_PORT:-5432} - POSTGRES_DBNAME=${POSTGRES_DBNAME:-postgres} - POSTGRES_VECS_COLLECTION=${POSTGRES_VECS_COLLECTION:-${CONFIG_NAME:-vecs}} # Neo4j @@ -86,7 +86,7 @@ services: networks: - r2r-network healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:${PORT:-8000}/v1/health"] + test: ["CMD", "curl", "-f", "http://localhost:${PORT:-8000}/v2/health"] interval: 10s timeout: 5s retries: 5 @@ -98,8 +98,8 @@ services: - "traefik.http.routers.r2r.rule=PathPrefix(`/api`)" - "traefik.http.services.r2r.loadbalancer.server.port=${PORT:-8000}" - "traefik.http.middlewares.r2r-strip-prefix.stripprefix.prefixes=/api" - - "traefik.http.middlewares.r2r-add-v1.addprefix.prefix=/v1" - - "traefik.http.routers.r2r.middlewares=r2r-strip-prefix,r2r-add-v1,r2r-headers" + - "traefik.http.middlewares.r2r-add-v2.addprefix.prefix=/v2" + - "traefik.http.routers.r2r.middlewares=r2r-strip-prefix,r2r-add-v2,r2r-headers" - "traefik.http.middlewares.r2r-headers.headers.customrequestheaders.Access-Control-Allow-Origin=*" - "traefik.http.middlewares.r2r-headers.headers.customrequestheaders.Access-Control-Allow-Methods=GET,POST,OPTIONS" - "traefik.http.middlewares.r2r-headers.headers.customrequestheaders.Access-Control-Allow-Headers=DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization" diff --git a/py/core/main/api/routes/management/base.py b/py/core/main/api/routes/management/base.py index d2fd42677..06419c5d1 100644 --- a/py/core/main/api/routes/management/base.py +++ b/py/core/main/api/routes/management/base.py @@ -367,9 +367,7 @@ async def add_user_to_group_app( ) user_uuid = UUID(user_id) group_uuid = UUID(group_id) - return await self.engine.aadd_user_to_group( - user_uuid, group_uuid - ) + return await self.engine.aadd_user_to_group(user_uuid, group_uuid) @self.router.post("/remove_user_from_group") @self.base_endpoint From 513c6489b7c2c5378e42886199b4a2bbc1f4782f Mon Sep 17 00:00:00 2001 From: Shreyas Pimpalgaonkar Date: Fri, 23 Aug 2024 14:07:24 -0400 Subject: [PATCH 62/74] Shreyas/kgsearchresult model (#957) * return type to kg_search_result * add model * local and global results * modify config * add models * up * fix config path * fix models --- js/sdk/src/models.tsx | 20 ++++++ py/cli/commands/server.py | 3 + py/cli/utils/docker_utils.py | 9 +-- py/core/__init__.py | 2 + py/core/base/__init__.py | 2 + py/core/base/abstractions/__init__.py | 4 ++ py/core/base/abstractions/search.py | 29 +++++--- .../base/api/models/retrieval/responses.py | 2 +- py/core/configs/neo4j_kg.toml | 2 +- .../pipes/retrieval/kg_search_search_pipe.py | 19 +++-- py/core/pipes/retrieval/vector_search_pipe.py | 1 + py/sdk/models.py | 72 ++++++++++++++++--- 12 files changed, 127 insertions(+), 38 deletions(-) diff --git a/js/sdk/src/models.tsx b/js/sdk/src/models.tsx index d2b74b61d..1d135b204 100644 --- a/js/sdk/src/models.tsx +++ b/js/sdk/src/models.tsx @@ -60,6 +60,26 @@ export interface KGSearchSettings { max_llm_queries_for_global_search?: number; local_search_limits?: Record; } + +export interface KGLocalSearchResult { + query: string; + entities: Record; + relationships: Record; + communities: Record; +} + +export interface KGGlobalSearchResult { + query: string; + search_result: string[]; +} + +export interface KGSearchResult { + local_result?: KGLocalSearchResult; + global_result?: KGGlobalSearchResult; +} + + + export interface Message { role: string; content: string; diff --git a/py/cli/commands/server.py b/py/cli/commands/server.py index 946c3bc98..678d0a029 100644 --- a/py/cli/commands/server.py +++ b/py/cli/commands/server.py @@ -217,6 +217,7 @@ def serve( ).replace(":", "") if docker: + run_docker_serve( client, host, @@ -226,6 +227,8 @@ def serve( exclude_postgres, project_name, image, + config_name, + config_path, ) if ( "pytest" in sys.modules diff --git a/py/cli/utils/docker_utils.py b/py/cli/utils/docker_utils.py index 4d6e48824..289bf3a1a 100644 --- a/py/cli/utils/docker_utils.py +++ b/py/cli/utils/docker_utils.py @@ -110,19 +110,20 @@ def run_docker_serve( exclude_postgres: bool, project_name: str, image: str, + config_name: Optional[str] = None, config_path: Optional[str] = None, ): check_set_docker_env_vars(exclude_neo4j, exclude_postgres) set_ollama_api_base(exclude_ollama) + if config_path and config_name: + raise ValueError("Cannot specify both config_path and config_name") + if config_path: config = R2RConfig.from_toml(config_path) else: - if hasattr(client, "config_name"): - config_name = client.config_name - else: + if not config_name: config_name = "default" - config = R2RConfig.from_toml(R2RBuilder.CONFIG_OPTIONS[config_name]) if config.parsing.provider == "unstructured" and not image: diff --git a/py/core/__init__.py b/py/core/__init__.py index 28f50891d..fbd510c8a 100644 --- a/py/core/__init__.py +++ b/py/core/__init__.py @@ -73,6 +73,8 @@ "Prompt", # Search abstractions "AggregateSearchResult", + "KGLocalSearchResult", + "KGGlobalSearchResult", "KGSearchResult", "KGSearchSettings", "VectorSearchResult", diff --git a/py/core/base/__init__.py b/py/core/base/__init__.py index 5fdb09128..48ac9dbdb 100644 --- a/py/core/base/__init__.py +++ b/py/core/base/__init__.py @@ -43,6 +43,8 @@ "Prompt", # Search abstractions "AggregateSearchResult", + "KGLocalSearchResult", + "KGGlobalSearchResult", "KGSearchResult", "KGSearchSettings", "VectorSearchResult", diff --git a/py/core/base/abstractions/__init__.py b/py/core/base/abstractions/__init__.py index 34f64ad71..971ad4c1c 100644 --- a/py/core/base/abstractions/__init__.py +++ b/py/core/base/abstractions/__init__.py @@ -31,6 +31,8 @@ from .restructure import KGEnrichmentSettings from .search import ( AggregateSearchResult, + KGLocalSearchResult, + KGGlobalSearchResult, KGSearchResult, KGSearchSettings, VectorSearchResult, @@ -78,6 +80,8 @@ "Prompt", # Search abstractions "AggregateSearchResult", + "KGLocalSearchResult", + "KGGlobalSearchResult", "KGSearchResult", "KGSearchSettings", "VectorSearchResult", diff --git a/py/core/base/abstractions/search.py b/py/core/base/abstractions/search.py index 565728794..d8e3bca0d 100644 --- a/py/core/base/abstractions/search.py +++ b/py/core/base/abstractions/search.py @@ -54,14 +54,12 @@ class Config: }, } - class KGLocalSearchResult(BaseModel): """Result of a local knowledge graph search operation.""" - query: str - entities: list[dict[str, Any]] - relationships: list[dict[str, Any]] - communities: list[dict[str, Any]] + entities: dict[str, Any] + relationships: dict[str, Any] + communities: dict[str, Any] def __str__(self) -> str: return f"LocalSearchResult(query={self.query}, search_result={self.search_result})" @@ -72,35 +70,44 @@ def __repr__(self) -> str: class KGGlobalSearchResult(BaseModel): """Result of a global knowledge graph search operation.""" - query: str - search_result: list[Dict[str, Any]] + search_result: list[str] def __str__(self) -> str: - return f"GlobalSearchResult(query={self.query}, search_result={self.search_result})" + return f"KGGlobalSearchResult(query={self.query}, search_result={self.search_result})" def __repr__(self) -> str: return self.__str__() + def dict(self) -> dict: + return { + "query": self.query, + "search_result": self.search_result + } class KGSearchResult(BaseModel): """Result of a knowledge graph search operation.""" - local_result: Optional[KGLocalSearchResult] = None global_result: Optional[KGGlobalSearchResult] = None - + def __str__(self) -> str: return f"KGSearchResult(local_result={self.local_result}, global_result={self.global_result})" def __repr__(self) -> str: return self.__str__() + + def dict(self) -> dict: + return { + "local_result": self.local_result.dict() if self.local_result else None, + "global_result": self.global_result.dict() if self.global_result else None + } class AggregateSearchResult(BaseModel): """Result of an aggregate search operation.""" vector_search_results: Optional[list[VectorSearchResult]] - kg_search_results: Optional[KGSearchResult] = None + kg_search_results: Optional[list[KGSearchResult]] = None def __str__(self) -> str: return f"AggregateSearchResult(vector_search_results={self.vector_search_results}, kg_search_results={self.kg_search_results})" diff --git a/py/core/base/api/models/retrieval/responses.py b/py/core/base/api/models/retrieval/responses.py index 6bb086971..e5c87a091 100644 --- a/py/core/base/api/models/retrieval/responses.py +++ b/py/core/base/api/models/retrieval/responses.py @@ -11,7 +11,7 @@ class SearchResponse(BaseModel): ..., description="List of vector search results", ) - kg_search_results: Optional[KGSearchResult] = Field( + kg_search_results: Optional[list[KGSearchResult]] = Field( None, description="Knowledge graph search results, if applicable", ) diff --git a/py/core/configs/neo4j_kg.toml b/py/core/configs/neo4j_kg.toml index cbaa13a0d..ee177aff6 100644 --- a/py/core/configs/neo4j_kg.toml +++ b/py/core/configs/neo4j_kg.toml @@ -28,7 +28,7 @@ kg_extraction_prompt = "graphrag_triplet_extraction_zero_shot" [kg.kg_extraction_config] model = "gpt-4o-mini" - [kg.kg_enrichment_config] + [kg.kg_enrichment_settings] max_knowledge_triples = 100 generation_config = { model = "gpt-4o-mini" } # and other params leiden_params = { max_cluster_size = 1000 } # more params in graspologic/partition/leiden.py diff --git a/py/core/pipes/retrieval/kg_search_search_pipe.py b/py/core/pipes/retrieval/kg_search_search_pipe.py index fcd37889a..e81c0eb51 100644 --- a/py/core/pipes/retrieval/kg_search_search_pipe.py +++ b/py/core/pipes/retrieval/kg_search_search_pipe.py @@ -13,6 +13,7 @@ PipeType, PromptProvider, RunLoggingSingleton, + R2RException ) from core.base.abstractions.search import ( KGGlobalSearchResult, @@ -24,7 +25,6 @@ logger = logging.getLogger(__name__) - class KGSearchSearchPipe(GeneratorPipe): """ Embeds and stores documents using a specified embedding model and database. @@ -132,12 +132,11 @@ async def local_search( ) all_search_results.append(search_result) - yield KGLocalSearchResult( - query=message, - entities=all_search_results[0], - relationships=all_search_results[1], - communities=all_search_results[2], - ) + + if len(all_search_results[0])==0: + raise R2RException("No search results found. Please make sure you have run the KG enrichment step before running the search: r2r enrich-graph", 400) + + yield KGLocalSearchResult(query=message, entities=all_search_results[0], relationships=all_search_results[1], communities=all_search_results[2]) async def global_search( self, @@ -217,11 +216,9 @@ async def process_community(merged_report): generation_config=kg_search_settings.kg_search_generation_config, ) - output = output.choices[0].message.content + output = [output.choices[0].message.content] - yield KGGlobalSearchResult( - query=message, search_result=output, citations=None - ) + yield KGGlobalSearchResult(query=message, search_result=output) async def _run_logic( self, diff --git a/py/core/pipes/retrieval/vector_search_pipe.py b/py/core/pipes/retrieval/vector_search_pipe.py index d01317f5f..a14f1fa46 100644 --- a/py/core/pipes/retrieval/vector_search_pipe.py +++ b/py/core/pipes/retrieval/vector_search_pipe.py @@ -91,6 +91,7 @@ async def search( result.metadata["associatedQuery"] = message results.append(result) yield result + await self.enqueue_log( run_id=run_id, key="search_results", diff --git a/py/sdk/models.py b/py/sdk/models.py index 571659dfb..69d481a89 100644 --- a/py/sdk/models.py +++ b/py/sdk/models.py @@ -187,27 +187,79 @@ class Config: }, } +class KGLocalSearchResult(BaseModel): + query: str + entities: list[dict[str, Any]] + relationships: list[dict[str, Any]] + communities: list[dict[str, Any]] -class KGSearchResult(BaseModel): + def __str__(self) -> str: + return f"KGLocalSearchResult(query={self.query}, entities={self.entities}, relationships={self.relationships}, communities={self.communities})" + + def dict(self) -> dict: + return { + "query": self.query, + "entities": self.entities, + "relationships": self.relationships, + "communities": self.communities + } + +class KGGlobalSearchResult(BaseModel): query: str - results: list[Dict[str, Any]] + search_result: list[str] + + def __str__(self) -> str: + return f"KGGlobalSearchResult(query={self.query}, search_result={self.search_result})" + + def __repr__(self) -> str: + return self.__str__() + + def dict(self) -> dict: + return { + "query": self.query, + "search_result": self.search_result + } + + +class KGSearchResult(BaseModel): + local_result: Optional[KGLocalSearchResult] = None + global_result: Optional[KGGlobalSearchResult] = None + + def __str__(self) -> str: + return f"KGSearchResult(local_result={self.local_result}, global_result={self.global_result})" + + def __repr__(self) -> str: + return self.__str__() + + def dict(self) -> dict: + return { + "local_result": self.local_result.dict() if self.local_result else None, + "global_result": self.global_result.dict() if self.global_result else None + } class Config: json_schema_extra = { "example": { - "query": "What is the capital of France?", - "results": [ - { + "local_result": { + "query": "What is the capital of France?", + "entities": { "Paris": { "name": "Paris", - "description": "Paris is the capital of France.", + "description": "Paris is the capital of France." } - } - ], + }, + "relationships": {}, + "communities": {}, + }, + "global_result": { + "query": "What is the capital of France?", + "search_result": [ + "Paris is the capital and most populous city of France." + ] + } } } - class R2RException(Exception): def __init__( self, message: str, status_code: int, detail: Optional[Any] = None @@ -419,7 +471,7 @@ class SearchResponse(BaseModel): ..., description="List of vector search results", ) - kg_search_results: Optional[KGSearchResult] = Field( + kg_search_results: Optional[list[KGSearchResult]] = Field( None, description="Knowledge graph search results, if applicable", ) From 6826f400d05ba357ae0d50cb4a379fbf9fedba0c Mon Sep 17 00:00:00 2001 From: Nolan Tremelling <34580718+NolanTrem@users.noreply.github.com> Date: Fri, 23 Aug 2024 11:23:25 -0700 Subject: [PATCH 63/74] Login and refresh token bug (#959) * Update Actions * Fix bug in login with refresh token --- .../r2rClientIntegrationUser.test.ts | 1 - js/sdk/package-lock.json | 12 ++----- js/sdk/package.json | 3 +- js/sdk/pnpm-lock.yaml | 25 ------------- js/sdk/src/r2rClient.ts | 35 +++++++++++-------- py/core/providers/auth/r2r_auth.py | 2 +- 6 files changed, 24 insertions(+), 54 deletions(-) diff --git a/js/sdk/__tests__/r2rClientIntegrationUser.test.ts b/js/sdk/__tests__/r2rClientIntegrationUser.test.ts index 0154a54a1..c3fb12b48 100644 --- a/js/sdk/__tests__/r2rClientIntegrationUser.test.ts +++ b/js/sdk/__tests__/r2rClientIntegrationUser.test.ts @@ -57,7 +57,6 @@ describe("r2rClient Integration Tests", () => { await expect( client.updateFiles(updated_file, { document_ids: ["0b80081e-a37a-579f-a06d-7d2032435d65"], - metadatas: [{ title: "updated_karamozov.txt" }], }), ).resolves.not.toThrow(); }); diff --git a/js/sdk/package-lock.json b/js/sdk/package-lock.json index 143b567ea..ad28a4326 100644 --- a/js/sdk/package-lock.json +++ b/js/sdk/package-lock.json @@ -1,12 +1,12 @@ { "name": "r2r-js", - "version": "1.2.15", + "version": "0.3.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "r2r-js", - "version": "1.2.15", + "version": "0.3.0", "license": "ISC", "dependencies": { "axios": "^1.7.4", @@ -17,7 +17,6 @@ }, "devDependencies": { "@types/jest": "^29.5.12", - "@types/mocha": "^10.0.7", "@types/node": "^20.14.15", "@types/uuid": "^10.0.0", "jest": "^29.7.0", @@ -1152,13 +1151,6 @@ "pretty-format": "^29.0.0" } }, - "node_modules/@types/mocha": { - "version": "10.0.7", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.7.tgz", - "integrity": "sha512-GN8yJ1mNTcFcah/wKEFIJckJx9iJLoMSzWcfRRuxz/Jk+U6KQNnml+etbtxFK8lPjzOw3zp4Ha/kjSst9fsHYw==", - "dev": true, - "license": "MIT" - }, "node_modules/@types/node": { "version": "20.16.1", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.1.tgz", diff --git a/js/sdk/package.json b/js/sdk/package.json index 91d8ef6fa..ff87d8757 100644 --- a/js/sdk/package.json +++ b/js/sdk/package.json @@ -1,6 +1,6 @@ { "name": "r2r-js", - "version": "1.2.15", + "version": "0.3.0", "description": "", "main": "dist/index.js", "browser": "dist/index.browser.js", @@ -32,7 +32,6 @@ }, "devDependencies": { "@types/jest": "^29.5.12", - "@types/mocha": "^10.0.7", "@types/node": "^20.14.15", "@types/uuid": "^10.0.0", "jest": "^29.7.0", diff --git a/js/sdk/pnpm-lock.yaml b/js/sdk/pnpm-lock.yaml index c38e0ba65..758f6559e 100644 --- a/js/sdk/pnpm-lock.yaml +++ b/js/sdk/pnpm-lock.yaml @@ -23,12 +23,6 @@ importers: specifier: ^10.0.0 version: 10.0.0 devDependencies: - "@types/jest": - specifier: ^29.5.12 - version: 29.5.12 - "@types/mocha": - specifier: ^10.0.7 - version: 10.0.7 "@types/node": specifier: ^20.14.15 version: 20.14.15 @@ -594,18 +588,6 @@ packages: integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==, } - "@types/jest@29.5.12": - resolution: - { - integrity: sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==, - } - - "@types/mocha@10.0.7": - resolution: - { - integrity: sha512-GN8yJ1mNTcFcah/wKEFIJckJx9iJLoMSzWcfRRuxz/Jk+U6KQNnml+etbtxFK8lPjzOw3zp4Ha/kjSst9fsHYw==, - } - "@types/node@20.14.15": resolution: { @@ -2784,13 +2766,6 @@ snapshots: dependencies: "@types/istanbul-lib-report": 3.0.3 - "@types/jest@29.5.12": - dependencies: - expect: 29.7.0 - pretty-format: 29.7.0 - - "@types/mocha@10.0.7": {} - "@types/node@20.14.15": dependencies: undici-types: 5.26.5 diff --git a/js/sdk/src/r2rClient.ts b/js/sdk/src/r2rClient.ts index be5f26cc5..0bdc1c546 100644 --- a/js/sdk/src/r2rClient.ts +++ b/js/sdk/src/r2rClient.ts @@ -5,7 +5,6 @@ import axios, { AxiosRequestConfig, } from "axios"; import FormData from "form-data"; -import { URLSearchParams } from "url"; let fs: any; if (typeof window === "undefined") { @@ -112,19 +111,24 @@ export class r2rClient { if (typeof FormData !== "undefined" && options.data instanceof FormData) { config.data = options.data; delete config.headers["Content-Type"]; - } else if ( - typeof URLSearchParams !== "undefined" && - options.data instanceof URLSearchParams - ) { - config.data = options.data.toString(); - config.headers["Content-Type"] = "application/x-www-form-urlencoded"; } else if (typeof options.data === "object") { - config.data = JSON.stringify(options.data); - if (method !== "DELETE") { - config.headers["Content-Type"] = "application/json"; + if ( + config.headers["Content-Type"] === "application/x-www-form-urlencoded" + ) { + config.data = Object.keys(options.data) + .map( + (key) => + `${encodeURIComponent(key)}=${encodeURIComponent(options.data[key])}`, + ) + .join("&"); } else { - config.headers["Content-Type"] = "application/json"; config.data = JSON.stringify(options.data); + if (method !== "DELETE") { + config.headers["Content-Type"] = "application/json"; + } else { + config.headers["Content-Type"] = "application/json"; + config.data = JSON.stringify(options.data); + } } } else { config.data = options.data; @@ -223,12 +227,13 @@ export class r2rClient { email: string, password: string, ): Promise<{ access_token: TokenInfo; refresh_token: TokenInfo }> { - const formData = new URLSearchParams(); - formData.append("username", email); - formData.append("password", password); + const data = { + username: email, + password: password, + }; const response = await this._makeRequest("POST", "login", { - data: formData, + data: data, headers: { "Content-Type": "application/x-www-form-urlencoded", }, diff --git a/py/core/providers/auth/r2r_auth.py b/py/core/providers/auth/r2r_auth.py index d82257f73..6fbc3aba2 100644 --- a/py/core/providers/auth/r2r_auth.py +++ b/py/core/providers/auth/r2r_auth.py @@ -197,7 +197,7 @@ def login(self, email: str, password: str) -> Dict[str, Token]: raise R2RException(status_code=401, message="Email not verified") access_token = self.create_access_token(data={"sub": user.email}) - refresh_token = self.create_refresh_token() + refresh_token = self.create_refresh_token(data={"sub": user.email}) return { "access_token": Token(token=access_token, token_type="access"), "refresh_token": Token(token=refresh_token, token_type="refresh"), From b5c3db0fba8f4608b03d38943b4e0b13d539556e Mon Sep 17 00:00:00 2001 From: Nolan Tremelling <34580718+NolanTrem@users.noreply.github.com> Date: Fri, 23 Aug 2024 11:26:56 -0700 Subject: [PATCH 64/74] Point pytest to linux (#960) --- .github/workflows/py-ci-cd.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/py-ci-cd.yml b/.github/workflows/py-ci-cd.yml index 2c40e8801..d61249ed5 100644 --- a/.github/workflows/py-ci-cd.yml +++ b/.github/workflows/py-ci-cd.yml @@ -11,7 +11,7 @@ on: jobs: pre-commit: continue-on-error: true - runs-on: ubuntu-latest + runs-on: [ self-hosted, Linux ] steps: - name: Checkout code @@ -41,7 +41,7 @@ jobs: pytest: continue-on-error: true - runs-on: ubuntu-latest + runs-on: [ self-hosted, Linux ] timeout-minutes: 15 env: From 7b1d406e6bc2fdab0f50fdfbeeef7e7032c5e434 Mon Sep 17 00:00:00 2001 From: emrgnt-cmplxty <68796651+emrgnt-cmplxty@users.noreply.github.com> Date: Fri, 23 Aug 2024 11:40:49 -0700 Subject: [PATCH 65/74] collection docs (#955) --- py/core/base/abstractions/search.py | 2 +- py/core/base/providers/auth.py | 2 +- py/core/main/api/routes/auth/base.py | 3 ++- py/core/main/api/routes/retrieval/base.py | 2 +- py/core/main/services/auth_service.py | 8 +++++++- py/core/providers/database/vecs/collection.py | 6 +++--- py/core/providers/database/vector.py | 5 +---- 7 files changed, 16 insertions(+), 12 deletions(-) diff --git a/py/core/base/abstractions/search.py b/py/core/base/abstractions/search.py index d8e3bca0d..07e923055 100644 --- a/py/core/base/abstractions/search.py +++ b/py/core/base/abstractions/search.py @@ -122,7 +122,7 @@ def dict(self) -> dict: if self.vector_search_results else [] ), - "kg_search_results": self.kg_search_results or [], + "kg_search_results": self.kg_search_results or None, } diff --git a/py/core/base/providers/auth.py b/py/core/base/providers/auth.py index 17f2a2508..cc7493b9e 100644 --- a/py/core/base/providers/auth.py +++ b/py/core/base/providers/auth.py @@ -82,7 +82,7 @@ def register(self, email: str, password: str) -> Dict[str, str]: pass @abstractmethod - def verify_email(self, verification_code: str) -> Dict[str, str]: + def verify_email(self, email: str, verification_code: str) -> Dict[str, str]: pass @abstractmethod diff --git a/py/core/main/api/routes/auth/base.py b/py/core/main/api/routes/auth/base.py index 9dac245b9..da21ddb01 100644 --- a/py/core/main/api/routes/auth/base.py +++ b/py/core/main/api/routes/auth/base.py @@ -45,6 +45,7 @@ async def register_app( ) @self.base_endpoint async def verify_email_app( + email: EmailStr = Body(..., description="User's email address"), verification_code: str = Body( ..., description="Email verification code" ) @@ -55,7 +56,7 @@ async def verify_email_app( This endpoint is used to confirm a user's email address using the verification code sent to their email after registration. """ - result = await self.engine.averify_email(verification_code) + result = await self.engine.averify_email(email, verification_code) return GenericMessageResponse(message=result["message"]) @self.router.post("/login", response_model=WrappedTokenResponse) diff --git a/py/core/main/api/routes/retrieval/base.py b/py/core/main/api/routes/retrieval/base.py index 87dbb789d..1e2601de9 100644 --- a/py/core/main/api/routes/retrieval/base.py +++ b/py/core/main/api/routes/retrieval/base.py @@ -62,7 +62,7 @@ async def search_app( description=search_descriptions.get("kg_search_settings"), ), auth_user=Depends(self.engine.providers.auth.auth_wrapper), - ) -> WrappedSearchResponse: + ) -> WrappedSearchResponse: """ Perform a search query on the vector database and knowledge graph. diff --git a/py/core/main/services/auth_service.py b/py/core/main/services/auth_service.py index d704ae91d..c18024404 100644 --- a/py/core/main/services/auth_service.py +++ b/py/core/main/services/auth_service.py @@ -35,7 +35,7 @@ async def register(self, email: str, password: str) -> UserResponse: return self.providers.auth.register(email, password) @telemetry_event("VerifyEmail") - async def verify_email(self, verification_code: str) -> bool: + async def verify_email(self, email: str, verification_code: str) -> bool: if not self.config.auth.require_email_verification: raise R2RException( @@ -49,6 +49,12 @@ async def verify_email(self, verification_code: str) -> bool: raise R2RException( status_code=400, message="Invalid or expired verification code" ) + + user = self.providers.database.relational.get_user_by_id(user_id) + if not user or user.email != email: + raise R2RException( + status_code=400, message="Invalid or expired verification code" + ) self.providers.database.relational.mark_user_as_verified(user_id) self.providers.database.relational.remove_verification_code( diff --git a/py/core/providers/database/vecs/collection.py b/py/core/providers/database/vecs/collection.py index a692ff48d..44cf7c290 100644 --- a/py/core/providers/database/vecs/collection.py +++ b/py/core/providers/database/vecs/collection.py @@ -378,7 +378,7 @@ def _create(self): tsvector_update_trigger(fts, 'pg_catalog.english', text); """ ) - ) + ) return self def _drop(self): @@ -1168,12 +1168,12 @@ def _build_table(name: str, meta: MetaData, dimension: int) -> Table: extend_existing=True, ) - # Add GIN index for full-text search and trigram similarity + # # Add GIN index for full-text search and trigram similarity Index( f"idx_{name}_fts_trgm", table.c.fts, table.c.text, postgresql_using="gin", - postgresql_ops={"text": "gin_trgm_ops"}, # Remove gin_tsvector_ops + postgresql_ops={"text": "gin_trgm_ops"}, # alternative, gin_tsvector_ops ) return table diff --git a/py/core/providers/database/vector.py b/py/core/providers/database/vector.py index 3a140b556..cc1034140 100644 --- a/py/core/providers/database/vector.py +++ b/py/core/providers/database/vector.py @@ -131,10 +131,7 @@ def _initialize_vector_db(self, dimension: int) -> None: self.collection = self.vx.get_or_create_collection( name=self.collection_name, dimension=dimension ) - self.collection.create_index(measure="cosine_distance") - self.collection.create_index(measure="l2_distance") - self.collection.create_index(measure="max_inner_product") - + def upsert(self, entry: VectorEntry) -> None: if self.collection is None: raise ValueError( From 8ad54bef6c8fc666df94bc3b29b8e445f1517572 Mon Sep 17 00:00:00 2001 From: emrgnt-cmplxty <68796651+emrgnt-cmplxty@users.noreply.github.com> Date: Fri, 23 Aug 2024 11:47:20 -0700 Subject: [PATCH 66/74] Feature/merge dev to main (#962) * merge dev and main * git rm * add back collection fix --- py/cli/commands/server.py | 2 +- py/cli/utils/docker_utils.py | 2 +- py/core/base/abstractions/__init__.py | 2 +- py/core/base/abstractions/search.py | 22 +++++++++----- py/core/base/providers/auth.py | 4 ++- py/core/main/api/routes/auth/base.py | 2 +- py/core/main/api/routes/retrieval/base.py | 2 +- py/core/main/assembly/config.py | 25 ++++++++++++++-- py/core/main/services/auth_service.py | 2 +- py/core/parsers/structured/csv_parser.py | 4 +-- .../pipes/retrieval/kg_search_search_pipe.py | 18 +++++++---- py/core/providers/database/postgres.py | 2 +- py/core/providers/database/vecs/collection.py | 6 ++-- py/core/providers/database/vector.py | 2 +- py/sdk/models.py | 30 +++++++++++-------- 15 files changed, 83 insertions(+), 42 deletions(-) diff --git a/py/cli/commands/server.py b/py/cli/commands/server.py index 678d0a029..ea7fbd84f 100644 --- a/py/cli/commands/server.py +++ b/py/cli/commands/server.py @@ -217,7 +217,7 @@ def serve( ).replace(":", "") if docker: - + run_docker_serve( client, host, diff --git a/py/cli/utils/docker_utils.py b/py/cli/utils/docker_utils.py index 289bf3a1a..efe874e00 100644 --- a/py/cli/utils/docker_utils.py +++ b/py/cli/utils/docker_utils.py @@ -377,7 +377,7 @@ def build_docker_command( os.environ["TRAEFIK_PORT"] = str(available_port + 1) os.environ["CONFIG_PATH"] = ( - os.path.basename(config_path) if config_path else "" + os.path.abspath(config_path) if config_path else "" ) os.environ["R2R_IMAGE"] = image or "" diff --git a/py/core/base/abstractions/__init__.py b/py/core/base/abstractions/__init__.py index 971ad4c1c..8284e60d4 100644 --- a/py/core/base/abstractions/__init__.py +++ b/py/core/base/abstractions/__init__.py @@ -31,8 +31,8 @@ from .restructure import KGEnrichmentSettings from .search import ( AggregateSearchResult, - KGLocalSearchResult, KGGlobalSearchResult, + KGLocalSearchResult, KGSearchResult, KGSearchSettings, VectorSearchResult, diff --git a/py/core/base/abstractions/search.py b/py/core/base/abstractions/search.py index 07e923055..54400794b 100644 --- a/py/core/base/abstractions/search.py +++ b/py/core/base/abstractions/search.py @@ -54,8 +54,10 @@ class Config: }, } + class KGLocalSearchResult(BaseModel): """Result of a local knowledge graph search operation.""" + query: str entities: dict[str, Any] relationships: dict[str, Any] @@ -70,6 +72,7 @@ def __repr__(self) -> str: class KGGlobalSearchResult(BaseModel): """Result of a global knowledge graph search operation.""" + query: str search_result: list[str] @@ -80,26 +83,29 @@ def __repr__(self) -> str: return self.__str__() def dict(self) -> dict: - return { - "query": self.query, - "search_result": self.search_result - } + return {"query": self.query, "search_result": self.search_result} + class KGSearchResult(BaseModel): """Result of a knowledge graph search operation.""" + local_result: Optional[KGLocalSearchResult] = None global_result: Optional[KGGlobalSearchResult] = None - + def __str__(self) -> str: return f"KGSearchResult(local_result={self.local_result}, global_result={self.global_result})" def __repr__(self) -> str: return self.__str__() - + def dict(self) -> dict: return { - "local_result": self.local_result.dict() if self.local_result else None, - "global_result": self.global_result.dict() if self.global_result else None + "local_result": ( + self.local_result.dict() if self.local_result else None + ), + "global_result": ( + self.global_result.dict() if self.global_result else None + ), } diff --git a/py/core/base/providers/auth.py b/py/core/base/providers/auth.py index cc7493b9e..5e6b0cbad 100644 --- a/py/core/base/providers/auth.py +++ b/py/core/base/providers/auth.py @@ -82,7 +82,9 @@ def register(self, email: str, password: str) -> Dict[str, str]: pass @abstractmethod - def verify_email(self, email: str, verification_code: str) -> Dict[str, str]: + def verify_email( + self, email: str, verification_code: str + ) -> Dict[str, str]: pass @abstractmethod diff --git a/py/core/main/api/routes/auth/base.py b/py/core/main/api/routes/auth/base.py index da21ddb01..f024709ed 100644 --- a/py/core/main/api/routes/auth/base.py +++ b/py/core/main/api/routes/auth/base.py @@ -48,7 +48,7 @@ async def verify_email_app( email: EmailStr = Body(..., description="User's email address"), verification_code: str = Body( ..., description="Email verification code" - ) + ), ): """ Verify a user's email address. diff --git a/py/core/main/api/routes/retrieval/base.py b/py/core/main/api/routes/retrieval/base.py index 1e2601de9..87dbb789d 100644 --- a/py/core/main/api/routes/retrieval/base.py +++ b/py/core/main/api/routes/retrieval/base.py @@ -62,7 +62,7 @@ async def search_app( description=search_descriptions.get("kg_search_settings"), ), auth_user=Depends(self.engine.providers.auth.auth_wrapper), - ) -> WrappedSearchResponse: + ) -> WrappedSearchResponse: """ Perform a search query on the vector database and knowledge graph. diff --git a/py/core/main/assembly/config.py b/py/core/main/assembly/config.py index 302b32686..7854b8797 100644 --- a/py/core/main/assembly/config.py +++ b/py/core/main/assembly/config.py @@ -1,7 +1,8 @@ import logging import os from enum import Enum -from typing import Any +from pathlib import Path +from typing import Any, Optional import toml from pydantic import BaseModel @@ -58,7 +59,13 @@ class R2RConfig: prompt: PromptConfig agent: AgentConfig - def __init__(self, config_data: dict[str, Any]): + def __init__( + self, config_data: dict[str, Any], base_path: Optional[Path] = None + ): + """ + :param config_data: dictionary of configuration parameters + :param base_path: base path when a relative path is specified for the prompts directory + """ # Load the default configuration default_config = self.load_default_config() @@ -79,6 +86,18 @@ def __init__(self, config_data: dict[str, Any]): and default_config[section]["provider"] != "null" ): self._validate_config_section(default_config, section, keys) + if ( + section == "prompt" + and "file_path" in default_config[section] + and not Path( + default_config[section]["file_path"] + ).is_absolute() + and base_path + ): + # Make file_path absolute and relative to the base path + default_config[section]["file_path"] = str( + base_path / default_config[section]["file_path"] + ) setattr(self, section, default_config[section]) self.completion = CompletionConfig.create(**self.completion) # override GenerationConfig defaults @@ -122,7 +141,7 @@ def from_toml(cls, config_path: str = None) -> "R2RConfig": with open(config_path) as f: config_data = toml.load(f) - return cls(config_data) + return cls(config_data, base_path=Path(config_path).parent) def to_toml(self): config_data = { diff --git a/py/core/main/services/auth_service.py b/py/core/main/services/auth_service.py index c18024404..6e83cb726 100644 --- a/py/core/main/services/auth_service.py +++ b/py/core/main/services/auth_service.py @@ -49,7 +49,7 @@ async def verify_email(self, email: str, verification_code: str) -> bool: raise R2RException( status_code=400, message="Invalid or expired verification code" ) - + user = self.providers.database.relational.get_user_by_id(user_id) if not user or user.email != email: raise R2RException( diff --git a/py/core/parsers/structured/csv_parser.py b/py/core/parsers/structured/csv_parser.py index cc58c52a5..2d7b40641 100644 --- a/py/core/parsers/structured/csv_parser.py +++ b/py/core/parsers/structured/csv_parser.py @@ -1,4 +1,4 @@ -from typing import IO, AsyncGenerator, Union +from typing import IO, AsyncGenerator, Optional, Union from core.base.abstractions.document import DataType from core.base.parsers.base_parser import AsyncParser @@ -36,7 +36,7 @@ def __init__(self): self.StringIO = StringIO def get_delimiter( - self, file_path: str | None = None, file: IO[bytes] | None = None + self, file_path: Optional[str] = None, file: Optional[IO[bytes]] = None ): sniffer = self.csv.Sniffer() diff --git a/py/core/pipes/retrieval/kg_search_search_pipe.py b/py/core/pipes/retrieval/kg_search_search_pipe.py index e81c0eb51..ed3eed707 100644 --- a/py/core/pipes/retrieval/kg_search_search_pipe.py +++ b/py/core/pipes/retrieval/kg_search_search_pipe.py @@ -12,8 +12,8 @@ KGSearchSettings, PipeType, PromptProvider, + R2RException, RunLoggingSingleton, - R2RException ) from core.base.abstractions.search import ( KGGlobalSearchResult, @@ -25,6 +25,7 @@ logger = logging.getLogger(__name__) + class KGSearchSearchPipe(GeneratorPipe): """ Embeds and stores documents using a specified embedding model and database. @@ -132,11 +133,18 @@ async def local_search( ) all_search_results.append(search_result) - - if len(all_search_results[0])==0: - raise R2RException("No search results found. Please make sure you have run the KG enrichment step before running the search: r2r enrich-graph", 400) + if len(all_search_results[0]) == 0: + raise R2RException( + "No search results found. Please make sure you have run the KG enrichment step before running the search: r2r enrich-graph", + 400, + ) - yield KGLocalSearchResult(query=message, entities=all_search_results[0], relationships=all_search_results[1], communities=all_search_results[2]) + yield KGLocalSearchResult( + query=message, + entities=all_search_results[0], + relationships=all_search_results[1], + communities=all_search_results[2], + ) async def global_search( self, diff --git a/py/core/providers/database/postgres.py b/py/core/providers/database/postgres.py index 7fc699422..f46b6fa88 100644 --- a/py/core/providers/database/postgres.py +++ b/py/core/providers/database/postgres.py @@ -70,7 +70,7 @@ def __init__( ) or os.getenv("POSTGRES_VECS_COLLECTION") if not collection_name: raise ValueError( - "Error, please set a valid POSTGRES_VECS_COLLECTION environment variable or set a 'collection' in the 'database' settings of your `r2r.toml`." + "Error, please set a valid POSTGRES_VECS_COLLECTION environment variable or set a 'vecs_collection' in the 'database' settings of your `r2r.toml`." ) if not all([user, password, host, port, db_name, collection_name]): diff --git a/py/core/providers/database/vecs/collection.py b/py/core/providers/database/vecs/collection.py index 44cf7c290..d3215168f 100644 --- a/py/core/providers/database/vecs/collection.py +++ b/py/core/providers/database/vecs/collection.py @@ -378,7 +378,7 @@ def _create(self): tsvector_update_trigger(fts, 'pg_catalog.english', text); """ ) - ) + ) return self def _drop(self): @@ -1174,6 +1174,8 @@ def _build_table(name: str, meta: MetaData, dimension: int) -> Table: table.c.fts, table.c.text, postgresql_using="gin", - postgresql_ops={"text": "gin_trgm_ops"}, # alternative, gin_tsvector_ops + postgresql_ops={ + "text": "gin_trgm_ops" + }, # alternative, gin_tsvector_ops ) return table diff --git a/py/core/providers/database/vector.py b/py/core/providers/database/vector.py index cc1034140..64f76a99d 100644 --- a/py/core/providers/database/vector.py +++ b/py/core/providers/database/vector.py @@ -131,7 +131,7 @@ def _initialize_vector_db(self, dimension: int) -> None: self.collection = self.vx.get_or_create_collection( name=self.collection_name, dimension=dimension ) - + def upsert(self, entry: VectorEntry) -> None: if self.collection is None: raise ValueError( diff --git a/py/sdk/models.py b/py/sdk/models.py index 69d481a89..b7c6f0309 100644 --- a/py/sdk/models.py +++ b/py/sdk/models.py @@ -187,6 +187,7 @@ class Config: }, } + class KGLocalSearchResult(BaseModel): query: str entities: list[dict[str, Any]] @@ -195,15 +196,16 @@ class KGLocalSearchResult(BaseModel): def __str__(self) -> str: return f"KGLocalSearchResult(query={self.query}, entities={self.entities}, relationships={self.relationships}, communities={self.communities})" - + def dict(self) -> dict: return { "query": self.query, "entities": self.entities, "relationships": self.relationships, - "communities": self.communities + "communities": self.communities, } + class KGGlobalSearchResult(BaseModel): query: str search_result: list[str] @@ -213,12 +215,9 @@ def __str__(self) -> str: def __repr__(self) -> str: return self.__str__() - + def dict(self) -> dict: - return { - "query": self.query, - "search_result": self.search_result - } + return {"query": self.query, "search_result": self.search_result} class KGSearchResult(BaseModel): @@ -230,11 +229,15 @@ def __str__(self) -> str: def __repr__(self) -> str: return self.__str__() - + def dict(self) -> dict: return { - "local_result": self.local_result.dict() if self.local_result else None, - "global_result": self.global_result.dict() if self.global_result else None + "local_result": ( + self.local_result.dict() if self.local_result else None + ), + "global_result": ( + self.global_result.dict() if self.global_result else None + ), } class Config: @@ -245,7 +248,7 @@ class Config: "entities": { "Paris": { "name": "Paris", - "description": "Paris is the capital of France." + "description": "Paris is the capital of France.", } }, "relationships": {}, @@ -255,11 +258,12 @@ class Config: "query": "What is the capital of France?", "search_result": [ "Paris is the capital and most populous city of France." - ] - } + ], + }, } } + class R2RException(Exception): def __init__( self, message: str, status_code: int, detail: Optional[Any] = None From d603a6b911f577d2b8ef4915bf697418fae96c8c Mon Sep 17 00:00:00 2001 From: emrgnt-cmplxty <68796651+emrgnt-cmplxty@users.noreply.github.com> Date: Fri, 23 Aug 2024 12:58:57 -0700 Subject: [PATCH 67/74] fix docker builds (#963) --- py/Dockerfile | 7 ++++++- py/Dockerfile.unstructured | 5 ++++- py/core/providers/database/group.py | 2 +- py/core/providers/database/relational.py | 12 +++++------- py/core/providers/database/tokens.py | 2 +- py/core/providers/database/user.py | 2 +- py/r2r/__init__.py | 2 +- 7 files changed, 19 insertions(+), 13 deletions(-) diff --git a/py/Dockerfile b/py/Dockerfile index 9d1a79ecc..c24074eae 100644 --- a/py/Dockerfile +++ b/py/Dockerfile @@ -17,11 +17,15 @@ COPY . /app # Ensure that the working directory is set to /app/py WORKDIR /app/py +COPY scripts /app/py/scripts # Install dependencies RUN poetry config virtualenvs.create false \ && poetry install --extras "core" --no-dev --no-root \ - && pip install --no-cache-dir gunicorn uvicorn + && pip install --no-cache-dir gunicorn uvicorn \ + && poetry run python scripts/download_nltk_data.py + + # Final stage to keep the image small FROM python:3.10-slim @@ -36,6 +40,7 @@ WORKDIR /app # Copy the installed packages from the builder COPY --from=builder /usr/local/lib/python3.10/site-packages /usr/local/lib/python3.10/site-packages COPY --from=builder /usr/local/bin /usr/local/bin +COPY --from=builder /root/nltk_data /root/nltk_data # Copy the necessary application files COPY core /app/core diff --git a/py/Dockerfile.unstructured b/py/Dockerfile.unstructured index 7250e432e..0e35d7e0d 100644 --- a/py/Dockerfile.unstructured +++ b/py/Dockerfile.unstructured @@ -12,6 +12,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ ENV PATH="/root/.cargo/bin:${PATH}" WORKDIR /app +COPY scripts /app/py/scripts RUN pip install --no-cache-dir poetry @@ -23,7 +24,8 @@ RUN poetry config virtualenvs.create false \ && poetry install --extras "core" --no-dev --no-root \ && poetry add "unstructured[all-docs]" \ && poetry add "unstructured_client" \ - && pip install --no-cache-dir gunicorn uvicorn + && pip install --no-cache-dir gunicorn uvicorn \ + && poetry run python scripts/download_nltk_data.py # Create the final image FROM python:3.10-slim @@ -40,6 +42,7 @@ WORKDIR /app/py # Copy the installed packages from the builder COPY --from=builder /usr/local/lib/python3.10/site-packages /usr/local/lib/python3.10/site-packages COPY --from=builder /usr/local/bin /usr/local/bin +COPY --from=builder /root/nltk_data /root/nltk_data # Copy the application and config COPY py/core /app/py/core diff --git a/py/core/providers/database/group.py b/py/core/providers/database/group.py index 9ec8d48ce..8732b2da5 100644 --- a/py/core/providers/database/group.py +++ b/py/core/providers/database/group.py @@ -17,7 +17,7 @@ class GroupMixin(DatabaseMixin): def create_table(self) -> None: query = f""" CREATE TABLE IF NOT EXISTS {self._get_table_name('groups')} ( - group_id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), + group_id UUID PRIMARY KEY DEFAULT public.uuid_generate_v4(), name TEXT NOT NULL, description TEXT, created_at TIMESTAMPTZ DEFAULT NOW(), diff --git a/py/core/providers/database/relational.py b/py/core/providers/database/relational.py index e07282cbb..a0ff0b311 100644 --- a/py/core/providers/database/relational.py +++ b/py/core/providers/database/relational.py @@ -30,14 +30,12 @@ def execute_query(self, query, params=None): def _initialize_relational_db(self): with self.vx.Session() as sess: with sess.begin(): - try: - sess.execute( - text('CREATE EXTENSION IF NOT EXISTS "uuid-ossp";') - ) - except exc.ProgrammingError as e: - logger.error(f"Error enabling uuid-ossp extension: {e}") - raise + sess.execute( + text('CREATE EXTENSION IF NOT EXISTS "uuid-ossp";') + ) + sess.commit() + with sess.begin(): # Call create_table for each mixin for base_class in self.__class__.__bases__: if issubclass(base_class, DatabaseMixin): diff --git a/py/core/providers/database/tokens.py b/py/core/providers/database/tokens.py index 0149c263f..87a81cf9a 100644 --- a/py/core/providers/database/tokens.py +++ b/py/core/providers/database/tokens.py @@ -8,7 +8,7 @@ class BlacklistedTokensMixin(DatabaseMixin): def create_table(self): query = f""" CREATE TABLE IF NOT EXISTS {self._get_table_name('blacklisted_tokens')} ( - id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), + id UUID PRIMARY KEY DEFAULT public.uuid_generate_v4(), token TEXT NOT NULL, blacklisted_at TIMESTAMPTZ DEFAULT NOW() ); diff --git a/py/core/providers/database/user.py b/py/core/providers/database/user.py index 40e1c2dd5..773e62680 100644 --- a/py/core/providers/database/user.py +++ b/py/core/providers/database/user.py @@ -15,7 +15,7 @@ class UserMixin(DatabaseMixin): def create_table(self): query = f""" CREATE TABLE IF NOT EXISTS {self._get_table_name('users')} ( - user_id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), + user_id UUID PRIMARY KEY DEFAULT public.uuid_generate_v4(), email TEXT UNIQUE NOT NULL, hashed_password TEXT NOT NULL, is_superuser BOOLEAN DEFAULT FALSE, diff --git a/py/r2r/__init__.py b/py/r2r/__init__.py index d568f22a2..3d25a876d 100644 --- a/py/r2r/__init__.py +++ b/py/r2r/__init__.py @@ -13,4 +13,4 @@ __all__ += core.__all__ except ImportError: # Core dependencies not installed - pass + pass \ No newline at end of file From b1b99ad5094b55c161dbf8e8c795394f4a1abac1 Mon Sep 17 00:00:00 2001 From: Shreyas Pimpalgaonkar Date: Fri, 23 Aug 2024 17:02:01 -0400 Subject: [PATCH 68/74] Running unstructured docker + code cleanups (#964) --- py/Dockerfile.unstructured | 24 +++++++------- py/cli/utils/docker_utils.py | 4 +-- py/compose.yaml | 5 +++ py/core/base/abstractions/graph.py | 5 ++- py/core/base/abstractions/restructure.py | 2 -- py/core/base/abstractions/search.py | 2 +- .../base/api/models/restructure/responses.py | 4 +-- py/core/base/providers/database.py | 5 --- py/core/main/services/restructure_service.py | 2 +- py/core/pipes/kg/clustering.py | 3 +- py/core/providers/kg/neo4j/__init__.py | 2 ++ py/core/providers/kg/neo4j/provider.py | 31 +++---------------- .../providers/parsing/unstructured_parsing.py | 3 -- py/r2r/__init__.py | 2 +- py/sdk/models.py | 2 +- 15 files changed, 34 insertions(+), 62 deletions(-) diff --git a/py/Dockerfile.unstructured b/py/Dockerfile.unstructured index 0e35d7e0d..3bc775157 100644 --- a/py/Dockerfile.unstructured +++ b/py/Dockerfile.unstructured @@ -16,8 +16,9 @@ COPY scripts /app/py/scripts RUN pip install --no-cache-dir poetry -# Copy the dependencies files -COPY py/pyproject.toml py/poetry.lock* ./ +COPY . /app + +WORKDIR /app/py # Install the dependencies, including gunicorn, uvicorn, and unstructured RUN poetry config virtualenvs.create false \ @@ -37,7 +38,7 @@ RUN apt-get update \ libgl1-mesa-glx libglib2.0-0 \ && apt-get clean && rm -rf /var/lib/apt/lists/* -WORKDIR /app/py +WORKDIR /app # Copy the installed packages from the builder COPY --from=builder /usr/local/lib/python3.10/site-packages /usr/local/lib/python3.10/site-packages @@ -45,11 +46,16 @@ COPY --from=builder /usr/local/bin /usr/local/bin COPY --from=builder /root/nltk_data /root/nltk_data # Copy the application and config -COPY py/core /app/py/core +COPY core /app/core +COPY r2r /app/r2r COPY r2r.toml /app/r2r.toml -COPY py/pyproject.toml /app/py/pyproject.toml +COPY pyproject.toml /app/pyproject.toml -ENV PYTHONPATH="${PYTHONPATH}:/app/py" +# Expose the port +ARG PORT=8000 +ARG HOST=0.0.0.0 +ENV PORT=$PORT HOST=$HOST +EXPOSE $PORT # Download NLTK packages and initialize models RUN python3 -m nltk.downloader punkt averaged_perceptron_tagger \ @@ -58,11 +64,5 @@ RUN python3 -m nltk.downloader punkt averaged_perceptron_tagger \ # Set environment variables ENV TESSDATA_PREFIX=/usr/share/tesseract-ocr/4.00/tessdata -# Expose the port -ARG PORT=8000 -ARG HOST=0.0.0.0 -ENV PORT=$PORT HOST=$HOST -EXPOSE $PORT - # Run the application CMD ["sh", "-c", "uvicorn core.main.app_entry:app --host $HOST --port $PORT"] diff --git a/py/cli/utils/docker_utils.py b/py/cli/utils/docker_utils.py index efe874e00..2c51af108 100644 --- a/py/cli/utils/docker_utils.py +++ b/py/cli/utils/docker_utils.py @@ -126,8 +126,8 @@ def run_docker_serve( config_name = "default" config = R2RConfig.from_toml(R2RBuilder.CONFIG_OPTIONS[config_name]) - if config.parsing.provider == "unstructured" and not image: - image = "ragtoriches/prod_unstructured" + if "unstructured" in config.parsing.provider and not image: + image = "ragtoriches/r2r-unstructured" completion_provider = config.completion.provider completion_model = config.completion.generation_config.model diff --git a/py/compose.yaml b/py/compose.yaml index 5e8d518e5..fd0315c13 100644 --- a/py/compose.yaml +++ b/py/compose.yaml @@ -83,6 +83,11 @@ services: # Ollama - OLLAMA_API_BASE=${OLLAMA_API_BASE:-http://host.docker.internal:11434} + + # Unstructured + - UNSTRUCTURED_API_KEY=${UNSTRUCTURED_API_KEY:-} + - UNSTRUCTURED_API_URL=${UNSTRUCTURED_API_URL:-https://api.unstructured.io/general/v0/general} + networks: - r2r-network healthcheck: diff --git a/py/core/base/abstractions/graph.py b/py/core/base/abstractions/graph.py index 597aefbaf..b492cc22a 100644 --- a/py/core/base/abstractions/graph.py +++ b/py/core/base/abstractions/graph.py @@ -67,7 +67,7 @@ def __init__(self, **kwargs): if isinstance(self.attributes, str): try: self.attributes = json.loads(self.attributes) - except Exception as e: + except json.JSONDecodeError: self.attributes = self.attributes pass @@ -107,9 +107,8 @@ def __init__(self, **kwargs): if isinstance(self.attributes, str): try: self.attributes = json.loads(self.attributes) - except Exception as e: + except json.JSONDecodeError: self.attributes = self.attributes - pass @classmethod def from_dict( diff --git a/py/core/base/abstractions/restructure.py b/py/core/base/abstractions/restructure.py index 3d1dd9b01..b5f4d19f2 100644 --- a/py/core/base/abstractions/restructure.py +++ b/py/core/base/abstractions/restructure.py @@ -1,5 +1,3 @@ -from typing import Optional - from pydantic import BaseModel, Field from .llm import GenerationConfig diff --git a/py/core/base/abstractions/search.py b/py/core/base/abstractions/search.py index 54400794b..588f676f0 100644 --- a/py/core/base/abstractions/search.py +++ b/py/core/base/abstractions/search.py @@ -1,7 +1,7 @@ """Abstractions for search functionality.""" from enum import Enum -from typing import Any, Dict, Optional, Tuple +from typing import Any, Optional from uuid import UUID from pydantic import BaseModel, Field diff --git a/py/core/base/api/models/restructure/responses.py b/py/core/base/api/models/restructure/responses.py index 766cd6700..292d3252f 100644 --- a/py/core/base/api/models/restructure/responses.py +++ b/py/core/base/api/models/restructure/responses.py @@ -1,6 +1,4 @@ -from datetime import datetime -from typing import Any, Dict, List, Optional -from uuid import UUID +from typing import Any, Dict from pydantic import BaseModel diff --git a/py/core/base/providers/database.py b/py/core/base/providers/database.py index 354c7a2da..8b38b5d6d 100644 --- a/py/core/base/providers/database.py +++ b/py/core/base/providers/database.py @@ -1,11 +1,6 @@ import logging from abc import ABC, abstractmethod -from datetime import datetime -from typing import Optional, Union -from uuid import UUID -from ..abstractions import DocumentInfo, VectorEntry, VectorSearchResult -from ..api.models import UserResponse from .base import Provider, ProviderConfig logger = logging.getLogger(__name__) diff --git a/py/core/main/services/restructure_service.py b/py/core/main/services/restructure_service.py index 42bdbcfd1..fa6990568 100644 --- a/py/core/main/services/restructure_service.py +++ b/py/core/main/services/restructure_service.py @@ -1,5 +1,5 @@ import logging -from typing import Any, Dict, List +from typing import Any, Dict from core.base import R2RException, RunLoggingSingleton, RunManager from core.base.abstractions import KGEnrichmentSettings diff --git a/py/core/pipes/kg/clustering.py b/py/core/pipes/kg/clustering.py index 964d7bab1..7fd79f79c 100644 --- a/py/core/pipes/kg/clustering.py +++ b/py/core/pipes/kg/clustering.py @@ -17,7 +17,6 @@ Community, CompletionProvider, EmbeddingProvider, - GenerationConfig, KGEnrichmentSettings, KGProvider, PipeType, @@ -206,7 +205,7 @@ async def process_community(community_key, community): for i, completed_task in enumerate(asyncio.as_completed(tasks), 1): result = await completed_task logger.info( - f"Progress: {i}/{total_tasks} communities completed ({i/total_tasks*100:.2f}%)" + f"Progress: {i}/{total_tasks} communities completed ({i / total_tasks * 100:.2f}%)" ) yield result diff --git a/py/core/providers/kg/neo4j/__init__.py b/py/core/providers/kg/neo4j/__init__.py index cb10b1add..63be447ee 100644 --- a/py/core/providers/kg/neo4j/__init__.py +++ b/py/core/providers/kg/neo4j/__init__.py @@ -1 +1,3 @@ from .provider import Neo4jKGProvider + +__all__ = ["Neo4jKGProvider"] diff --git a/py/core/providers/kg/neo4j/provider.py b/py/core/providers/kg/neo4j/provider.py index aa862b202..8bed342b1 100644 --- a/py/core/providers/kg/neo4j/provider.py +++ b/py/core/providers/kg/neo4j/provider.py @@ -1,17 +1,11 @@ import json import os -import time from datetime import date, datetime from decimal import Decimal from typing import Any, Dict, List, Optional from uuid import UUID -from core.base import ( - KGConfig, - KGProvider, - format_entity_types, - format_relations, -) +from core.base import KGConfig, KGProvider from core.base.abstractions.document import DocumentFragment from core.base.abstractions.graph import ( Community, @@ -24,15 +18,11 @@ from .graph_queries import ( GET_CHUNKS_QUERY, GET_COMMUNITIES_QUERY, - GET_COMMUNITIES_REPORT_QUERY, - GET_COVARIATES_QUERY, GET_ENTITIES_QUERY, GET_TRIPLES_BY_SUBJECT_AND_OBJECT_QUERY, GET_TRIPLES_QUERY, PUT_CHUNKS_QUERY, PUT_COMMUNITIES_QUERY, - PUT_COMMUNITIES_REPORT_QUERY, - PUT_COVARIATES_QUERY, PUT_ENTITIES_EMBEDDINGS_QUERY, PUT_ENTITIES_QUERY, PUT_TRIPLES_QUERY, @@ -141,7 +131,7 @@ def batched_import(self, statement, df, batch_size=1000): Parameters: statement is the Cypher query to execute, df is the dataframe to import, and batch_size is the number of rows to import in each batch. """ total = len(df) - start_s = time.time() + results = [] for start in range(0, total, batch_size): batch = df[start : min(start + batch_size, total)] batch = self.convert_model_list_to_neo4j_compatible(batch) @@ -150,7 +140,8 @@ def batched_import(self, statement, df, batch_size=1000): rows=batch, database_=self._database, ) - return total + results.append(result) + return results def get_chunks( self, chunk_ids: List[str] = None @@ -189,7 +180,7 @@ def upsert_communities(self, communities: List[Community]): """ Upsert communities into the graph. """ - self.batched_import(PUT_COMMUNITIES_QUERY, communities) + return self.batched_import(PUT_COMMUNITIES_QUERY, communities) def get_entities(self, entity_ids: List[str] = []) -> List[Entity]: """ @@ -316,9 +307,6 @@ def get_rel_map( ) -> List[Triple]: pass - def client(self): - return self._driver - def create_vector_index( self, node_type: str, node_property: str, dimension: int ) -> None: @@ -331,15 +319,6 @@ def create_vector_index( self.structured_query(query) - def get_rel_map( - self, - graph_nodes: Any, - depth: int = 2, - limit: int = 30, - ignore_rels: Optional[List[str]] = None, - ) -> List[Triple]: - pass - def get_schema(self, refresh: bool = False) -> str: return super().get_schema(refresh) diff --git a/py/core/providers/parsing/unstructured_parsing.py b/py/core/providers/parsing/unstructured_parsing.py index 26e2933ab..51d489b4e 100644 --- a/py/core/providers/parsing/unstructured_parsing.py +++ b/py/core/providers/parsing/unstructured_parsing.py @@ -103,9 +103,6 @@ async def parse( for iteration, element in enumerate(elements): - if isinstance(element, dict): - element_dict = element - for key, value in element.items(): if key != "text": if key == "metadata": diff --git a/py/r2r/__init__.py b/py/r2r/__init__.py index 3d25a876d..d568f22a2 100644 --- a/py/r2r/__init__.py +++ b/py/r2r/__init__.py @@ -13,4 +13,4 @@ __all__ += core.__all__ except ImportError: # Core dependencies not installed - pass \ No newline at end of file + pass diff --git a/py/sdk/models.py b/py/sdk/models.py index b7c6f0309..a832c36c3 100644 --- a/py/sdk/models.py +++ b/py/sdk/models.py @@ -1,7 +1,7 @@ from abc import ABC, abstractmethod from datetime import datetime from enum import Enum -from typing import Any, ClassVar, Dict, Optional, Tuple, Type, Union +from typing import Any, ClassVar, Dict, Optional, Type, Union from uuid import UUID from pydantic import BaseModel, Field From f943b39dedffafc31340d62aaccb08929a68327e Mon Sep 17 00:00:00 2001 From: Nolan Tremelling <34580718+NolanTrem@users.noreply.github.com> Date: Fri, 23 Aug 2024 14:12:56 -0700 Subject: [PATCH 69/74] Small bugfixes on prompts, return types (#965) --- js/sdk/r2r-js-0.3.0.tgz | Bin 0 -> 20514 bytes js/sdk/src/r2rClient.ts | 58 +++--------------- py/core/main/engine.py | 8 --- py/core/main/services/ingestion_service.py | 2 +- py/core/main/services/management_service.py | 12 ++++ py/core/providers/database/vecs/collection.py | 7 +-- .../providers/prompts/defaults/rag_agent.yaml | 2 +- .../test_document_management.json | 2 +- 8 files changed, 27 insertions(+), 64 deletions(-) create mode 100644 js/sdk/r2r-js-0.3.0.tgz diff --git a/js/sdk/r2r-js-0.3.0.tgz b/js/sdk/r2r-js-0.3.0.tgz new file mode 100644 index 0000000000000000000000000000000000000000..8327690dce7d2a05f3f58e335ae4939556d012e2 GIT binary patch literal 20514 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 literal 0 HcmV?d00001 diff --git a/js/sdk/src/r2rClient.ts b/js/sdk/src/r2rClient.ts index 0bdc1c546..fb5c9e5d5 100644 --- a/js/sdk/src/r2rClient.ts +++ b/js/sdk/src/r2rClient.ts @@ -1156,7 +1156,7 @@ export class r2rClient { rag_generation_config?: GenerationConfig | Record, task_prompt_override?: string, include_title_if_available?: boolean, - ): Promise { + ): Promise> { this._ensureAuthenticated(); const json_data: Record = { @@ -1180,38 +1180,19 @@ export class r2rClient { } // TODO: can we remove this and pull this into rag? - @featureGenerator("streamingRag") - private async *streamRag( + @feature("streamingRag") + private async streamRag( rag_data: Record, - ): AsyncGenerator { + ): Promise> { this._ensureAuthenticated(); - const response = await this._makeRequest("POST", "rag", { + return this._makeRequest>("POST", "rag", { data: rag_data, headers: { "Content-Type": "application/json", }, responseType: "stream", }); - - if (!response.body) { - throw new Error("Response body is null"); - } - - const reader = response.body.getReader(); - const decoder = new TextDecoder(); - - try { - while (true) { - const { done, value } = await reader.read(); - if (done) { - break; - } - yield decoder.decode(value); - } - } finally { - reader.releaseLock(); - } } /** @@ -1232,7 +1213,7 @@ export class r2rClient { rag_generation_config?: GenerationConfig | Record, task_prompt_override?: string, include_title_if_available?: boolean, - ): Promise { + ): Promise> { this._ensureAuthenticated(); const json_data: Record = { @@ -1256,38 +1237,19 @@ export class r2rClient { } // TODO: can we remove this and pull this into agent? - @featureGenerator("streamingAgent") - private async *streamAgent( + @feature("streamingAgent") + private async streamAgent( agent_data: Record, - ): AsyncGenerator { + ): Promise> { this._ensureAuthenticated(); - const response = await this._makeRequest("POST", "agent", { + return this._makeRequest>("POST", "agent", { data: agent_data, headers: { "Content-Type": "application/json", }, responseType: "stream", }); - - if (!response.body) { - throw new Error("Response body is null"); - } - - const reader = response.body.getReader(); - const decoder = new TextDecoder(); - - try { - while (true) { - const { done, value } = await reader.read(); - if (done) { - break; - } - yield decoder.decode(value); - } - } finally { - reader.releaseLock(); - } } } diff --git a/py/core/main/engine.py b/py/core/main/engine.py index c9ae9c361..0a8dfc383 100644 --- a/py/core/main/engine.py +++ b/py/core/main/engine.py @@ -81,10 +81,6 @@ def __init__( async def aingest_documents(self, *args, **kwargs): return await self.ingestion_service.ingest_documents(*args, **kwargs) - @syncable - async def aupdate_documents(self, *args, **kwargs): - return await self.ingestion_service.update_documents(*args, **kwargs) - @syncable async def aingest_files(self, *args, **kwargs): return await self.ingestion_service.ingest_files(*args, **kwargs) @@ -109,10 +105,6 @@ async def arag(self, *args, **kwargs): async def arag_agent(self, *args, **kwargs): return await self.retrieval_service.agent(*args, **kwargs) - @syncable - async def aevaluate(self, *args, **kwargs): - return await self.retrieval_service.evaluate(*args, **kwargs) - @syncable async def aupdate_prompt(self, *args, **kwargs): return await self.management_service.update_prompt(*args, **kwargs) diff --git a/py/core/main/services/ingestion_service.py b/py/core/main/services/ingestion_service.py index ba1f5724c..f73adde6e 100644 --- a/py/core/main/services/ingestion_service.py +++ b/py/core/main/services/ingestion_service.py @@ -321,7 +321,7 @@ async def ingest_documents( logger.error("All provided documents already exist.") raise R2RException( status_code=409, - message="All provided documents already exist. Use the `update_documents` endpoint instead to update these documents.", + message="All provided documents already exist. Use the `update_files` endpoint instead to update these documents.", ) # Insert pending document info diff --git a/py/core/main/services/management_service.py b/py/core/main/services/management_service.py index af4108bf5..2e9239436 100644 --- a/py/core/main/services/management_service.py +++ b/py/core/main/services/management_service.py @@ -321,6 +321,18 @@ async def document_chunks( document_id, offset=offset, limit=limit ) + @telemetry_event("UpdatePrompt") + async def update_prompt( + self, + name: str, + template: Optional[str] = None, + input_types: Optional[dict[str, str]] = None, + ): + if input_types is None: + input_types = {} + self.providers.prompt.update_prompt(name, template, input_types) + return {"message": f"Prompt '{name}' updated successfully."} + @telemetry_event("UsersOverview") async def users_overview( self, diff --git a/py/core/providers/database/vecs/collection.py b/py/core/providers/database/vecs/collection.py index d3215168f..e1f09f18a 100644 --- a/py/core/providers/database/vecs/collection.py +++ b/py/core/providers/database/vecs/collection.py @@ -800,11 +800,8 @@ def parse_condition(key, value): else: # Handle JSON-based filters json_col = self.table.c.metadata - if not key.startswith("metadata."): - raise FilterError( - "metadata key must start with 'metadata.'" - ) - key = key.split("metadata.")[1] + if key.startswith("metadata."): + key.split("metadata.")[1] if isinstance(value, dict): if len(value) > 1: raise FilterError("only one operator permitted") diff --git a/py/core/providers/prompts/defaults/rag_agent.yaml b/py/core/providers/prompts/defaults/rag_agent.yaml index fe9caa250..a180b285b 100644 --- a/py/core/providers/prompts/defaults/rag_agent.yaml +++ b/py/core/providers/prompts/defaults/rag_agent.yaml @@ -6,7 +6,7 @@ rag_agent: When asked a question, perform a search to find relevant information and provide a response. - The response should contain line-item attributions to relevent search results, and be as informative if possible. + The response should contain line-item attributions to relevant search results, and be as informative if possible. If no relevant results are found, then state that no results were found. diff --git a/py/tests/regression/expected_outputs/test_document_management.json b/py/tests/regression/expected_outputs/test_document_management.json index 39c49fd88..74175a24f 100644 --- a/py/tests/regression/expected_outputs/test_document_management.json +++ b/py/tests/regression/expected_outputs/test_document_management.json @@ -203,7 +203,7 @@ } }, "reingest_sample_file": { - "results": "All provided documents already exist. Use the `update_documents` endpoint instead to update these documents." + "results": "All provided documents already exist. Use the `update_files` endpoint instead to update these documents." }, "documents_overview": { "results": [ From 8e5e69234b198700e0d974d4f6ae985ed150bbb2 Mon Sep 17 00:00:00 2001 From: NolanTrem <34580718+NolanTrem@users.noreply.github.com> Date: Fri, 23 Aug 2024 14:41:30 -0700 Subject: [PATCH 70/74] Fix failing CLI tests --- py/cli/commands/ingestion.py | 2 +- py/cli/commands/management.py | 3 +- py/tests/cli/commands/test_ingestion.py | 25 ++------------- py/tests/cli/commands/test_management.py | 38 ++++++++++------------- py/tests/cli/commands/test_restructure.py | 3 +- py/tests/cli/test_command_group.py | 13 ++------ 6 files changed, 24 insertions(+), 60 deletions(-) diff --git a/py/cli/commands/ingestion.py b/py/cli/commands/ingestion.py index 1099b299f..007f0f8b4 100644 --- a/py/cli/commands/ingestion.py +++ b/py/cli/commands/ingestion.py @@ -141,5 +141,5 @@ def ingest_sample_files(client): response = ingest_files_from_urls(client, urls) click.echo( - f"Sample file ingestion completed. Ingest files response:\n\n{response}" + f"Sample files ingestion completed. Ingest files response:\n\n{response}" ) diff --git a/py/cli/commands/management.py b/py/cli/commands/management.py index 474b7b648..9c9ca7ed4 100644 --- a/py/cli/commands/management.py +++ b/py/cli/commands/management.py @@ -130,9 +130,8 @@ def documents_overview(client, document_ids, offset, limit): def document_chunks(client, document_id, offset, limit): """Get chunks of a specific document.""" with timer(): - response = client.document_chunks(document_id, offset, limit) + chunks = client.document_chunks(document_id, offset, limit) - chunks = response.get("results", []) click.echo(f"\nNumber of chunks: {len(chunks)}") for index, chunk in enumerate(chunks, 1): click.echo(f"\nChunk {index}:") diff --git a/py/tests/cli/commands/test_ingestion.py b/py/tests/cli/commands/test_ingestion.py index 16cdf7636..914d1e6d9 100644 --- a/py/tests/cli/commands/test_ingestion.py +++ b/py/tests/cli/commands/test_ingestion.py @@ -63,7 +63,7 @@ def test_ingest_files(runner, mock_r2r_client, temp_file): assert result.exit_code == 0 assert '"status": "success"' in result.output mock_r2r_client.ingest_files.assert_called_once_with( - [temp_file], None, None, None + [temp_file], None, None ) @@ -77,15 +77,13 @@ def test_ingest_files_with_options(runner, mock_r2r_client, temp_file): "doc1", "--metadatas", '{"key": "value"}', - "--versions", - "v1", ], ) assert result.exit_code == 0 assert '"status": "success"' in result.output assert mock_r2r_client.ingest_files.called, "ingest_files was not called" mock_r2r_client.ingest_files.assert_called_once_with( - [temp_file], {"key": "value"}, ["doc1"], ["v1"] + [temp_file], {"key": "value"}, ["doc1"] ) @@ -130,25 +128,6 @@ def test_ingest_sample_files(mock_ingest, runner, mock_r2r_client): mock_ingest.assert_called_once() -@patch("cli.commands.ingestion.requests.get") -@patch("cli.commands.ingestion.tempfile.NamedTemporaryFile") -def test_ingest_files_from_urls(mock_temp_file, mock_get, mock_r2r_client): - mock_get.return_value.text = "File content" - mock_temp_file.return_value.__enter__.return_value.name = "/tmp/test_file" - mock_r2r_client.ingest_files.return_value = {"status": "success"} - - with patch("cli.commands.ingestion.os.unlink") as mock_unlink: - from cli.commands.ingestion import ingest_files_from_urls - - result = ingest_files_from_urls( - mock_r2r_client, ["http://example.com/file.txt"] - ) - - assert result == ["file.txt"] - mock_r2r_client.ingest_files.assert_called_once_with(["/tmp/test_file"]) - mock_unlink.assert_called_once_with("/tmp/test_file") - - def test_ingest_files_with_invalid_file(runner, mock_r2r_client): result = runner.invoke(cli, ["ingest-files", "nonexistent_file.txt"]) assert result.exit_code != 0 diff --git a/py/tests/cli/commands/test_management.py b/py/tests/cli/commands/test_management.py index 68435dba9..05854c7d2 100644 --- a/py/tests/cli/commands/test_management.py +++ b/py/tests/cli/commands/test_management.py @@ -39,8 +39,8 @@ def mock_r2r_client(): ] } mock_client.document_chunks.return_value = [ - {"id": "chunk1", "content": "Content 1"}, - {"id": "chunk2", "content": "Content 2"}, + {"fragment_id": "chunk1", "text": "Content 1", "metadata": {}}, + {"fragment_id": "chunk2", "text": "Content 2", "metadata": {}}, ] mock_client.inspect_knowledge_graph.return_value = { "nodes": 100, @@ -109,21 +109,19 @@ def test_app_settings(runner, mock_r2r_client): def test_users_overview(runner, mock_r2r_client): result = runner.invoke(cli, ["users-overview", "--user-ids", "user1"]) - print(f"Exit code: {result.exit_code}") - print(f"Output: {result.output}") - assert result.exit_code == 0 - assert "user1" in result.output - mock_r2r_client.users_overview.assert_called_once_with(["user1"]) + assert "Time taken:" in result.output + mock_r2r_client.users_overview.assert_called_once_with( + ["user1"], None, None + ) def test_users_overview_no_ids(runner, mock_r2r_client): result = runner.invoke(cli, ["users-overview"]) assert result.exit_code == 0 - assert "user1" in result.output - assert "Jane" in result.output - mock_r2r_client.users_overview.assert_called_once_with(None) + assert "Time taken:" in result.output + mock_r2r_client.users_overview.assert_called_once_with(None, None, None) def test_delete(runner, mock_r2r_client): @@ -163,12 +161,11 @@ def test_documents_overview_with_document_id(runner, mock_r2r_client): cli, ["documents-overview", "--document-ids", "doc1"] ) - print(f"Exit code: {result.exit_code}") - print(f"Output: {result.output}") - assert result.exit_code == 0 assert "doc1" in result.output - mock_r2r_client.documents_overview.assert_called_once_with(["doc1"]) + mock_r2r_client.documents_overview.assert_called_once_with( + ["doc1"], None, None + ) def test_document_chunks(runner, mock_r2r_client): @@ -177,17 +174,14 @@ def test_document_chunks(runner, mock_r2r_client): assert result.exit_code == 0 assert "chunk1" in result.output assert "Content 2" in result.output - mock_r2r_client.document_chunks.assert_called_once_with("doc1") + mock_r2r_client.document_chunks.assert_called_once_with("doc1", None, None) def test_document_chunks_no_id(runner, mock_r2r_client): result = runner.invoke(cli, ["document-chunks"]) - print(f"Exit code: {result.exit_code}") - print(f"Output: {result.output}") - assert result.exit_code == 0 - mock_r2r_client.document_chunks.assert_called_once_with(None) + mock_r2r_client.document_chunks.assert_called_once_with(None, None, None) assert "chunk1" in result.output @@ -197,7 +191,9 @@ def test_inspect_knowledge_graph(runner, mock_r2r_client): assert result.exit_code == 0 assert "nodes" in result.output assert "500" in result.output - mock_r2r_client.inspect_knowledge_graph.assert_called_once_with("100") + mock_r2r_client.inspect_knowledge_graph.assert_called_once_with( + None, "100" + ) def test_inspect_knowledge_graph_no_limit(runner, mock_r2r_client): @@ -206,4 +202,4 @@ def test_inspect_knowledge_graph_no_limit(runner, mock_r2r_client): assert result.exit_code == 0 assert "nodes" in result.output assert "500" in result.output - mock_r2r_client.inspect_knowledge_graph.assert_called_once_with(None) + mock_r2r_client.inspect_knowledge_graph.assert_called_once_with(None, None) diff --git a/py/tests/cli/commands/test_restructure.py b/py/tests/cli/commands/test_restructure.py index e7ebaf5ba..1a90ac6ed 100644 --- a/py/tests/cli/commands/test_restructure.py +++ b/py/tests/cli/commands/test_restructure.py @@ -1,4 +1,3 @@ -import json from unittest.mock import MagicMock, patch import click @@ -53,4 +52,4 @@ def test_enrich_graph(runner, mock_r2r_client): assert result.exit_code == 0 assert "Time taken" in result.output - mock_r2r_client.restructure.assert_called_once() + mock_r2r_client.enrich_graph.assert_called_once() diff --git a/py/tests/cli/test_command_group.py b/py/tests/cli/test_command_group.py index 408703027..a09b42db9 100644 --- a/py/tests/cli/test_command_group.py +++ b/py/tests/cli/test_command_group.py @@ -9,20 +9,11 @@ def runner(): return CliRunner() -def test_cli_group_options(): - assert "config_path" in [param.name for param in cli.params] - assert "config_name" in [param.name for param in cli.params] - assert "base_url" in [param.name for param in cli.params] +def test_cli_group_no_options(): + assert len(cli.params) == 0 def test_cli_group_help(runner): result = runner.invoke(cli, ["--help"]) assert result.exit_code == 0 assert "R2R CLI for all core operations." in result.output - - -def test_base_url_option(runner): - result = runner.invoke( - cli, ["--base-url", "http://example.com", "generate-private-key"] - ) - assert result.exit_code == 0 From 0cf1bb0a386a2e4083bc798e720f52115bef7d9e Mon Sep 17 00:00:00 2001 From: NolanTrem <34580718+NolanTrem@users.noreply.github.com> Date: Fri, 23 Aug 2024 14:51:30 -0700 Subject: [PATCH 71/74] NPM publish action --- .github/workflows/publish-to-npm.yml | 35 + js/sdk/pnpm-lock.yaml | 3046 +++++++++----------------- 2 files changed, 1088 insertions(+), 1993 deletions(-) create mode 100644 .github/workflows/publish-to-npm.yml diff --git a/.github/workflows/publish-to-npm.yml b/.github/workflows/publish-to-npm.yml new file mode 100644 index 000000000..86ef27372 --- /dev/null +++ b/.github/workflows/publish-to-npm.yml @@ -0,0 +1,35 @@ +name: Publish NPM Package + +on: + workflow_dispatch: + +jobs: + publish: + runs-on: ubuntu-latest + defaults: + run: + working-directory: js/sdk + steps: + - uses: actions/checkout@v3 + + - name: Set up Node.js + uses: actions/setup-node@v3 + with: + node-version: '16' + registry-url: 'https://registry.npmjs.org' + + - name: Install pnpm + uses: pnpm/action-setup@v2 + with: + version: 6.0.2 + + - name: Install dependencies + run: pnpm install + + - name: Build + run: pnpm run build + + - name: Publish to npm + run: pnpm publish --no-git-checks + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/js/sdk/pnpm-lock.yaml b/js/sdk/pnpm-lock.yaml index 758f6559e..2a8a5ce9a 100644 --- a/js/sdk/pnpm-lock.yaml +++ b/js/sdk/pnpm-lock.yaml @@ -1,10 +1,11 @@ -lockfileVersion: "9.0" +lockfileVersion: '9.0' settings: autoInstallPeers: true excludeLinksFromLockfile: false importers: + .: dependencies: axios: @@ -23,10 +24,13 @@ importers: specifier: ^10.0.0 version: 10.0.0 devDependencies: - "@types/node": + '@types/jest': + specifier: ^29.5.12 + version: 29.5.12 + '@types/node': specifier: ^20.14.15 version: 20.14.15 - "@types/uuid": + '@types/uuid': specifier: ^10.0.0 version: 10.0.0 jest: @@ -46,920 +50,534 @@ importers: version: 5.5.4 packages: - "@ampproject/remapping@2.3.0": - resolution: - { - integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==, - } - engines: { node: ">=6.0.0" } - - "@babel/code-frame@7.24.7": - resolution: - { - integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==, - } - engines: { node: ">=6.9.0" } - - "@babel/compat-data@7.25.2": - resolution: - { - integrity: sha512-bYcppcpKBvX4znYaPEeFau03bp89ShqNMLs+rmdptMw+heSZh9+z84d2YG+K7cYLbWwzdjtDoW/uqZmPjulClQ==, - } - engines: { node: ">=6.9.0" } - - "@babel/core@7.25.2": - resolution: - { - integrity: sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==, - } - engines: { node: ">=6.9.0" } - - "@babel/generator@7.25.0": - resolution: - { - integrity: sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw==, - } - engines: { node: ">=6.9.0" } - - "@babel/helper-compilation-targets@7.25.2": - resolution: - { - integrity: sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==, - } - engines: { node: ">=6.9.0" } - - "@babel/helper-module-imports@7.24.7": - resolution: - { - integrity: sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==, - } - engines: { node: ">=6.9.0" } - - "@babel/helper-module-transforms@7.25.2": - resolution: - { - integrity: sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==, - } - engines: { node: ">=6.9.0" } + + '@ampproject/remapping@2.3.0': + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + + '@babel/code-frame@7.24.7': + resolution: {integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.25.2': + resolution: {integrity: sha512-bYcppcpKBvX4znYaPEeFau03bp89ShqNMLs+rmdptMw+heSZh9+z84d2YG+K7cYLbWwzdjtDoW/uqZmPjulClQ==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.25.2': + resolution: {integrity: sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.25.0': + resolution: {integrity: sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.25.2': + resolution: {integrity: sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.24.7': + resolution: {integrity: sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.25.2': + resolution: {integrity: sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==} + engines: {node: '>=6.9.0'} peerDependencies: - "@babel/core": ^7.0.0 - - "@babel/helper-plugin-utils@7.24.8": - resolution: - { - integrity: sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==, - } - engines: { node: ">=6.9.0" } - - "@babel/helper-simple-access@7.24.7": - resolution: - { - integrity: sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==, - } - engines: { node: ">=6.9.0" } - - "@babel/helper-string-parser@7.24.8": - resolution: - { - integrity: sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==, - } - engines: { node: ">=6.9.0" } - - "@babel/helper-validator-identifier@7.24.7": - resolution: - { - integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==, - } - engines: { node: ">=6.9.0" } - - "@babel/helper-validator-option@7.24.8": - resolution: - { - integrity: sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==, - } - engines: { node: ">=6.9.0" } - - "@babel/helpers@7.25.0": - resolution: - { - integrity: sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw==, - } - engines: { node: ">=6.9.0" } - - "@babel/highlight@7.24.7": - resolution: - { - integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==, - } - engines: { node: ">=6.9.0" } - - "@babel/parser@7.25.3": - resolution: - { - integrity: sha512-iLTJKDbJ4hMvFPgQwwsVoxtHyWpKKPBrxkANrSYewDPaPpT5py5yeVkgPIJ7XYXhndxJpaA3PyALSXQ7u8e/Dw==, - } - engines: { node: ">=6.0.0" } + '@babel/core': ^7.0.0 + + '@babel/helper-plugin-utils@7.24.8': + resolution: {integrity: sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-simple-access@7.24.7': + resolution: {integrity: sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.24.8': + resolution: {integrity: sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.24.7': + resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.24.8': + resolution: {integrity: sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.25.0': + resolution: {integrity: sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw==} + engines: {node: '>=6.9.0'} + + '@babel/highlight@7.24.7': + resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.25.3': + resolution: {integrity: sha512-iLTJKDbJ4hMvFPgQwwsVoxtHyWpKKPBrxkANrSYewDPaPpT5py5yeVkgPIJ7XYXhndxJpaA3PyALSXQ7u8e/Dw==} + engines: {node: '>=6.0.0'} hasBin: true - "@babel/plugin-syntax-async-generators@7.8.4": - resolution: - { - integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==, - } + '@babel/plugin-syntax-async-generators@7.8.4': + resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} peerDependencies: - "@babel/core": ^7.0.0-0 + '@babel/core': ^7.0.0-0 - "@babel/plugin-syntax-bigint@7.8.3": - resolution: - { - integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==, - } + '@babel/plugin-syntax-bigint@7.8.3': + resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} peerDependencies: - "@babel/core": ^7.0.0-0 + '@babel/core': ^7.0.0-0 - "@babel/plugin-syntax-class-properties@7.12.13": - resolution: - { - integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==, - } + '@babel/plugin-syntax-class-properties@7.12.13': + resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} peerDependencies: - "@babel/core": ^7.0.0-0 - - "@babel/plugin-syntax-class-static-block@7.14.5": - resolution: - { - integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==, - } - engines: { node: ">=6.9.0" } + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-class-static-block@7.14.5': + resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} + engines: {node: '>=6.9.0'} peerDependencies: - "@babel/core": ^7.0.0-0 - - "@babel/plugin-syntax-import-attributes@7.24.7": - resolution: - { - integrity: sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==, - } - engines: { node: ">=6.9.0" } + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-attributes@7.24.7': + resolution: {integrity: sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==} + engines: {node: '>=6.9.0'} peerDependencies: - "@babel/core": ^7.0.0-0 + '@babel/core': ^7.0.0-0 - "@babel/plugin-syntax-import-meta@7.10.4": - resolution: - { - integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==, - } + '@babel/plugin-syntax-import-meta@7.10.4': + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} peerDependencies: - "@babel/core": ^7.0.0-0 + '@babel/core': ^7.0.0-0 - "@babel/plugin-syntax-json-strings@7.8.3": - resolution: - { - integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==, - } + '@babel/plugin-syntax-json-strings@7.8.3': + resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} peerDependencies: - "@babel/core": ^7.0.0-0 - - "@babel/plugin-syntax-jsx@7.24.7": - resolution: - { - integrity: sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==, - } - engines: { node: ">=6.9.0" } + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-jsx@7.24.7': + resolution: {integrity: sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==} + engines: {node: '>=6.9.0'} peerDependencies: - "@babel/core": ^7.0.0-0 + '@babel/core': ^7.0.0-0 - "@babel/plugin-syntax-logical-assignment-operators@7.10.4": - resolution: - { - integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==, - } + '@babel/plugin-syntax-logical-assignment-operators@7.10.4': + resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} peerDependencies: - "@babel/core": ^7.0.0-0 + '@babel/core': ^7.0.0-0 - "@babel/plugin-syntax-nullish-coalescing-operator@7.8.3": - resolution: - { - integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==, - } + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3': + resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} peerDependencies: - "@babel/core": ^7.0.0-0 + '@babel/core': ^7.0.0-0 - "@babel/plugin-syntax-numeric-separator@7.10.4": - resolution: - { - integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==, - } + '@babel/plugin-syntax-numeric-separator@7.10.4': + resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} peerDependencies: - "@babel/core": ^7.0.0-0 + '@babel/core': ^7.0.0-0 - "@babel/plugin-syntax-object-rest-spread@7.8.3": - resolution: - { - integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==, - } + '@babel/plugin-syntax-object-rest-spread@7.8.3': + resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} peerDependencies: - "@babel/core": ^7.0.0-0 + '@babel/core': ^7.0.0-0 - "@babel/plugin-syntax-optional-catch-binding@7.8.3": - resolution: - { - integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==, - } + '@babel/plugin-syntax-optional-catch-binding@7.8.3': + resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} peerDependencies: - "@babel/core": ^7.0.0-0 + '@babel/core': ^7.0.0-0 - "@babel/plugin-syntax-optional-chaining@7.8.3": - resolution: - { - integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==, - } + '@babel/plugin-syntax-optional-chaining@7.8.3': + resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} peerDependencies: - "@babel/core": ^7.0.0-0 - - "@babel/plugin-syntax-private-property-in-object@7.14.5": - resolution: - { - integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==, - } - engines: { node: ">=6.9.0" } + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-private-property-in-object@7.14.5': + resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} + engines: {node: '>=6.9.0'} peerDependencies: - "@babel/core": ^7.0.0-0 - - "@babel/plugin-syntax-top-level-await@7.14.5": - resolution: - { - integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==, - } - engines: { node: ">=6.9.0" } + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-top-level-await@7.14.5': + resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} + engines: {node: '>=6.9.0'} peerDependencies: - "@babel/core": ^7.0.0-0 - - "@babel/plugin-syntax-typescript@7.24.7": - resolution: - { - integrity: sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA==, - } - engines: { node: ">=6.9.0" } + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-typescript@7.24.7': + resolution: {integrity: sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA==} + engines: {node: '>=6.9.0'} peerDependencies: - "@babel/core": ^7.0.0-0 - - "@babel/template@7.25.0": - resolution: - { - integrity: sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==, - } - engines: { node: ">=6.9.0" } - - "@babel/traverse@7.25.3": - resolution: - { - integrity: sha512-HefgyP1x754oGCsKmV5reSmtV7IXj/kpaE1XYY+D9G5PvKKoFfSbiS4M77MdjuwlZKDIKFCffq9rPU+H/s3ZdQ==, - } - engines: { node: ">=6.9.0" } - - "@babel/types@7.25.2": - resolution: - { - integrity: sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q==, - } - engines: { node: ">=6.9.0" } - - "@bcoe/v8-coverage@0.2.3": - resolution: - { - integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==, - } - - "@cspotcode/source-map-support@0.8.1": - resolution: - { - integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==, - } - engines: { node: ">=12" } - - "@istanbuljs/load-nyc-config@1.1.0": - resolution: - { - integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==, - } - engines: { node: ">=8" } - - "@istanbuljs/schema@0.1.3": - resolution: - { - integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==, - } - engines: { node: ">=8" } - - "@jest/console@29.7.0": - resolution: - { - integrity: sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - "@jest/core@29.7.0": - resolution: - { - integrity: sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + '@babel/core': ^7.0.0-0 + + '@babel/template@7.25.0': + resolution: {integrity: sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.25.3': + resolution: {integrity: sha512-HefgyP1x754oGCsKmV5reSmtV7IXj/kpaE1XYY+D9G5PvKKoFfSbiS4M77MdjuwlZKDIKFCffq9rPU+H/s3ZdQ==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.25.2': + resolution: {integrity: sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q==} + engines: {node: '>=6.9.0'} + + '@bcoe/v8-coverage@0.2.3': + resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + + '@cspotcode/source-map-support@0.8.1': + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + + '@istanbuljs/load-nyc-config@1.1.0': + resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} + engines: {node: '>=8'} + + '@istanbuljs/schema@0.1.3': + resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} + engines: {node: '>=8'} + + '@jest/console@29.7.0': + resolution: {integrity: sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/core@29.7.0': + resolution: {integrity: sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 peerDependenciesMeta: node-notifier: optional: true - "@jest/environment@29.7.0": - resolution: - { - integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - "@jest/expect-utils@29.7.0": - resolution: - { - integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - "@jest/expect@29.7.0": - resolution: - { - integrity: sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - "@jest/fake-timers@29.7.0": - resolution: - { - integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - "@jest/globals@29.7.0": - resolution: - { - integrity: sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - "@jest/reporters@29.7.0": - resolution: - { - integrity: sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + '@jest/environment@29.7.0': + resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/expect-utils@29.7.0': + resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/expect@29.7.0': + resolution: {integrity: sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/fake-timers@29.7.0': + resolution: {integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/globals@29.7.0': + resolution: {integrity: sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/reporters@29.7.0': + resolution: {integrity: sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 peerDependenciesMeta: node-notifier: optional: true - "@jest/schemas@29.6.3": - resolution: - { - integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - "@jest/source-map@29.6.3": - resolution: - { - integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - "@jest/test-result@29.7.0": - resolution: - { - integrity: sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - "@jest/test-sequencer@29.7.0": - resolution: - { - integrity: sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - "@jest/transform@29.7.0": - resolution: - { - integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - "@jest/types@29.6.3": - resolution: - { - integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - "@jridgewell/gen-mapping@0.3.5": - resolution: - { - integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==, - } - engines: { node: ">=6.0.0" } - - "@jridgewell/resolve-uri@3.1.2": - resolution: - { - integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==, - } - engines: { node: ">=6.0.0" } - - "@jridgewell/set-array@1.2.1": - resolution: - { - integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==, - } - engines: { node: ">=6.0.0" } - - "@jridgewell/sourcemap-codec@1.5.0": - resolution: - { - integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==, - } - - "@jridgewell/trace-mapping@0.3.25": - resolution: - { - integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==, - } - - "@jridgewell/trace-mapping@0.3.9": - resolution: - { - integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==, - } - - "@sinclair/typebox@0.27.8": - resolution: - { - integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==, - } - - "@sinonjs/commons@3.0.1": - resolution: - { - integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==, - } - - "@sinonjs/fake-timers@10.3.0": - resolution: - { - integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==, - } - - "@tsconfig/node10@1.0.11": - resolution: - { - integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==, - } - - "@tsconfig/node12@1.0.11": - resolution: - { - integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==, - } - - "@tsconfig/node14@1.0.3": - resolution: - { - integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==, - } - - "@tsconfig/node16@1.0.4": - resolution: - { - integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==, - } - - "@types/babel__core@7.20.5": - resolution: - { - integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==, - } - - "@types/babel__generator@7.6.8": - resolution: - { - integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==, - } - - "@types/babel__template@7.4.4": - resolution: - { - integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==, - } - - "@types/babel__traverse@7.20.6": - resolution: - { - integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==, - } - - "@types/graceful-fs@4.1.9": - resolution: - { - integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==, - } - - "@types/istanbul-lib-coverage@2.0.6": - resolution: - { - integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==, - } - - "@types/istanbul-lib-report@3.0.3": - resolution: - { - integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==, - } - - "@types/istanbul-reports@3.0.4": - resolution: - { - integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==, - } - - "@types/node@20.14.15": - resolution: - { - integrity: sha512-Fz1xDMCF/B00/tYSVMlmK7hVeLh7jE5f3B7X1/hmV0MJBwE27KlS7EvD/Yp+z1lm8mVhwV5w+n8jOZG8AfTlKw==, - } - - "@types/stack-utils@2.0.3": - resolution: - { - integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==, - } - - "@types/uuid@10.0.0": - resolution: - { - integrity: sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==, - } - - "@types/yargs-parser@21.0.3": - resolution: - { - integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==, - } - - "@types/yargs@17.0.33": - resolution: - { - integrity: sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==, - } + '@jest/schemas@29.6.3': + resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/source-map@29.6.3': + resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/test-result@29.7.0': + resolution: {integrity: sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/test-sequencer@29.7.0': + resolution: {integrity: sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/transform@29.7.0': + resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/types@29.6.3': + resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jridgewell/gen-mapping@0.3.5': + resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} + engines: {node: '>=6.0.0'} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + + '@jridgewell/trace-mapping@0.3.9': + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + + '@sinclair/typebox@0.27.8': + resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + + '@sinonjs/commons@3.0.1': + resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} + + '@sinonjs/fake-timers@10.3.0': + resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} + + '@tsconfig/node10@1.0.11': + resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} + + '@tsconfig/node12@1.0.11': + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + + '@tsconfig/node14@1.0.3': + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + + '@tsconfig/node16@1.0.4': + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + + '@types/babel__core@7.20.5': + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + + '@types/babel__generator@7.6.8': + resolution: {integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==} + + '@types/babel__template@7.4.4': + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + + '@types/babel__traverse@7.20.6': + resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==} + + '@types/graceful-fs@4.1.9': + resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} + + '@types/istanbul-lib-coverage@2.0.6': + resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} + + '@types/istanbul-lib-report@3.0.3': + resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} + + '@types/istanbul-reports@3.0.4': + resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} + + '@types/jest@29.5.12': + resolution: {integrity: sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==} + + '@types/node@20.14.15': + resolution: {integrity: sha512-Fz1xDMCF/B00/tYSVMlmK7hVeLh7jE5f3B7X1/hmV0MJBwE27KlS7EvD/Yp+z1lm8mVhwV5w+n8jOZG8AfTlKw==} + + '@types/stack-utils@2.0.3': + resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} + + '@types/uuid@10.0.0': + resolution: {integrity: sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==} + + '@types/yargs-parser@21.0.3': + resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} + + '@types/yargs@17.0.33': + resolution: {integrity: sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==} acorn-walk@8.3.3: - resolution: - { - integrity: sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==, - } - engines: { node: ">=0.4.0" } + resolution: {integrity: sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==} + engines: {node: '>=0.4.0'} acorn@8.12.1: - resolution: - { - integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==, - } - engines: { node: ">=0.4.0" } + resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==} + engines: {node: '>=0.4.0'} hasBin: true ansi-escapes@4.3.2: - resolution: - { - integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} ansi-regex@5.0.1: - resolution: - { - integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} ansi-styles@3.2.1: - resolution: - { - integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==, - } - engines: { node: ">=4" } + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} ansi-styles@4.3.0: - resolution: - { - integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} ansi-styles@5.2.0: - resolution: - { - integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==, - } - engines: { node: ">=10" } + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} anymatch@3.1.3: - resolution: - { - integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==, - } - engines: { node: ">= 8" } + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} arg@4.1.3: - resolution: - { - integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==, - } + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} argparse@1.0.10: - resolution: - { - integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==, - } + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} async@3.2.5: - resolution: - { - integrity: sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==, - } + resolution: {integrity: sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==} asynckit@0.4.0: - resolution: - { - integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==, - } + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} axios@1.7.4: - resolution: - { - integrity: sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==, - } + resolution: {integrity: sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==} babel-jest@29.7.0: - resolution: - { - integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: - "@babel/core": ^7.8.0 + '@babel/core': ^7.8.0 babel-plugin-istanbul@6.1.1: - resolution: - { - integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} + engines: {node: '>=8'} babel-plugin-jest-hoist@29.6.3: - resolution: - { - integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} babel-preset-current-node-syntax@1.1.0: - resolution: - { - integrity: sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==, - } + resolution: {integrity: sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==} peerDependencies: - "@babel/core": ^7.0.0 + '@babel/core': ^7.0.0 babel-preset-jest@29.6.3: - resolution: - { - integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: - "@babel/core": ^7.0.0 + '@babel/core': ^7.0.0 balanced-match@1.0.2: - resolution: - { - integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==, - } + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} brace-expansion@1.1.11: - resolution: - { - integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==, - } + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} brace-expansion@2.0.1: - resolution: - { - integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==, - } + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} braces@3.0.3: - resolution: - { - integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} browserslist@4.23.3: - resolution: - { - integrity: sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==, - } - engines: { node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7 } + resolution: {integrity: sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true bs-logger@0.2.6: - resolution: - { - integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==, - } - engines: { node: ">= 6" } + resolution: {integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==} + engines: {node: '>= 6'} bser@2.1.1: - resolution: - { - integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==, - } + resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} buffer-from@1.1.2: - resolution: - { - integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==, - } + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} callsites@3.1.0: - resolution: - { - integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==, - } - engines: { node: ">=6" } + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} camelcase@5.3.1: - resolution: - { - integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==, - } - engines: { node: ">=6" } + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} camelcase@6.3.0: - resolution: - { - integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==, - } - engines: { node: ">=10" } + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} caniuse-lite@1.0.30001651: - resolution: - { - integrity: sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==, - } + resolution: {integrity: sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==} chalk@2.4.2: - resolution: - { - integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==, - } - engines: { node: ">=4" } + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} chalk@4.1.2: - resolution: - { - integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==, - } - engines: { node: ">=10" } + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} char-regex@1.0.2: - resolution: - { - integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==, - } - engines: { node: ">=10" } + resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} + engines: {node: '>=10'} ci-info@3.9.0: - resolution: - { - integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} + engines: {node: '>=8'} cjs-module-lexer@1.3.1: - resolution: - { - integrity: sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==, - } + resolution: {integrity: sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==} cliui@8.0.1: - resolution: - { - integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==, - } - engines: { node: ">=12" } + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} co@4.6.0: - resolution: - { - integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==, - } - engines: { iojs: ">= 1.0.0", node: ">= 0.12.0" } + resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} + engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} collect-v8-coverage@1.0.2: - resolution: - { - integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==, - } + resolution: {integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==} color-convert@1.9.3: - resolution: - { - integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==, - } + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} color-convert@2.0.1: - resolution: - { - integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==, - } - engines: { node: ">=7.0.0" } + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} color-name@1.1.3: - resolution: - { - integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==, - } + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} color-name@1.1.4: - resolution: - { - integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==, - } + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} combined-stream@1.0.8: - resolution: - { - integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==, - } - engines: { node: ">= 0.8" } + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} concat-map@0.0.1: - resolution: - { - integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==, - } + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} convert-source-map@2.0.0: - resolution: - { - integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==, - } + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} create-jest@29.7.0: - resolution: - { - integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true create-require@1.1.1: - resolution: - { - integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==, - } + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} cross-spawn@7.0.3: - resolution: - { - integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==, - } - engines: { node: ">= 8" } + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} debug@4.3.6: - resolution: - { - integrity: sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==, - } - engines: { node: ">=6.0" } + resolution: {integrity: sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==} + engines: {node: '>=6.0'} peerDependencies: - supports-color: "*" + supports-color: '*' peerDependenciesMeta: supports-color: optional: true dedent@1.5.3: - resolution: - { - integrity: sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==, - } + resolution: {integrity: sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==} peerDependencies: babel-plugin-macros: ^3.1.0 peerDependenciesMeta: @@ -967,427 +585,244 @@ packages: optional: true deepmerge@4.3.1: - resolution: - { - integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==, - } - engines: { node: ">=0.10.0" } + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} delayed-stream@1.0.0: - resolution: - { - integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==, - } - engines: { node: ">=0.4.0" } + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} detect-newline@3.1.0: - resolution: - { - integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} + engines: {node: '>=8'} diff-sequences@29.6.3: - resolution: - { - integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} diff@4.0.2: - resolution: - { - integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==, - } - engines: { node: ">=0.3.1" } + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + engines: {node: '>=0.3.1'} ejs@3.1.10: - resolution: - { - integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==, - } - engines: { node: ">=0.10.0" } + resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==} + engines: {node: '>=0.10.0'} hasBin: true electron-to-chromium@1.5.9: - resolution: - { - integrity: sha512-HfkT8ndXR0SEkU8gBQQM3rz035bpE/hxkZ1YIt4KJPEFES68HfIU6LzKukH0H794Lm83WJtkSAMfEToxCs15VA==, - } + resolution: {integrity: sha512-HfkT8ndXR0SEkU8gBQQM3rz035bpE/hxkZ1YIt4KJPEFES68HfIU6LzKukH0H794Lm83WJtkSAMfEToxCs15VA==} emittery@0.13.1: - resolution: - { - integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==, - } - engines: { node: ">=12" } + resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} + engines: {node: '>=12'} emoji-regex@8.0.0: - resolution: - { - integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==, - } + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} error-ex@1.3.2: - resolution: - { - integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==, - } + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} escalade@3.1.2: - resolution: - { - integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==, - } - engines: { node: ">=6" } + resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} + engines: {node: '>=6'} escape-string-regexp@1.0.5: - resolution: - { - integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==, - } - engines: { node: ">=0.8.0" } + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} escape-string-regexp@2.0.0: - resolution: - { - integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} + engines: {node: '>=8'} esprima@4.0.1: - resolution: - { - integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==, - } - engines: { node: ">=4" } + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} hasBin: true execa@5.1.1: - resolution: - { - integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==, - } - engines: { node: ">=10" } + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} exit@0.1.2: - resolution: - { - integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==, - } - engines: { node: ">= 0.8.0" } + resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} + engines: {node: '>= 0.8.0'} expect@29.7.0: - resolution: - { - integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} fast-json-stable-stringify@2.1.0: - resolution: - { - integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==, - } + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} fb-watchman@2.0.2: - resolution: - { - integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==, - } + resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} fflate@0.4.8: - resolution: - { - integrity: sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA==, - } + resolution: {integrity: sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA==} filelist@1.0.4: - resolution: - { - integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==, - } + resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} fill-range@7.1.1: - resolution: - { - integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} find-up@4.1.0: - resolution: - { - integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} follow-redirects@1.15.6: - resolution: - { - integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==, - } - engines: { node: ">=4.0" } + resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==} + engines: {node: '>=4.0'} peerDependencies: - debug: "*" + debug: '*' peerDependenciesMeta: debug: optional: true form-data@4.0.0: - resolution: - { - integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==, - } - engines: { node: ">= 6" } + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} fs.realpath@1.0.0: - resolution: - { - integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==, - } + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} fsevents@2.3.3: - resolution: - { - integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==, - } - engines: { node: ^8.16.0 || ^10.6.0 || >=11.0.0 } + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] function-bind@1.1.2: - resolution: - { - integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==, - } + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} gensync@1.0.0-beta.2: - resolution: - { - integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==, - } - engines: { node: ">=6.9.0" } + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} get-caller-file@2.0.5: - resolution: - { - integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==, - } - engines: { node: 6.* || 8.* || >= 10.* } + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} get-package-type@0.1.0: - resolution: - { - integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==, - } - engines: { node: ">=8.0.0" } + resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} + engines: {node: '>=8.0.0'} get-stream@6.0.1: - resolution: - { - integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==, - } - engines: { node: ">=10" } + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} glob@7.2.3: - resolution: - { - integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==, - } + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} deprecated: Glob versions prior to v9 are no longer supported globals@11.12.0: - resolution: - { - integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==, - } - engines: { node: ">=4" } + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} graceful-fs@4.2.11: - resolution: - { - integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==, - } + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} has-flag@3.0.0: - resolution: - { - integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==, - } - engines: { node: ">=4" } + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} has-flag@4.0.0: - resolution: - { - integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} hasown@2.0.2: - resolution: - { - integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==, - } - engines: { node: ">= 0.4" } + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} html-escaper@2.0.2: - resolution: - { - integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==, - } + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} human-signals@2.1.0: - resolution: - { - integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==, - } - engines: { node: ">=10.17.0" } + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} import-local@3.2.0: - resolution: - { - integrity: sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==} + engines: {node: '>=8'} hasBin: true imurmurhash@0.1.4: - resolution: - { - integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==, - } - engines: { node: ">=0.8.19" } + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} inflight@1.0.6: - resolution: - { - integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==, - } + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. inherits@2.0.4: - resolution: - { - integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==, - } + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} is-arrayish@0.2.1: - resolution: - { - integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==, - } + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} is-core-module@2.15.0: - resolution: - { - integrity: sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==, - } - engines: { node: ">= 0.4" } + resolution: {integrity: sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==} + engines: {node: '>= 0.4'} is-fullwidth-code-point@3.0.0: - resolution: - { - integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} is-generator-fn@2.1.0: - resolution: - { - integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==, - } - engines: { node: ">=6" } + resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} + engines: {node: '>=6'} is-number@7.0.0: - resolution: - { - integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==, - } - engines: { node: ">=0.12.0" } + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} is-stream@2.0.1: - resolution: - { - integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} isexe@2.0.0: - resolution: - { - integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==, - } + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} istanbul-lib-coverage@3.2.2: - resolution: - { - integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} + engines: {node: '>=8'} istanbul-lib-instrument@5.2.1: - resolution: - { - integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} + engines: {node: '>=8'} istanbul-lib-instrument@6.0.3: - resolution: - { - integrity: sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==, - } - engines: { node: ">=10" } + resolution: {integrity: sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==} + engines: {node: '>=10'} istanbul-lib-report@3.0.1: - resolution: - { - integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==, - } - engines: { node: ">=10" } + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} istanbul-lib-source-maps@4.0.1: - resolution: - { - integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==, - } - engines: { node: ">=10" } + resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} + engines: {node: '>=10'} istanbul-reports@3.1.7: - resolution: - { - integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} + engines: {node: '>=8'} jake@10.9.2: - resolution: - { - integrity: sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==, - } - engines: { node: ">=10" } + resolution: {integrity: sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==} + engines: {node: '>=10'} hasBin: true jest-changed-files@29.7.0: - resolution: - { - integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} jest-circus@29.7.0: - resolution: - { - integrity: sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} jest-cli@29.7.0: - resolution: - { - integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 @@ -1396,178 +831,109 @@ packages: optional: true jest-config@29.7.0: - resolution: - { - integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: - "@types/node": "*" - ts-node: ">=9.0.0" + '@types/node': '*' + ts-node: '>=9.0.0' peerDependenciesMeta: - "@types/node": + '@types/node': optional: true ts-node: optional: true jest-diff@29.7.0: - resolution: - { - integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} jest-docblock@29.7.0: - resolution: - { - integrity: sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} jest-each@29.7.0: - resolution: - { - integrity: sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} jest-environment-node@29.7.0: - resolution: - { - integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} jest-get-type@29.6.3: - resolution: - { - integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} jest-haste-map@29.7.0: - resolution: - { - integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} jest-leak-detector@29.7.0: - resolution: - { - integrity: sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} jest-matcher-utils@29.7.0: - resolution: - { - integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} jest-message-util@29.7.0: - resolution: - { - integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} jest-mock@29.7.0: - resolution: - { - integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} jest-pnp-resolver@1.2.3: - resolution: - { - integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==, - } - engines: { node: ">=6" } + resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==} + engines: {node: '>=6'} peerDependencies: - jest-resolve: "*" + jest-resolve: '*' peerDependenciesMeta: jest-resolve: optional: true jest-regex-util@29.6.3: - resolution: - { - integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} jest-resolve-dependencies@29.7.0: - resolution: - { - integrity: sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} jest-resolve@29.7.0: - resolution: - { - integrity: sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} jest-runner@29.7.0: - resolution: - { - integrity: sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} jest-runtime@29.7.0: - resolution: - { - integrity: sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} jest-snapshot@29.7.0: - resolution: - { - integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} jest-util@29.7.0: - resolution: - { - integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} jest-validate@29.7.0: - resolution: - { - integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} jest-watcher@29.7.0: - resolution: - { - integrity: sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} jest-worker@29.7.0: - resolution: - { - integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} jest@29.7.0: - resolution: - { - integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 @@ -1576,577 +942,328 @@ packages: optional: true js-tokens@4.0.0: - resolution: - { - integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==, - } + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} js-yaml@3.14.1: - resolution: - { - integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==, - } + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} hasBin: true jsesc@2.5.2: - resolution: - { - integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==, - } - engines: { node: ">=4" } + resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} + engines: {node: '>=4'} hasBin: true json-parse-even-better-errors@2.3.1: - resolution: - { - integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==, - } + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} json5@2.2.3: - resolution: - { - integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==, - } - engines: { node: ">=6" } + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} hasBin: true kleur@3.0.3: - resolution: - { - integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==, - } - engines: { node: ">=6" } + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} leven@3.1.0: - resolution: - { - integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==, - } - engines: { node: ">=6" } + resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} + engines: {node: '>=6'} lines-and-columns@1.2.4: - resolution: - { - integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==, - } + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} locate-path@5.0.0: - resolution: - { - integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} lodash.memoize@4.1.2: - resolution: - { - integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==, - } + resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} lru-cache@5.1.1: - resolution: - { - integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==, - } + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} make-dir@4.0.0: - resolution: - { - integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==, - } - engines: { node: ">=10" } + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} make-error@1.3.6: - resolution: - { - integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==, - } + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} makeerror@1.0.12: - resolution: - { - integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==, - } + resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} merge-stream@2.0.0: - resolution: - { - integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==, - } + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} micromatch@4.0.7: - resolution: - { - integrity: sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==, - } - engines: { node: ">=8.6" } + resolution: {integrity: sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==} + engines: {node: '>=8.6'} mime-db@1.52.0: - resolution: - { - integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==, - } - engines: { node: ">= 0.6" } + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} mime-types@2.1.35: - resolution: - { - integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==, - } - engines: { node: ">= 0.6" } + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} mimic-fn@2.1.0: - resolution: - { - integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==, - } - engines: { node: ">=6" } + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} minimatch@3.1.2: - resolution: - { - integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==, - } + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} minimatch@5.1.6: - resolution: - { - integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==, - } - engines: { node: ">=10" } + resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} + engines: {node: '>=10'} ms@2.1.2: - resolution: - { - integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==, - } + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} natural-compare@1.4.0: - resolution: - { - integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==, - } + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} node-int64@0.4.0: - resolution: - { - integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==, - } + resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} node-releases@2.0.18: - resolution: - { - integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==, - } + resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} normalize-path@3.0.0: - resolution: - { - integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==, - } - engines: { node: ">=0.10.0" } + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} npm-run-path@4.0.1: - resolution: - { - integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} once@1.4.0: - resolution: - { - integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==, - } + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} onetime@5.1.2: - resolution: - { - integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==, - } - engines: { node: ">=6" } + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} p-limit@2.3.0: - resolution: - { - integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==, - } - engines: { node: ">=6" } + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} p-limit@3.1.0: - resolution: - { - integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==, - } - engines: { node: ">=10" } + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} p-locate@4.1.0: - resolution: - { - integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} p-try@2.2.0: - resolution: - { - integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==, - } - engines: { node: ">=6" } + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} parse-json@5.2.0: - resolution: - { - integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} path-exists@4.0.0: - resolution: - { - integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} path-is-absolute@1.0.1: - resolution: - { - integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==, - } - engines: { node: ">=0.10.0" } + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} path-key@3.1.1: - resolution: - { - integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} path-parse@1.0.7: - resolution: - { - integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==, - } + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} picocolors@1.0.1: - resolution: - { - integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==, - } + resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} picomatch@2.3.1: - resolution: - { - integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==, - } - engines: { node: ">=8.6" } + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} pirates@4.0.6: - resolution: - { - integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==, - } - engines: { node: ">= 6" } + resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} + engines: {node: '>= 6'} pkg-dir@4.2.0: - resolution: - { - integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} + engines: {node: '>=8'} posthog-js@1.155.4: - resolution: - { - integrity: sha512-suxwAsmZGqMDXJe/RaCKI3PaDEHiuMDDhKcJklgGAg7eDnywieRkr5CoPcOOvnqTDMnuOPETr98jpYBXKUwGFQ==, - } + resolution: {integrity: sha512-suxwAsmZGqMDXJe/RaCKI3PaDEHiuMDDhKcJklgGAg7eDnywieRkr5CoPcOOvnqTDMnuOPETr98jpYBXKUwGFQ==} posthog-node@4.1.0: - resolution: - { - integrity: sha512-Fd+aMWLjUttlPrfOniDWs35v62rOEIqP5GBzUvRswsNY8rr1g1KuDobqaRFGMCNnrtDmhzUN8y7QucrcwMY/+w==, - } - engines: { node: ">=15.0.0" } + resolution: {integrity: sha512-Fd+aMWLjUttlPrfOniDWs35v62rOEIqP5GBzUvRswsNY8rr1g1KuDobqaRFGMCNnrtDmhzUN8y7QucrcwMY/+w==} + engines: {node: '>=15.0.0'} preact@10.23.2: - resolution: - { - integrity: sha512-kKYfePf9rzKnxOAKDpsWhg/ysrHPqT+yQ7UW4JjdnqjFIeNUnNcEJvhuA8fDenxAGWzUqtd51DfVg7xp/8T9NA==, - } + resolution: {integrity: sha512-kKYfePf9rzKnxOAKDpsWhg/ysrHPqT+yQ7UW4JjdnqjFIeNUnNcEJvhuA8fDenxAGWzUqtd51DfVg7xp/8T9NA==} prettier@3.3.3: - resolution: - { - integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==, - } - engines: { node: ">=14" } + resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} + engines: {node: '>=14'} hasBin: true pretty-format@29.7.0: - resolution: - { - integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} prompts@2.4.2: - resolution: - { - integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==, - } - engines: { node: ">= 6" } + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} proxy-from-env@1.1.0: - resolution: - { - integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==, - } + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} pure-rand@6.1.0: - resolution: - { - integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==, - } + resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} react-is@18.3.1: - resolution: - { - integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==, - } + resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} require-directory@2.1.1: - resolution: - { - integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==, - } - engines: { node: ">=0.10.0" } + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} resolve-cwd@3.0.0: - resolution: - { - integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} + engines: {node: '>=8'} resolve-from@5.0.0: - resolution: - { - integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} resolve.exports@2.0.2: - resolution: - { - integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==, - } - engines: { node: ">=10" } + resolution: {integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==} + engines: {node: '>=10'} resolve@1.22.8: - resolution: - { - integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==, - } + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} hasBin: true rusha@0.8.14: - resolution: - { - integrity: sha512-cLgakCUf6PedEu15t8kbsjnwIFFR2D4RfL+W3iWFJ4iac7z4B0ZI8fxy4R3J956kAI68HclCFGL8MPoUVC3qVA==, - } + resolution: {integrity: sha512-cLgakCUf6PedEu15t8kbsjnwIFFR2D4RfL+W3iWFJ4iac7z4B0ZI8fxy4R3J956kAI68HclCFGL8MPoUVC3qVA==} semver@6.3.1: - resolution: - { - integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==, - } + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true semver@7.6.3: - resolution: - { - integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==, - } - engines: { node: ">=10" } + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} + engines: {node: '>=10'} hasBin: true shebang-command@2.0.0: - resolution: - { - integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} shebang-regex@3.0.0: - resolution: - { - integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} signal-exit@3.0.7: - resolution: - { - integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==, - } + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} sisteransi@1.0.5: - resolution: - { - integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==, - } + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} slash@3.0.0: - resolution: - { - integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} source-map-support@0.5.13: - resolution: - { - integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==, - } + resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} source-map@0.6.1: - resolution: - { - integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==, - } - engines: { node: ">=0.10.0" } + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} sprintf-js@1.0.3: - resolution: - { - integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==, - } + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} stack-utils@2.0.6: - resolution: - { - integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==, - } - engines: { node: ">=10" } + resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} + engines: {node: '>=10'} string-length@4.0.2: - resolution: - { - integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==, - } - engines: { node: ">=10" } + resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} + engines: {node: '>=10'} string-width@4.2.3: - resolution: - { - integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} strip-ansi@6.0.1: - resolution: - { - integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} strip-bom@4.0.0: - resolution: - { - integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} + engines: {node: '>=8'} strip-final-newline@2.0.0: - resolution: - { - integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==, - } - engines: { node: ">=6" } + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} strip-json-comments@3.1.1: - resolution: - { - integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} supports-color@5.5.0: - resolution: - { - integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==, - } - engines: { node: ">=4" } + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} supports-color@7.2.0: - resolution: - { - integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} supports-color@8.1.1: - resolution: - { - integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==, - } - engines: { node: ">=10" } + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} supports-preserve-symlinks-flag@1.0.0: - resolution: - { - integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==, - } - engines: { node: ">= 0.4" } + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} test-exclude@6.0.0: - resolution: - { - integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==, - } - engines: { node: ">=8" } + resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} + engines: {node: '>=8'} tmpl@1.0.5: - resolution: - { - integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==, - } + resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} to-fast-properties@2.0.0: - resolution: - { - integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==, - } - engines: { node: ">=4" } + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} to-regex-range@5.0.1: - resolution: - { - integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==, - } - engines: { node: ">=8.0" } + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} ts-jest@29.2.4: - resolution: - { - integrity: sha512-3d6tgDyhCI29HlpwIq87sNuI+3Q6GLTTCeYRHCs7vDz+/3GCMwEtV9jezLyl4ZtnBgx00I7hm8PCP8cTksMGrw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0 } + resolution: {integrity: sha512-3d6tgDyhCI29HlpwIq87sNuI+3Q6GLTTCeYRHCs7vDz+/3GCMwEtV9jezLyl4ZtnBgx00I7hm8PCP8cTksMGrw==} + engines: {node: ^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: - "@babel/core": ">=7.0.0-beta.0 <8" - "@jest/transform": ^29.0.0 - "@jest/types": ^29.0.0 + '@babel/core': '>=7.0.0-beta.0 <8' + '@jest/transform': ^29.0.0 + '@jest/types': ^29.0.0 babel-jest: ^29.0.0 - esbuild: "*" + esbuild: '*' jest: ^29.0.0 - typescript: ">=4.3 <6" + typescript: '>=4.3 <6' peerDependenciesMeta: - "@babel/core": + '@babel/core': optional: true - "@jest/transform": + '@jest/transform': optional: true - "@jest/types": + '@jest/types': optional: true babel-jest: optional: true @@ -2154,185 +1271,123 @@ packages: optional: true ts-node@10.9.2: - resolution: - { - integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==, - } + resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} hasBin: true peerDependencies: - "@swc/core": ">=1.2.50" - "@swc/wasm": ">=1.2.50" - "@types/node": "*" - typescript: ">=2.7" + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' peerDependenciesMeta: - "@swc/core": + '@swc/core': optional: true - "@swc/wasm": + '@swc/wasm': optional: true type-detect@4.0.8: - resolution: - { - integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==, - } - engines: { node: ">=4" } + resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} + engines: {node: '>=4'} type-fest@0.21.3: - resolution: - { - integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==, - } - engines: { node: ">=10" } + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} typescript@5.5.4: - resolution: - { - integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==, - } - engines: { node: ">=14.17" } + resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==} + engines: {node: '>=14.17'} hasBin: true undici-types@5.26.5: - resolution: - { - integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==, - } + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} update-browserslist-db@1.1.0: - resolution: - { - integrity: sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==, - } + resolution: {integrity: sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==} hasBin: true peerDependencies: - browserslist: ">= 4.21.0" + browserslist: '>= 4.21.0' uuid@10.0.0: - resolution: - { - integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==, - } + resolution: {integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==} hasBin: true v8-compile-cache-lib@3.0.1: - resolution: - { - integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==, - } + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} v8-to-istanbul@9.3.0: - resolution: - { - integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==, - } - engines: { node: ">=10.12.0" } + resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} + engines: {node: '>=10.12.0'} walker@1.0.8: - resolution: - { - integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==, - } + resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} web-vitals@4.2.3: - resolution: - { - integrity: sha512-/CFAm1mNxSmOj6i0Co+iGFJ58OS4NRGVP+AWS/l509uIK5a1bSoIVaHz/ZumpHTfHSZBpgrJ+wjfpAOrTHok5Q==, - } + resolution: {integrity: sha512-/CFAm1mNxSmOj6i0Co+iGFJ58OS4NRGVP+AWS/l509uIK5a1bSoIVaHz/ZumpHTfHSZBpgrJ+wjfpAOrTHok5Q==} which@2.0.2: - resolution: - { - integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==, - } - engines: { node: ">= 8" } + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} hasBin: true wrap-ansi@7.0.0: - resolution: - { - integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==, - } - engines: { node: ">=10" } + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} wrappy@1.0.2: - resolution: - { - integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==, - } + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} write-file-atomic@4.0.2: - resolution: - { - integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==, - } - engines: { node: ^12.13.0 || ^14.15.0 || >=16.0.0 } + resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} y18n@5.0.8: - resolution: - { - integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==, - } - engines: { node: ">=10" } + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} yallist@3.1.1: - resolution: - { - integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==, - } + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} yargs-parser@21.1.1: - resolution: - { - integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==, - } - engines: { node: ">=12" } + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} yargs@17.7.2: - resolution: - { - integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==, - } - engines: { node: ">=12" } + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} yn@3.1.1: - resolution: - { - integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==, - } - engines: { node: ">=6" } + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} yocto-queue@0.1.0: - resolution: - { - integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==, - } - engines: { node: ">=10" } + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} snapshots: - "@ampproject/remapping@2.3.0": + + '@ampproject/remapping@2.3.0': dependencies: - "@jridgewell/gen-mapping": 0.3.5 - "@jridgewell/trace-mapping": 0.3.25 + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 - "@babel/code-frame@7.24.7": + '@babel/code-frame@7.24.7': dependencies: - "@babel/highlight": 7.24.7 + '@babel/highlight': 7.24.7 picocolors: 1.0.1 - "@babel/compat-data@7.25.2": {} + '@babel/compat-data@7.25.2': {} - "@babel/core@7.25.2": + '@babel/core@7.25.2': dependencies: - "@ampproject/remapping": 2.3.0 - "@babel/code-frame": 7.24.7 - "@babel/generator": 7.25.0 - "@babel/helper-compilation-targets": 7.25.2 - "@babel/helper-module-transforms": 7.25.2(@babel/core@7.25.2) - "@babel/helpers": 7.25.0 - "@babel/parser": 7.25.3 - "@babel/template": 7.25.0 - "@babel/traverse": 7.25.3 - "@babel/types": 7.25.2 + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.24.7 + '@babel/generator': 7.25.0 + '@babel/helper-compilation-targets': 7.25.2 + '@babel/helper-module-transforms': 7.25.2(@babel/core@7.25.2) + '@babel/helpers': 7.25.0 + '@babel/parser': 7.25.3 + '@babel/template': 7.25.0 + '@babel/traverse': 7.25.3 + '@babel/types': 7.25.2 convert-source-map: 2.0.0 debug: 4.3.6 gensync: 1.0.0-beta.2 @@ -2341,185 +1396,185 @@ snapshots: transitivePeerDependencies: - supports-color - "@babel/generator@7.25.0": + '@babel/generator@7.25.0': dependencies: - "@babel/types": 7.25.2 - "@jridgewell/gen-mapping": 0.3.5 - "@jridgewell/trace-mapping": 0.3.25 + '@babel/types': 7.25.2 + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 jsesc: 2.5.2 - "@babel/helper-compilation-targets@7.25.2": + '@babel/helper-compilation-targets@7.25.2': dependencies: - "@babel/compat-data": 7.25.2 - "@babel/helper-validator-option": 7.24.8 + '@babel/compat-data': 7.25.2 + '@babel/helper-validator-option': 7.24.8 browserslist: 4.23.3 lru-cache: 5.1.1 semver: 6.3.1 - "@babel/helper-module-imports@7.24.7": + '@babel/helper-module-imports@7.24.7': dependencies: - "@babel/traverse": 7.25.3 - "@babel/types": 7.25.2 + '@babel/traverse': 7.25.3 + '@babel/types': 7.25.2 transitivePeerDependencies: - supports-color - "@babel/helper-module-transforms@7.25.2(@babel/core@7.25.2)": + '@babel/helper-module-transforms@7.25.2(@babel/core@7.25.2)': dependencies: - "@babel/core": 7.25.2 - "@babel/helper-module-imports": 7.24.7 - "@babel/helper-simple-access": 7.24.7 - "@babel/helper-validator-identifier": 7.24.7 - "@babel/traverse": 7.25.3 + '@babel/core': 7.25.2 + '@babel/helper-module-imports': 7.24.7 + '@babel/helper-simple-access': 7.24.7 + '@babel/helper-validator-identifier': 7.24.7 + '@babel/traverse': 7.25.3 transitivePeerDependencies: - supports-color - "@babel/helper-plugin-utils@7.24.8": {} + '@babel/helper-plugin-utils@7.24.8': {} - "@babel/helper-simple-access@7.24.7": + '@babel/helper-simple-access@7.24.7': dependencies: - "@babel/traverse": 7.25.3 - "@babel/types": 7.25.2 + '@babel/traverse': 7.25.3 + '@babel/types': 7.25.2 transitivePeerDependencies: - supports-color - "@babel/helper-string-parser@7.24.8": {} + '@babel/helper-string-parser@7.24.8': {} - "@babel/helper-validator-identifier@7.24.7": {} + '@babel/helper-validator-identifier@7.24.7': {} - "@babel/helper-validator-option@7.24.8": {} + '@babel/helper-validator-option@7.24.8': {} - "@babel/helpers@7.25.0": + '@babel/helpers@7.25.0': dependencies: - "@babel/template": 7.25.0 - "@babel/types": 7.25.2 + '@babel/template': 7.25.0 + '@babel/types': 7.25.2 - "@babel/highlight@7.24.7": + '@babel/highlight@7.24.7': dependencies: - "@babel/helper-validator-identifier": 7.24.7 + '@babel/helper-validator-identifier': 7.24.7 chalk: 2.4.2 js-tokens: 4.0.0 picocolors: 1.0.1 - "@babel/parser@7.25.3": + '@babel/parser@7.25.3': dependencies: - "@babel/types": 7.25.2 + '@babel/types': 7.25.2 - "@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.25.2)": + '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.25.2)': dependencies: - "@babel/core": 7.25.2 - "@babel/helper-plugin-utils": 7.24.8 + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 - "@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.25.2)": + '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.25.2)': dependencies: - "@babel/core": 7.25.2 - "@babel/helper-plugin-utils": 7.24.8 + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 - "@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.25.2)": + '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.25.2)': dependencies: - "@babel/core": 7.25.2 - "@babel/helper-plugin-utils": 7.24.8 + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 - "@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.25.2)": + '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.25.2)': dependencies: - "@babel/core": 7.25.2 - "@babel/helper-plugin-utils": 7.24.8 + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 - "@babel/plugin-syntax-import-attributes@7.24.7(@babel/core@7.25.2)": + '@babel/plugin-syntax-import-attributes@7.24.7(@babel/core@7.25.2)': dependencies: - "@babel/core": 7.25.2 - "@babel/helper-plugin-utils": 7.24.8 + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 - "@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.25.2)": + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.25.2)': dependencies: - "@babel/core": 7.25.2 - "@babel/helper-plugin-utils": 7.24.8 + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 - "@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.25.2)": + '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.25.2)': dependencies: - "@babel/core": 7.25.2 - "@babel/helper-plugin-utils": 7.24.8 + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 - "@babel/plugin-syntax-jsx@7.24.7(@babel/core@7.25.2)": + '@babel/plugin-syntax-jsx@7.24.7(@babel/core@7.25.2)': dependencies: - "@babel/core": 7.25.2 - "@babel/helper-plugin-utils": 7.24.8 + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 - "@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.25.2)": + '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.25.2)': dependencies: - "@babel/core": 7.25.2 - "@babel/helper-plugin-utils": 7.24.8 + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 - "@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.25.2)": + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.25.2)': dependencies: - "@babel/core": 7.25.2 - "@babel/helper-plugin-utils": 7.24.8 + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 - "@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.25.2)": + '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.25.2)': dependencies: - "@babel/core": 7.25.2 - "@babel/helper-plugin-utils": 7.24.8 + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 - "@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.25.2)": + '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.25.2)': dependencies: - "@babel/core": 7.25.2 - "@babel/helper-plugin-utils": 7.24.8 + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 - "@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.25.2)": + '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.25.2)': dependencies: - "@babel/core": 7.25.2 - "@babel/helper-plugin-utils": 7.24.8 + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 - "@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.25.2)": + '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.25.2)': dependencies: - "@babel/core": 7.25.2 - "@babel/helper-plugin-utils": 7.24.8 + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 - "@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.25.2)": + '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.25.2)': dependencies: - "@babel/core": 7.25.2 - "@babel/helper-plugin-utils": 7.24.8 + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 - "@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.25.2)": + '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.25.2)': dependencies: - "@babel/core": 7.25.2 - "@babel/helper-plugin-utils": 7.24.8 + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 - "@babel/plugin-syntax-typescript@7.24.7(@babel/core@7.25.2)": + '@babel/plugin-syntax-typescript@7.24.7(@babel/core@7.25.2)': dependencies: - "@babel/core": 7.25.2 - "@babel/helper-plugin-utils": 7.24.8 + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 - "@babel/template@7.25.0": + '@babel/template@7.25.0': dependencies: - "@babel/code-frame": 7.24.7 - "@babel/parser": 7.25.3 - "@babel/types": 7.25.2 + '@babel/code-frame': 7.24.7 + '@babel/parser': 7.25.3 + '@babel/types': 7.25.2 - "@babel/traverse@7.25.3": + '@babel/traverse@7.25.3': dependencies: - "@babel/code-frame": 7.24.7 - "@babel/generator": 7.25.0 - "@babel/parser": 7.25.3 - "@babel/template": 7.25.0 - "@babel/types": 7.25.2 + '@babel/code-frame': 7.24.7 + '@babel/generator': 7.25.0 + '@babel/parser': 7.25.3 + '@babel/template': 7.25.0 + '@babel/types': 7.25.2 debug: 4.3.6 globals: 11.12.0 transitivePeerDependencies: - supports-color - "@babel/types@7.25.2": + '@babel/types@7.25.2': dependencies: - "@babel/helper-string-parser": 7.24.8 - "@babel/helper-validator-identifier": 7.24.7 + '@babel/helper-string-parser': 7.24.8 + '@babel/helper-validator-identifier': 7.24.7 to-fast-properties: 2.0.0 - "@bcoe/v8-coverage@0.2.3": {} + '@bcoe/v8-coverage@0.2.3': {} - "@cspotcode/source-map-support@0.8.1": + '@cspotcode/source-map-support@0.8.1': dependencies: - "@jridgewell/trace-mapping": 0.3.9 + '@jridgewell/trace-mapping': 0.3.9 - "@istanbuljs/load-nyc-config@1.1.0": + '@istanbuljs/load-nyc-config@1.1.0': dependencies: camelcase: 5.3.1 find-up: 4.1.0 @@ -2527,25 +1582,25 @@ snapshots: js-yaml: 3.14.1 resolve-from: 5.0.0 - "@istanbuljs/schema@0.1.3": {} + '@istanbuljs/schema@0.1.3': {} - "@jest/console@29.7.0": + '@jest/console@29.7.0': dependencies: - "@jest/types": 29.6.3 - "@types/node": 20.14.15 + '@jest/types': 29.6.3 + '@types/node': 20.14.15 chalk: 4.1.2 jest-message-util: 29.7.0 jest-util: 29.7.0 slash: 3.0.0 - "@jest/core@29.7.0(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))": + '@jest/core@29.7.0(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))': dependencies: - "@jest/console": 29.7.0 - "@jest/reporters": 29.7.0 - "@jest/test-result": 29.7.0 - "@jest/transform": 29.7.0 - "@jest/types": 29.6.3 - "@types/node": 20.14.15 + '@jest/console': 29.7.0 + '@jest/reporters': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.14.15 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.9.0 @@ -2573,51 +1628,51 @@ snapshots: - supports-color - ts-node - "@jest/environment@29.7.0": + '@jest/environment@29.7.0': dependencies: - "@jest/fake-timers": 29.7.0 - "@jest/types": 29.6.3 - "@types/node": 20.14.15 + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.14.15 jest-mock: 29.7.0 - "@jest/expect-utils@29.7.0": + '@jest/expect-utils@29.7.0': dependencies: jest-get-type: 29.6.3 - "@jest/expect@29.7.0": + '@jest/expect@29.7.0': dependencies: expect: 29.7.0 jest-snapshot: 29.7.0 transitivePeerDependencies: - supports-color - "@jest/fake-timers@29.7.0": + '@jest/fake-timers@29.7.0': dependencies: - "@jest/types": 29.6.3 - "@sinonjs/fake-timers": 10.3.0 - "@types/node": 20.14.15 + '@jest/types': 29.6.3 + '@sinonjs/fake-timers': 10.3.0 + '@types/node': 20.14.15 jest-message-util: 29.7.0 jest-mock: 29.7.0 jest-util: 29.7.0 - "@jest/globals@29.7.0": + '@jest/globals@29.7.0': dependencies: - "@jest/environment": 29.7.0 - "@jest/expect": 29.7.0 - "@jest/types": 29.6.3 + '@jest/environment': 29.7.0 + '@jest/expect': 29.7.0 + '@jest/types': 29.6.3 jest-mock: 29.7.0 transitivePeerDependencies: - supports-color - "@jest/reporters@29.7.0": + '@jest/reporters@29.7.0': dependencies: - "@bcoe/v8-coverage": 0.2.3 - "@jest/console": 29.7.0 - "@jest/test-result": 29.7.0 - "@jest/transform": 29.7.0 - "@jest/types": 29.6.3 - "@jridgewell/trace-mapping": 0.3.25 - "@types/node": 20.14.15 + '@bcoe/v8-coverage': 0.2.3 + '@jest/console': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@jridgewell/trace-mapping': 0.3.25 + '@types/node': 20.14.15 chalk: 4.1.2 collect-v8-coverage: 1.0.2 exit: 0.1.2 @@ -2638,35 +1693,35 @@ snapshots: transitivePeerDependencies: - supports-color - "@jest/schemas@29.6.3": + '@jest/schemas@29.6.3': dependencies: - "@sinclair/typebox": 0.27.8 + '@sinclair/typebox': 0.27.8 - "@jest/source-map@29.6.3": + '@jest/source-map@29.6.3': dependencies: - "@jridgewell/trace-mapping": 0.3.25 + '@jridgewell/trace-mapping': 0.3.25 callsites: 3.1.0 graceful-fs: 4.2.11 - "@jest/test-result@29.7.0": + '@jest/test-result@29.7.0': dependencies: - "@jest/console": 29.7.0 - "@jest/types": 29.6.3 - "@types/istanbul-lib-coverage": 2.0.6 + '@jest/console': 29.7.0 + '@jest/types': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.6 collect-v8-coverage: 1.0.2 - "@jest/test-sequencer@29.7.0": + '@jest/test-sequencer@29.7.0': dependencies: - "@jest/test-result": 29.7.0 + '@jest/test-result': 29.7.0 graceful-fs: 4.2.11 jest-haste-map: 29.7.0 slash: 3.0.0 - "@jest/transform@29.7.0": + '@jest/transform@29.7.0': dependencies: - "@babel/core": 7.25.2 - "@jest/types": 29.6.3 - "@jridgewell/trace-mapping": 0.3.25 + '@babel/core': 7.25.2 + '@jest/types': 29.6.3 + '@jridgewell/trace-mapping': 0.3.25 babel-plugin-istanbul: 6.1.1 chalk: 4.1.2 convert-source-map: 2.0.0 @@ -2682,103 +1737,108 @@ snapshots: transitivePeerDependencies: - supports-color - "@jest/types@29.6.3": + '@jest/types@29.6.3': dependencies: - "@jest/schemas": 29.6.3 - "@types/istanbul-lib-coverage": 2.0.6 - "@types/istanbul-reports": 3.0.4 - "@types/node": 20.14.15 - "@types/yargs": 17.0.33 + '@jest/schemas': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-reports': 3.0.4 + '@types/node': 20.14.15 + '@types/yargs': 17.0.33 chalk: 4.1.2 - "@jridgewell/gen-mapping@0.3.5": + '@jridgewell/gen-mapping@0.3.5': dependencies: - "@jridgewell/set-array": 1.2.1 - "@jridgewell/sourcemap-codec": 1.5.0 - "@jridgewell/trace-mapping": 0.3.25 + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 - "@jridgewell/resolve-uri@3.1.2": {} + '@jridgewell/resolve-uri@3.1.2': {} - "@jridgewell/set-array@1.2.1": {} + '@jridgewell/set-array@1.2.1': {} - "@jridgewell/sourcemap-codec@1.5.0": {} + '@jridgewell/sourcemap-codec@1.5.0': {} - "@jridgewell/trace-mapping@0.3.25": + '@jridgewell/trace-mapping@0.3.25': dependencies: - "@jridgewell/resolve-uri": 3.1.2 - "@jridgewell/sourcemap-codec": 1.5.0 + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 - "@jridgewell/trace-mapping@0.3.9": + '@jridgewell/trace-mapping@0.3.9': dependencies: - "@jridgewell/resolve-uri": 3.1.2 - "@jridgewell/sourcemap-codec": 1.5.0 + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 - "@sinclair/typebox@0.27.8": {} + '@sinclair/typebox@0.27.8': {} - "@sinonjs/commons@3.0.1": + '@sinonjs/commons@3.0.1': dependencies: type-detect: 4.0.8 - "@sinonjs/fake-timers@10.3.0": + '@sinonjs/fake-timers@10.3.0': dependencies: - "@sinonjs/commons": 3.0.1 + '@sinonjs/commons': 3.0.1 - "@tsconfig/node10@1.0.11": {} + '@tsconfig/node10@1.0.11': {} - "@tsconfig/node12@1.0.11": {} + '@tsconfig/node12@1.0.11': {} - "@tsconfig/node14@1.0.3": {} + '@tsconfig/node14@1.0.3': {} - "@tsconfig/node16@1.0.4": {} + '@tsconfig/node16@1.0.4': {} - "@types/babel__core@7.20.5": + '@types/babel__core@7.20.5': dependencies: - "@babel/parser": 7.25.3 - "@babel/types": 7.25.2 - "@types/babel__generator": 7.6.8 - "@types/babel__template": 7.4.4 - "@types/babel__traverse": 7.20.6 + '@babel/parser': 7.25.3 + '@babel/types': 7.25.2 + '@types/babel__generator': 7.6.8 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.20.6 - "@types/babel__generator@7.6.8": + '@types/babel__generator@7.6.8': dependencies: - "@babel/types": 7.25.2 + '@babel/types': 7.25.2 - "@types/babel__template@7.4.4": + '@types/babel__template@7.4.4': dependencies: - "@babel/parser": 7.25.3 - "@babel/types": 7.25.2 + '@babel/parser': 7.25.3 + '@babel/types': 7.25.2 - "@types/babel__traverse@7.20.6": + '@types/babel__traverse@7.20.6': dependencies: - "@babel/types": 7.25.2 + '@babel/types': 7.25.2 - "@types/graceful-fs@4.1.9": + '@types/graceful-fs@4.1.9': dependencies: - "@types/node": 20.14.15 + '@types/node': 20.14.15 - "@types/istanbul-lib-coverage@2.0.6": {} + '@types/istanbul-lib-coverage@2.0.6': {} - "@types/istanbul-lib-report@3.0.3": + '@types/istanbul-lib-report@3.0.3': dependencies: - "@types/istanbul-lib-coverage": 2.0.6 + '@types/istanbul-lib-coverage': 2.0.6 - "@types/istanbul-reports@3.0.4": + '@types/istanbul-reports@3.0.4': dependencies: - "@types/istanbul-lib-report": 3.0.3 + '@types/istanbul-lib-report': 3.0.3 + + '@types/jest@29.5.12': + dependencies: + expect: 29.7.0 + pretty-format: 29.7.0 - "@types/node@20.14.15": + '@types/node@20.14.15': dependencies: undici-types: 5.26.5 - "@types/stack-utils@2.0.3": {} + '@types/stack-utils@2.0.3': {} - "@types/uuid@10.0.0": {} + '@types/uuid@10.0.0': {} - "@types/yargs-parser@21.0.3": {} + '@types/yargs-parser@21.0.3': {} - "@types/yargs@17.0.33": + '@types/yargs@17.0.33': dependencies: - "@types/yargs-parser": 21.0.3 + '@types/yargs-parser': 21.0.3 acorn-walk@8.3.3: dependencies: @@ -2827,9 +1887,9 @@ snapshots: babel-jest@29.7.0(@babel/core@7.25.2): dependencies: - "@babel/core": 7.25.2 - "@jest/transform": 29.7.0 - "@types/babel__core": 7.20.5 + '@babel/core': 7.25.2 + '@jest/transform': 29.7.0 + '@types/babel__core': 7.20.5 babel-plugin-istanbul: 6.1.1 babel-preset-jest: 29.6.3(@babel/core@7.25.2) chalk: 4.1.2 @@ -2840,9 +1900,9 @@ snapshots: babel-plugin-istanbul@6.1.1: dependencies: - "@babel/helper-plugin-utils": 7.24.8 - "@istanbuljs/load-nyc-config": 1.1.0 - "@istanbuljs/schema": 0.1.3 + '@babel/helper-plugin-utils': 7.24.8 + '@istanbuljs/load-nyc-config': 1.1.0 + '@istanbuljs/schema': 0.1.3 istanbul-lib-instrument: 5.2.1 test-exclude: 6.0.0 transitivePeerDependencies: @@ -2850,33 +1910,33 @@ snapshots: babel-plugin-jest-hoist@29.6.3: dependencies: - "@babel/template": 7.25.0 - "@babel/types": 7.25.2 - "@types/babel__core": 7.20.5 - "@types/babel__traverse": 7.20.6 + '@babel/template': 7.25.0 + '@babel/types': 7.25.2 + '@types/babel__core': 7.20.5 + '@types/babel__traverse': 7.20.6 babel-preset-current-node-syntax@1.1.0(@babel/core@7.25.2): dependencies: - "@babel/core": 7.25.2 - "@babel/plugin-syntax-async-generators": 7.8.4(@babel/core@7.25.2) - "@babel/plugin-syntax-bigint": 7.8.3(@babel/core@7.25.2) - "@babel/plugin-syntax-class-properties": 7.12.13(@babel/core@7.25.2) - "@babel/plugin-syntax-class-static-block": 7.14.5(@babel/core@7.25.2) - "@babel/plugin-syntax-import-attributes": 7.24.7(@babel/core@7.25.2) - "@babel/plugin-syntax-import-meta": 7.10.4(@babel/core@7.25.2) - "@babel/plugin-syntax-json-strings": 7.8.3(@babel/core@7.25.2) - "@babel/plugin-syntax-logical-assignment-operators": 7.10.4(@babel/core@7.25.2) - "@babel/plugin-syntax-nullish-coalescing-operator": 7.8.3(@babel/core@7.25.2) - "@babel/plugin-syntax-numeric-separator": 7.10.4(@babel/core@7.25.2) - "@babel/plugin-syntax-object-rest-spread": 7.8.3(@babel/core@7.25.2) - "@babel/plugin-syntax-optional-catch-binding": 7.8.3(@babel/core@7.25.2) - "@babel/plugin-syntax-optional-chaining": 7.8.3(@babel/core@7.25.2) - "@babel/plugin-syntax-private-property-in-object": 7.14.5(@babel/core@7.25.2) - "@babel/plugin-syntax-top-level-await": 7.14.5(@babel/core@7.25.2) + '@babel/core': 7.25.2 + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.25.2) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.25.2) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.25.2) + '@babel/plugin-syntax-import-attributes': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.25.2) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.25.2) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.25.2) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.25.2) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.25.2) babel-preset-jest@29.6.3(@babel/core@7.25.2): dependencies: - "@babel/core": 7.25.2 + '@babel/core': 7.25.2 babel-plugin-jest-hoist: 29.6.3 babel-preset-current-node-syntax: 1.1.0(@babel/core@7.25.2) @@ -2969,7 +2029,7 @@ snapshots: create-jest@29.7.0(@types/node@20.14.15)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)): dependencies: - "@jest/types": 29.6.3 + '@jest/types': 29.6.3 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 @@ -2977,7 +2037,7 @@ snapshots: jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: - - "@types/node" + - '@types/node' - babel-plugin-macros - supports-color - ts-node @@ -3044,7 +2104,7 @@ snapshots: expect@29.7.0: dependencies: - "@jest/expect-utils": 29.7.0 + '@jest/expect-utils': 29.7.0 jest-get-type: 29.6.3 jest-matcher-utils: 29.7.0 jest-message-util: 29.7.0 @@ -3153,9 +2213,9 @@ snapshots: istanbul-lib-instrument@5.2.1: dependencies: - "@babel/core": 7.25.2 - "@babel/parser": 7.25.3 - "@istanbuljs/schema": 0.1.3 + '@babel/core': 7.25.2 + '@babel/parser': 7.25.3 + '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 semver: 6.3.1 transitivePeerDependencies: @@ -3163,9 +2223,9 @@ snapshots: istanbul-lib-instrument@6.0.3: dependencies: - "@babel/core": 7.25.2 - "@babel/parser": 7.25.3 - "@istanbuljs/schema": 0.1.3 + '@babel/core': 7.25.2 + '@babel/parser': 7.25.3 + '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 semver: 7.6.3 transitivePeerDependencies: @@ -3205,11 +2265,11 @@ snapshots: jest-circus@29.7.0: dependencies: - "@jest/environment": 29.7.0 - "@jest/expect": 29.7.0 - "@jest/test-result": 29.7.0 - "@jest/types": 29.6.3 - "@types/node": 20.14.15 + '@jest/environment': 29.7.0 + '@jest/expect': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.14.15 chalk: 4.1.2 co: 4.6.0 dedent: 1.5.3 @@ -3231,9 +2291,9 @@ snapshots: jest-cli@29.7.0(@types/node@20.14.15)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)): dependencies: - "@jest/core": 29.7.0(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)) - "@jest/test-result": 29.7.0 - "@jest/types": 29.6.3 + '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)) + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 chalk: 4.1.2 create-jest: 29.7.0(@types/node@20.14.15)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)) exit: 0.1.2 @@ -3243,16 +2303,16 @@ snapshots: jest-validate: 29.7.0 yargs: 17.7.2 transitivePeerDependencies: - - "@types/node" + - '@types/node' - babel-plugin-macros - supports-color - ts-node jest-config@29.7.0(@types/node@20.14.15)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)): dependencies: - "@babel/core": 7.25.2 - "@jest/test-sequencer": 29.7.0 - "@jest/types": 29.6.3 + '@babel/core': 7.25.2 + '@jest/test-sequencer': 29.7.0 + '@jest/types': 29.6.3 babel-jest: 29.7.0(@babel/core@7.25.2) chalk: 4.1.2 ci-info: 3.9.0 @@ -3273,7 +2333,7 @@ snapshots: slash: 3.0.0 strip-json-comments: 3.1.1 optionalDependencies: - "@types/node": 20.14.15 + '@types/node': 20.14.15 ts-node: 10.9.2(@types/node@20.14.15)(typescript@5.5.4) transitivePeerDependencies: - babel-plugin-macros @@ -3292,7 +2352,7 @@ snapshots: jest-each@29.7.0: dependencies: - "@jest/types": 29.6.3 + '@jest/types': 29.6.3 chalk: 4.1.2 jest-get-type: 29.6.3 jest-util: 29.7.0 @@ -3300,10 +2360,10 @@ snapshots: jest-environment-node@29.7.0: dependencies: - "@jest/environment": 29.7.0 - "@jest/fake-timers": 29.7.0 - "@jest/types": 29.6.3 - "@types/node": 20.14.15 + '@jest/environment': 29.7.0 + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.14.15 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -3311,9 +2371,9 @@ snapshots: jest-haste-map@29.7.0: dependencies: - "@jest/types": 29.6.3 - "@types/graceful-fs": 4.1.9 - "@types/node": 20.14.15 + '@jest/types': 29.6.3 + '@types/graceful-fs': 4.1.9 + '@types/node': 20.14.15 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 @@ -3339,9 +2399,9 @@ snapshots: jest-message-util@29.7.0: dependencies: - "@babel/code-frame": 7.24.7 - "@jest/types": 29.6.3 - "@types/stack-utils": 2.0.3 + '@babel/code-frame': 7.24.7 + '@jest/types': 29.6.3 + '@types/stack-utils': 2.0.3 chalk: 4.1.2 graceful-fs: 4.2.11 micromatch: 4.0.7 @@ -3351,8 +2411,8 @@ snapshots: jest-mock@29.7.0: dependencies: - "@jest/types": 29.6.3 - "@types/node": 20.14.15 + '@jest/types': 29.6.3 + '@types/node': 20.14.15 jest-util: 29.7.0 jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): @@ -3382,12 +2442,12 @@ snapshots: jest-runner@29.7.0: dependencies: - "@jest/console": 29.7.0 - "@jest/environment": 29.7.0 - "@jest/test-result": 29.7.0 - "@jest/transform": 29.7.0 - "@jest/types": 29.6.3 - "@types/node": 20.14.15 + '@jest/console': 29.7.0 + '@jest/environment': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.14.15 chalk: 4.1.2 emittery: 0.13.1 graceful-fs: 4.2.11 @@ -3408,14 +2468,14 @@ snapshots: jest-runtime@29.7.0: dependencies: - "@jest/environment": 29.7.0 - "@jest/fake-timers": 29.7.0 - "@jest/globals": 29.7.0 - "@jest/source-map": 29.6.3 - "@jest/test-result": 29.7.0 - "@jest/transform": 29.7.0 - "@jest/types": 29.6.3 - "@types/node": 20.14.15 + '@jest/environment': 29.7.0 + '@jest/fake-timers': 29.7.0 + '@jest/globals': 29.7.0 + '@jest/source-map': 29.6.3 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.14.15 chalk: 4.1.2 cjs-module-lexer: 1.3.1 collect-v8-coverage: 1.0.2 @@ -3435,14 +2495,14 @@ snapshots: jest-snapshot@29.7.0: dependencies: - "@babel/core": 7.25.2 - "@babel/generator": 7.25.0 - "@babel/plugin-syntax-jsx": 7.24.7(@babel/core@7.25.2) - "@babel/plugin-syntax-typescript": 7.24.7(@babel/core@7.25.2) - "@babel/types": 7.25.2 - "@jest/expect-utils": 29.7.0 - "@jest/transform": 29.7.0 - "@jest/types": 29.6.3 + '@babel/core': 7.25.2 + '@babel/generator': 7.25.0 + '@babel/plugin-syntax-jsx': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-syntax-typescript': 7.24.7(@babel/core@7.25.2) + '@babel/types': 7.25.2 + '@jest/expect-utils': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 babel-preset-current-node-syntax: 1.1.0(@babel/core@7.25.2) chalk: 4.1.2 expect: 29.7.0 @@ -3460,8 +2520,8 @@ snapshots: jest-util@29.7.0: dependencies: - "@jest/types": 29.6.3 - "@types/node": 20.14.15 + '@jest/types': 29.6.3 + '@types/node': 20.14.15 chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 @@ -3469,7 +2529,7 @@ snapshots: jest-validate@29.7.0: dependencies: - "@jest/types": 29.6.3 + '@jest/types': 29.6.3 camelcase: 6.3.0 chalk: 4.1.2 jest-get-type: 29.6.3 @@ -3478,9 +2538,9 @@ snapshots: jest-watcher@29.7.0: dependencies: - "@jest/test-result": 29.7.0 - "@jest/types": 29.6.3 - "@types/node": 20.14.15 + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.14.15 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 @@ -3489,19 +2549,19 @@ snapshots: jest-worker@29.7.0: dependencies: - "@types/node": 20.14.15 + '@types/node': 20.14.15 jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 jest@29.7.0(@types/node@20.14.15)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)): dependencies: - "@jest/core": 29.7.0(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)) - "@jest/types": 29.6.3 + '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)) + '@jest/types': 29.6.3 import-local: 3.2.0 jest-cli: 29.7.0(@types/node@20.14.15)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)) transitivePeerDependencies: - - "@types/node" + - '@types/node' - babel-plugin-macros - supports-color - ts-node @@ -3606,7 +2666,7 @@ snapshots: parse-json@5.2.0: dependencies: - "@babel/code-frame": 7.24.7 + '@babel/code-frame': 7.24.7 error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 @@ -3648,7 +2708,7 @@ snapshots: pretty-format@29.7.0: dependencies: - "@jest/schemas": 29.6.3 + '@jest/schemas': 29.6.3 ansi-styles: 5.2.0 react-is: 18.3.1 @@ -3747,7 +2807,7 @@ snapshots: test-exclude@6.0.0: dependencies: - "@istanbuljs/schema": 0.1.3 + '@istanbuljs/schema': 0.1.3 glob: 7.2.3 minimatch: 3.1.2 @@ -3773,19 +2833,19 @@ snapshots: typescript: 5.5.4 yargs-parser: 21.1.1 optionalDependencies: - "@babel/core": 7.25.2 - "@jest/transform": 29.7.0 - "@jest/types": 29.6.3 + '@babel/core': 7.25.2 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 babel-jest: 29.7.0(@babel/core@7.25.2) ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4): dependencies: - "@cspotcode/source-map-support": 0.8.1 - "@tsconfig/node10": 1.0.11 - "@tsconfig/node12": 1.0.11 - "@tsconfig/node14": 1.0.3 - "@tsconfig/node16": 1.0.4 - "@types/node": 20.14.15 + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.11 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 20.14.15 acorn: 8.12.1 acorn-walk: 8.3.3 arg: 4.1.3 @@ -3816,8 +2876,8 @@ snapshots: v8-to-istanbul@9.3.0: dependencies: - "@jridgewell/trace-mapping": 0.3.25 - "@types/istanbul-lib-coverage": 2.0.6 + '@jridgewell/trace-mapping': 0.3.25 + '@types/istanbul-lib-coverage': 2.0.6 convert-source-map: 2.0.0 walker@1.0.8: From 74e881bad1d4aa153a1e25440f64d51d9a70adf2 Mon Sep 17 00:00:00 2001 From: NolanTrem <34580718+NolanTrem@users.noreply.github.com> Date: Fri, 23 Aug 2024 14:52:31 -0700 Subject: [PATCH 72/74] remove tarball --- js/sdk/r2r-js-0.3.0.tgz | Bin 20514 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 js/sdk/r2r-js-0.3.0.tgz diff --git a/js/sdk/r2r-js-0.3.0.tgz b/js/sdk/r2r-js-0.3.0.tgz deleted file mode 100644 index 8327690dce7d2a05f3f58e335ae4939556d012e2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20514 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 From c57f08e69e119fe59fb976ee98aefe41ce97b4c5 Mon Sep 17 00:00:00 2001 From: emrgnt-cmplxty <68796651+emrgnt-cmplxty@users.noreply.github.com> Date: Fri, 23 Aug 2024 15:10:05 -0700 Subject: [PATCH 73/74] Feature/fix dev tests (#966) * update auth tests * fix tests * back and sort * decruft * revert back to gpt-4o --- py/core/base/abstractions/exception.py | 13 ++++ py/core/main/api/routes/base_router.py | 4 +- py/core/main/services/ingestion_service.py | 5 +- py/core/parsers/media/img_parser.py | 29 ++++++--- py/core/providers/auth/r2r_auth.py | 4 +- py/core/providers/database/group.py | 2 +- py/core/providers/database/tokens.py | 2 +- py/core/providers/database/user.py | 14 +---- py/sdk/management.py | 68 +++++++++++---------- py/tests/test_auth.py | 70 ++++++---------------- py/tests/test_end_to_end.py | 4 +- py/tests/test_groups_client.py | 35 +++++------ 12 files changed, 121 insertions(+), 129 deletions(-) diff --git a/py/core/base/abstractions/exception.py b/py/core/base/abstractions/exception.py index c76625a35..5c7593f85 100644 --- a/py/core/base/abstractions/exception.py +++ b/py/core/base/abstractions/exception.py @@ -9,8 +9,21 @@ def __init__( self.status_code = status_code super().__init__(self.message) + def to_dict(self): + return { + "message": self.message, + "status_code": self.status_code, + "detail": self.detail, + "error_type": self.__class__.__name__, + } + class R2RDocumentProcessingError(R2RException): def __init__(self, error_message, document_id): self.document_id = document_id super().__init__(error_message, 400, {"document_id": document_id}) + + def to_dict(self): + result = super().to_dict() + result["document_id"] = self.document_id + return result diff --git a/py/core/main/api/routes/base_router.py b/py/core/main/api/routes/base_router.py index c621ab94f..55563e8ed 100644 --- a/py/core/main/api/routes/base_router.py +++ b/py/core/main/api/routes/base_router.py @@ -5,7 +5,7 @@ from fastapi import APIRouter, HTTPException from fastapi.responses import StreamingResponse -from core.base import R2RException, manage_run +from core.base import R2RDocumentProcessingError, R2RException, manage_run from core.base.logging.base import RunType logger = logging.getLogger(__name__) @@ -48,6 +48,8 @@ async def wrapper(*args, **kwargs): }, ) except Exception as e: + print("cc") + await self.engine.logging_connection.log( run_id=run_id, key="error", diff --git a/py/core/main/services/ingestion_service.py b/py/core/main/services/ingestion_service.py index f73adde6e..017d4736c 100644 --- a/py/core/main/services/ingestion_service.py +++ b/py/core/main/services/ingestion_service.py @@ -425,7 +425,10 @@ async def _process_ingestion_results( if document.id in successful_ids ], "failed_documents": [ - {"document_id": document_id, "result": results[document_id]} + { + "document_id": document_id, + "result": str(results[document_id]), + } for document_id in failed_ids ], "skipped_documents": skipped_ids, diff --git a/py/core/parsers/media/img_parser.py b/py/core/parsers/media/img_parser.py index c679b2772..bad80612d 100644 --- a/py/core/parsers/media/img_parser.py +++ b/py/core/parsers/media/img_parser.py @@ -1,6 +1,10 @@ +import base64 import os +from io import BytesIO from typing import AsyncGenerator +from PIL import Image + from core.base.abstractions.document import DataType from core.base.parsers.base_parser import AsyncParser from core.parsers.media.openai_helpers import process_frame_with_openai @@ -13,7 +17,8 @@ def __init__( self, model: str = "gpt-4o", max_tokens: int = 2_048, - api_base: str = "https://api.openai.com/v2/chat/completions", + api_base: str = "https://api.openai.com/v1/chat/completions", + max_image_size: int = 1 * 1024 * 1024, # 4MB limit ): self.model = model self.max_tokens = max_tokens @@ -23,12 +28,26 @@ def __init__( "Error, environment variable `OPENAI_API_KEY` is required to run `ImageParser`." ) self.api_base = api_base + self.max_image_size = max_image_size + + def _resize_image(self, image_data: bytes, compression_ratio) -> bytes: + img = Image.open(BytesIO(image_data)) + img_byte_arr = BytesIO() + img.save( + img_byte_arr, format="JPEG", quality=int(100 * compression_ratio) + ) + return img_byte_arr.getvalue() async def ingest(self, data: DataType) -> AsyncGenerator[str, None]: """Ingest image data and yield a description.""" if isinstance(data, bytes): - import base64 + # Resize the image if it's too large + if len(data) > self.max_image_size: + data = self._resize_image( + data, float(self.max_image_size) / len(data) + ) + # Encode to base64 data = base64.b64encode(data).decode("utf-8") yield process_frame_with_openai( @@ -38,9 +57,3 @@ async def ingest(self, data: DataType) -> AsyncGenerator[str, None]: self.max_tokens, self.api_base, ) - - -class ImageParserLocal(AsyncParser[DataType]): - - def __init__(self): - pass diff --git a/py/core/providers/auth/r2r_auth.py b/py/core/providers/auth/r2r_auth.py index 6fbc3aba2..e87fb3b7b 100644 --- a/py/core/providers/auth/r2r_auth.py +++ b/py/core/providers/auth/r2r_auth.py @@ -216,7 +216,9 @@ def refresh_access_token(self, refresh_token: str) -> Dict[str, Token]: new_access_token = self.create_access_token( data={"sub": token_data.email} ) - new_refresh_token = self.create_refresh_token() + new_refresh_token = self.create_refresh_token( + data={"sub": token_data.email} + ) return { "access_token": Token(token=new_access_token, token_type="access"), "refresh_token": Token( diff --git a/py/core/providers/database/group.py b/py/core/providers/database/group.py index 8732b2da5..9ec8d48ce 100644 --- a/py/core/providers/database/group.py +++ b/py/core/providers/database/group.py @@ -17,7 +17,7 @@ class GroupMixin(DatabaseMixin): def create_table(self) -> None: query = f""" CREATE TABLE IF NOT EXISTS {self._get_table_name('groups')} ( - group_id UUID PRIMARY KEY DEFAULT public.uuid_generate_v4(), + group_id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), name TEXT NOT NULL, description TEXT, created_at TIMESTAMPTZ DEFAULT NOW(), diff --git a/py/core/providers/database/tokens.py b/py/core/providers/database/tokens.py index 87a81cf9a..0149c263f 100644 --- a/py/core/providers/database/tokens.py +++ b/py/core/providers/database/tokens.py @@ -8,7 +8,7 @@ class BlacklistedTokensMixin(DatabaseMixin): def create_table(self): query = f""" CREATE TABLE IF NOT EXISTS {self._get_table_name('blacklisted_tokens')} ( - id UUID PRIMARY KEY DEFAULT public.uuid_generate_v4(), + id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), token TEXT NOT NULL, blacklisted_at TIMESTAMPTZ DEFAULT NOW() ); diff --git a/py/core/providers/database/user.py b/py/core/providers/database/user.py index 773e62680..2c6990906 100644 --- a/py/core/providers/database/user.py +++ b/py/core/providers/database/user.py @@ -15,7 +15,7 @@ class UserMixin(DatabaseMixin): def create_table(self): query = f""" CREATE TABLE IF NOT EXISTS {self._get_table_name('users')} ( - user_id UUID PRIMARY KEY DEFAULT public.uuid_generate_v4(), + user_id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), email TEXT UNIQUE NOT NULL, hashed_password TEXT NOT NULL, is_superuser BOOLEAN DEFAULT FALSE, @@ -209,18 +209,6 @@ def delete_user(self, user_id: UUID) -> None: user_groups = group_result[0] - # Remove user from all groups they belong to - if user_groups: - group_update_query = f""" - UPDATE {self._get_table_name('groups')} - SET user_ids = array_remove(user_ids, :user_id) - WHERE group_id = ANY(:group_ids) - """ - self.execute_query( - group_update_query, - {"user_id": user_id, "group_ids": user_groups}, - ) - # Remove user from documents doc_update_query = f""" UPDATE {self._get_table_name('document_info')} diff --git a/py/sdk/management.py b/py/sdk/management.py index a8f82522b..95fd7387c 100644 --- a/py/sdk/management.py +++ b/py/sdk/management.py @@ -276,7 +276,7 @@ async def create_group( @staticmethod async def get_group( client, - group_id: str, + group_id: Union[str, UUID], ) -> dict: """ Get a group by its ID. @@ -287,12 +287,12 @@ async def get_group( Returns: dict: The group data. """ - return await client._make_request("GET", f"get_group/{group_id}") + return await client._make_request("GET", f"get_group/{str(group_id)}") @staticmethod async def update_group( client, - group_id: str, + group_id: Union[str, UUID], name: Optional[str] = None, description: Optional[str] = None, ) -> dict: @@ -307,7 +307,7 @@ async def update_group( Returns: dict: The response from the server. """ - data = {"group_id": group_id} + data = {"group_id": str(group_id)} if name is not None: data["name"] = name if description is not None: @@ -318,7 +318,7 @@ async def update_group( @staticmethod async def delete_group( client, - group_id: str, + group_id: Union[str, UUID], ) -> dict: """ Delete a group by its ID. @@ -329,7 +329,9 @@ async def delete_group( Returns: dict: The response from the server. """ - return await client._make_request("DELETE", f"delete_group/{group_id}") + return await client._make_request( + "DELETE", f"delete_group/{str(group_id)}" + ) @staticmethod async def delete_user( @@ -385,8 +387,8 @@ async def list_groups( @staticmethod async def add_user_to_group( client, - user_id: str, - group_id: str, + user_id: Union[str, UUID], + group_id: Union[str, UUID], ) -> dict: """ Add a user to a group. @@ -399,8 +401,8 @@ async def add_user_to_group( dict: The response from the server. """ data = { - "user_id": user_id, - "group_id": group_id, + "user_id": str(user_id), + "group_id": str(group_id), } return await client._make_request( "POST", "add_user_to_group", json=data @@ -409,8 +411,8 @@ async def add_user_to_group( @staticmethod async def remove_user_from_group( client, - user_id: str, - group_id: str, + user_id: Union[str, UUID], + group_id: Union[str, UUID], ) -> dict: """ Remove a user from a group. @@ -423,8 +425,8 @@ async def remove_user_from_group( dict: The response from the server. """ data = { - "user_id": user_id, - "group_id": group_id, + "user_id": str(user_id), + "group_id": str(group_id), } return await client._make_request( "POST", "remove_user_from_group", json=data @@ -433,7 +435,7 @@ async def remove_user_from_group( @staticmethod async def get_users_in_group( client, - group_id: str, + group_id: Union[str, UUID], offset: Optional[int] = None, limit: Optional[int] = None, ) -> dict: @@ -454,13 +456,13 @@ async def get_users_in_group( if limit is not None: params["limit"] = limit return await client._make_request( - "GET", f"get_users_in_group/{group_id}", params=params + "GET", f"get_users_in_group/{str(group_id)}", params=params ) @staticmethod async def user_groups( client, - user_id: str, + user_id: Union[str, UUID], offset: Optional[int] = None, limit: Optional[int] = None, ) -> dict: @@ -479,17 +481,19 @@ async def user_groups( if limit is not None: params["limit"] = limit if params: - return await client._make_request("GET", f"user_groups/{user_id}") + return await client._make_request( + "GET", f"user_groups/{str(user_id)}" + ) else: return await client._make_request( - "GET", f"user_groups/{user_id}", params=params + "GET", f"user_groups/{str(user_id)}", params=params ) @staticmethod async def assign_document_to_group( client, - document_id: str, - group_id: str, + document_id: Union[str, UUID], + group_id: Union[str, UUID], ) -> dict: """ Assign a document to a group. @@ -502,8 +506,8 @@ async def assign_document_to_group( dict: The response from the server. """ data = { - "document_id": document_id, - "group_id": group_id, + "document_id": str(document_id), + "group_id": str(group_id), } return await client._make_request( "POST", "assign_document_to_group", json=data @@ -513,8 +517,8 @@ async def assign_document_to_group( @staticmethod async def remove_document_from_group( client, - document_id: str, - group_id: str, + document_id: Union[str, UUID], + group_id: Union[str, UUID], ) -> dict: """ Remove a document from a group. @@ -527,8 +531,8 @@ async def remove_document_from_group( dict: The response from the server. """ data = { - "document_id": document_id, - "group_id": group_id, + "document_id": str(document_id), + "group_id": str(group_id), } return await client._make_request( "POST", "remove_document_from_group", json=data @@ -537,7 +541,7 @@ async def remove_document_from_group( @staticmethod async def document_groups( client, - document_id: str, + document_id: Union[str, UUID], offset: Optional[int] = None, limit: Optional[int] = None, ) -> dict: @@ -557,17 +561,17 @@ async def document_groups( params["limit"] = limit if params: return await client._make_request( - "GET", f"document_groups/{document_id}", params=params + "GET", f"document_groups/{str(document_id)}", params=params ) else: return await client._make_request( - "GET", f"document_groups/{document_id}" + "GET", f"document_groups/{str(document_id)}" ) @staticmethod async def documents_in_group( client, - group_id: str, + group_id: Union[str, UUID], offset: Optional[int] = None, limit: Optional[int] = None, ) -> dict: @@ -588,5 +592,5 @@ async def documents_in_group( if limit is not None: params["limit"] = limit return await client._make_request( - "GET", f"group/{group_id}/documents", params=params + "GET", f"group/{str(group_id)}/documents", params=params ) diff --git a/py/tests/test_auth.py b/py/tests/test_auth.py index e4199f1a7..af9d4d98a 100644 --- a/py/tests/test_auth.py +++ b/py/tests/test_auth.py @@ -227,7 +227,9 @@ async def test_verify_email_with_expired_code(auth_service, auth_provider): ) with pytest.raises(R2RException) as exc_info: - await auth_service.verify_email("123456") + await auth_service.verify_email( + "verify_expired@example.com", "123456" + ) assert "Invalid or expired verification code" in str(exc_info.value) @@ -243,7 +245,7 @@ async def test_refresh_token_flow(auth_service, auth_provider): email="refresh@example.com", password="password123" ) - await auth_service.verify_email("123456") + await auth_service.verify_email("refresh@example.com", "123456") # Login to get initial tokens tokens = await auth_service.login("refresh@example.com", "password123") @@ -251,47 +253,11 @@ async def test_refresh_token_flow(auth_service, auth_provider): refresh_token = tokens["refresh_token"] # Use refresh token to get new access token - new_tokens = await auth_service.refresh_access_token( - "refresh@example.com", refresh_token.token - ) + new_tokens = await auth_service.refresh_access_token(refresh_token.token) assert "access_token" in new_tokens assert new_tokens["access_token"].token != initial_access_token.token -@pytest.mark.asyncio -async def test_refresh_token_with_wrong_user(auth_service, auth_provider): - with patch.object( - auth_provider.crypto_provider, - "generate_verification_code", - return_value="123456", - ): - new_user1 = await auth_service.register( - email="user1@example.com", password="password123" - ) - with patch.object( - auth_provider.crypto_provider, - "generate_verification_code", - return_value="1234567", - ): - new_user2 = await auth_service.register( - email="user2@example.com", password="password123" - ) - - await auth_service.verify_email("123456") - await auth_service.verify_email("1234567") - - # Login as user1 - tokens = await auth_service.login("user1@example.com", "password123") - refresh_token = tokens["refresh_token"] - - # Try to use user1's refresh token for user2 - with pytest.raises(R2RException) as exc_info: - await auth_service.refresh_access_token( - "user2@example.com", refresh_token.token - ) - assert "Invalid email address attached to token" in str(exc_info.value) - - @pytest.mark.asyncio async def test_get_current_user_with_expired_token( auth_service, auth_provider @@ -305,7 +271,7 @@ async def test_get_current_user_with_expired_token( email="expired_token@example.com", password="password123" ) - await auth_service.verify_email("123456") + await auth_service.verify_email("expired_token@example.com", "123456") # Manually expire the token auth_provider.access_token_lifetime_in_minutes = ( @@ -339,7 +305,7 @@ async def test_change_password(auth_service, auth_provider): new_user = await auth_service.register( email="change_password@example.com", password="old_password" ) - await auth_service.verify_email("123456") + await auth_service.verify_email("change_password@example.com", "123456") # Change password await auth_service.change_password( @@ -370,7 +336,7 @@ async def test_reset_password_flow( new_user = await auth_service.register( email="reset_password@example.com", password="old_password" ) - await auth_service.verify_email("123456") + await auth_service.verify_email("reset_password@example.com", "123456") # Request password reset await auth_service.request_password_reset("reset_password@example.com") @@ -411,7 +377,7 @@ async def test_logout(auth_service, auth_provider): new_user = await auth_service.register( email="logout@example.com", password="password123" ) - await auth_service.verify_email("123456") + await auth_service.verify_email("logout@example.com", "123456") # Login to get tokens tokens = await auth_service.login("logout@example.com", "password123") @@ -437,7 +403,7 @@ async def test_update_user_profile(auth_service, auth_provider): new_user = await auth_service.register( email="update_profile@example.com", password="password123" ) - await auth_service.verify_email("123456") + await auth_service.verify_email("update_profile@example.com", "123456") # Update user profile updated_profile = await auth_service.update_user( @@ -462,7 +428,7 @@ async def test_delete_user_account(auth_service, auth_provider): new_user = await auth_service.register( email="delete_user@example.com", password="password123" ) - await auth_service.verify_email("123456") + await auth_service.verify_email("delete_user@example.com", "123456") # Delete user account await auth_service.delete_user(new_user.id, "password123") @@ -491,7 +457,7 @@ async def test_token_blacklist_cleanup(auth_service, auth_provider): await auth_service.register( email="cleanup@example.com", password="password123" ) - await auth_service.verify_email("123456") + await auth_service.verify_email("cleanup@example.com", "123456") # Login and logout to create a blacklisted token tokens = await auth_service.login("cleanup@example.com", "password123") @@ -539,7 +505,7 @@ async def test_register_and_verify(auth_service, auth_provider): assert new_user.email == "newuser@example.com" assert not new_user.is_verified - await auth_service.verify_email("123456") + await auth_service.verify_email("newuser@example.com", "123456") new_user = auth_provider.db_provider.relational.get_user_by_email( "newuser@example.com" @@ -559,7 +525,7 @@ async def test_login_logout(auth_service, auth_provider): await auth_service.register( email="loginuser@example.com", password="password123" ) - await auth_service.verify_email("123456") + await auth_service.verify_email("loginuser@example.com", "123456") tokens = await auth_service.login("loginuser@example.com", "password123") assert "access_token" in tokens @@ -580,11 +546,11 @@ async def test_refresh_token(auth_service, auth_provider): await auth_service.register( email="refreshuser@example.com", password="password123" ) - await auth_service.verify_email("123456") + await auth_service.verify_email("refreshuser@example.com", "123456") tokens = await auth_service.login("refreshuser@example.com", "password123") new_tokens = await auth_service.refresh_access_token( - "refreshuser@example.com", tokens["refresh_token"].token + tokens["refresh_token"].token ) assert new_tokens["access_token"].token != tokens["access_token"].token @@ -599,7 +565,7 @@ async def test_change_password(auth_service, auth_provider): new_user = await auth_service.register( email="changepass@example.com", password="oldpassword" ) - await auth_service.verify_email("123456") + await auth_service.verify_email("changepass@example.com", "123456") result = await auth_service.change_password( new_user, "oldpassword", "newpassword" @@ -636,7 +602,7 @@ async def test_confirm_reset_password(auth_service, auth_provider): await auth_service.register( email="confirmreset@example.com", password="oldpassword" ) - await auth_service.verify_email("123456") + await auth_service.verify_email("confirmreset@example.com", "123456") await auth_service.request_password_reset("confirmreset@example.com") result = await auth_service.confirm_password_reset( "123456", "newpassword" diff --git a/py/tests/test_end_to_end.py b/py/tests/test_end_to_end.py index b74d6b61e..4cd0ef1d6 100644 --- a/py/tests/test_end_to_end.py +++ b/py/tests/test_end_to_end.py @@ -130,7 +130,7 @@ async def test_ingest_txt_file(app, user): os.path.join( os.path.dirname(__file__), "..", - "r2r", + "core", "examples", "data", "test.txt", @@ -163,7 +163,7 @@ async def test_ingest_search_txt_file(app, user, logging_connection): os.path.join( os.path.dirname(__file__), "..", - "r2r", + "core", "examples", "data", "aristotle.txt", diff --git a/py/tests/test_groups_client.py b/py/tests/test_groups_client.py index 06e0520ea..92780af9c 100644 --- a/py/tests/test_groups_client.py +++ b/py/tests/test_groups_client.py @@ -312,9 +312,10 @@ async def test_update_group(r2r_client, mock_db, group_id): async def test_list_groups(r2r_client, mock_db): authenticate_superuser(r2r_client, mock_db) # mock_db.relational.list_groups.return_value = mock_groups - response = r2r_client.list_groups() + response = r2r_client.list_groups(0, 100) assert "results" in response assert len(response["results"]) == 2 + mock_db.relational.list_groups.assert_called_once_with(offset=0, limit=100) @@ -325,23 +326,23 @@ async def test_get_users_in_group(r2r_client, mock_db, group_id): assert "results" in response assert len(response["results"]) == 2 mock_db.relational.get_users_in_group.assert_called_once_with( - group_id, 0, 100 + group_id, offset=0, limit=100 ) -@pytest.mark.asyncio -async def test_get_groups_for_user(r2r_client, mock_db, user_id): - authenticate_superuser(r2r_client, mock_db) - # mock_groups = [ - # {"id": str(uuid.uuid4()), "name": "Group 1"}, - # {"id": str(uuid.uuid4()), "name": "Group 2"}, - # ] - # mock_db.relational.get_groups_for_user.return_value = mock_groups - response = r2r_client.get_groups_for_user(user_id) - assert "results" in response - assert len(response["results"]) == 2 - # assert response["results"] == mock_groups - mock_db.relational.get_groups_for_user.assert_called_once_with(user_id) +# @pytest.mark.asyncio +# async def test_get_groups_for_user(r2r_client, mock_db, user_id): +# authenticate_superuser(r2r_client, mock_db) +# # mock_groups = [ +# # {"id": str(uuid.uuid4()), "name": "Group 1"}, +# # {"id": str(uuid.uuid4()), "name": "Group 2"}, +# # ] +# # mock_db.relational.get_groups_for_user.return_value = mock_groups +# response = r2r_client.user_groups(user_id) +# assert "results" in response +# assert len(response["results"]) == 2 +# # assert response["results"] == mock_groups +# mock_db.relational.get_groups_for_user.assert_called_once_with(user_id, offset=0, limit=100) @pytest.mark.asyncio @@ -357,7 +358,7 @@ async def test_groups_overview(r2r_client, mock_db): assert len(response["results"]) == 2 # assert response["results"] == mock_overview mock_db.relational.get_groups_overview.assert_called_once_with( - None, 0, 100 + None, offset=0, limit=100 ) @@ -375,5 +376,5 @@ async def test_groups_overview_with_ids(r2r_client, mock_db): assert len(response["results"]) == 2 # assert response["results"] == mock_overview mock_db.relational.get_groups_overview.assert_called_once_with( - [str(gid) for gid in group_ids], 100, 10 + [str(gid) for gid in group_ids], offset=10, limit=100 ) From 52dcea6414997092236c1cf34a806117bc32e489 Mon Sep 17 00:00:00 2001 From: emrgnt-cmplxty <68796651+emrgnt-cmplxty@users.noreply.github.com> Date: Fri, 23 Aug 2024 15:13:35 -0700 Subject: [PATCH 74/74] Feature/merge dev and main (#967) * Fix argument order on ingest_files (#883) * change get basename to get abspath of config (#893) * Fix typos (#919) * Fix typo in README (`Pyhon` -> `Python`) * Fix incorrect setting name in error message `collection` was used, but it should be `vecs_collection`. * Fix type annotations to run with Python 3.9 (#943) According to the `tool.poetry.dependencies.python` key of `pyproject.toml`, the package supports `">=3.9,<3.13"`. However, when running `r2r --help` with Python 3.9, I received the following error: > `TypeError: unsupported operand type(s) for |: 'type' and 'NoneType'` The problem was that one set of type annotations uses the `|` operator instead of `typing.Union`, which was not supported until Python 3.10. I switched to using the `typing` module to restore support for Python 3.9. * Fix typo in variable name (#961) * Add support for relative paths for the prompt directory in config (#958) --------- Co-authored-by: Tim Kellogg Co-authored-by: Maxine Lai <76145646+mmtmr@users.noreply.github.com> Co-authored-by: Alex Hedges Co-authored-by: Manuel R. Ciosici

U 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 z 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%0ApCIq-3L4%jdyD#S`nY@K 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

fD~l_ql9;cD&R(>x4&6%l4E zKVITb@Tc7f+%=9UwTMLgB;?lhQ0EfhpIZC0Eh1TKjNVRIN+YlX6%DgS2zg?Zt)uR% zK_Vn#DxQXuF50=A-;%Jm)!rl{b8`1?A%0A0{?;@|?-_>SJi-}A_`pSWsm4tE+~YV0 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°2L+#MWl+%J1?od)D^y z)dUhhd`!4ZjEO%50O{yd6Co= zOk?AQDk|+(!)tV4E^xm%728nv{t!!s(PZ+lLcdG`e_dpKVXAW>#DcW?kUsT(MP9ng zj79mxIU@t(c~dz`lESGei_y~UL}SOzxc!^cO~ORQ8prW5TPAN(k`YViCV?oRyMWIE zelaUf@S}q>3lJ??!ma&q{K(I{ZJqlT9StFl6(u8nO`>tzG@|uk^>Yyki4Q~5dvJ`l z8-ou~$CQM{vc98%R?05Eg{T>?qDu-X`DjQrhN+TVpeodVo8g&1{h9Y=scw6H3$*^N zx)2V1?axUt@6U90!I*v$TB5ctu!X>sbC|nPjj&~Ft1B5S=4I9zd1uR-5;h9S?J7y^ znE(zh9M&_~uw9~Yvqos|qIX6^r0b66*m!=0Zj#WP$?jb-U3oo@(!MMDm9>B8!_n|s z`(Ct?P(;Cb=#V7f<=CDis~aAS@*xki78>S>^$TJR-NMF(_wj`P3KuWUYRV zMJ%p~_T3@$D1r*shYr{Q#)*lXAn+D>&QQo}0YRq6@uAu-LHDIf|2oL+ZHLPU$x{3r z0PA85e+@jw!`4FB_yoL~S&VBQf4co+gcUV99=Q9H4|v7nW7RgI*aC3r@c<2kSoF#O z96YS~ICRcxGz1=&6BVk{1}+^QV30B3A97{U0gy_C6CzKXF|~1ra+9!;Q2TwpwY9T4OHNn3#2J{(j2RG%5Ub(j}lpIMdQ78$C)`(?8CFW zFM@%fUMG@(cnyG&hh3-zGJW43tt;4O&k%DDbq~)T3xduN9*jkVm9T^5K?EDC2GcP) zF?gWH@1Xpvc1gs?LRcsVsf76^fKgZD!f~i@rKn)Y4)iq@x@~Gi!S7%|n5k+wE;qi3 z!Zz;pjje7IR(%&NhtLI}9g0c>`y_3j&KI>+;BRe&2R90Q-sn%(;O|WZtEoo&9PaZE z9!zxhj0+EdZ-mij^bCa>66xV2P6QzA!pg>j@fhK?;lZw{z;(AVv6@)_2ps0m6x5n* zs~DbTG~g88VztCYX6&Gt?V%*rM?ND&e#)TlOvq|kETT!j0fLia=8Z!I`+kOw7U2iP zi|(}y1QP=WrBQ*^nBO^2pWy+%cR{8-e8oKg*iC?VSJZzSKFMa!q|d%E!7S?GSb)Zl zSmv=yzYzusudI(!Lqb!W&x&C$l|!9~V64iauQ_0DTK=A26C_J?F(IITU8uGvdF=$BWfW|I1;O_Ay zsxVl;lfmX&g#BT1zm$euhub9=d;u?fv4N%57x)wXMJ61f@W-JKXeJY3Bon<(?vYOZ zcNX{jZ*p}U06h-!XCv8&7@+TuD-aii1NCsH!nN!|;ZjEX)D^?{DYfRksU5~wGls96 zC7)b}V?#onPZwYqc>X7apio{I9#!UUA&5{028j!WaAZvF>x5$fBcRwPQ0(e16kNpL zBn*t`WQ=f)v@}KsgN`Y5;^z2;pP0*pFf$IULjcZqq&bf$V;Yvj^gE@u`XdM7SLc$9 z{cUfO-x=?lVHnks`);u3MsQhe*oB+>wl4yRHZ@KhMHN7a1zZel*ngIKn z^H!(uqOqVYt~m=VS6ge(FJS7Jq5JPU*j^5-0xr zT&vRZrP9h${bH|@Qp{qjyV3@)vL)x^;XDmi%Ofw z%AwNAu7k=;ohm8Js+rRA>z1mA^t@aCvb&`!6oKmNzg0^l)u4=OOz$ML`yxndH6H2r z^o8nS{>m5L--*inUa?dWFMp>P^&rhCp%kd0YjvV-Ev3(>VHU7uY(-SC+}Ci(S+U($ zztydMXKle{{hhb9R`A~JeQTuSagk%v$w5Wg;t`5f;rgAk*Ag(@*9=uruE0%-tPc^pGwg4o$gWnEmGL-XluOy?3cIxP8964On31fcA?w(m8Y{Xxg+JO9q8YA*s6n&)4A1c zHneVACe_&=ZB8!eEWB#YuLpmD$8D6g{ju%_;&nCScc8Yx@Rc#k`#bZmx+$=GIu2V> z3cA1Zp!T!CI2};UjJiQkbia)@y*P9RWuPxHZ2sQxVYD0FMhDjhMl%MZ^XXaZ?_`#T zNwLDj#&i{Yx*xClRNHhU1YzWYFgYI`n7pn&s}9ym^GQ^9F}OQV10r0FDKrd`JVQ^6 z3-1iUloI#z!K6?iBcI{nYfsSTYzbermP~&k?JA zDpC-J6*B>cPjIl!#%s)GgD29D+HqD#J0E6J>pNa#`BssQlCzDZ&`-0+K@wcil#Hg! z1g8hdX1T`arZRtEkIm?|&uDs&#+!{tc>G8)o5?z}M8(<75N-Bp_ax&V$IPeP|0D1-l`J=+S0Kkov zDYjLOqju{q04D%5_~+_6`C6(gkbw;L!*_L2Xv8sQ)C3PeU3^bXwcDTBB5Y>}h-$CgYA2_uE z1N<7xs^i~)&_Mz0)vd`IlS!_V31FcA8Q@-UGnWdS=>TbGg8_YE@p0iqT^OxIfG~lr zJf97W?DaLFUyC<859FH!?7x1sZ{Q#{E(8a(_115WckbENlELfKLaW+(8hg~eMOzQ7WC=MjK?z49s>1Xd+vG1tc?c^Q(9;bjswC|o9se?bo!G74;2xj*!j@vUDkmTgT>usi%uR*< zT>KSy2*?Ew`30mq`%Zn$s55auyI5&|eugOvf$(q~m+Ll=_+y?tuFYv7Uhx*^2wRJ%xK^S1`!@go-$wr^6UL% zHvJ^zg*{A|5=KS|Yw&~Rf4BlFUk$RI3n`-wjspb%*NInu-r%;Gm0giNLy@5b5O=nR zEu&qg!9+j6#3^9LP+u88lrkzb>@$=Cqi_{FSiJIuJ=EQ)>{>+WQgZ#0?(|lG@*I=x zkK&h0SwkRSb|*n5gy-``+~h?P{smX(U$EU@xtw|pcrxooa&p0~rqW*O6-qpweIzo( z>e!1!>58Z8TK3;HFzyameV1o;9np0wwSJxY=Auz}JW1(K6+-wf?doqXMkCKz)Xe%- zBKVtizgT>|}03Vq{@;X}OHC4~|!%oLf9e ziNX?|raoh=9!8`5J{nb=YAca{o6jY{YU;O?l6eaPzLondflV4^qpLT3y7Z;!bCzt` zwBH+mbg1c?VDZHqRso4H0TD5+?Q$=8$?ew=bs1LEdv8tI)*_Rk1k}s4`gXK`9iIW9Q*{(?TTzXMnZRQ9g8W$ah?$*0@& z?|M3s)0q70ZDrJhqaIUZPc z%CG52$_71`JSM1pTfiygjJ)*s`P2CGfCUi4Ba|ilv!f(RvcY_Kd#@}fhz#@IcBWxw z)J_uIh?j8uG#9TeWt+Wl8hK@rUM)KLY6q|A9^{oE^UG9SUVWGor>jR+F4$4LoouJB zDedE<8kLkxfr zRS*g^TqVp7-b;LW7;wrw@D}80oOHEVD^5>iDvIg@8;D0INe*bWY4BGV+33Fpb00-ah$ZUJ-9`D5V zg##iH9`t+gNh70VFltk8H-IV$4?SQ{xrHNkxd7k9bANonv<#fy^f4D=H*8cM#Y3q7 zK!yw0tVFF&EfTWy5D(5SyylzCUMudQZrLY*n8(xRzGn(t3DrIMs6_xVdh^rHo4K>m zZOCrXJWvpTLPIT*2xfUhT+p~Rz-1ab9lEeOO~PiDy;QNrc=( zyA$as{kX*+k6y=_YPQg;@CKUq3&}9S>99a33b2w&5F5i3{R_JYJ(JSD=WW>UTh43qeWqf%Ga z1mLO^u?!E(s1<^e-}*3+?MO?VOgoD#FPoD-hlpvQQNbA<8MxcI6_m4s<70!j&p{+( zIGca6OZ#@jC>P^oKdL2yGBK|Sc*>5hE^>v8EyV_g!zC-Ja?yMl|ILIYU%ejn9gn1} z+heS_*O2?Xknoxq8NVbp_7X1|3Px_Y1p)M^Uu55+Vw3#=@F~;0z=8nKw*fztRDP6d z<4Y6pQAeUfz&I%zeWXqv3GC%SX2CoZswMvrsqoPf<>UkPHZO#Rkj6&&C;da2KlvJ! zn0=ric<-x7vDO#czi{=LB*Y#fHR~sw8G;{si(DcSy6t#salac7G!pqYP1IN7K4*cI zBrMf@y#7FU*4s`q%AU`hTms|}rG`49r-1+{Rn@W3%RM|g%nHcK5E62p61nkGi&L@IVU+puq{ls(7Tv{x4{i-Yi!7SW_diD_wkuV#tTg_5E%Xr- zwZ-iWgSDy4&8>Kyas^&7alhSwm^LCyN~~6cOFIA101Y+cr+!L*mNzEy>s(^YuTQ+! zva7FK*B%#SW|kArDaOH78}<=wWrm1rI;Beun+i#669mjwwg1GI*$14kygJg?((veD z*2ud_X>!xb-(HD^TK^!nhEKw+GEAQ(juy*wbTW@KW**C6v=B7< zLIUG>Vr3`WM!V)nACI;Y8X?8!-p6?yahLGpgL(HU?4oSF?#!a%@z>&1n50WCe!Hb4 z@6z-a18!99=czWsT`xcSbkm_3^NHX8dhV!0CrvG6rON9CghOmfsM$Wr=J1E55agAb zJz8o_F3mR%@Dz$?9qt~d|LjC-(6DUTHEW-Q{fSC>EKcsU1}`s8hPu@itR@nW;bAy# ztmDH;kECzCmewWLpC15DY%~M_KN(J%lyYsI5K6i$$DxhLcG9uu;PP7dJlB0>%&agY zGVsXux*hz%Ay6s2vlT|yKH+8KKjVZy?Ei_CQ;@) z|I8?uo_)4>`4P-^R0X`g{+>w z3Yz+IT|-Yw%k}pJTaxqZ1=XHjMJHub_2a^_Dw- z=nA(}0al#3aj~FjBv4gdsGfJ1WJX&?sbCUn%NQ1)*r;$`R6F+}6i7$V-qe|736*B) z&R&2z2y|ltIA&_&Co>|}TR(*H`LlBbU@V|;z|w25IskD2q)e!!)Bt2skul7lRuHHt z4G5F|(Am{NiQOYaBWf%Y%tD3muUdvPh)1CE^{6@ofVD-%e+44VzlY)mH@+0)Ch*}VR_7KNdk@QiCSJV%toHsJSKTWkWQY#XHK9C|G zdjdzGa4P6x%Aao|SlEbRi8|l|0L+?NA#NltCElX!BTfe`Rr&?s-vG&`qLeZPiY!!w z7Wc`G^}TKilHy|*6Bm~V7MJ0ErY0Vu6wk$f2xLJ8>dT8ub}<`0B*FT`)2k))E;%(! z`?H~v1}>83vJuwmlF?KW0jd7nQ^8_X*`v7wnh(U^wDal=6`A^z@kgMbn#15m%DPoE7pt718dkb1{! zuMpH1ozX|cq||||cy!wrDBD{iM=v2cj^S}+!>YjB~HHj2mme}ohs$R> zP`vCzDIY~h7bo|<#+36JFh3Y^c_rN=FK<~l27nB?>J2Sz%hqQ`!sR8_le&y&c`*f> zb9x2+P2LM`wec7MhymCMO+hI4fcz2~1tyjykv!C)z$zKgZm^=PT*Rr*#NJU6=TsoT z5>S_hLGBRD=LF<$2|658JjVlG2vSO>Dq_7Sqx4Md#^3{4mDzN1VNRBh0C4gmzC6UhYd zApr7ctqe!qNj5W#kVynLAA>kG%k!RC@sP&GxiQ&mBx%#n|S{CXadFMEB6^NY{OrwS`n44 zEKU2z6=eGPF{7f{tO!_(X!VEDu{v6Nw$fkCVcLm=!)CwMw$HlF-%Pp)=fX1(%8`1% zNFz$py1T=Dcc!>$wR@H$O8v>(8&lU^u|i`j8h z_N|YIy$z4^h)mjB5Sbxv(alPbh>Ul@NZpvmr~gXum=ux~Nx_6#u;EY6gqp_zn=Ofm z=>oL;jerwjTDkTl`TL7a0TcC9!<2^skf8YRnJXqxQnhLlwtq>*63X)w0_k8aK*+)2 zPzlv6vKzP+wFn5ufcwIfVd zYeyCmMI?nR=kIAXM8=UUpcc`s446S4U&3-FBI@ZiKfGV?lZCbaKWx2KSd;%B|9@|6 zbZo?E*yxgu5z013N+aD!OA87Deg=#b=`QI;QW_nI3M#3fQjQS8KtMzgnLob&>wogQ zuHWf>bRWGBUeD+A@z{5wl+~rq2G+dbPn9iNd1>uj{>lD29i{m$-%F<1pQ*o{3knhpX!I->HL`JV2#CBUw z?ms;$H>c<@+YG?+NF0A@pZv{dgY10_g|{NY^G>Ji4`!Lq$n$-|5DCW8 zKCOX3(ef;DFiL`G(8dwegLX||#K6@RPD^oi!;ZSDhq9rg$eai1P-^R?1NUDNqf$w( z2D_YE&-To^5X4O-fc$lfB7wZuK7r^Yl?Ji2poL6Y;3 z*BNe+@sk1u6>N%YF3BC9KknOBZ1(MsU_Oo8Qr6wVHcFGQ{2LtarH)D2JR83z%Jbw` z|6AQW<4~y=7Mzs-)YHU~e!iS&;q`;=!>V%;xE{sqUS1JWzVoT#L$MbfMb78pS~F== ziOk1be}P4E|0azB%`fE=*B?ke5qk_=L$7dB3_>a%E6K-MhoopmjFcegJN%Q0m& ztgyQ+M6I$aT} zAsQc6(>;AzpIe-eCOP=XepUEe+&Fm-9Pq>?&(KIRjzp;XW$;QpLCJt1Omtv-euZ-7 zP#A-I_>7Q{C+`yn`>su2OBDr}_b;*n(7=`TJcDK8pX!X4BJ!+aG}AtD262|YOam0Q zks6RO8o8;r*Rxmk=piaoqrz)Y^pW@5f9Z`~)ZgmQ>O%(WSEs)|HVtqX{Z3GC>{OK; zeJsOqr(W((4H|btg~Co+3kp4K^gC|Ylnjos@tS5WZ*yt5l_MscR!6?Hy>as8dI`PF zMPR0Z+U~6;nbwWo`Z1Ofyi;F(yw-3=+4K0$dz56`Sn$rYm$Wr(i|6fZ6|0o1>C}$u zxaa9=cQ06w>a7Y0^r6R9Jm^kk|2pSM%W8siNA?F58Lxx~aNDrQ){& zA)8WxaT3HE-?tktJ*IwPU7MN$?IG-cUm=LDO&;peXL$)}I9VJk~4o}&r z`f|eiaEISU4|A&Jn@<#xpSyU}(j|VB<)S;;?}dpzNL6&r6JsdSy!lbrUdj9ioz1^P zfj7BIL!Fi{Jkh*AC1wuAAEYWR|De-rq-Hx5S87j!9e?u+O*ifm4{qr@?4o|EFdRlJ zuO<$tNj=C#j#&w=Q6XFCz0o zA_HEXxavgSYwJ>p62_U7I3EIxS|XHg@iQ>Z!(@XGkX=kJ1zfw zTJihz0nMMvnS#u|(>u;5*_>#up1?Y5<#fpK;8T^lhUI`%t(9So{#;G#mOJsh*ilX8 z@zSSl4fL&rR$Wh2y2a6*FO(knl=hb{H@j&ya-KBk3-$yn`@CZqdT@tX4lyE!X!@r@ zdWYzHqE^jUp79Ssdr9V*Uw|DRi^dnX8x<3Ww|^lnA`Vx@K083^DG36s|{G!(M!-# z8#~{dJAa`~S)7YqZW;L`SGc90y7Avr&N7|m$XGw6zfF`a))!A;TTeVjqd&c?_)60| zFQ=l_%D79TwnTI8#(Vxm=|9#RSSHB7U;1~qhyVNL^Pk1qe{NJM;C3)M6i!Bt5$QP< z@r^pBI!Sf1_*O1>CNq)4hNGj%oSrLFNS_)gmY<`~5fE%JQS~j_$ zzv!^>#df&Z9bUD88}BvBuNM5=v0i7VNq!i3^@HN}+zedWn-4P(evo4r@I2n33KL)b z7XgB(+PNpsak>CHk7(gIX-m76R3bO^H6seB1M2R}Jj#`w&bC;zarX)T z*2jcwLg))YP34o1QFG5!9Rq2g+^*Q!OKSXnN+rKH4Au919emjDPkf5}c0uOVWyp_% zP`9sijG=Us#4l*(Oi|afK*&kQo6f2tn-$4TNltl=IktS6tnv01A=OX~f#M&cwIaEu z)LH9E)tB$g7AK08xB%nDoK2Y=sdpMZv0*RQbBCa4HvpQ^^Ch(H4`QvQf_dR9*1t<# zI*uA)J!fHfY2mHa#Y%X=+Wx}TYU_UAdePqR;4Q!TbqEqHL33nILsj#7pNIef2cQdH z>KF;Dy-TL0gY;K|%x}meb^1XQ>$+eOw|Ec*l!y!^AliE*=Lf$(UjE*gDDa$jp9K55A~bTm5j{JlaX#FMr17Z=!DApHI#3$^Hbqc&9t;Dn2q7rWOP?8b zO=3nvW`$+=XlbaV)2mg510Jk&yfXUD(EUc~#>y#_Bpb?cZ*WXC)J}cJ#mSV?>7CNrvxk6vimN6-bad{FHlR>XB|n z?qg-LqSe~!IPG<3&FPB^^DmICV>)G)-RbSV0f$CU_Ss888kiz3yFn{zty_D|{EKM$ zL#yX1G~~$rlZ$6%hhgMj^A z7U8wv7dKK_V`=e>0iE|;(>K@`dLJL9uQSeErxjLy)Fdq+a*v*FlWmR*kg^%St<8vm zoxShYrd9;fuhPyjk0GQzDA}|gkgb=8Xv{W@l?qAr0E9xGr^$C^WPBUr0GlUVe%+a^ zpK~2(h9v{J`?*wfaYZ@I2n`|v!`j?E-xbh}@z^NW!Q8aOQeqi}H<|&J*`eZ^+sQYF>sv>IO zRgv98O)o|QCnsVC>Cz=!5_286)sZA=?9OCB9@AWI$|@V~E)bvlgyVUs?s^E1qG{U3 zjd49mAs&=w4f|aAaeG>jHn-?`x-0OX$6S;uzJ|_e0{;d*okLw&^aY8d!pLm2kAJc1pYaN}E#g$1~L8Y3HFCTetr4f5%zj7(A9C})1EKt{8O1X zKh0VK-|t~Lm7u6>N4EuP!Xw7wAJ{KvD?6rYagu=>M*7BUkNw%i-^qj|?P_c$7~FnJ zv)&dQ_sZ&^>)DVFGbUU6m**}||Fa9CaBy)6u0ggXaXQ|;$J_3y|2oW3b8AvC#5S!r z{8x+n<);w6P#06;jyRX|4v(i z*ARPtKwLTL;gwUZ>gx@A@b`TilU(z7#MBK}IeW62{y?{NMppIUpU9!TM+LmqW3p;r z6K8YQdjfph_`F-hZ}@^eT}QX8qc|jjw*hhTqXb*x4o!HaHAc{)9YMb57~W68ftit1 z%I6-&<26!TFn~T=*(g$nDW2^yT3ptcXB)R^N-*y;zo=kGCstfjjs&=X$jo zpm&WEV=!z}%%p|xHN^8*=K(7@f0rKU+4=ow^oR80s(EpL1_Wy_0um~m_kX>S(hxer z$$wpPVtwT~VF-5BB}104lqZmq8C36V-nAhO^G!zlnn1Pi-5%(|)m7 zdlT~U)ZO_{9EQx~^4zcD>u80G$=EL^tTg%F@dc_O|Ko=^*Uj%P2ksR(%It%`?iHJS z$mKTI6bUz-4kVc)e)ZYfxdMh_G5(W3<0$as?@qp^GO|%qB{j+I%zm71upFo`Vb*i) zzE6(&>w?=_T~io`A7>q3T4zSAW8K!}O~?l)0{bW;yO=W|!_S~nel5}dZ8o=!HNROA z2{}8;{>`8?s@x6=Z~!=7w^3o@1QiJ+iXU@_5a8@%9_gkm)&P$kSbTW&Lmoz81TIH}aARWFLCo&?m8z%tC5cxC3#*>HBL$wT z360AmYP4BvHjac*JR3@XxRLZ80N*BG?=y{{4ea0RkV|;&?d!P1O(EIq8UlC`r#Mlq zc)t7O%LN;f^&U`otwFk{CQmJo;TG<>yACx*+*C-nQKZkjM&<6tU(h?I$}z&xb;D*M z+)fRSb&K{`=!#dZDr;TUQI-*+_R^BQKjJ1@3@_?J@zCk_5|aA#VO-QsjCl1=T{wA5g~!ra zXxurciW|33c$we&{s(J|)#7ZFm%u&7$oMnsdhZ}HpIi0bih%UDbRXGqFkx)(zLGz9iy-XXDkZ@1xZLAR0`A{V`bGJI|Y`P?pPxD(_Z^-w(E zZUfF-{FeXcsM-c{oDXh7JWT3dnCkYm)M9Is@?yXIXhdV2fP_CQNYp%@@1)*e42K#P zi#L@>l)^{b?08E_Bxpz^-P*Zl*qBVIh7sc%Bm8|6zTk-&+a7m{-<*Hu(c2~@HKtEX z++S?Gzb28f-I%c_k$LQE(kj8D`1v}uMED@e3i`~O8s`6Hi%R~27&kp^?VEc=(oAC4 zz)sTNbT`x2?`lX><{EF41hLRVya4g6=&mHli0Iz_ZKXj+zb7GFH3(7W+;AHCNs2s`6yr=|nbVqIRlrl5JO{CXO5HGQJrV zwR#7Q3a@~yu&ui9zqF3AXFT%<`emBq{msU|;ihC>-uhKi;mq7;${FbYD(2^Y2L_g`9(9lu)H_O=->6nW`AGn)XJ1ePI9^960BZ7=eC zUSg&tH@7W#1a8QZ=t6K{2x&_XvS1^-#C=I8&*`~5Nq^iK9KIO%|A z-y9i&qp;IMoXjD{IQo>A*sP#7S;ju&j`Hyfwn<8!r`|rI?U_sn6~lL|2q3ld43rYj zzz0a|ui#z-FQJBY=ENU&3~oU%k~_KpyCa_VKz=fXg{l*W3B|*(h*pq#$%Tn4C0?GE zE**?Zi6=_QA#NxzK6nl_?$kfoV-+M;u8$h3f8>jviV#u2VH9|kh#bNY&PXiqEfg0L ziaQDgxA>R7r@6aBbGY%464rj4_6GXHFHCWJSJmeWqN#EWe_{-ya-VsYnDr%P#)xCq z;PuQ8gY;3ZnUW>0rbx4;^swdEnUHcuXtB9Y<>6Z{^N);XQ0J`U5HrZ)+;=-p3J#*Q zM`WgfVg#;@f(%Bb%Ys?v!X_)m zp31tjhYfxp1RseBJ+`fSkwNyn3z?-U3pZ*%3K&pkRe(T%F{;YYZ3we4?Z;K(0awj+ z4MB52MBw-UvD$IR z=m;x@Oef)Sz1)i*ntGo%^&xLYTiZ&3liDsU}}%o$Fk%4^FB4IY7Wf#NnTUzga-y&3Fp5B zx5g_!-NcfPXUC7FE?MJOAk$Io+VB-MIS6Y?38Hp1fGPy=y*5AP{|YsqseH}L|C(QW zULecSENIny>ZTHi<5J=`Y{;m<3TSEf+w)`d$lP1{?QFhQeFkMDDGVuQ4#c|C$0bi< z$Q#?k0yO4Wnfq^IOOLlvcm|O%X~LMG3NcPNQZkB_Kw&_~3E~rdZs0DyDEulP&5?nF zRuQ9M*^(VN`gS>>g^;Jbh7tb*2|H^e{)PJ09`Ez89tuz`y^8h?I92;Gj)>W z`Y2o262%9}c`(%+f%b~ek;rC^6~{-iD0$1>67BZA&LUaqEn_im+Z_A;)VR1~v?(R3 z-yqMf%DVWTSGV_*!_y=BfeQY97j-g8M|#U>{T_y8MJ#EC!4wGWl=Z6ZKkt~ zV$N)Bg7{w&s0R>N<`ms(Nnj;)YZi9}yLZz7{VgVanbGt|qXhX!84B?sa9f6NAc;Jz zfUnWu50})o=pnXu9pYzQPaPlU+NG5f9$g>mRpShO2%-5W*)5$4p0{k3iJg-Gv=NLz3MTv8oPAxj;x>sZIfu&-Sroov^O_HJg zqOos;i8I=<_&mq3A6hr5_NgjylC6|;>8vzntreX7Wo{3(^6SelC$+35W2ch+?vY|m z-Fl7kdDoUT^xlCu@wjhXJq3a1B`C`gd#7{mpFzJqJW)|ICU-C=#52f~q`s~3=M81Z zuk;@Lg-(q46qBTol)`~=5AXzgri;#bc9JZ30@&VW?o{a=FGKGO3uHqhwj6CGepYXgfCZUjY2PLZG7t6fR51@Q!iMSfv4*0FT=Ff2qWu>5LsC0Mg4m|S)^c-5rO`*LVEW>hu75ix2#iv8zm6Z!58m|GO;Kj z4g5C1plbDDNsuZcednPPZ-R{#>pAH77A^p@jkxtlmS4=C@V0 zn{p&egJ^AJK0Lds?Z|Q8a=;s$NXsIFF6j#+`cEr|9PVHUs?N+E63^livKiqI(|Jl9 zH-CMDSd#WW{CNXRij&=RQBwN8bnjHm!2{F;P2ktQMiB0ScVm#2-lB{ZhfW0pu8@M7Pw zYwfIul>VA~mc6A?45s*~%7qIQjSAsn2_NysRQpro>kA&u;&PI#TOF>C#8L2m7;Iqc zlu&Vhu`+CiiJWF&nK+8Hb6-wqck3`Rb2+;$MBI4iB0ges&9dS9 zJBNU{HM=$9knY^43ORw_$oTV--);#hvKJ%$H?4n=S=orTPlab^QE}`N+|2~7j7o=q z@~H3j9%)MXOWr2x*6;oLDl0hby=-lG0@S1lHF?^`V?c%lb1_E(8qF=5$<6phgXBpm zywtcWbgJo_bOqxMNuA@m%@;N}usRVk&cSjX`pKqt!N$pKFg{1WRk!*;S*TxqMbYu& z&>>)I=JdPlf2(}@L)f!iwIiHM)HaKvqWpqB%avcxZPglK081C8(joYnTj)3a2mYTc zs6y8B?}*wmp$4GSnx3t5+O($XyFF}Xmrsw_%&~M{5_ripi;VcZ+AoC|=&><%MgJ5S z#WiYp31C;usq~Y$VCDpMh{852v5F_7N%8~^JgfUT&k2d`VOHX$aCa}u6CC$+R+383 zI#Ve6Dc5#Z;_p(c^1Zx<%fEKb;&}2d(?>MoFEv|arm?fwM-mqMsVu6322ISsc!0U{*fD z&V9xKsceFY7Foib`>OqPPQjy|PnSZAuR8CACDy%t06VkA140&rt1^{r@QGItmu4T2 z#(3JZf>*weEtHsw#hC29rs6%Vik&y=5l{TGZrF&G?MRDXYM~nq7w{}|2>47hvs-?9 zaKBV{=US%&*NoD|bNYB(SSoSyg-0)I*5nFORBKm^Xj2ak=31f9!MeCVK&*~XjJ5r z6Sp?6B{-)bT#6}nr*>XG)nWyk9g1yo3>$n?KPXx%&hKYL1+%Wuo38qg;A=7T$2v3q z2r23N9vKwUSJ3*p(M2W2Ci>1qXHwq94wopgg8^qVbA)|t^(&+_mle8%bTDP_LRp3u zy`i^i=q|?%92?DZzy0+v$~pjGorRjD;247!c5Ni@*^Xpv)yUUfvl4V{e>wc7xt-*H zqf_HuQf)zVng~e(?V0sDsJFZ7(YI^lmkTw6EU3V9sQ^mVAN$-1oBp6*-+j%N*`ME< ze9*wSEnvI*;`-ymgg0&Jw-*T1v<9PaC_3f#>W1^ZLAn~jfTr-^F9`0HN=A8SQmh#% z71BsY^IN6Lr1a1Qfl!T8zW?L)W+}lCSO*M3Ai6PwQ%xSQCx6O~B40SVs7(S?FbS|| zdIC)A=r-t|Zc04&H!>{uXO{4>oHyqRnT7^NVHUczG)}4MkW9}*(ZqeaS zyPPHx=%g^*A}#MH%?rYSqSqS*DaEf3hnwzQr3An*Y?3oH>)rmmV^j2=)5xGCC9f~T z+nRlz(@N8wQQc8~l*j#&`Sk`>_sZ76_>w8B&O>kugYo6&oTAph!ipS4DUvJeaNU$f zaRvF5dE|Sftid>TdY=fX9D`g$OcJ!jwWg3B+Jt^nrruWt)W;Q`fYlG3R65sie|3{Q#^x`9C3_aIq>a;@jH52Su%lx(d zgiYRegF!Mlp1a8mS#In!@I-ws6lF;Nh=i2-*EAg^0Eml#*`tx>uP;wR3Aan$Ki9hj zD9Q#WFplg%6ek#6s>b?hhfxL%15=k-f8DpD-vQ}QykiRc>CSof-bQ<3sob>kZg=;4 z5Em4G^U6@=* z-?hqlaI%rG`orw^m6>HTZi<%OgQFShVKS4)$%(MYIdwMWESPCwV=MWtWTvHG(VvMT zC&{cY;_&B401vPmr_dN>cojTXmY7A-B3XxpKw5EBI5GzpnO=&-@;|#GEY?yU2q(c6 z$DwEu_#y%1i2(~{IA6Fh0%wbj35P2i%$_=I%1Q7&ZyKWFJ| z=iZ7auq}u%s&BzfvLPlNl4)>`LYDd-fPtAz%~$pEZZ<330izs}+r*qx7|vEF5ACTN6fub2=&%$4sSI%7g@Bg?TJ%P+ zPzpmtB`gOAF+ef_>(9R=%QNL7|8|K3Sn^sI>Pr`mWf~mqM)MM>z}c;E5o$0A!AdVw z)K*roumruI-^HqE5dfVHO5&82Ii*sSr+O3R70!UdK9&U-7Zik&0u!wcB?N6f45rUPb$vjlqm`pysh#U7o)#70W|J zccp4j3*yGvBX@mO2`fYh69;i=(dTNf>(AVfDDN9AV?Lj6iGB42eoPG7Fo9^kEcCa4 zxbqWKvmnau!heG>R}8f79kV!K%D&}TJR{R1-B`PNP5Fk$a>?cC_&n=k0;MA7bynFh<63zSn0V zFtI26BNVPJ7AC;@QM8rJ{YX~UU;*2j*eA{ZJ$Wbi02c+#Fk8hbP4`6$H_|43;n)kj z`wX7Q;*lap0NG%b_mII%9z-*AB15~KePrDI$i{gSt@8KEJa&AkYT83ZwIV8W4)4WU z&}mE_Y4`7^jyxrxiiqm{8IzHO1`pywPewZz%J_D|tJ?`XM}u~kKy>tr1x**Ph4Sp@ zt7GFxl8)8{MOd-l(^6JMN43_s__~Zup|gA%wLJD5Z>+jR?6-qxI@Ka~5{&bnX0OHr z2ol4X8wf^a#4KcRXG=f)YtB%uZjX+MaWP8q)abF0j25?To5`Jv^G%v6;Q!Ru>h#J6 zL&0ioky;eqNW_SE2qvh<{&xVjgp}T7D3rdQ^P)z}L0!8Gf_1=O2tzxl3ZHOgs`y_TsbeTT@x97Y$thD3BO?QKjpVQ3*$tZH|+}~m(UeGXCfu{nLLcp zm5s4WmyjjTA%i(X#jTQ2&56XqN&8iU@rvxFf;o-y(LasLe_G`lv*c_modSorV6lXL zN!CuEx5=@PpiY~umgS-0})K-cu$);CTk z+F8Gf*I-?Ah%v55|K(!ZiinBh)vEfqvp&4FM%M`Nf56L~og^MYYSwE7xthPSwiE#1=&CKI>j!y#1 zhP-$u9km{p@^#*esWsjhI4{kTe3y6aJ8;TlHZWgstFd&t@%5C})I!XZHtp1hzfD#;N1deEqHg;6Wo-RTI*OS&|2wljJOhfIr5l+YNto_FH0`s@W-3oW`{mkDdgfer z=2Rr-MbGCIVzVShaurA3$nnp8XU|so-F|uGt;zXYi^~hvu?x2RZ&}oDo;#TN_?06K zNISkG8!3yzJ0Px6)-51*oD6@x!;x6NaR2;$_T>*&s|yN!?LV(2<=szUeRaw6rj(5y z)lMZl^*Yo>VoB3iQ@P4`k?LJAEwu~Q{Q8%d&HSiAW173?pQ;-;j-}T=JAe3ozIJf= z<5by)r!jK}Wr@S(NsH%QdjKPnM2p5=AAB{>Yc|`}1GcFGCRUSr$?&}kK^4WP^yg}* zT-C$L#b1}Vbnk8%QqoUWr}do|%~GlxgN}?7nbC2q8wa1R-`#fnv18PZq7I#ei{ zX8tr1J*=N07m1$sZo*xX%n~UgSAH2fTa*=Fx7=yyBm+f3YIvZS0nPz^%R1_FaW8QzScNztM9o26E9U55)XRhLo;j0!kf zh{$RKQiA=qRiMAfLC25un%X7>Pfk??5)#a>FO_fJ4rLjFGf=rvVAadW3GIV9?em5I z&RIrYF?5)^u6}r-m7J#pJSQ`1?NUmgB^MW}I8;+WLIies5WPR- zk*9>7+Ba7eQ_TTYi9;93lg8rHZ`m=Liy8xnbko5YI=1Z$6|4GI?3k|b{rF0Gd?d6A zS;-?`8lvuIIG&*_tB_4Azx_I~2$4NYSD7ejm@9iW(ZLn*Wik%&A2pMF5AwssS ztp8VymGTM^N_HRjU7$@qF<)`I;Ht}-GyS3Lq%!Cu z?41b;FRS?^dDN-*-=CjV?u)E)LaKHFPMP~=TNY181)ccjT=bFhpZUV&1~ADCvB*v+ zE9iu}EM%Pf1&48%Ih@2;$!GrY>H@04Dd`53;D()PdQ`3(XwNPfY4$ol87{jp;h3SZ zH*r1l3We4)3&(8enXTuL_rbe77O~`8S6;B>-!_6+4tTU$upBgOB5!o7td@k3kljVr z+vDI1NkpN$96+Hzy64!w+=gSKBYpB2`?zr$hcVw4-Mrjz{U1eCReaFpvT zc3t{F@QQ*?+>banF$ere9w2T#+d<8Lso#FK(Ea%lAXV4;hrTrV;VEk|qP)n@A#@`m zADegxO{13mb;q+~jQMIn=W~I30bMV_#Uefxabi4v^;PveH;((MO9Og7B$Wmwi2_Ls zgiw+pPIDN%%@nf+GsJ$GUkCysJwpNJGRUK+!XmKQ_;%=hgNFkAT{5dH5~>?`tjl4aMx8dbuMK`Gay%k@X?4tlidXwO#l3qL6mSg- zePHT=8ITN#V+^RI5~RiUsoXG}4V&+&_Pi8e?dNEBXyfilrlgkZb|4|1(Kc}biTAQTTE2EW{IqnZbpnPIT^JH}#e|V#e z0%JS|kuAhgmGVr+KlGl{H=*m1zG@6$i(sB_j_}Jn&t8gD!^E!E@P4Fyfqog95gx$E zC4KUA*efd-{|!n0LOX$>56dFT)S`AH^#wPW5^yV(AJcug1VqMIqPerL&Z^eZGFC^# zjCy8N+HjdkQRm6QKe-ruFzn_4-8zn6`4iBy z8@m+OB;a9QT;s;f_TQL@w`({z+jaWw{LZp_%A&awlp$yNlxSWdnt!*rwEymkK%E|_3A0cX?v0S=>dug)` ztbxs!#%=%x4)aEj9_hyXk}g9mTgOulKjE8d>Ajl3i%(MCh`Nomx@wi$KOt~Xw-dmw zvjdznkGHzyq`Xz=tS;t+i@MXT0mc&1Q%@%H>iYt->m+hb6uxw3dmnAOo2!{WiB#-) zb<+n+mYn%K{}W)agEBZY%s>ckOpzx|V)K(uJ)#@*kRq%keu5J`JIeCXii!t`gz9TS z>XJum?|g8~Iw<%(tT0N&jOYMhm)q`(V|fXjAz;(j`=Yg47*1pPxJy|y^%IiMTvixd zPhWn00_rt@$^^h=w?-ixu)+kC%zAuE(RlCM_Ncj*m8JIz5Wszy6f2c_q z2W8(ojV42$cDy$HepvXF&x_~mSWdg*p8s|5l;iih>6_Sxx*D3FXQ)eNic~%$1VWR? zSE6KYR(y92V{in2otOhvDt{1pRh^3&loPCI4OaVJMBdKMUJc*k{)a9yEFyG!>wtG^ zz2mPCs_9>;h*MLqD;D9^G!DXL+b?yc4Lz<#GD##xJ5?5LAw(9t^&BN__zAL)B$-Ok z5N7%fBA(#E(#r_IFDQ}6A^=Cr6@tXL3drBFRK&J&TzJPYUx+dOrj@&D+q1*(Aq@0O z^Lsn>GGi&XovqPdYG9DE=tiKH? z!)Q$ZRxPK?j|qx}Ciy*a`T!k>c&M(sS9<$QL@d*AQkR*ngtPXmd@;xzy#FmeJoOtC zg}p;BL@!@=d5MkV?D0Z|HSxjtUQnOG$|aBA75D0Bq9Vt+=P{|)Lout8ZV+({sBE#V zY#9=Kd`(R5;dAXPhai&H0+n0D(*lXU>=l-`(w#a;D7z5BH>`26Ues}6f#_5K9P<@c_n zY--9Ft$lwY7bZ!~7fwTS0xlQ3m6|I zy6;He&QjvmVZFU?CJ3ZqB+?KmartkwuEnKU8latjrevd2!!1%@rKA%2_zNb|t;gxw zNmeEA6W*qz#?subt+~&Dh+L0Mj_SX?ynY{qq_4Gt#nEsny{C#G0X6beX0Urzk%@N@ zKzRz05lFEb&3w?93F2l2b)=0O#LFqfanQy;HLyR~QCBjjWvrx7>lFIQhGq#*aJEc< z{s(p=QvomTfynp%38{2Q+%vAt?6;E}Y|PBJafET3{EybQk2>=uo=dQHqVLhaNUjjh zRV=2xP7qStO>{E=JW_HixLEf&b4h68KVSO?dbz4}LW;W)3H^B*O_{0Y`D&^8>GC^)jB#CM}E$Os} zjdKHelK&q{tONJtRD4#l{4F=oR9qyt&R#kRW5yQM+rgek6&I^>>cfekyY)0rkG}mRoGMxm{G^Zv~6$3C#jMfhaea|NCj+*%Zp zD)EXAp|S1uO?Kz7tKu-r%_?|Xkxu=<$6dPhlQH@a>!qh`&c5(W`&#09Zj$Pzi^6 zpAC);kvB~-gDNDJ840G7?|?$6U+T~u<1zE0tT{ZuHoUp!r9l3jreb6w;>ti)yx6 zi)@66+@~5$Ybwz|y+iReN(r#pv}|z$AN-pq`yJv8xhCUKGtVp}=J}+mk?C%N`wm>k zJizi7)@`YWTMjTrX^PzDQpPf-clh^h2us#ZvbNtUWfGD|)HHicWY9B@8_v zPQI^6>O}E-_mmrP1pMi}bpxq+_0dfuHTGHqAHRlrZ>J=8Iyn_iVatolO=-LW zsC~8}K7=aQae(hpqsgogR^<%y zm>4vpx*2kTE}3W+`|U1XBMt9xwDfTsY%INdaeZ#wXHU->!XO80m&+PSb&QL{de5m% z*?<||l!Y&>Jq+}Yg~M{6${0K7A>lNef0W)|eY|}}^=!FN7b6AQ7j5~U=n+I5iCwr8qDn>r zDo7yCvOy}In+<1==QKx@mPe(PyW=dndE&Z#FeKSfp@TEga;A>-J4@4aV|O{F@HV}=e%2puzJR#ZxL%W^$$E>*Y&uheqKOiLYzxv=BAYgVdP``6`cMsr;I`wygkbx{dw+mWqKY{ zDIQJa)4@xR*aIw+FcTv{C+GtH#-l(dtfFV9Bwl_IM1}{A0+!pSe}pO`ENQN)bcF?S zN8@tk^?kW@7yrSWf0>z@A#BzlPZBLAZ_q6PL}~8}1<~B^P8&;vKcV+lk{Fn{?DN=s zkOn_AFf;`2t+_A?qoIH&On{Fiz^6o}mG%){+)&!@SM?g$XY1GujbUgr;E9IQM_?am z47Pp_%6b_v$IQ9aNtIoylKVR^{VPv7NXPWhoGlyaKN~hmUaEp6jjRrhY$D$YXudP} zeR?ayiddBLdPBL;ASWyxoAtZNEQ@Dp%YKuJRgI{=kQ1+^-emyas34U{SA( zc5aP67yBUBp6Ua>WKEYrVS85k$^9pd=xwW`2`eO*b+pd8r^zacnDbd=F_6B7AB$G~ z@cF)&d1ne^w4xDDtMhOTTI{^~`bmvi zFW=A~;?5sQU6H$4@;qx#w!7(VBm{x~DxfM zK`p3@R9jEmm9z7Brb)T5Ik__JT|0Hw9Cc3qFA;e^j(+{HXIilDn87kFH7v~YlEC>C zaTtllK7T1DeBoN8mP4f$B#yc9SW7`qOI&Mt@0R9%r8eiZ_DS>)=|$!&%_TAF)y>|V zD`hJMkDq=ioi9^df<>+vyAkWHWvnf@q|T|>O!LZrWA3YgvB+kG z-logq#;oV&n(W!>YcuheL)T@uepzn)4&V9{uD6*}uwC|ie{<^uwGEQnhFs)2y!M=; zMeWPgu}Ju8PW)+>YshDr$UI>0hSUA&@aZ|THU~!&C!?1PueQib6ep$$Cvw6p_C}b0 zYumDYTP%c&EM`j>;K1JFl=>#DbaTgmu%mLFOXFL2#DkxF0=w1zDq34RDL>?Hdm_ zIA6AM6tI6#_{PDO;u;P5t?e7)uvN1p^81nP&(!kY{ZYR)g?5tU_cV7}u1D@!{r#=Z zyhkWd`mwkx{&Vlf+_USsL05Htxt(ytZV6vueAbiq+e41aXUpZ<7IXSN&P*#G_v@}i z0Tz>!HNw!w&9M-xZ+mxa_Us?+of|(0+2SY_(5ZOGbGK=)XiJ#!KX-X(%?;K!-3VBy3W zyO{Mq99s+*-=DA#{<+rL^Y`iQUo!fb#@X(!W?o2U6;u+kFe`x_!n=VM0*c-~0~JWEXUr1507cr^S9A4_F*K9aV%c=Pr#E zDdn3(y<<|wEBU#&xDFIo%ty;XnGgMoZq*EDsRnJXAF#;SR2m!EwxrABZ|PIXd+p{O z=`0e4S?o~b7DBlg8u=_vGx~IAF-!Toq2VC9>Fb?b=AcFYh$zGV+W2{qejUjO4zc5Z z=T+e937kL6+Q(4srYFoY_weaTQmv87Rqoh_Z>t}J=*5tyJ^z=XT*b34-Pjy^hPm+E^*Ah2^Tn>)qsR}@X{aabLx70cns#Zz4nm@Q zHnd5j7ra06_$|On65PeHWGmH_5KJG!Ch12MH@NGtDsKwvELur>Jo5NMtVnp*19taZ z*=aBt#kz*%9!t?zP+vfN8(+g#{Xd~m>i?uh?@9hYsnG!A_07I{fLG}fzMS5)BfJxs z@P9uHKy~KvGM+w7H+N$qh)}TmC|S>N*4sP92HQtFnzep9p9DzPMGu>t&KX)IGbbgL z8#ymy^LnwfBBCZg>tjTW74yJIM+jfbs9w@O9^l3K%+|jf7!|_9UCAMidIAf zh{cG7OBi6nsbO%wj0TP_fn!K==2=eD-@_L#WwY98{9b%-)v3jRnLsspuqX4cdVA+{ zmF+8!8Spr)=g@-pF&@?i4DpkZTZ!-8EkT}66R^@0#~C23$H6Jpli@*gmx>?J>pE5V zweklKL|K+)hK^+y%_#rMsFQa}b-}1FSEw=&|0Gs*CIr&#TvY@~SDfm5s44aJ(%Nxr zpiyk9a;5(1J~KT1jVPI<*^1+^$vL@j7?Pgbm=JQYzdB~&+R14_t&q`!Gy#}fWPJA) zx4q+`^ImKyr1m~v;Yb9N;fMG5G?ABnO=dOD{(g!CH|L6#)@NNWLcTm(@AiPb+_@vF z?e^1aA^dZ&QqXIcnFn>R)$xvq^eQ62yiJ4*wK99{yd(HaZ zrAWQiOF<`*@2(hkKoN&&r|40VCTRJqjcYZ?o>-4uH0wrk&LfPJv1ge4`=DdH1moTF z*OfVaP7J4Cub0=+{k-dyhLO+_+9f0H=P0N^TCJbCH>G~{_tAYfdc#~JcWFs)?kI7( z6Xmc?Fc~xky@`|Wf&%iHb92Te>8e$uk|MA$FbB#T!L*KH;4_^CEB8H_Y;R6xZSe-M z`}#_$i$Rh8eO$RhdfYSC*`RImxNO`T01t);BRhVBt&`rjrZG8)AThAEw_0Fq`VFWn zA5FU0(cBgdNW#xJ$5G56D;F-IdB&%N$b*n77$msBMp zriL)Jt;oCG?9X^6vfs>`nWbo`dpI{8VB^Ywpi9o)ALzSPhKooNR_LS)Raj)4d(SS+ z83&iNx4egZ5Ol)MjlaD2>mD4GB!;5EWF~I<1SfRr@wg72c#IT+IBSg~@M)C#c_@vB zDXbfdFwM&+$Hbi0=_B780SG@^b8{0#+xK@-LihDDDZ-u<^i8nf15~NF-oc7hDsUP! zI)yShp!OwNMNZ zZb;T84&_Ybuy7i9s*T+RN)jx|%~g>1 zwHa;RQ#ss}M?b$>!;tshbs_@$5IpNesO!@ynj`6#S_f$nPi`||M~w4yG!`*UP3gRQ z*z}cRdG?o_y@1GrLDO=1sk9tIrnP3|D_1W~@$*l(>Lo5xalq zz9jpWrVVnAq*8_VL2D;A`w zv?6?f=`*KTkx}S+T(;QJjBH7pu=v(Uk>%{8=!7la2;*(Mq^0>gitzzntcC+0{Y3Ih zu@Hrgx1@|ugJ6Be+6_zr$d$7iC8N1q@lDh|AnH%j{tNXCDugy5p@ zF1Rmg1kv`0LsC?;c)u=rF!svI;}KDUH#f;C3=BpzazoK)Z6 zE8DKUdv%pj{M^)uW|2{)`*)cj<36L;sbYVBvjxK~2CiGi6R-c3u)cHjje6x)nl3M% zp_tQr?dvt~!oj~whmCDBbgyD7jx>Ncqet(`-nx+8w8r|UWPdaaAG{9?TiHpaOl-yz z>jFGvJJ>hL7GCkWcS?WzFa|E)pe9tgmw>p=_AvNE-+$z~o5m@=-mlHM`8vl3NC$86B0GNJu z7VseH38*(Ugh9kVbKUN&v}kBdbBEczXs#7?eyK&csOnUGx8C8PXV*CR$&!Ua7XGx3$S!&P?tV;{drXh4Go-X1B4}>VhSgIVN>^U&R2k|t zS=1Z8+bPwq%SF_IbaisI>#6Xf%rvT0tGb;^dS|G2E39RbG@d8R26r2myt4Y$7Sy5= zlGS6~-V->~8(^;Ehtv|**GA$8CA>)pHi7Ql2_^BM@m=qDlZvHEl~SKb2q zJsv|kVIn%$|FZtP(pUN1=<8tm4dh#Aq{#*UUeb{9{$OKoL|>vtCTUkKTK_F$ylIlEAgUm2S zpS%Crv{A&gZrxNV$uyN@`Vfh4f)3_l1}j(x0qemmRkM~XvyVw;ZS`g^OU!E82OFx) zZoD6;j4*rUZ$?oXY@aY&m^178Jb3DoQtu;if9Icq7v&<3UAYRo%m?7&I4)#=IyZT4vIXA{s+Q@A39dfFkT$09bY8IP^e3^q)BHq2*iSTt=| zEyfNjM&B-u+#4Dt*PH)btTF7S=FoUU&6-*L6o+_*ZIo7Q_!>sIdn_>qgIp3Y!)=8G zb)8QwgJnz^LVWMU11J&>W1zd^0H^KYgl(<_Sgqv@xLUJi(e~A@ttDV5ogyw{VF#ZW zDQmax|2x9KHvkg0Yb$KzbH?1~Rq3P~-z#ifX?c&DdtU*yuP6ce+P~IthBbF2J0(nb z&LkPINy-L~17xVC2ilwgp*3u0$tJ1CmSHhjU}L~yRf^PQ%kZIhuxEQ<7(Hprm*?Ct zXvdbpUFu*FaFZ?}*>*p<-4ri73bjE)QjL>MI8)9!kID>BWMS|&&F!px5Nl3i5jVom zz;Pey=p#A>JfHHX9%r$r_N=kIWM59US%w6#Wkg&sPJNELz&9nBF%=>zVU#jadu76D zxf+OY9Q@_TdBrLG_Xj`%lz7#i9_-wPp3b67?s+>`)H}EYIIc%b|D1R5VnAe;W@UMd z%{;K~Tel=v4Q>15bT;g|%qL0SljnZFUy%8@hx-_1=aQg1LHegDCmZ&h63O_IM=m97 z8K!Iw8OK@9DIZyHeKg~9&3152P?*_zSbZmU(jwWR#vn8M)u3C$Or?Z_G7dsZ0vl2I zW&0p3wfG_u2#LoF8I#_jC+PMyI-i5Vs^fJ^gDoCz)$|#U&U||E%I&Ep9heN!_WnR3 zzk(J*sTfs2B!bv}oJHaLoclcImGUP+6KGqtTf%#nvTXHXi-BhiE^qiU`#0QLEl8yv zc$QfrlomgBo4)1Dm)w^#4U;q7`CoGTrW=oEnmwFn*k&4H?C7)2wUkUeDBof^D<>QtNRGaUX+5TZ)&iw#`3q?TYkl33}4Cf zi!OeDl|@r$!E&^Kre!W;$3i^4ch+wt|4$~&$}HN4i4Bzp5@hU5V0h^~3k#j4DY#){ z;s5AVEgYHS`|*XvlYBfoeKccvuY0r~YK6L8I<5xPt*{O$l#q%Vi(GhXNE~kuZtJ|_ zZPMXw`p9Fpa@XSEZktcx9yy>hfxYC?cV~WX4|u7U*b{H|yZtMiJ}87QRqKwWT3}n> zH`26M3VoImS~GIW&Fp(puO3S*)qcy>!R+8W5F9j`05jC3yS!JJfhg*bzpLBzeTbVg z0fo3!<|-u%gh;m3q9K-jAA~In;vWSkTL-?QNBobE?Ceox9a2!kbtkZZ5fgIDaAn^$ZPq`EU$2y;o{e(kS(aMLaz0yDCfLBgnq|C3 zQU%PhS*<@-YaDr=jije;qAxr0O-1re=PuXJRgR23q3Y7#88b1>np%E0y*3$A`e9}H zCMtw(a1GYK)R)0kx<1Wr@m*EalS{cQSiS1aqb?Wj`XU`M57!#cuNcnNd(Lzf%a>Y( zlkW*A@QX)@A?Y?kxVZzyg;Ddud|>j2&6Yyba-`n9X{~VQ$_pa8bP*v=3=o_a5>(ENXmV-;OGSWv`m=Ziv^ z2#C?Pmiu-nTLu;*P(u~vrNjSJ`z+*41w@=-LK<}9Qa=IJ1)4wG5GyOLvt&fmwn|?3 z>eEfmyPK=8H)994w>u)y@y1M6A9cNHMbk=sb)yInhQmJ9?ydWlID*dho zSpIiR^yO)`UPI3wPjh&DS5y8f=py%EN3AQb5mU;wV`>uMh6XYl#*5L~;*E*6b?LTe z9vn6ZKKK<01*ru&8vKg(p^MSI^Y}6IZWdPdxo+db;;g0Ka3>GEgZ23Ork~lFflcoLFn%B>TqBn~$*EaI zLqa(f1DH|(ZGkwaZ}l{%D+AR3Fymn|(a6FoC~ePStJeRfdf>MYL0+@rH?y@k>1t4o z&2;!jp-GxRib5ZRe||6Wx@@~?Qf$*tVrY!N)1GZt{Q0_Hp>OuWzGXc^{w4vja(8jj zZ}E8XKcxLQU%JkWv}YD{P3hkT{$w^C9LB!MjP-Ms8kQcod8Y}Gh)YGUG%W55xfixkutJhUdcJ7^y~TcFgEr9^GL%<1@n zkh-V6jH+*V4|gOV-4Y+zN-G`M^4UqgujGX;T3VmW9?OmWuA874({b(<1hfG;olVlh z|Etwk0h+x~<9waBMF5ByA2}BxWRRx4j4m`@G9^G1R8{|y5d^~=ex3i@rq2WEzd(|r z0tNvBm4tr2vr5nt!Bee?5|8HfQ6-$v>7P;toop!OB#d>sAzt`g2Dg4K$p@d!r|sJ9 zyd!OTTgF4dS3UB_N0RV|;)Y9#OOt?Bl4Un3eYKnGk_5B!tmqIJ%oJx|J1aVt1SHXL zl=Xe5n<6tw`=KJ_g?qFVB*JTGqt{J_E*}Ke1hYP{Z4Jq|T$Z4R>BuPOd))BAWxab0 z^{N0B!L76f*iCa@^m~~QQ2rpJF@za-D~*PPaIA+ihv7fG^E+4O+A2FW_fGPm+IvcW zW$%R-yxumM5E@}FA$KlO^uEyp`v%WuS6ef+7#&F#O(2sIln)G8vrWc(T|2r!Gfuto zbC^T$+F|w6R94i+_NnLDLe`0oz&3YEXcS>};6W6dB7B3*qEEt!M{Ic_hDmwB79l%L zrcV=nIt|j7>UB<{QLmaKf|d)*ukz5b;#uV_Sw)QnbDS$~@v6jsyu=zSXe3Y-xm2q6 zgdx9FZ?>P6!z4qM4Y04-P!=l+w9Nl{dBf*NNtsE8aYaV5rTq=r*T`g~;;8cz2Gx1; zlN^n`=_fa}sq4uPG}g$%DAiBS5C+9QwkMxmjMQJNaL#ZfPXPd+-VEOhl&utxV?YAxr-nz z+Xjljq&>N30j+Ode{n?9F0$WY!uEu{Zy=4u<;I!7w#}LIc2+KbLhJuB$C6sytIx^a zoQYby(7pEbXj4CQye_hRDK4x@Z+~@g8%BM&H-KV2FvxXiqPXkBE~U@+^Gs#a{E{{> zHgpLDJu{7b*3EsR{xOJlqd{+{f~T>&Fp{iL0sXaF+@vpXcm46O){WVxdO=Ut(iyL3tbrjoUZ_j0cFGpJ)bxl_S;u%*vrQ4IWR1L1iGn_Z1=W1UjVr!LU zuOHp*TM#mOo;hn}^%_#P?aBri$Pd_%@>r{7QY0-R2kgkqY!A#+q#Pa%5Tx9F0{v$* z3Y)R1e!hS-HwzwyuW$!N2qFWPy95qNsVd#&s7E^l6QnLwVYf?|OycGT%V*k_2(i^I zqa|GBZ@7LI;&{2-BS)}FaYhPrRjc;O`8J;x`6sHVQn3%rFFdr{+qbVZba-f29qJGO zoo7pY`u0}~4r83&rJrM+mbv@$W@fiJX5%!r#2J;VZ&D>99bzJByOUS^Sw#HYO20th z&aG0UC^tuSFT>NZ8iW< zIceKr<*3nYfvif}HD_Ioiii|=*lo^-ScBAZ7IG<(#Q?f$a2kg5qP?(miT#CfntC_6 zC@Hv3Lfw+^7+uM9p+;0x-QY&q+e){XV5V-W!+jY-OP=I$m0{byrM+)-S^eS<>7NKo z`b`#_B?y9uL(r5#UuGO!2 zmC?m5m(O{U(3}#g=&&|XRt5wFT7(8^^SD-QOM^T{i4xtjPVEZS&&X_Ne9zwCO8Zd| zU&JKoD_iqDw>lqTGu46lnkILH#< zGkZ@R+TJt_h4|g&{uCJbv?%fdtJh_VON~)?8{3!827G*2f(pHFn-v-WeD37Q*Lg%g zy^T=K#q&f>ccp`|DNl^O>3t{P6g}G369W+;m<}ecTp24z(|iUwa+g4FCif@+l2ok# zF6V*Z7;C6$M5;srr6cu%aX$1pXRpH4d(WbFd@t^xM}EZk=5^l1ff%kn-2zZ5+ud|& zv^TsOgUE)Ue_(=K1{B43ixk&MkeG445+ZUXJdenO-zKWW{ z3K!Al=Us*Fp_CofHNT&w=PIWZnAF{6`F>_AVgd!)Yn0BuO_ePk_0exZGVoeCggz%GOz=H2b=QM@Vqf zLJUBKKc}z|!eiwMm`a@agjXGzL^$a^LAComd{L)2L7G;+6IFzvJd+JJg{k|BJ|k~u zbP84W)e0y=R|xkgjfUYE#haZFZJoOVN!JyUW_+$!8~&R{%^%*hJm(sU%dht$FB=67 zOuJFnYZrPqSaM(Lk;;H38el#6Uf;Jj{CgSLM4@WqOMu~+V>O4>s?{6Z97G`QH4U)R zbwi_w``Qa9`~JDyo|hff*|!^}Ub+5n(6kEoL&?eY)z%mE6R*+*{tuVegGSPeKZ!1} z^zZk2lx;@(!Io-A4;Ia=n26HtoxGyD>|y#$jdqJ*^0$N6L8pORiO4O(t)s~nfx~X? zJG&tA>)#L{e$%bw#pR3V97ng%d-sZkNI@_3{uTNEdeS9&?K7nu_`rTp5BO#gUw{1c z`hEt(KXh-C>C1jVSrhplguiS*?B3CaXZ8axfR;NjjBS$vMl%W$x9((B>POU&_0R%S zvEJKfzUh;^hYt9+tIOzI+@u0nG+XmDFWJegyywQ^k$7D{Vo94Ik(Sp7*u90Q=MVgx z<{gbOjF}hD?w-P%paUiWV)kfZ?>RGbDC4yIj7Hk=7cQ|9``Hekx>~^? zHZaF!K`Zk)Q+pp^884ibPG4xuyock%QY3~bEWtVezMM19M_0y&#WiEe2bK`#!;xpi z$8G@jNfkR3#4zJALgdF-aAqwn+})SI%s4ZPuni=!&jVBmOpgG(B7u*>>uW&U4u-hv z!1h5;mF78L2+0go=%s_i+dE@@VElhQxq0c%q*lPQgoIPeu{(DppH`SFRc2&W$nI3g z(U}`0_{mX)<|PZ*y*ogk@xqDDl8=R?z6y$YQd9{GN-q{9i-m1IQ$$2Qo|)>`46M{k zm?tOrVzuUxtYAoO5}i7+yvTAg} zcT5%61uz=8qkbP=6jVEB5tfMm&$!clZ&4Yx?Wd*1p+aY6+PL@zSBdHM55Niws|tsQ z`7MF6OdtCj0RFJ-cV?qi7N(_^Vq69>)CJi*;ivkdngt6sV&BE5d@bR?VN!tVYkxyz zb%uTb_e@DyLWRDqKak%cq=KVY?e>79YpqOPo;aUrTNRgm*fvpqaWU%eDD3iWp$N-7w z&_~doh?*9oFAWUc><)TC4AwPSvxW-Jun9*{Q2C(qF9NwJfkNJaFdLpQ%3%04`b&SU zd1&wJ;ar$x0OopvQ=Awt8Wj65Fgry&%oZw^&K~Cr3-|3s)Pte=VER!Iv&52T#gcyQ z>63qiU660jKY5ONO3%@9U19zz5^+Bs+;R1_*!9vS95OhGoe~$f6yJG2aXcu_RzGzl z=<1F?(1H_c2TLrYgiFLPZ4%SMYf}`0<4?yEM#Z4K1e7)LilJi`m6WWo)UeUPCsL$0 z5O}#!Jk7T%MxA&uwdRxBeLercKzv$e@mDet6!uso2W*~QEEejx1f$&NJoWX4(r#P} zDwqjQ*K#8|h5*h21a)G*V=A7xHpz6kgsvz{YN}YPn%c8$e=VeNB&~@16Tvq)@mla2 zxmGV-{05=6#5Onro`I3>42UdvNzhZN-lz){Q035|B|+sG_9gqvxeHsG1R` zmE0HJ)bsQAQN?-69&U^y69kygvpM_H&lv%(HJo@buQk16Iv{1P&r6FGF3G1?<&k#B z(~~|x@#C?>9#NZKG$g4 zBkJ_9b*vfZ4O%GtcwMf=jsYxq4MyQI)@g@R+V|@8fb|&O?@}!eub5Mwa`O)1iLz3| zauw%WETvH*>o3*dqV{M}T$q6jMM{FH%d-2`kG0p1^)D=?X|ILF@2_=O>i0?I_OGs? zjO+FCg$G~jcE9fIwv}?w{9ka-*{Fkho+7)Zu_rU)OFz6>H^?os_1p(MO4WI~gBtH# zXRKa-QT(ITnyA++*h?+zgaiGS(2AtD&(w*J9!rnd!xL!N+rc(;yE=x=Rb8P=lj_}{ zJ@K^bGU0#m>GS7@H#Z)%mA{2IPKY&pncsLrZuoZSKG<8|XG^&T(c5QR`X``#J>PUpB_ko@C5d!RVPDC*>n+-1@#TpXejisS%N2f;sF<65|Y_ys_lL}G8v`dOOvQ-56^QV+iQS!abm5>E3K;{?5+E6Q;sZ>vnK z*^CTjm1kPRT3J3Gfu0w+xt-^}EqL;M_F5$8JsK*r;v@ajacJ*H92XzMY02DiRpo)?WrBKG$IBu~kA328x>H>R?Hw^7Qgzgn&oJo zMX6UUX!lOyFMUi#F52`?q4AA&+5+V66PsNVX@r?s%iRYw#>pQoAg1Ry;3TXu3&h_* zeAgjSi9D)Q0B!Z7O+Cj#;VRJqhdIyqQv3CvR9r`7mLYc|MczjFR~P%onEr~^ae|f* z6?Ft!_~z5E7a7&Hcp07jZD-VK@QYZ0i!nQwYNyvazTKj85ow^!n9gdN(WmU#x0{PG z%v0+1Jo&Bc*eVf(NL=r8TT%|>{rz|)#!n>Hh9@ppqTldCtcCQ`K(jde9;UKlQzh>vmlFZDD2(HN_HPCMh~9@xn(iOnmv_x zb^*C^DgD_t=ADGZyJfa_V~KyLR6dK9+MYze_)sO%VqeY+Jn{MmtAIqSKg2(ON8@*7 z7-uER(Q54I^GhEux_$|^olJ*2| zyN3Pgwcmdi^Q^4I;#0fD=OK%p=Ntz6&-4J*@zHD`#A2G2bny7k9C4&`pCk5(^47%u z((wMRnY0b_v&<^p8OMSDd<2t}y=bRxPyZE}MB?cK$adpe0f;cbx7BGSf{P{H04D@+(qTL zm)Ud28;=f~?p$ty95u5XJ)}R^;I(!C)8&RJIc2$V1xXeGjw5!RD+(q@Eq+&?ve>mM z-gYXQCsDe7j;K3o?LnP@}*w-%RQ~Y(?Kix+tV^Sg%YjyNKHW4 znZUdKUU)y3h3@Z5p1&Q!iJj7kND)JXygQ}r89@EZ&2><(EG&UPk)EqY`RWV8qd8%{v71PgP@!s zap!W@kiRQuQ2g~5VfDJ8L~0`Eg;N(hiLo?srsnU!iIWxA#H)qG4_A&qBp-LI{cSk= zvdwLDG3494M(2QYAS#ZgqqKt#Q=}KB!=dWs33yCxi86arq(4*Wcy)F0cb~VB+pFV5 zC=GI6IEKgc^a}m~{~^-EH?KDO$svPFyraSYJe52iErJNQ zM?wn(g-By4f4uv3~A44O3lNE`&23B^@Orf2Bm z<%4AFS<{J@z!^iGOqpq;UP`qE!W5*4T^a#2VVBR;>W$#Cc_9fgm;D@s2oc}aTd#0j z^n7*YVDI-4M}+sk0I5nMXQXe>4X(3se>tQ4`)~c88vlNtQz3A){sKfC^+o;C-ulL` zrHcX~m)1rzAkT)ml>+-x55^tVn&^!n{~Gt9WL`coOsdW*J^a7EP>yxHn_8 zsJTWAY1-~N=r^>w(1%Hp_^KG4w*~?tZX_rrDUGSpL7Y9ah&8I3R|*t}SD*cisfRzL zX#E{HG$n8MO3MLHXm!tH7V~+CYWH`r6=ZtJPoyrC=3jI-+JHB=o7qBxsfYE?W2EA+ z>Mx|yn6V;*@}zS#gUZL?Ck$ub;AZv7G~6#{Z_`09>!$(KU>&lp0-+CMXe$xS$j#3L zdPF1hQ5b)Av#{gb0*>~E_&ua4{+3j*b8-&57-!0BK(#0e!-un30oj{={B^q?Oj5vU z3$*{jHOELj8EvazHik(21REq1Fb=unre|KUzBgC?lKtFh*A~M$k{Z#Vo_SOp>;Wt ziN7WGi1B$c@gMm*{bH?&<}yB_i)MhpVsov5yj*$95y2*m82G$6qItr*J8B?M8pCMA z&t_;BWIoyJ7)`wWwwu=4FRX(d_`WlKj;%Z&N<050{!5BL+5UXCHvc7NtLu;KxojFD zCwV+3<)`?W%9)i5uK_DwcRpTbVUb+? z_WSp@dneT669N2-^IoeZA0AJ2WL0u=HnlZDE#9SA!PRX(u zcjo#7R(|@ooF<%=miP89-MQDkAjt#+X$iqpTC_j?uwZ3x94XCVsDYHmYK+(nHp0%$ z-8hBsy*}^J5(FZLr(cY}Nt_Tq|mwvOrsQmnx0YtGO+EM+C=vgEnVeo+2 zW&V3=Mv2>hXT{NsJFlzkz%R%Mn{=Oo|DaD&KH$uJs~CyHUYA6Nj!QD!;_Tr|bs6$Q zWQ1aw9sI0B*XQvUQ%N#FqxdXwYa0)F zPNi{=^8h?qB4OYmGV8eqYaUy1cj)pvWs|?u;SLW!P#)?(N^n4&UiWC6ZKobf=YIFu zh#GwPxw(PXlp=zU07O&?RG{+AM#%4;6pcbMSp9!G^6RNW*I+VG`}3|7dj+i^5(u7P zkTLaI<>{_t8 zbQ@q$Z${tc@|M;C%lX>OvQ%M~l}#1P-8dAW-=lG+a|`cTbtHb^hn@2ocm}p8^Io|F}Hygg?Rc zy8mFUa2dAnA(FdFnDv|52ED>}Z$WV2Sz3Ko$>v?0!d1Z9TT)bCVf-!(eBZ+FG)aoW z)gTlgr3u^B-`Wb7s_$pE*wBzAjcJ zvv8-Ur4Uq-Q8NZ$D%7XLdH!U91C=~)2Gs=1egdpBLuWYDD0h#={e;~_RjmYtua$*~ zbSGdmg4S6#x6_4atL9X~=^9TLqi#=>OlNq%cwcVm_u%}~W#OQ>(h3Q5J-x;vJ0oSx zX70WS<05j{=5Q+N)!M6)QX#kNmw}2Ao6CV7-ox`vBZAU4!uy${brDr-6JivBc zgqG1$mV_UpL!5SH8=<}FuS8AzuwsS(;=Yce?!hx zEkO_@LV^Ag1kz~$b>O@9n`iW$w2RXB4nPsql`(DQjOWIU0e%$iH zWC9*ANTSigu~y+(P~~H^VqR6?eWKi7dj=5W=tVFNsp@l@1O;)O-b$NxxJ5o5g7;>0 zPkm9)<^07U+^~c+35{P2wK1TPeA3Y!e}*v1h(Nq*2kk4 zF?rTr1re&(NFYK4Z8eE5i9(k`(ot!KbW|VFR_wV3e{F2Sl#t}SoBkIv#lYUk{q4Qk z0S0Kb@IVB>$_e~ZVsu*FM*X5jppMauABBK8^zJ%%N8}>c6m<|VWP#Y2GrO}SI3ai#n%5(pgMx#vx29S5v~{}PY^4G=q+U{bfRB8J1g8W%<_q> z`J+>qDyJZPHcC{2Sx7YMjQYHA=dAGPO|hhu<6sF9qo~ue;ipVs-PfdGFPlI;mFpTSBVi zELd-qUpA73x^m%)O!X}1SO_YmgE%l=9fI%5=`4zqBEG=$pU0ck+R1{t&UGlBJO2cu zlxf~e7=+Gi$<1n{N%7g-Cp?w7rXZ0-sg*OEbHep)wAY;l^dN^eCJElU-y|Rq0Fx1x zTzj%yOmWICR(4$I@u2&q#-0 z<`eSO)teDlj@-eC46#~F+C#JKeXaqLE0hrXd;^ab=V>L257b@rKlvD1JTrFI;uf57 z(Vl{0#?mfo)$5wk=;}ZT8h}0~FJCvbLGIc%F%>HcSGHW52qCkI_h(v4KQPf_vx8O8 z{iJnxWbFXK*$qltBRchk3CGOL1_2Xxuu2+t`TuBBysb1;g=SuJ-cKtg`D}58^LJrO zjZl{*J**{O=c=M^o}S6^FShguXO;z*1*rNnWoK9hQ+glfb*wuiz_y{)wrf!p(;~^* zs=-j<_K^)ra=-{p6qE_O-^j)Mh;_4**9CMS-v~pmG7t&ZTdkCJ_GE?@O!uw1{#l9D`40xIL{;basBCs z7miUn9WdSan8^!K^x%l{siLU3AhvM~X)5~Ea=iK***Jw!TD6$>w=`7&h>PGTC(I9G z2j0nYhsNJvFYY=^6pR3@o(|Ip=|oc}vFT0;=j63-pDoCG=5AqA0Pc-L`1I|7fF2k$3JP@<+YPdp6tlOJDRX+E)yI}Vb9ff1ncej#1)6DrDob(e`M+BumAcZ z$9$8Ik@bP23|2_zO7*Qv=S6|=p0?VQ1!M)fm<$4L94I6tnvQbRy`v&Su z{+9yX4M=g@PZ8gK!-*U@}zySz4rX+6m+&|6Ln7nug!! z&=m*C*-vA{q^CVkmpuDDQ8gnQ=8`WOpCVddB`NxFnH6M@S-xtZZ2l>H$gV>qF} zc{=5H^-~4vEHbokOANUA`#HmlS-^Q#3Necu!GLBT#-|jf8^qr{;#}QVz4@${RsjQU z^k&Ukya_qLvJ6!)1IU*BGppY{N0zf27~wpB8XU9o?KDp%jY_~g_l;XK;@r_k77aV^3bV&(ML#=Yu2&rJ%GkX``aV;oyc` zAf5X~y4k$&`HzyDTyisNp394Fe_Tpj)NY$SI?g&vbUg6wbSf3+bb{A-Cxn%;6nn}Q z6R65-UJ~jdB8D>P!%`Y<-var)MKU9tP=zqe?|*pL0bD)yOce{R`oK{p80gd2<4(0F z=&9GpKkfc(^mB$u=awm!)m(HZ@Zw==`UQAU$r{?J6S_lYW$uuAe7TORHFqcY=AkhY z1VbvBcidcF8K247Yec7Vl6P>d8gmSp)!@bAMxPjXa2C_dLgUhlMjhQz1*Hk|F-uL^?xz7Ln^V!$6 z_j=a4ZyLk`O7#y_#=WUdQOK9y40%+fiq7=Y=wsVIO?=dl6(@SC?t6sdl+wQXKfi_S zt~EaiZ{Am$)8?X9Y-qlBo7hO+13Sn^p-{Ik3hyj?pmeh@S_XWfB{70!4GYI7l4g9u z0M(}tHZ}8kcdotNl<@rrn+*E%Y;M83FS{M&)BX=@ys^+3x6qUn&c%C88?sVOs@{~~ zR1aC`*e4k0XM69jWrv?x2`vPYl=)MA^P7&T@Y(WEEbW<%F=qDcfjIT%+Maf)bnn{q zu*bd=6MzYJ>yn|Udj@;i2TS$XB-HH+jHCvr1^UJQ6zEA89%q_`nYfxw8858-bEsNj{+kIWrGFH7w{zy$slW`CH9>CI*9EnqWg zU<+sn=bO%PEnO_1CDxS*Oi!o!IghnQAb3aQCgP-E9ZtA)zue$=wZ={}x@&-BIn94$&= zUXaat=6>>B`gD)|vr5eLe!Huy+UF;by&F zwjGC^<&KW`@)o?1l&ygNc;)>On8YE{$z7lGhC`SJhlJuXO0%k$LR1P}C6OAjqi}si zZDZY?bXV>=-*5Z9f4IG+zZ%66eEGyRxcWZGbw$d3?Hz{%(xHM$ae^Gb|JUV!k665X zo$u$>HQRgh-<@v^+q#%^+AiUwW%0G| z$7fonQm;DAaVKhD^|lW;Sg|BMOX61u*PL+4oX%oqM?S#uDYSP74*7ne{?q%_ce9P} zPnn3n2J;R;8o%}hE+Ajmq?Y%yze=nT%_%q&tl2B*=BCwdeL4gGm^`_FannA_qZ7yO zUvB)M5}?UnK`KW2kaGVO!u?%xL{Uv#kgn}b-yl*aZ9g0Hg@aN5_10@$Ews1&3uQO+ zHDXiHsvAKdQXWfbs#2#uQhFY3axgD0kYJG#E68GBa9TdtP3kSn-Vx0QxL8s=9sRoPK81bIdb=QXxxko;N*^M>KUZ!{cz9&rEJy$AZ#dDkZiq9L zkLh>4FixY?xWKk=TXNgD;Rb|R%Lm!?1+d}lNz;4&V<=Ss;@|IGNL?;mA}&bsSGH>} zQ&s6DWu{j@#t0jy@t0Np*U@~(6L`|D^2Tm)mQwhEcxv&7bg7gCsL0R!oq|kuhljOq zxGt99HyeUNC7XMvSf*lcg|@Im^EGCgm;lmF=X!g~x4BGRk>G>A&ksqoWT#-HTa2^e zR18uG!G{PY=ex`tX)aG}g|wIBwx@pDSoDt#rZe9>JRKtaezR=NY{h#Usl_fF^VNot z_N*|JV?f7JtnFNyLV6VKIwrqDz>g~*&$&)qC!W7aNAbSgY`4v4u{e$se6vc;@3tBrB~_#D|%9{#%vJd>Q6l zn%l+-R5eVK?P`pUSI+&fV?Mu9*f9ki4H973+c9l;#V@T5aGzKDmX8bwi^xF}0mkV(k*QIZH79mj6gpC84$ck^=f{Rnu6` z2%l?Rm2lEs)5h_dKggy}E`RnkvPqowDv&>k!-B08NK*tY-0LXb|9z=)!{`f+KMhvn zFd%p6byh-6t&D5F%*1sF`)m!U?$MoQ&M=CG@;&t|!5OVryFqPK*IoAgHtK5%4jz5wOd zf`r4w4WddzilWpOgK2MyLA{ygjuKbgss_~pl^ z&%-8U=5l{dTrK;MbR0c_&nKZ#%kCOjQ5SaYI z1rgiE)R%T8-VH*skC{x<)0t~CUk&b&y}ZmA?KHu(0;*^)z`^FjmTFm{ke)R#j)FZ8 zoGB7}>}}|&uU#efqVy3BNSKWljw)}AQrE)k&l5w<9=sg9v;< z<4(`M$3Ef05)rfocmRv0gRg)Y*LpuG{XF9$w~j{CAnICo0aw;Hd2HoKEK7L;jR^Z! zi)>cm3iH{@7aNskW^FeMqk_Hl)FR2*R*|_s_^&oHrp7ZmkKerV#^u$vQTco zvi=-C2txt?as>#Gnmg}f84slD0-2_$6<&^vheT+Sef|kprmaoYA|{jKdOnJAR*z)z zz47s4d-a`6X;26N2~ZtlwP@X^h1XxqZyD!)D>#vihulx6L(w zC*8;mPRy;s%MI$x2?{j}j;L;wpjqBz8RwTw?b$={PA_jY@;!Wg`;O>+mMCt`z<4X7 z-~One3h=>>U#lQ)$E#Pd3x#e@Pbl>HKv*S1W@y@1QyK+`v@U91G`@KM=-?sbvfB*z z?P#k)HC$fe)x>()DbYsldjOU$Y`$9rdkHd;ui^$0Y~-fd@%av@_rXU!-SK zS?P9x+>+_3D9JT&S*d0}qR*f`baQ{ldgB&l4N(Q<(r~0m4cx!98WW;H%#qC`;xQe4> z*JyuVKNr**%hXc`fc?7=EQBrwZK+zNKZo($iU1s_zsU=%QETb6udzHKp7%*~f@$V3 zFyWPG%{?l`kCgX2Rrq)en=uAOq7!f;3Vtt6vdW4LWrlF`QjFnG zkM$Xfxr>N>H^^j+h&E>itdOL6hj5Z!Ci~=Q^SWsJ^JwStSPO;6B1Z@(gvFin7*-j= zLoWiMoIuqb%N0O~YawuQ!{ZbMXP6jL{9!K-5pr^|U)JKHb?+1-;>!eC*bd3$W<922 zwY0Dx9VxOU_2Ubfz+Le^`Ianz(SKr_2^qel3oun?QSFYwv&BZ;;;md6GHqq zK^CS8DIukJZ)RFZD}8!K+~w60`S{sUdBQ2dLs=-!OB)>F?{bYLdG_r2F>`#mEXC{{|+&=dZqAZTF-n=t+|hMNshLSO9D+3Z0E3o zQqL_(UrO1;U89R4S8&!k_h;e{&~I@zWX`}TWklIz#Dr!LGBa>2q>iN-pfm7uNyOu3 zsfa^_sgoKxKnCn&`0_yVP}m$IOID#$Rm7*xEoOKA!bZ?`ULi4sW^P+5WcH=VQuJ-m{@{W~Wo!Y#5rUy+!lLpph z{`~Ta=$-NPgFn4T6f!o7MLXbMWHYXPlt!8l8PSZ4P6PI`x40qCZ8 z)CG{}M0)0$r4^dNr(ED%k|ES4g%U0_HizD2wux#jJpEG0la(*KYcD@v(CU(*#F}+u zw?H+XR&tnBy0TE`D(s5ROjc)Q5STYMX_Gf%%}^0mtrpC-*yUx6&t9|1-?&KctjO@s zw-_LW)cR*;)t={TZxk}PEsR{N!N`(}8i zuqtV5MJA@~8eK^mYelAQIc>kVU6Yg*Yj#z{esKhiQ(l%>$xO9u8Vml80hs5HwDG>I%yfUt8 z*r&QoKkIuXF=Nq34c`TU11fGll_zb*ALD6jlm*OoYerZ(c}uEOQ(o`3maOXKKmL%7 zU^SJeWf<5+Mim4S0+8J5+&#`bpJySVhX~JPk~Al%e( zdb9d^zCud>s9h_;B)q9|#!g4_YB=+tdYI0+-U!z7!d%#P z%&u{ob8<;@E0FW(l5;q|rbmP$0}m0khcsNx+y)pPK)z`>h1J2}%}5`|r+_990IH`0 zJx>Ok|3NNs@hUw4(Y+HAPexD$kZ|z5WxUNCo5Cy~$m{#A!Q?xyI~K}(NTyH+-rsJb zCl;#3|KSu%Km}dn5He_@U8^q|Y4q)FEx65f7)guub!V7rlXh+P@@nfUD3Yo!WajxBh0ZN(AySY;o3uU@p|0FK$BI)*eh#Ic` zrF31g>o#pgeVNjb=q|tq;9RXlzwHHKaqqL$ffQ3PC>hAhmr}eGyv&xY*67u47naUp zvFL)y9U^Y#L+(uWy50{{z1dyP!&2MV{iwdnQRBKo&fuf=fy|V?S?wWsKtFc+4wGb` zTlSz?{ks7(1ZDkuIFDtQ#o+o!mBd~q{&wA3%N~`J?j}A3w#yGqn}d`&1IWb>{xaS0 z+c#VLAqXys7lsugolFUmCx|dDq*~f3d_oO1b+KdN&1QD49mom4x+FmyAzU z-k{fn9_CyXHz%6<#sSY;a2owrX~wAmH{=YQFmRvKUQz zw~<&#!hEsNw$BeKXYSmcnd(;6&F*7bGSn-%ucy5~p3|s*jc2B&Sl>5(8qqiOY;=-Z z3PEm0=AADfBQ~biZ>%5oahrEmGi4&54VBUNsbW}t6Z%>Iuhz1vcACfR9sTiU+Zm~S z*HT`L_SnQv4X~R3*cUqzyQj1^tei*WRV-xnKSfl}XGi~pS%ngttUz53)XsLC;o@=0 zAmz#Cqx##=npBcse5L|9yyJGf6Q%ItDQ(U^vgWb<7Y1M<+T)G=1PFQiZHK*C{ld2N z%@+5YVr({j?shBDP9t*Wqw$m4p^kr=Y&Gj0_TBFsZ_d*h(K9?o&gaf&PPxs=E#;Qn zeIIQ8ngLvkeFk4Dh5j@>XOIyG5FivuI?DoeV+mFK|zrI?v)0+L- zv;UQQ7LqSE?}^=LAB;+RTHsJwK;x@+{PMkKf#;(K$V<_C)en%hB%9n^oA-Nslli@m zb_!q$`)*f%i(CH!pe96+u7*krDcVEwnpdE;*L?oT+jg+scvJ-+!2 zFo7Ss^DjAd-?|r`&fRhc4@% zA~T3P)ZP8O`J}A(cd0>J_-Mc9RBo-d{zpf^%fsn=S4S@juX^)a6LAI4{i0~w>yE?f z(XH?1dV9Iet3O`v*XOxyl+K=R@unuyc2d=ja-h1Yh%y5&zZMOAyJNI{aM!o2=^%`F z5IdeSbKrZoX8uF7N8rIuCdqDl9_IxAy-T(|FOK;l`@?CH_kDY>ndVEVZ@=#oRuv`C z`X55cCy(B_hGslOvJOQ;>7IOf`}j%yp$`Y}Xz;pOeFQuuJkt7(YDh%SXJ&IN9GdCA z%^(wx3BW$YNE>3mrV|13KVB4|xxsmQ@GWrF3Nbl|)p;9-dCy6~r;s9Pug5|m7pw%Q9$M#xl;Q8#}xejGI z73f6gYs7oNvq+e8K2h^bB>pDN{l91282E&*cv^amL za9;F3u^nS_(WE|GAHgneZ%{h{-K(?D02n1JFJxdPNdtB@ z!9@^gg!L0cpe?i?K5{aXaCTiabuj={p#1P5!o0X!G)GenVG4T6XM9hQt_%5f7)K_7IvGY!$P_x&=DdF(@?6$J#o3#%qzm;5DsWK_lPI+mWEx+CU zQi2lRV!Dgk8l!?ex!&Gz>{9%+`@nu|u4arrO&BVe{7tvJT7>c!#}{`aKq!=~t<$DX zW)u*2(32uup1^KRCQWpH`E}3fV}RVQm|*gXr?NG85v_%)-vnrdY~6NfOHVrvL>v;I zHv08MQ(7dA*4EVCB|}Q%Q6VtI47ic{I)sw$nd16<_I4*uU4_uuK*I6^wOh6RwC>Eh z=&&Q95kgT2|79L8R7TWqG;L!Xl%~)+0OuU_|D_iu6dX|a92PP}el#rqw{~Kvk;B}2 zWndSlos|0UKz(F@K8)G5oFYh(=PC~(qm`TSnd(n>PIe|?^=$^}umyce8RQ86c{KRy z@kW{_dr%+9^O|qIGfAfNqp1=`DQc~tS{PbS+)RfvTGm`oprp~?EO*Psvn2SI^q8iFk^EAWg|YH}pM}Zwzfen4b;=iK z1Z5xhW*g5}(ek$5Wx+RXd}?#g;zjDlW^C`ihbh?U-BXhplUsNsGp_W#{bQc$uf3BA zG+fN`lO~yxksa~zug$lPPyTJ5EV-8uTAn;uzeS*;#9 zf#Z#ctPt@R+ZI+T%sU$QN?-2Wda*p?S&$peYF4Ba(6-Z29uf4t=Eif@n{^sue=O_S zjTSyu$z1>An@ioKe5>U9OW6ZsqfZP=4xeG4?48%eUOKqB&aV3CePz54Zy-y>4dUjn z3r1T}6uK%H(+$Sm&tV%(!rhdMQjC{Ggf$M1pHhEu6fz8( zA=Lgg`)FqM*Ly=QhT|`;U1ui5vf%Ak$qPvSlONI}``7v`85QGc4&0eFa@M$`Rdfn! z!$5UxTe5E}E;sL4Fd)Y~$s|d6MFEJeQ(hxg9Tt|>10&Z(|IUG5@0Faip?)-T<+Ont z?$?SQzd=>oSu;|s^~I#%3W~xMJMd65b3SVr&&-<+8x}Kj9y=I08QpV=yreME85CR% zq5dmnFE(Yk;B`+(vc${yd(;LjEBx|`>Gpg6=$tEyO1BylZx6~dME!qkG2O8Kced<5 zGKhnu#TdHSu5R1kK)kS|IPGsCgn&3UDh|O1OI(2pGIt{Y%qlWxW!Zt-I(Zb9pB!sg ztnr`OagY$LQ%f%=q5-U5E&$x#R>ugJE9w{a=(6QQ1O%m`C-&--o={-fIF90ts6m!W=`Z<#Ia9S>_S{*YiJh#3K19mdmLys(lLS7H+rW-B zCifLZiBeOAuJ)Sot8Gzo$!I-8wd1Lz=LzdfLd|=TO_`hRJDf>v)3GrPWrlnLh5D#?xkVIUnCOGK zIw5(g{TcAF9W9yo+54<+)pyv3EdnQ<;T*q>Y=?VHVvhke@YbYPo6W62;Wl7FcPM*p#=$2p|QGYD1h{^&*&gI z`l`%LH!8&uT%E9#J=9H3iURRVqOt0zRlqg`W(r9r;UuP=UTwj%A)mVd7G0~fbe_$- zqX`aY${SRif3bJoMS+YL`Dubeq2xgoXmayv3R?skVtbgm|KQg}aR$iJv`#(Ubq06V{Bt5h-l*xayT^VJt z9S701k04ze>_0YpSeE?($R2G z->l5tvhqVO7K3S_<~iV>ov+Q02Yg-jbiIvL$3Dx0~MfUb=z+g0v#(eR?MQu>jZz$#-ITHxiZv~fX8LoM4eVZ~PX?`Z8R$&p&GWv6I&y-AT z!}(iSXm;oQ^5Ew8wqNHLzuY~J>bE>_ISCu<9PsC5Ty#=}9HYuQPbU+v2*XcUW>S>b z19+OHyPHN`Vu~!eJxq}%=f&g;mE9a*LJoA{lEAx#`Yqb?Z_?&F;HZ7Rqb8v|90vqfSmgRW z{1u9s={$aEwX*rD;EzKiQL&Z@x~GvD0tk1eXH2wjDVRW4uKhdWNLv+Sn~VJR3kOw( zqRACZ!feW$Lpb&Co+MGX%o^1^4A+i0zAu3Jc7yYGJE#5T9R=0Tl&K+}C!s$(P5$D5 zr2C%|D$W)4+99B?e*n~9vA`QM)}+Y@3Q4mi5^o68yXAnv&*)!?K*x5h2@Z(*S3g2+ zdcwnCO>Gkd^0Z%{;`e+pKew_(XADFxGdF!}1S=qz2dwCoTMaxx0C0zN?~ed%o_L*n%a zD!r2Gyp}!RG@dd6FkTH#wl2JpZ8Tk-y67Xe77bP{w?4XZ70v}wxtt!Qs$P{D(VzL6 z+FpG+q6AUdL{mS_-W81-yaco;ftQWuZC9MwUXKK{;L^Vz&{Y?mq7|n-aVu$LCru=A8E~sCNzMpQTUvn;1CPZ79w;zz~??7uA(5pzN=G;lt zcAL^5|)sta`%E3SI7@iBr8)-A$30R$sIJ;)4UN1j+aFS#7GgQrfJg=~LwrI5!Qq%n7CrpR5Vhe4 z36&lzwjt4OZO5oyTyif%Bj+e)uy320LXadX|D_cx)LRvA1RlQcc;@ZXT(#s+IivATrm2!ldg;&>6Gy#r|Ht!m< zLdG}SVeEe!gi;t@d@-ohOuIZE1x!c3sNzRe39m=>FO-e@q4l3+5LIS?wr#Du{t{x1%Z6ok7D3Es?tC6de0CoM#hXyTDY|SR!qrXcHgR3Y2Lf(h7@U=D~`D zs0@i#sBdy=iXkY5+RJRp{EHxx_R~013;F%gB9x_u)(k%-R^Uag=~K(Sc93$@N1)4s z)13h>hY%_;7diW2_1A23F@Ze;dfOHvUT&I0yghs3H47kT*!RuUTQ^jgs6yvuaW19wCU`8jf<4OnLmouMd@rOQ+Jcr-=w<0 z(!ejC4Iu>cB~uA*V=@_0=7LZ@Raz0!D?tFh=241dt4-%&0zGL`WSwOLFU{}C1rsf@ z!7&=4`->eR$h!Tx4$}ovQsm6+Ec;H96XkO*8k!kOn!fD?Ua5uqluIL&6!tG@>br8M z`82r;Ztra@R%R@9xqn8A*mIL6ulJKeofjJ>tyn`~2L+2C1XJUb=K(?cgJ{u;e6nI| znj3k{We|e(u+9< z;iI^}n+qK)4xj%n>(5hGb{p z7DC2PZA^XfIK7j#$Rg=X6rx>XKYeKvUp_5sp+I~j~ElvjXbe<>HP z2WtX(jCUf}gi6Nv{KzRsZMQ1H0Gts0T#`^8PadqX(FZ8d?B$=2<$)P%{G0#l_;1>y!H3?(bQp^|4t z`-%Q!hyExrO*kZ)iHHCY=;+l9&I_Dd!#TQlh5f7ZOJe3rX_srFl`mYyjlE*%^-=D< zbsmAD3FjZs-s4-k7aqFK9_!?JcW>ou25fnV68t0RAIQHTwz51lPV=w9DhNj3Kn_B; z!A8jFpL+l01*4boPAEI$NL3&j0}OSXf5U1!Jl^trLUIKOc}`dUY(jG4zo1}zq&!6e z2@O7khH&srM`=5XL{~MLead2I&g_QWU9b4gn#bZh7g=6}mb{}(#nii;F`Ya3WKT`f zT|<^{m{MDtW>*$=XU@?yu48)pm^5KQsD$Jvb)?6P;FfA)0n7Y)P~Mhr%9cjGn-q&r zgLWPlJsjL#=I_8UTI z#>Dq@LidL9{H*#xv}7`>L;El<=Q1i_0xQvx$ygjv_@|K-j=EvT=hhcNbu#|PwGS=A6ucn;>I2Nm1oQ3 z^I0MVS!KBLvJPGUKT3y(4}|-0{up6|YTIFn?YCVLpN8#f{nXME2cb)O1evEN1#?t< z_4h%&L%70W1vmdkvU?vJ0?s^+UKJg|uvo-Gi=HlsC;cvy0>S^TJ(tdLX4v7>^MF@9 z-|>?H9D^PWx`5?mIRpt~QUpv}MmjP;$A5(XM5K)D9w5Z-ebjua;Q1oY_C#KSTzI7|M5DFJyyd<@AHHtE%$T#%y-gTDd7}UD z{;>=~Jm1Is214To0(~z)@4|zg8esVR1AfE*YpR$&vGsttf8N%^$B;`i=$(|<_bJ(T zZ?#0eamUMZi_|rggCzm{wJr#%#iyjT`Mm9cE0wIrlde?TXriKMLP_61w3z83LqZ`{zA~NGm6-NI7srSIR6IY^(^?l0ZnU zL|Gv_3`ZV>yl(jR5iF{Rz2+Z9FHKRN{<~o9Cz0ATtn}e;uEel25%T}wfRlq5gWkHh zMoHU8nsouRPNz5|Oi(Dn!ZrMD>@z=sKPC5m2fupw@ncwx373x{e$)AKlhmq_`cJn) zI35UZx&aspk_}5dY7uDOY`w%EhUy%hM+->A-fL31c0nsfNPRVLeM@og;H-pd&4BbL zRmvEx;d{4V^*b_cy9+9wa0p8XR4D&v1YOsP0Z~^b?=LyA0j2iwozg(iJ92*_kbGkf z-31-Js9I3gDNrFRF@@h70{pvoFCP=>e7}~dMST8C*QeH*-BzhWPi@I|L2j6A*Llv_ zn))un7=#dV0wb?R^xEA3n2uzUtL#ceYDs~3$<=enJ&?#Om4X`b8tliz26I}w{JFXj zwJ0Ri5|0|jQE}-Pdr7$(;_QAda+yk&4dk=ZRinyDHGx!qQtce({6d{%bqL}AF8{@H zcjda`ZX&ts^YOe@%p?-}0VqTyIo#%x;a-2i^cCI zy>cN!EfKZ4S2x`lGoO;8_VF*dS(uwI+yDi}1hYDF~Zp55t07(Qm01^27F8;jbQ@eu;e*ad`pH$3j^N`8W!) zG1E4fRH`~=qsg*2@7jZNu4-28kTjAk!zLGuq&Pc($SEJW`SpoJFoYfXMQjFAPE2b! z7m>zxW$81`RHsnoC#vmgz3`On7IY-(BAuV)hP2dg_hjm8{gzLsqEw#N!(qAb zxWPF2J7^En%Oma>^yiz`*IOZ5FJIqTHh4Zx2|lc$Lz0qaHOl?jd_Q1h`r?hWX3OfV z>rDG$rA(R{CW|ioGIU;`Pt79Mn|2(K=3tb`&=s#};WFqYeJ6ZbD+1uEi2zaUwR zI1MX^)%`}phJ;d?xMBrddXa~%htai)c#>9}`qlI(Jh#`L3@xZm%eX-V%C~jtUTtF% z?feNKK^JxLAtp;FEb5kMAq7jJ7WBGA*vI>h>V2NVBm0zB6$kT~`IEf!(X#8mK1@XX zc1`*R^+LmxO>vA-UFqKZSlN*tkbf5`V&>ou%LR!2k$ST0)G8UNB9`JRb8M&4yf;Tj z4I;zf0k%ky0ycM{^ka}wngH;k-Hl(W0k5YUNNI<_qOQ8WB5a2*GWhGM&6 z1GXH>&J`bUvd0u_?fgm*?3F7A!}BYs^zbTQb)|aaN+ejiiHtP1KiPUi9=NT6dBif3 zSoblPQu^DuE(4IrsF_b=^i5L=7pa*Ts7yimitC0A632hPC`A;(LDe=C*x6WAby==T zDm|S#eVSw8qydyp#^C%dc^K|YvbO9P71yPqXrDf1&4uZkr5;i5z5{7ON|F3f0Ww%vx4>tp^k6?ZE=Q<* zO;JwScK?~pM;^|1KXvLzX(QcF2wX}ixXC4m>uhG|Dn^adwf=6+fX4GF9+6CtV4s5~ zuc4SD$@C?0@CReP>}{rG&(nY|@PR&~B3C@z3)XpDBEjNyhSz{%p%GUuCX&UK^Kk{h ziU19DMm1g@ynW9>a>S{bLn90nQd);Z9VVJ0Ocx6hK*>^1-+AFMlg?ybyU)06_FR}> z8+7a~9paa`s~*N9KCpkXh*{j?;(Bi#!sHY^ers_}n2EQW{CWW4hRX6W6)ew^Kd{Up zW%E~HMyGznyw&tO2j7&8tMHSUpHi)bl#t07)2rDNaXWh2N|p*QB&%Q#iMx7BTtP-L{g zGB%CuQe{OzVU*W<%5(KhA! zNpR*9k51+6kx$6XJdvYyYp@n(?uTzz8o%$LMpC!dr2J2563-1W;g#KHvbo}w`JLud zcWfIxQJyJ!mRD-fv3u*i@~1a7XJrwyeYP+wK)2H8bp4B|*&}KAQs(;V+PFhFh;T@_! zODCPbI{&F1;w3Iu>E53&Kkt~ckFbB^o4)0va6LCmj$O)fb?dFi-?Kl)ogb?scIu4@ zG4H7#ClYRa-~8(MizpXJB&mLXw%|DX=gp7ci}m)u76tF8`W>Ur_1_ZZ9C3(WN@-uSU|*YSQoKzt&sfG+oi6cV?p1L_BlC6r(w?Jt)nA3vXuT zFk{98Crlz&4iaEi#R*PgbbtbCnwaz1e5-Tk^2Lct!Z1}M3Nheh1+2kpmPws5?P04F zlLhQ+t3)j?YtlR?GLo)qBv{^MF8UA7rUXYG4;#}JN4n_|y1X@!Vs1hHKEX=IZJI7Y z>yOG;+^Ikp_AqYxwR}b&7*m*WRg?3eowK&znp_;J8sREn?xKBKz*U+v6U7cv&fDk8 zKQYStCFo-6Rm7SPg6c-{xM{&~@$y-Ec)t}?W}&thkM>X(Wg4j3AH$J>hFQ~xofjyB zm&lD{DXy<;39fkp-5^vX&v_qfmL|Zl1QzWg^;ZYGX(~jxDqcO~1VHIQd^vO)DuapnG5ro#khzD@(KAw31w}7+h5vue!BfT!LDbGsmBn=aaWU1wocvj zFDce-C{}3OuwaZbnKsl}=F{TxFgjYxKDd zyV+I2bWhj&D8VMx>*g(JZu&kJ)kv_^B#3}hi{Q89*QB8UKh4zSMt5`hgX!1}d}{dV z?l_UD;+XiONSGHm=XiLSyEzSUu^C;B?iqT9XjZQtuE}H_r?Lk`#y&C^z|UBViJnjJ z{2AE;*h3ud;W#XK-qoL~Y>}W#z0u8+gJCrVLn6yUQojW@cmTx!k3YCc3YTXOrQK$# z81;PIR%%@RjT>C%zuXN=?h>Sr63nOM$zR|(1u&*w=PBiJBv?9Lu;3mj;;xs2eXJBuP z_0HXS*KkHnAxTq!ZHiF35MQ_r^Afse>Dym|J<4Lw1rs?c5~+Ofwg$wgLU4tlfPm#U-U@!4hi0*{*F%?0 z-+@y27L3NNyJbf+m$45v;GU`H@#N8II9oJwV2;+`6t2buS z2Uyv)D@~~$?&fI+rx&ANduUdUdt=&t$nq;xp6=wDi;Mxjz;$W15n^axiBe&EG}HEb zrd=S;>i=kiRiQS)kad!KnWLH{e}ATMZ$*CHrC)5!UvK@^ zT&%ee_2qt7Pv+N7^{$wjw~SH$%RW}+U2LdcZ~(Sl5;i((p2Dzow0)G5=5$BZI(Fg< z1AA%M>J{7l|ALRZ>F1I>T0}?3#XvLrOIc!K@%k?iVpPaG+)mY&`@UR>RiDZ3%@L>f zw6J1Opa+t+3pzjeJ!!tT>^FWO`VF_8yCeQ%yb_f~dH7)JqO^8gRlIjVJjF*`OuA-y zO}zT_UWLy9ahTz9S9D@|;IA}ve*CWYTn)@qoX79()K>Mz+K=s*;@vg$KfwMja*`PA zeycXm`qc6qIRZ>+D}qGBx_cPrK-(!SFpa%Ve~R7lM|~;8)Fnz4c8b zL`pwqz{^h36WPu9{tmlLpF@<{g`|%5siaLtG|PP*%pNQd9ix3daMvxGNbxv^?fC%e zYoC^%HlDN3e-p%V7x}B2tic6A4X>=%DqN))`ur%Hkfp5Ua^hUmlKnKF@&c+Ik-cX@w#Cj z7Rn=N2uLOl1jU-l7%IdiW*^FqCv*2}o@zq6r*cL*mlNBu6dH}A-E;XS28Mb!n#?39 zgnXKM(TRPQBTc%)7DZRQblIHL#CKf=*3?b(UKF?K{A~W6+VPx;)Y7q!x{qg!nK6BD zObe=0rIb)GcrDpv^ux#?UE9dB@6AS#WmtcIF^Le#gO|kMB-01_;RX%{iH;K`byre@ zgfsVR6edh(H%|;PUT40q4F$^{yv+RRG&1X%B%kNf#Q)%oYViz4E${y((N8AWYlJL^ z>LEBl9wT|?{qbyqrIGx($2*60iXt7iD<-9$33#a-LUi7l3ki6>IkAJ%(sl$v4b|lx zqv#Yoka|?CpyXd&J4_X(`1XfP5Sh>)6Vt;%v6m*(#Eee|W8u`aoZ)6v!SK*|(@2>f z90UVDI)eG9n1%j={565QPa$2R=z{wq;Q&X;n~~hbVtntp8>qDQb!+>jVZ)5CxjkD1E!10`e!Qh zQqeE61xl0hHm%jFxFy=^JN|1(&e!|eQ6WUZuPv`2vRNNPf{I@MAG+=`tjU1=8~?Qc zHgb%RW}{oWV{~_?luC)9NQ#UxB&EBgLy$&7z!6f4k|y9lP)Y@q6z0S4zJJgE#s4^- zmwR=+*mhjUah~7v^OfcLLzQ3q+>@6^q0@jSI9M&mE6~%QS!5%mhg_dXq!%dXjc_7Pe!NNe6q(7^gQ8wBEP?fBFfoERWMm~^6&1*zrKyy z{{E!Z!Ib9%-FbdA{r*bll>rtyx8x~S+u(Z8RfR7Xb! z>?@)tKc7E)p{D!v{E5M_PkW=>l%%!-YqP20_*2%F)1tAYpEeF9^dr_!P75MN7?hJW zQ-$UyCsj3PiVej+Kc#s2np{_S00FmLDwcz77B5xVy7X?bq&t!#k{+1ecGAmn*%5pY zXE3PV_4)b7t zE*IKlSZ7f~P5^E$RNz1vL2S7KT0ookwL(=~w}F)&7%smaxp)0_;msQk5DWO^o>m>5H| zOJDA3bKu1%iIx67kApPMf+t!JojU#>G-~+&k4B}6jQ)GPFPOUu*Lv{pABft5aCWqF zn*gCVu^1v_4VW3CK&M)0;VDaIhN+}pTa3^s?FJ1~LUPiScUtGuRDKZ{(p7)YSf{HU z6SLFR>A3sXDA|JhXT~@pc4x=AW2vQwIOE0UCU`SV=Ja{AOPc$3+CMix|253sq8jza z`1ZijO3H0@{-Nq8$x@R|T5XcEuUkx{-k69FExy_LvJICXgx?K_{Jr(@YObCOe8G;iSle)j4Z2AMm-i*U!1J05|kp&WD}AjQjIij({JTD zt_R)){=Jozdg7HOV^@v`;+}1;l|PhX!IMWYi9+DiZoMAy+F%1{vbN$-!1j}tP@$|P z>a}%TYx;vC-?|2o^#ofRDr_c!BH`6eT#lO>&_1mfRsHtq%D`^NynNzD+*v4lMXG)w zyyDyKG`F*@hL%Aq!K*aPGo~qr3p3uV>mGb@*po{e1LJ|hN_WD_W0|QvzeJxvdU#VH zK{M-@i(+&va78uE)K$^5~@LB zhEY1eRM_C3r!CRHswgS!W&sUG%TOL_08S%~5qR?pCDg%9`g0SJ%lQ_?6;S>g42;B4 zgsx{Qj1BF>Y0k<&2+MS6A zOtPhumG(=}D-0fyS_w2ZxYNi6XUKb_@9OR|!(@XdPv~R$BxDVkh7ka>Bu-PsVT7@^ zm7FgKeK(y75R$|i=t|F_O^L%GF*J^|x&oaoTWv?mz$5@Zv4u}V5}6+-WhB7oQ7P5l z+7ksvChb`w3J$tF2v4)in0D!pknbw1;o}+``|j#HyeB9;M78`Dlc2*R7J(ty6+56D zOoN441ZOBpuG1-C*Wdq{G>_qF%>o61M94E|^;L(+(iCB$Vu?f2q49B7rZ-XYMo4Qm zD6~isxY9}}XIR&y;W&X@Q6ARBi~Lcd`M;O`tC{rIbu|95TG%V=(AvNV)RFab{tq6N z8~yOq4fD&0fAHINzgl5R*>yGB+8>CqyzR@EEZ6k`R}}~e5^5k8 z*t;!D{cv8+Q;WET!)Eb_0&*=<5&{u4%*(`RtOwppOuLAEP=mSd$!?YPa5t7b{W9&u z<({MlCDMcyXbL|9gI`3>qyKMVd?&WG=GBfH_rc}$Ij*|}m3xC7Y4~+Duad%1T*@{S z;%h|HF>|?dp+9hWW|rT#*cDi`)F<=v$7~cOl~bG|0e<*{sHiY;*;ej>_)QKBkPkr+ zO0$nSRfl85v4H?N%gR2NAfQn`vP!M>-&S@a0Ojt^Z!n++>%zXW6(InQey}iDpf%PI zEYWj$mF+Zy;kh62*pRqK`4ontfb6-Qzf=(Z--B|pO$A_GZZh)o-waL@Fu|W#vn!iQ z`qHwhI6%IC6>Cj>4Z_Ka=AOaFg56iacTu8JRPQ^Qi?55{E_{WU`g!yxvGwt(l$MYs z+!!1bZvec+`?~$+{w*D7FMu3CtFFSn?n^2fMyQMcc`9NbSEqP2Bnuu4YU z>u*eg?>71#e1CH8z0mtCNwb{*w{#Jki>sv+K}8|F!wNr6haPqO`h7j}C^h|yv%@s3 zoZOnu2UK1l+quJwv)X)xS`$#{nJo>xXKnw9yec&8JKF$s#vG$xKhoF1^N^$&g17rS zcKiawwWs)uy?H5Dw6L)_Q48vL`Hi29pv`1(x9wja_lJ&3l?6Y#UGf!E6khPd_s6fZ z1d61+I6J&QLiDQ;IF5z;q20>9h*zPAZo!0+%&VY;R&MsW&M-a~oIq z+WBgh^toGZb`7YYG(rL*Lap+(-SVWKI&5HLHbL)c)((Ml&{ZmfAyFqyxYVcw;EeEJ z{C5{;%+B{8a2QAZhjZP7DOW5u*z9ixG(?l35&>EMkrsBGRYQF;1o_%v6|2y5qcZAO zR2&R=sGo?VjqOk05LG@I=6)cT{cl8v%shO=D_SI-+xRO4b+$-i#{*S8Et>0TzC`(I z4~ZUyZlAO^qK3{vPF?b@A>G--^#}Vc3I_jSkvpqT>Jk#S1SzAp;!;jy#$WmFJP7;w z_5$_#?fEwqZtU;7E5AQI9*pT+X-?Lv+Y~W2I_RxgD z-NBzsea#eLBEam<BECb zc+xYo?$dk?qV+=1Zp>6U1Tz}bPwsjlIV=BVtpUyt!Q7S5D+&MjX8!S6u+nP*a0~4c zDGl;i3R(h`Yc-S0f>gGzC5FIIx+62(L6TUGyJXO>ey{cRGz5mAN54>g`)@fX*`*n)^)1AOiR-OjOsgR^>&RtYypDD|CxaBjdrvJ#brq-)80OygATEf77d+4 zC1>3>lIGpoV9I)mmPDc-N|U=H(UAv&amavVfqPB|{B&A;^E`rdo}%npv|Ou9GqwEk zRx)`IG!2i}6!FJ_m)jjdKcNGGSiz7R`ay31;fotQi^IWbZw0;fL^!p?IC(^9c*NB* z1upk?IwF_PC3|v5($!r$c8-kWH;P9_N(nhntHsaGBcRm5%hWMffV@^9EkolevtQ*L ziK63LrJlng_x4G`5eeaXYeEBeM3N8WqbWpRj$I`~D*u$?j;{+#{w|CL;=w4e0GjN6 zNBAdc6i5c3K+rV{APGcT5+OeAj)WtHDut-S8-1|4`*btLb;YBJoGd;!%~}L z;w91vL{j7Q=zXpl{@hp}PqM3x`S2%!V35c%lx(nRVcn%GCoasvWEHh-ESf700i<+o zWmaU(Y#F2@i1z!8uo5}*d|O7!H3u~r^5;2rm5fJCayG@Cyo-$%bZg|{0Zu9->hARv z+gOmE2YFd}bO_V+Guh~R8$JF-^OPObw?nK$PJDo@=q3E>D;wL&h`&*eAYEd_4uaR{ zae7g?A}pQ*;E=0QSO#g&YuzxrYq<}gU2achh5KQN!<*=(?Aw&F_tqJ_So7@S4B}n7 zk~XK&NDpdSkteirNTGM0cYP89p1Dh56NA1da(IFShNw({$sjxNkRuDr055v2l&oi- zGCY3wp80ybOKYWY_%^xxZFWuXr}`y89KbJ1?vt(D09HTJpgllEgrF&AP(O)3sqI2 zc`~qLja)+E?$v!1&=8D9Asw)^#9;Fd&n&(qD5XL+EtmwRjos#0yGN%W!hRggn-4K~ zA7a^EXn+bs+q*!o+^QSCD`kH-J}hjD%;qrf_Pv%ntHdDgHCT`jrhO8n*sY{_(9$%S zH71OSJPui%m_6cW6AL z<>Ig{wxPZX078-RYuJN0IgQBj{r|ed0r`y_;EZI2TQs!1zeV!^2q#O*K=4G}3XAg%Ebhzi;_yTi)H2QyvFjc8q)vLWc%lwv_EbR- zi4XBK;D=F@DC}hDBY0s>LlG>CT9V{}Jef{1+@X+Qd71G+mu@(v;zO#JL#l6qra|YL z&QGwhX5vJijq-L?xsl50?9MzmzJgLCBW;@4T6I!D5 zQtuRu$<5?+Jhl=7-VmMgGXo*jPpJKNMY@-eMvY~0^mfSw5S>B@HjjO+NSDa&7wt9SWedih(1|1)u z3dtgj? z`*Bg6vr6xdV6i4s`@ZK@*45iYVgvn}IFn9GXZQU_;qP`CdO+1Z+~7W4_QwsyViUbx z^f-`eEF}4JKOJ~b$$elPXRGkMr-RD)|>%L!{1Yr<}`&+ES$U(E8BuD*~{To{`%cfkY$GpY5Td@#kY=X(~&;6BeQq;qj5rO`)f#lRwn&G`J zbxhlX1E!ea46UCGsBgvII-N&Pg#w$WOQ7>E!h21^WjrLQz>qQe|CNQ~UAT{26L%+u zcW2Cge0cMtv+|9dHV@yU^+lZDCF~1snW?S(Q2$zb3@kG^Jn~^!{NXi;)EGH7hysjP z>E!d7Ag_YWwEV*={(^r@k|XHBYj3S^Zy#KnQN+ql@d)Q!Te_+(UKt}ltg$%9J*}mE z1{Xi9S(69WE?Y4{k_6U!i4;S?6(jNcJ$jUydiFwURwt5GDJrb!esGqQ_k?Js>P2kZ zi~-srOcF{&jaR3}r&_5tVaJel3LHAf^*z7K`!*(G&Y9Qmn=|p`^q#5*BHN8T2!6W> z-l=R1&Oq^z5kqXfWwmFzz>hPzfW`Ru`y|OnU*+DWrqXX2^`qqcDElLBRgyiQ;hm^J zN2S6ugyPa`!IoBZa;moy(`d}g)%ogWI{ z-9&w0?Fd31Vr6&cM_!Dd%go;l*-`(W%&c$u*CkNa)r4Ez56(Q^TVL^qqI9{``Gdyz zY8a&pVqUu*JD3YlUzX3GS_*P%VkL2u{Ha2G=m36Xh{r?rHwvx*j#J;^{{@!PWgIk- z{wtRLe_$z?*CPU9c|Ff55bgzy<0D)z@JutjQFx;)=|+*C-{cq->m(5l^?ze{vov&t zmA&N7+GJg!{Za1?K0}a^PlX4ilThV7kv>F~^R{7as_du4sx;LzSapUDTT*qFi88z< z$0kc@gzEuIvfq;@%~O7jjc&p5jqPuYcC=dG_4zf_t+5qX^^+oNTf!-eYgq9N7D_Q;Pd-N zQvo$^Jw<-hE`}zH*MCmy3nYN)OoE2Uxl=D^%U53qJ^5p`y<0O&@-uqcRd$12q&rld zkjQ^$l$ltF=65{FIbcM*3$h&ze^JjOTXjT>8 z?bdy(B>PxRW8q+YeEPNF^!TC;|AN*0$IiJb`kYP!Rt=&rgDS`eGiIr0vAO5?TqRAlguK~zH0iB_Bj*AdhM>`94#+(3uaY`Sn<_2 z%Ao4ngOl(0k7>`}X{&KLe=9z|)o*UY{av**u7A#m&y@p%_)Qwue|!DyWYn#20~sNM zNUlbfYeVe%rF)1gH|c6rezoLZwc2By{5g;}^3SZU`=hbv-TC~NXYmS;mK$PV$z1zE z#mnZkSQ$f2XW(H89BO)$7 z{ObR`!hgjFrc5A0Z7! z`=8#Nhe){O(kfkR5}%;JDT7^~bpF%(*8#00%52L~9yJ6Xli+_#!`0CnXoe&fJ>@J^ z^tl(R)OYI4;CJSPjetxvPlA3wI8%P>n{>mLK4xwd7E=KAdVOlj;N4EyJR%^gqBIQ< z?g}m12zu5ACFoncEXxDcPHI`jOP<66MM@SL!mL;xY8-#n$D6=9oH8L@OIr%|PB!I7q^!qV{k6s&tXVaI45ja=3FaMMq;1*Y@OMk(PW=oXo+f&3FBIQl5>!G98zxHQN`Eein(In);leAZt?y45#7tQx zKCFJa#QMbJtCG2R~%?P8P}J%fQxv73oe< zjB20Muj76J?T(_9j%4zaA@M7DE{}G0Z^CyXgxtvQ1U$6=s@E+wu^%i`vSIR_JJ{IOAhe3I;Tk^0rC4*PEfjUoM*`hrQ+jWr@8| z0t5Mt-u|T?;F3Pn%T65w{ASc6t9t#9|yIi~P* zdLFMDb`7@WoE{z5y|OfZJh@l>;C|(C;484y3;x^Wc>NUX3mXA>rRJ zOyNnq^-0>XiGRPxR0*L#8Oe2ZaarLkNo_1?i4SS(VOvk7WUH1x~I)c>7I;I14B}24L3FZShf^njodJ4W$hFB!XHKJT?>hy8}uNmEMLL zErja*x`Mp3msH{7mWohTxtqLN`zUTmKsfDR{N3AmxDZ7aa;tg`hh(HBk{+ZHn|?F1Mz$ z8KQM?meFK=C6kaBY- z_clBUGn&Welh3mc)LT%-oKo&F9vvh=!!#-N6ge;7EVaqcFeW6pFRS`PVfpxaYK+N zVX?ba7HNo3m|<5yz+3s;#Uv@K(2w8iJ_fm$Ba6zBk>yO=B_Mfs8Y9GJLs>`=89WG( zo?%c&mxl_Mt^1bkd@Lj3+a6xprhG>6bf7BUDUdK5uu;fpWK+er?MWhM>JO{@)r(eh zs$`9=QvQ@AvQR1Ft2`FxZP-_-vIjGJ2QK!i)?foP*&hEE7G!IXwkpc|w^ek-2%*Va`o53D$%KGh+n1Y zS)%8sy0(hiF9wAv`?Xk+D)eeSM}3XUHUn25!pELSD#Rwx3B1$>OOu3$_qPDkBFjKiPm#wO$h~Dq4?rUGQOJylR?lwh^{&Akb8!2{> zJJ%+fqhU6Q2;vsPq1mJnd_;;8qTPpH1UHh0_fE?wJ(66MhjNIgwVH$B0Qrlao9-3* z&rmBY#hyhIaahFl7sRT*%2_JZvK!l?crzI)T}1_ISF>#Y7|G6r1U}KT^((ade`r_V zZ!b`6XMNR1=aCDw486(@hzubmGCO2nah|bp`)_t^?{h$n5zNIMs-L-DQSi{HG^AQ~ z-B4<07Dbwic6qz2Y6QXHjRwM^9saOqXw6Pu(RTai4{t|x1*f#AKkt%y#m&>!!CT+i zPttGszTYOo{)7tD9cD{^MH3yxe&58HVLPj%M*zu1)zu-@p0>jflhQ@eh%o%iD%Z&P z=Vp@yn#snJ@dmxdL@&bo)zh1=o{$xH!Kj|)8@D}l?vC|u$$XW6r}5c2x=XUXnIc^O zP|t;uQSwp%_81dAn3J5|>3>T#Fe^GR?<{mx5*~+(>_ezM* zup1yKR)+gmUJd@(8T>`{Vqf&dZ>kI^OktmS5PI576)vHJf#;wo){{kdj9-ui5GYa! z@FoIPzX(w!W7#odZ;HTRGQ<=xbR~6&wP{Go^97`{^hXi)B~=-9wmfUBF2#~2iQp-B zxUa&m$|(B!rq`We-?d?H@Cev?#4BrrGb!xhosrP2VRfky2{ui0Z5eF)<;PLScKMFE zQPcYz+Pl?4Q5>4P479IHe?GyEeU|*nfINg!I%|`AmW$Xy^<9Rwn>@$pEYCegP=a0Vc9Cp7p!bAYaA@E3*F@!qhZytX}6F>DIz4Z?M*6gvs009T;;nBaPRhw+xyNsrwEcOtV&9#ylWr$g+vRv<=&|{ne$n>>INM^-e#%?OEv^qjl|n@hCYT z&J0x>X_A>ekW*8bc0vp|Tk1Mi<$;UNYlmX(3|wb!Ff9mF*)`|R@wCm0-dIqdX0GFR zu7R5VOCc(V>w4>6XF(lLMnUp)q`5F~Ep_63%75o6 z^Icst4Y@@ejh**X1I#UF*4YI?*SS5lh#`G(HJGV>8fJWI|MNt>Qrb47}U zLlxm;(F{k9;f?^830qI?1#k0bN+#dDEiMOwH++NTZ(h(}`z_}&H{kX2Tgmv5XGLue zoh3AfnDOkLN7=LGuc6mI+*)Rc^<0u)VY=a2Wqp(QESU}zpnu}BQ|qxQfIND-3<;b+ zUA`qCON@8smitx$kP1Kc-&!8KE-)V$cI3Nd8sJE_7=qv+HIKn)SC$K&)&5mmW-g6$|uW4ZIoi(1&+(twiVx&k#t)%!hg9`uZ(TcYSX?yU;hnU+5pKb=mQ2 zmffNP70r6B(V7txgMDCwjVKAPd*A%G?cCHsUs)vH6jOg8KU!bPTl?~(#O>WzJbFVm z?Tf|WDiw%W#jtwn;CCZ$L$TQ#ih%PY05}n@w(2)9fY@}sUX@4wX$+L!y7t0k6)ojP zu8w{6W9Ue1kpA@xKhL|Dig~3O;`BYFtuFkcEtu8y?wJ7g%Sp89c(nF@fGsgfO)$LY zN@lfsjQx0I?%n&x6!+>U(?=;>f!42 zzYeYd!)3C13G1Hvq2f9baS267Zv6k$e<4>Q*9VgpS?@hQzRx=QV`4D!T;Lwh>QDUs z0HFy8>k~&JoNiZwKm?DJ1D}IiMh$P05)WCBDgS<=j?yYm z5DlBBaW9Uo6FV}@%eRW?f5MWHdS_u~h=#=VI|d1`+jU^%$H*Y`Ii23U`<(y!~(R1rvxs-=UX{#=Pt$!(~nnJ~CBsUX8|_`g^ERpSLflJuq`0}4rt3wamy2F>f!e?ywkPdojGv#Fz>NPsP;gbnR|YV_|$5oH`Tp%UHn7iZJ>)$X6U7hztDvV zBG>>?l&?Pa#5M%0Ar8yiX2GSlVe`ve@-HO`c;}37#_`T=fOeK5gDC&)-V{`{QPrIMZj+pjyKHCL+ zj1AOklE2c)Wvvyr_CC{9h)D3j66H|$B_v*cxNGuaQO_zv{a{7AUiKfx zMOHPja0`P5MN7{~UczAB4NR)<#cGRDa1mg$$EZ-6Q%qfw-} zw_vqDu?BD`#$qS-UgP3G%zC}3c~g~KqnZ8I=RC0xZz2|}R5I-BJ8ZoAtHbJ?0qVD2}lW$=1F(tUR| zy=mlUqEDT!y_dtIT{-OSd#0Ct^#5)tdZmXJtS`&;Ao5*sp0xH~(^a-vTw~$#;Wtw3 zWhB?|A>TgUO!if`+JwWOAkfq`o$qdpA;wVjUdCBPrJEa-UaH{G9`^!=P?styl@ z*1Z}U*>@g)5%1%B$a+~jogEYM*(+~I#7Z^E;~k?*!;`?Gaws84v!MfWRJfU6IH>4R zzDh=V{tK@@*wq>2-(z1Q-7_y^d|yR?i%W`&(&M4N~wgUF=fs`hP1iUNiW1*5_b;6fFN(v%JB+ST9;`POi6XpTEa0lF2wAY(V@vy>50RCabZ#6NNmV|dtH?t!^ zo&}|>Sh_UzIp`vfekI3bco>!>B7~55YTL6R^iieu>dRnhOC%#pl8+8wsCU{uzDaht zkLv%hp(*Q>zyJ%NndR+&Wh#SLNoZ6ZoeF80xMp}XA+MqQn%CIHgDpC-6$;8qXznc5 zA3Gt$u}Ei2W%2XHksGP{1@pzHFi%kzD(IzYev^|R6m-yy+hm} zoL9-iv&hU6*FZiC?&9{s#+5(j$XYVMT4}66P%;C0pQ8?a+fgqo1g&i~q0Qf5KnVCb zlOMBFW@s_2s-t$>a_+9pAu4{r@YY)^vKk*<24qr?qfHh22FXWX?aVUcp-nX}zptTb zq*YF>O^xVvUt`x#R;=Nbp;v2sO>eQyZE#LSBqzI7)!!U2xSnpc^n9yE(#fV;z_!8o zx}SCFnN7W(?GtO)Ev9CSZPSg#Dy3U)mF460TWZ^pS#xeR?U6Q5Yi*zUU-x%jKC|l? zvu(axBWl`PWKo9es=&niI3_vS6UgmaGLwQHO)t6-;&FBEw^lW%Ol5W4lz?{ikYyiSiR zWkA&v=QO{(4)N>af-cWLf6aPk&ZGQPFShs-EUmheYvUFvwJ2)tyHi+?)2$}^E8Es> zE*)wWdXrJXwyz;xeEV7+Z4aS(RWg1$)a~necR80? zS;FZ~-KjKulxa0cUtINTQ>cA~8cn12xQI>CAk#RX5&_I?L3u?C1v*%+Px|fr^{>|H zZ+ zm1l1xm!YsrF-(X9$Dmto!X_IG>tqz5Ejbz4c%8LnS}d^G_$`f|B$?E%_&*KzaZmY8 zeU0m|^d$fpFAG{#lk@o;zomRfskkc5>%MmjZlN8IIrCgQ`c#`Ac3Ek0ZW)@ZsQqJ- zZ@X2RD7>^vzb3EAjj@aeZWh0LmN&xdwz``ds)S}hg*DaO^8M@*i%j3tbnU#g8^T*+ zm|0I_BZ2j^O(`a}q;=i8PqQ0*x8(CX(zC&CP5}9Vo$C5hcyHs6TRsWT7kPfY8)wz; z3B1O>#QHd**B+A;cB_KQ$OAvEO>zq?(Cz=;78uqRb>Y9y=z;jI0vn5n{^Rie@5;yM z-ZxL1_i+ratJGm9gOHiS+X@%U`(Fr#|DoQ^!?Hc&XoM!vDBDgEbzZP?_5|yjIU?OdpgWf zxA}wLRbS-860twP00~cr0yuzp)1<+z&kQgIIHX$rEm88si|LeCDwXi!xABWZ{}+FR zGt?akYOK-#BL+-O)ryGy&CATE2#6anr-x%W5;3+;l(E{dLobbEDu8x3&(Sf~GW^8} zdmTGRj_e-jRTRFp9P_7GlX{n#^jm|kX((%ghB+0ZsW>E7o+j`b!z`smRXs%QjpsiH z;2bXw8VRD*Daw&hA7S{_T@6XG5pJ;&Iu3&AM-6#ufHMec860b62o>+wV$jiKT55%J zjPUkj1R1k9mWF`D;ov?=+LRH537)=*prbe<%K6HWE`A_Wvo&t;U$ zr5jHYdMT`m6=_m77E7|aKSa(kdj5HsZvlfp(NsBaF=5m+6C2V})U*&wa$6cTJ0Hb( zr)^BpxN;IyQ-(u!&;duwTr0^aK~bkrCnYOHO5t~H(zETZexM0lz^*!)Rq zAi0T~z2!xFlR9gh3{1B}s9517_C*r({=)d1kGcZ%8uLQz76gC>6R#u&;pxemCFPn5@I!(1Sk>)M5Z=FcN0@PW$^A3k{kv&p@}#X10DxT$d4h>JRdB6bRse}m7O>l|Jtykb3D@rETIS(BVsuX;z)@chH>YH z?5c*J%O|p+MooN4bM6L+a>J4m`bKIa{ZUxb(p2Lvb29a012vE(_A0vxCkeaE6ysOs zjCxI`UVnIn_nBXDr+Y?`F(F=Syd>}fK}wi&6U1{4*IIJamh{3mt7Ckv>7 zzE0zQYWmj;CWVZzMyX$3xx`Yv3^JewGZT}oO_NQEiEsK}WjRcjx|j@ym^AB5MsQ5! z@+HmiB^Icf6x&P@@sqPUCNIy&mn;lxg5E6I7oEXrk)ndoyQ4Y1J|Dp2K)i zXX-WM8|qylohY%r1F8Lk#;HmnNCO~M0M+v`PEW+k>ck0t82|g4^fm_if>K3}HW*~X z0tH9o1rZ<{Orm0~x9HmJkx$zcuI3cx>C>_sW zst8CBa4S!&ga@o>r)K~MYnJO!s+u|cN!)~qH9}}!f(BscpB189P@=I$qpf&NXE-=# zmnP=bm>3a0^9r_*Mk?T51|G1ghVL%lVz=8A0UPMe(ex%I^ zc<(c-?*`B2Q%V=6x5gztx_9wj?82a0)&_Gg)7iE8PdGw+6*;x}z8jmSn3>5DLF34u zRA%FF=#F=YgP9?ML7Pge@FO zzbXEQ_~A`CeG+H&MNhK!a$2(Mo5Gil=+h6R47Cq`S)6clj%DIWY!wbHZ6C72<3uDs zOu3jwkQuk7n&Qeol?{A2n)rY-b*OdykcmP>3^>smIx%K{9xeaObWbKr^8IvpMh-tb z!quec;-kXQ=d8rf74aVjVQ;6F?9!Cq{sP;7iyJ=@6M|%xyloqFY{-o>D8hNXpYFJ^*Q;yx)i^{8vmeb-AMpR;6T z*7Dl;WNy%E?&;HODv=z8!YiJW>|${^#l2#{!gZN{nO5K$pX3*%Bw`I_MLfIsV@>fN z@uXMN*KjOuln>l#>4^eGtF8^JR4b)l_&JGPY=n3Z=Co^w8}3IJE5OR?MvezXUh;w3 zHL|h1rxvbmmo0D&LKC*?VJ>g=8teUWXyrcHzeC(_wfQpZAO98RH$STl@*7=}c7;k+ zt4OCveUs%d6xiQN!(8 zW-G^$WDT;_H$3rekb0%D+M6V{*{qp5s+~GVk-A^eg7ld+N&+B_)@*6zTJ5n+uO}ZJ z$#cB=06QPS$EGmTZ(g_=eggrgbfD7OuFCLXx?AOjjsV=uP0{>YEtay{LqN#&+eX#| zpJ5=%<&KBN3^eHH3ndBf@H^{v53bMre&p(wY-F~2cTPY@Z$q!WS_J7G8R<=$^uQS2 z$eOt!we}5g_R?VXPWPz|x8s%1tMe5Q#HS&nz?&BR-%ajZcTi6Z{wCnYTElNzCKfoZ z%V7WAS-8_FIn(Y*mYZ14jfR3E;isN}-OP(7C*YD5%n21Kto7}_<9qRZtLUe1*W6a+ zwvVp0xgNWHp0aNiW}8%L<@Y#nJH7o$mmlb!CQi|!k+&XF_uxrmo@hhfmnQ;=Pv7{p z-FVVm>sO83{zLu#TZ(?J=XT0mYtfyZwle<_p8trmgsplbycX8K?}qT;(N0slfB(CD z0?B{0R(SZ$PRCEX@#LkADE%XoO9La|)nLHuHv!WtyXB#~>%V;}$$g(O3xAqw+G%%r zDBe)?vT1>~dA_+}Yf8KZDyy3EBdh(^JVB;<_|~d)=W^hWN83L}(|#ywi_nQmEI)X% z_^p0TKzMyHU`bxMGtXu6=UUnv{z8b1w*2W8uW8(NpupCovE$EV+@|eR|h{55eTuH`%cv=X{aU#$74ZIL9xB32h!#;bu ziE8-O;Z1jO{Y2Jl`^?;TcGQAJ=nf?FlaW2^_C9&S6nC-^2N!#Lnwh`T*M2RQ|28iC zIq}W2>YI@23@FSg9t@NHA|SkfqeGyjUOXJHvMEGmzo!-R1Yn0=_9ifd&m9{Q}ecXf?5_v ztxt3?3vqkt?!Zj}6-Sxpi`L!7!gy|ncv7QMefF2EmQ(Lny;)H`9So7A)!^GX$BA4M zar%mJvgJ?)7%=<0r>rhA!}@gcmD+svFRKHbG^YRZIAD=I;_($ZJVNa~JL8h|X$sf?wdJ22BX9|%vs;8}9d$3`wW{+nLVXxt8U)lKCE9(J*wOaL;zaG+&FpRcn zA)e9V9H5iInv?&}u3pJ9CZ_@An?IqU_+{iNd*C?>vM1F#H=g#hs#oJp)fG)s_+ zIK;phqz6bk12*kz5-*{%b|Yg6jpVYaWGzpuxD~|v zfl`zHvji^%BnvDao{(O0?}K*K^n4#R1qqJmGoAU19*A4VP#peDUd=*oyo<`^iHhF@ zU!wp{ZjdN;`{O7~{~7B)wfafTtOJc#i2H*JpSnhk-^3)LYDGX`9>;jS*8>3Cw*SS4 z?SJR)89i9=bFd7q>#@zX5(<<>TrZH6-x#l zhFV{<{;>Gu_N&alOVxC7CejrPu;Unj&Y0#{uP!|za5v7Ceo)hp0MCWk*at%u-AUSb z$^;t0*nmR>^(Wy?cOV0lKe*AO1__g{>P;SdT%}bdq8|Y)F{xz465zx$5w=# zA8&que&xNk(D+(V_)v@E#h|Sd*_iw-pYFcGTYewyv~J#^1%=JH#W9|3xZ6-tta*Hk z$#(>#83yreWR>-ZxSu@@+?Pv^HIx*a9$K5e&sk4b{f9XVZGmfKctWhUB+H-}jjc%x zcY6vSOepDOCi_3T^NGnjf899(K|wz^vCR2ZIZRd@{&D=2EWxf1ZdILO^UW;7vrBE5 zU?3j)X5L|}l7c!Ibk+TE-9FM0Gbl`(GN@tV7*#LyFe-$#rtEUZouQ_iR9^hC1oR&+ z)q{bmsi8&=SEn6nD(6-g;*|0UOYWflp*D!bx<{yOUxDXH(24Maa`NFAaD_h{pNV+w z<`}jr+v(`;R$FV=N=*EJW~R>8^5>0I|1vBXF9~+NVly*nBSYF^G+$u}`JZlkkbB^% z;$7j`Mc0%G|7@Y%@P!9je@X0zEN&F%>$KzpSRAwk;}7SNg&z73N$_1FY&JEZ<(vny zJ8jym_GJM8d-pH5WEyU$gpR8FC7!-yS;+m+Im?@btiHLySt z+(*!u;@Tv6aLOPXAC8Z1Fxe3G3e8fX&n6&a<_$EALf&y24@>(--L zRdt~)*_>Qa1QG&#iLte=eZ=xn>R?NxfS1%nh{{nMq!W+QuNe}1y^jcLx?8NpAf!0C z499cDKO`AoxzX}{z#m6^_~UquscoUQKqPG4PWp)$(J4dBzAiOZL+{Cgs- za>IB!;-hpv$ciX>>7JIXm{ck|4%;2g1w**d@s9rr)4}5xPD`EbQ#_b%?*EysO6}Gw=>8^i~ zoPN6mSPcJs@itM$q(y5MBzznTNd;l!Bi{PbTz34>6O0w8Ql#9NGfqr*I&rTNAV zkmgW|E3`mp@CqE&%xA-@n=Z&!wid^sFhKp9<4DCcKC0?h7Uhd|M+iXfPKF1KfJfsk zBAgidw`t&AUt#Lal?d*d*CNE$MA<;V9C*yDZFH=nI_Jnuju|i#T!$IwunCj&!-skH z{ezM;!G`GZf%mYKfLSg3em&`C^uZ$KKellb#guy6O2!2BAN1D=l!Y+- ze;4Ij)v`}4QoO?l!E8Q^Sk%hQN!v6nUrwP$MiqY;1r41-PTR%In>lh_fJM+WpVMGF z*NedHRiM0YEWbk@^bFmg@O3|Kq+~Jw{H_L%-JXWLOQ*5O6>^1uQqC7nPiKZ(9!2`> zZ7qGFAo=L{s>c57?Dmj7x#@W8z**?`+X7#TMngLWx0dPat0b51S=En2`O3au60baQ zdyKdaS$VH{DH<%2Rr`?x%VSgD!!fGg?#{QKEv}f&;Q}82;8-G0iMYhJPQlv$*V!e~zdW>TJ6!MeJ?;IX z^4k4SxRX#XnczRas)kDK?6Nhu?_~rpH`=aM)s+q^mrJTmn@+AtZFQRp zUu7!!lCYo4Yqmc#%1%%ZbSH~f7apL{=0uaI%ix-hqIfcW|83fP@2rlprfqu#Y2FCj zRXeHW#*5(wQPJ5`5l=8F+B^>-f$(Tc;2Hh@XB4bzCvh4tN-r8DURJMNC)K?I z3E*O*8n}Oh2*8*QAk6(kcJhbj#t9`m_qhpRd}-5ym{bOd;keI;4U#qYPgMsXAH%hF z`5mqydBJi+V7bf2A@`a9MX&iL?2ZFTv6B4k_N9h;dC&%t23&ExG=dw) z7LGqhGjrT=Y*#T<#<7tM7!ub(HeAoKLYTL;h{!WDz~Ev;#}$vb$EyQWR$tDWR}f5y zyj|u1NB$spGZPtc;PU2Q?Ev7?)w$qVyjQCzLxz~vdFEw@Xih-F60xWEhXe!Fg`%n$ z1=9qasssb8gi_yV!0-qLu<+V|l|<}$<78Le7(4zHZE@hfmySO+f2|!uB?nVbGaarpUK(^=$iEm2*nW5Z%;9 zHI-#|$ z0>TE|IMW)-mbZ+s|B5_xs7Xy$9T!Cy>%b! zx6x&rBYVqSSL+giUbH$d&z5z&>#gUt`j%MRF;~W*`CBWycH6G@-wX{yYD?d9+3c>D zwH4SS?>Mr3bmY6^B>K@w>W;ILV91ex^?9xO=NgC1UFQ(S-efGJ!%hD6S~sQIXc?&c z1DDU?IR284&TN{VFVS9HP!GXGuh$vg+qLewnLcEI_h5~$6SL1cxt|l-iwSfBo7cGb zXu##BOVScl-$q+Wp>NzlYhNCk47RTcnA>qB1hHw}aT>o9A{Y`I9|9i#kG`8u2Eq^U zCxbcBtX;|VT7Zz&B2wo7kB<2m0j7?+_g{cFhKvd3`DE85AIR(jtJ*LIlVXC`wb={? zFaP-XZBXjzMAX@*Xs0v}BlqiDl+hQTJS{E}(FW~!_h2q)c!`_Fe*s>VEN?ldl&gE# zFyX{AXAQz$c-^OaV8fVgtAW8ilK_L@)_6D+C%piU*kOab?r zgd(Iow9y!5_gLX%P=}mPvccHBxUPYu)v)jRkr|Y( z-pE2-c+Ue!7kR*>nGxHN%vF_6$}P2Q(4uH6i%PD%*v|xizRSy-BS==e{w8pJ=O*}$ zm7L2Bt(w{<5E};1pa7n?{j_c+8VXJe)w+3KtugOjJk1)0HT^XxXkf)>fWIv*`*{`f{gz&!PVqTC&oK37Z5?kXho+mPUG;A}4!Lw>H0r~Bo@N5-8f610 zpa{>27cN?T7x-9xlg6d*Rr493~O*X8`>thqA_r zQDz%j6C=o>p4ON2LETs5h0sdV6`i1gAUmSii&*Y(#9{~xs* zi?_b|v1@753HL9x8!IZM4kp=@s@o=hZh!Jgi)JtNO~mVOoVNHXiBwnEhx4~7$5nL_ ziz)vlb`L&3KJkPyhk^EBOZZuzySBa`x#EAuw)Aig(Kr~GY{qPDe*IS3LPp=11{vwDC@JHgM>O1%lJxp=&UQbS(`d6#V|*xCi`x$>C1y@wBLxDD;rJ z@V76f@tS{pO&9`>jjp~nvRzU08-in*_O`J_ew3w8R#cB*@FG7Lo;=RK$@>VK-3r|G z(=czl3YKJU@g$-)tK4b#*{ z9mjB28`|-HPw&d_x1OD^y%rKOjmNLPDhxF2Xkqy-#hf61yMrvbt-6e}D*dkVZ&;DS zNa)1z6JhJe3@|bI(LCYt;#g^HJWpk+?0mb@kMHElW9|2$Dp@cr^O(|?4zai) z+>Z{{Xp&BSL&_^BHZp?_O~`-}JJm{ow)8x?%ruo+mP}RlkM$SHnS|uj*5t6SI<7#F z>N_dJc|+Ogj;A~}mgzsR!graj>VWme80YmQRHZ=%KOVcJ>c|h7Y8>~3oE#jCYHW3q zK~J?YGJ55y6=XzKZdoo3EemP;M-F3D%F=of@wjWFYST#?ah;9ndW|l!=1HgS6T#*h zcP(3jRH&aGfvLrv^_Pt92;UVADye~Bv!TUwpBw1JzU4kJ8Cu!Yr%{I;anP9C`I>q_ z!_N(YGWtM&Blme@X$>Op9stQWgJmT|x_cl0tiX6Ww>{roSvpJDXBa6ifTx`W?M`}xVk z6+&I&aN#Xe=JW1{G&k&NLcOZxk;$R{`ZUAhbe@moJQ%VgR^`nK&OYF#0*mFAfXTpj zbADyTccS5BoKQb$#&g>?x`R-SnlsN=KSiHqUQEdUG7gJ+)D7^<$DLS40ywi}NnP3b zy5X~uliCHhlaQJY9(JgQ*5WIj=YktaW&hA=c`)2{n8kX}R`io=o{wrX=05bou{V2Y zr<{r5QE=P5DlrRB%!T1w2Gg%X1V07~*9(HzY{_=MX7~jiE*!9xsj0un&pXuL%2VT1 zs?;B-=)SmbYp&(9(42LV#GY0X5nruARwd17p_;epy~%5R$zqsU_MKZ!l4C^+EA`EE z3Z_e_lzTwG%`?tnzs&V^?-82wQ0E?N z5$iZapVMqWu4MF`*SgMw|CqJ0>CsU4M{AimXGuK|WXg{~t)NGe@bTV|zrOIS2;9gg zL5hVQ?iALFhmC>D_x<#{v_`DjB`*IVTg_fmb)qbuDr_xag^@EC#cB3w`7fJ@7cWHP z=F*n$N~)#@M{1z^-pU^~1l)&ak>z;kXsPt2fnp}BRp+Ly*7}!{##JV>DBrR(Ih}Wp z{}zepDa1drU10we#H%p%>heAJuee#u_@i*AHLKLq$nb+mjU|-_SFGmfmnNd)bvsy` zETXPA7P&C1zT+>>d8{^A7?nwRxU`}CDOzoVdw99!Z$x_Jd$Hxuq-*lYlPrVpB0oB> z&wlu;T7k}$|5T?|zietWk;1hvJ2Y`QNnoKm;yC^hfmwF!8p&B35i1Fu0|d)jyH`ra z8*JZ4>Wf`_VCh$#Z>38pS?=H@LD;C;P9MTI&k+&USf$L$o~a+ z*4Y4$V+|^!#C+0=g-9vr*dloFf^eSb8D0SCs+S+>f=3%CYvK7@t~MB?@R}HuDx1)W zhe_a5C|Re7piv6CIL7L$FVYn|1WjuV6#boe4lSr+ptO86Jj22_vOT9{{EzpD!|Cjb z=6%ok#mMFw*tRfl}}DqpDdyIH9;S)cNH_ValF^Ugc4xustr{-BE- zTP<;Y*wdM+hFVY8CqlCt?#>-J6%mI09y@wYee=mfw)LqtA{^D}rYbQeq0VJCM-E`To zZ4BKFlKZ|eR)73M=2gAMMzD6d&gg79UzzprFJI^1CNusZy|c|!C1b70-G?=9VTPMnm2HD*9TL?rj!?>oqqm_} zLDqlg?}Y7^_iR*R=gtf4A|@G?6Ox>*6&;on6c!nT2Oi;7G69cO-~PU*)LV=A?=KTQ^8XK-#VP< zRNX8+@*Z9;_HFpo+w4q7{Bu+MF|`}Bo=9USQvXWN3DQ7vR0d@zyBvfvQmntu9hvWP zi0(UiAI(krHEh#=$-$EPx&Qfdy7BNI(%*kJqD~;20HqZM!Uey4_;uKVUY2tW8})9E z%{_R2QY(=$%H^tLR5nKtaHmhr3TZO8$(iF2tq*3KpAsdS{ zuSFr!DerHdq8s|CLg?ezXl|2_k`GF}L}Ui!f8f}+(pFwaWQE&qvG5nEQU!jG-B>03 zQn6BFeJ&KWKUlTyovd@N`fv7eYv_;ySyhu;xbQ(xaas396f(ckfRa1HT?<2Il7SPi zVYho0ceM^jqH-XbJ(s~GnbK^-E~dGuo_(_!82lQoe{L* zYC@L}{}DQL<)I{40i_cs zNEZXiE+V>FSTVMw{zz7q%vDtvXfnxiiob5KO(RCY1$WKB@`V{7aSd5kRn}x^hfPM3 zyww0N8l0fvuO575cSt`RN%<0nM=_5y>X><&=BL)euUid|nmSuF4}Pf==54$UA(}mu z0yluN#q2nL&-?K*2$){+)MH@7n>?cxcv!pVu6xU7zJe*0>2!+~A~J++pH1HT-#oo- z?SJ>{f!wukUEQE(8sV2U{P5321S}xtCKx}mym;2d!`r~|BKvX%5e&J89Rzh^P%PRt(vAIqC2Ay&^k8s~R3M;7XS)_2sdhas~#?(+bQUKH}0sWlKj#Oq=5acr+ zL^&P|F$j^$_nCuUW~h*SOIS8@Cs%=0a>^hIJQK^;k0L@}W?K!~2-xEtG5H_Gxo_M3 zQV3=2&3p(E#o(sUHP4&NutjufOnuVg%tDnA$maq;w~qE2*a@*JRBqVNMpatyQq zqsu{an#6tp&FTGi+G3K9WF|Plm!n8Smv0#;@>{pT8?=5=BN1P{>77=!dl+;ugcOKB zi2A28mTQ3+bKT$3d&lssJ+2nXJTm}`#0)aU3i@dMVp|%F>M-2Fz$zH6-WM*`w{5(b zij0e2erOrcF!}hakgyQFma*=Lvt3}`Lyq0bGFh!#rDJzrhulN4z@92PigM!B1?1_0 z%c{n%oQ|SOO|If(TZa*CzM=rnCUn_-Q0xVC6LJ1W!(YGhPR%2zkH|8FmWwy`w<-}C zK|y5yMvy!{UYnQG1%#R~ak4X&Fb#6u$lOV#0i4S@*LlvJb4>VoB z@mI?}8PbYHQ75bJY2LUfKX5?4wbpp(CU7(t8m-iMLp8wq`frK=E7WO6Uvt>@46xLH zeE#kq()o4b_`~)x`?PASM*oF62k<5pAJ%-08pL==&vNLS>*}(jWqavq(!iC+1bv^? z@q>lz6bN*dm5e&W*21+xrXOv_rc111ZjdF}?eVPp0*prB3qE7<=R~s_9(q8_VX+Rx zoGmoMGaQ9~Y))#O7j5-L!YM|{eDSZyif6oy`KT4J3?EY<1rWvxI)V1qf1b}!_rq!G zKm8Lmu^3D9Q6&XfAeybYfiN+oL1RT6fuWTWy^~G11*iXEO#j1=#%pp{E(=f=0mX_% zW)kSmvW12m;IGN@m=FkV1d>1C%|+|3j3029_9?Ow?yiYco<&_pFo>igrEdTMR~T*} z7|l!=Zc>{&L>wDV<7R4== zb0OA3#6QWiEc6Mq4ylZ)`>dc5rhuHPpf=rSk_mtIBVQl{N)Y&=fEXx zQ#wdx6vf`Ll}h7kpIydD1o8s}`cM)eIe0Sh!0am-g|RdgVnEmChxLGaMtGRVM_M3Z zCEkQ3ln-_cFpzC6hdGfSJ20AxgPvn9^R+a_v4GZqn4Uv`%pIXa!p$)NEqcr+-45nD zrf;AXlr$ChmE!k%g^q~jH={wbw8KhqLb~ljyKRDU?ffR&{2GC12oJ5GBf~d9*@i%` zRY~8fArccPq&IgIre0~g39nD$I4Al7pOE9ZJgufJ(eSG zB5*Nusm*QTNFhqhwez`aaqYa-Edt-$1sU^J?jWzhwy$6ZMcZ;wl_|{OgCs)!2R8DS z!mD{gD<%RAqSEDP>FIW9Y!xk&HUl8cwOlJ(UIP{0q6@F0sng2SK?x7cM%s6XWg(-b z^5j2|)8XkNXAmRyzMS=+0LI+%omVoU>fFC2xo>ZAMeqQ04j{`I7@nU81wa=8`XWjTuI&@J4-7x|+ow@F( zctTJ|bd*f=ABO0}ACc)DG&$06YB!|8<_(jFKO#*=|c!$1>0=4z}*svmDkF-#JyS+UA$TA5NA=>=zSz_j_cKB7MKvQ?i`}y}K5A=T;AMy}(v-)CpBhcn^DC(C zzy~Whb@>L1`qgccE@wT1O_^#3L%heCEN;qLOLVuGFWzmNa24tfwD?4J;h-k+E-*6f zk1_ay>Pyqqrhg1SVvXtv#_5jh&(;v9Aj9rp)y3OSo!af??#LE;Ps#(kOX{qTp$vC!5 zOtu}bWBvtqd2d26njuW62a*C|8Hl;d7eEfNVhSLtqRVr6j6hNBl_DYYu*5cz_(-{7 za2P&`)LzV`5bINv;FyG_cI}|a5a>B`Iu!t9n0oTZ#R6H-Pgr7$ zz3$hJ^HI6o$BI9DrVy)txwPf{YUxY#u72d#aY0*_#NSs0WQyWc6$E1C-02vDL&XJiVWRO`~ICp z*1OMAaS+YNhXb}p6ac03JPqq^6>)1q@wi|*{C3t*ve*E!vY0m$K=Kwk$d{4kt7z=y z{jLh!$}WB-W5fqdC(gy@zwdb!2F@X}F7wdEn=oYDn5d{_&DXRpc2tx`>_03Hf5;v5 zV3;pr-Yw$FEW@-Ljs2F~@Sy5T@d;5NQh7SE7IkyC@a7k0^fw;fTAuW9r%4^3+Mecx zLBfLQ4%89^=8J*t@wl__@^29qg4obuN@M0#Fys~^1}os_KXk{2hGi2*7oU9h3EaRC zs>4GI@J=K?Z;-uH=XFsRNA@VgM*QVP!_#NECg3{MVA5o|0tC}s+lZ01naEXWyy@6j zYGcWRhcs+1dv;PV0hE@N8!~5~ykncmS9LQnN^3&%#(4_V({omyqy<~H$gY*TfO|su zC5`25?mbfO!8}bS;FeP*K)Cl2_BVX3?Xlr1=k$fYuS3(L=YS4-z3XL%uebSA5c1-p zWxvSo9#Mcb1`oT$d}mR@?{%-q7=b}1rvG79xyHvO znJWT;+eZ@k=iJK7d73XF_?N#~1vr#t*AHIA+mFeT6% z#o}*o-Et~IY>NR?Jl7v^pvzuxhnn6}*&?SSz!Z30gn4hSA3ADoGP=O%(QgMVs%UMp z$6whBw3|V>h+}QG(Hgb-hbRAwct(w|Wap^1? z#)8*;*(Zj}ChTI7Y_=07<{=K|7?SKKA1Yck5YL*r9Fk^ zOZ3^EHM=%NMZ$3m&>e zcU^YrM#`G8EQ}a^MLK{{hX{T0vL6 z_!Jh&{oqTV+T6Pj4G{dLo=bv8kRHpbHI&!5>}r4FdU#mUJWnzCJ)0D{Qo&~8bg2J) zQITEvn!`b;I_eJoM@t^9edzb^n7dED2Y-EeQ~mvcF8+sK|Ne~+U1oeo8?D{^>Z{Y3 zA28d{pNuW0o8P(df;-=S$!4DKPet0R71u=^*;f6B+wGKCpLbi&I6Qy4y#u*c5)-`v zdHF5S=m4B6Tep zS@I#(AO<5#CZ$)|`oA{4wBtfbOqnoQHdw22P)&+VDu@N()4Du@mXs-?=#V7}cSZl- z94hJm22pGOe?im-Q!Rr0DSuJ}d1BOMz#QShSfNCmM=+D;oP(AK4d~-yANwXT)K zs&ga?N|p^{5S&@C6e<^^q#N0UZwBm)3ck}}ZTM&a5z3;2I{X_=_0cWW;&gb!kA&K| zhXG^ScqGAg2i;24FM>hAo%?}!O_4DWd@3LO$?LyY*&uwE&)Re4XgZ(2A--kr+qexH zvb+5@i{(EB(cTLA^?h`dT%k0?=hlz@IQnZ*WpOz)2wO=#7^p}BOXemcf7|c;>6wi; zTe=%E0)EL{>Qdq>*{!7CV>W4XXmFL@Akt>eFi63Fa1JMEEyxD|wl~j>6kWu3RkU+vbF|vtTL{>L+E8gLIPpeDbjj5Vt^%-4lJ3u#eQJ}D5`PpXp z0BiDQHmmQ*)}{MbGs{|lJ=?}ypFyC>%Oqx2#6)K5nQn!B?twfET2VA6L}Y53Wjdt5 zEX%R4!&zO;S`kDBA7QA7Rr(VTQxOSW8K$Z@(|ig87;Lk$iMOkGR!gW>W~PZ}>cTO( zP1J=iRrIBdaTCOqI0}K3Up&IP`a8O!K%0lD2I3{19&HV5JA8MlMVid47r4YKp9s}G z+qQc0QdhJRWKjAA)0_Im%YXz4PDOFtQ0XCNRFn+m-M~<4=9}n<4Ck8}>uMHQSa}Q= z+&tetN$!#c4N{2aOANm9316Gl6v@~c8W2;y@2bvKi$(^HXx>WvcM^QcF~Jjq?i@x65VM zH|WgOU$b}b{uFa?=8;=gcs(#G96lidM;6wb{CIeq9{22RN}7@EzG9F68w2BWwE8;T<)AlI^m5Q!0#2(gAv6|e z2Vh)t-DzE7Q1@>(xo9h|ZqXYdtBZ!6*3U-BrMvxlbtM;pAwkc-Fy9HDnb5|&en8NAGjZoq$R_Tj42o_ zBgRB{7;ljM<;#9OiR~0ccrUYrvkf> zl$_G_N|U2+qW&TrVmYjM>BA*7MVoWJOw_CW9G#B3`0)^+ZNQN0&BQWwmPh@$$ph0G ziM`xPNV6@%3hB+J+MHCeOg3oAkIiNVqAFj-3u$EO-f-1oc$mAxB%DUcfg4b~6 zEjrwA_jZ5#yO(r0a;L|a{lD$``vaSd#+x$^!N{c+^Rw2JT3t%vn9&yVEykL7Ky>kN zbUe_a#UU(Scn=dBQ{#xNex~tz-M=%-A*(C8)klGvdMVfCxHHdU%SqA2=IOo9Z8Gnk$M_Q6)S`MmW89|SIPVTOr~%|0S`nO2C4T&p&qK% zwuW2;YO}iKAdvrp!_k zoa{OrkFOEvY7?mX;!3@;pa43%yu4qY&cXiwa>1>Y?$K=GtNhvOcV@Ex6W@(QBv2n@ ze246@3$@bCHTU)H$J9i;_jJN__x{aUMu}@ zT6zC5$~;c}Z4F7Tp7#lRn$YTpk7TwlsT{p*#qNIqxd*kdM;!!s_3lQ!3$i1hF)&XdAu4uAXll)2(> zLHE5>XH`Pai#@7-Jl4Op?bIFQB$*Ll)XVN2INdV>fd{*OKqDQVz2Y|dc-qZxe>BYh zeC#ftTb}>g7RDDMF^^qJlELq{jFnA4M1{-PCL9{O_%w0Oup$q}!T< zw*7i=xeS+~la)Qf>3J3tOuN$_c&HB6!Bf6Szw-+utajjfBcfg5f{zav&UoFBt$$Mt z7`+|!Lozn58z9vtmNq--%J1Hr*9MBt_|C<=gLgyV7U*JWa& zA#KqD!ck#Iv62dLgW9q4Nq9xx1gQq07oYHgh?prMJbEcWY$^7a6MmtaJpqV5e#hj% z0@&yz@aM$3x<^$Ef=HKXCt3XK(1f@0NrIqQz9Kuyv&54(Ne)YpU?Na00l5K>2pCBK z5lm%SfMp@Js0LK5j(9;>%8jsCg|?L1JXD=UQk7$}bY*h-UUHjIYVlqIhkAa(mxhdhT-uOP9-MuziRMqa7Vr@R2is`6?c!SN=7;806E5B zP&QD3VNDcHoPDF)@X7M4h3ofV)1X>yQCTuK|C_ijBs~Jrset;wnpU_B+pzO}yaJpJ zPi1RGmQ#}@Sedz>l_#uUpV*?0LmePgYZy$$_GxQ@Ek$M zT;bw;Wkr;U2;#SU_WALHPAh9ARsc*{=m27dY~{ZeDpVTC;TmNMEiM$q7S_GZzcI?I z)0%tb{Pu4vd>^EUQYVl0D6@4bQn5HEOfg&4LM1^Ls=67MP6R1$#w9J=XykkmfE!%%C?ewFBjk2 z*WDViH@7qmOmNMsG5xR2JFMZtho_=Kke|(G%WQ#zHo=j2DCrhaHl1K8Wnq04PZgJ4 znT40G-ZK4%m5`&0%KsJFxfl5+u##1Yf}Kt45}@U4gbO!S-q-}Q%fXxdv#ST9LH=Z= zAaIF4V2g(-@sgXv0cnRMlxS7ok4msjF~o#G?s;8-vYJJ-8Zrx%0sKV|V*VrdZpIiZ z!6`%$mB?z*vC3Xu=Z&PxkDlA3L&W_;6eWiIvm+9Up=1H#-7MqpDZw?1P-;{)>YjCC zV|Bisw{)A}25ePSjt%LDb=B^b7We90o)@B(QuL_^hN&o-Cb+y_gTjY~Y^8GX&muU_ z8XdjLVyY@5&lEDzI@1fhc}bO+UbL%HBYO!+tE%Z1|K}@dB`8NWz&X`}kct{msyos_ zF*2csn?jh6MBV(GTYfw$_K5WSd_}-BO(^w|0;;}uNxAoPnl$18B!*0S?C~5Mu)_v? zyyr5hgrfOOfZszEJ$OPr_87DY#=`+8xbHU070Kj*6!${% z5Ge(qxiSM3Wn|=M9po~H6nxpJ%csg(iOv=tF_v59+^bCo#dZRZ;F9_%8;loUX$+M~ z{t0$cfZOyP*L>D8nRu4r^B9e{8qDmwne-@d0a=OR?ZiRskwccAUdQbCVyVs@rh z71c_QSYEr>m*?vxE^DUG`9Lr7-*^NO%O8FzpJ1;b-s+V>w4rXbbtZW{qwaX(m4PNu z=41N+EnTp(slTi1VS;I9jcI4B*uImn((KhfWG__?d4fb&iT@pKu`7pSB6qiysb*h} zEcY%o5iT9zhEB4HZE?~fpHR_2C_j?--5@B+iTmUxTm3AH4nPr2uv1h}bM5W#8Wb&= z>pvbxenv)8G+)+g;DhZEw^nSqtoXL1`Yjg*6)Ue6gjCitA_wu+1LeV|+mhkA!qp8|6;xh!P>a_;678-^Je7<_(F}iQ7YQg4nW_YUD+Oz$Gx_j2nCm+0w+R4RZxKj{Q};vH{?eckDC3| zU%l9dN87$`(;@1*5XDr~sQ-wQeiP9pgZ28aga0t*7_*5J*{+Dcsh$98*H|i5;HkF# zKgY?=$Ey+yNGOFhSm2@elY=1>n#_S6qc5_ppKfJ7{-om^?xPf|Ry%}}1 zra;Xplg~RpPJ<1wxvtbUU9vsBCXQ2zpHM8HgyUw(CMO^{Ged#1@?NtvlOPZD{MMgH z3DQ?d*kqNZ57PK?sf^^zefdT2!I4(e#oMYg3bSuv6J;RGTNt0FxeMHup&pVkiLraP z`y!%04EErVLgkoC@;oM3rj>YV`oz(mH4Te!SHDWs`Ph^P7ii zaw`uz0RoQ-q(HwHw{p*ArD1Yq?nJLub+yyZFtbX%+ivyt*7Apjhh&dlKIdHH2!sY3 zo9v<2&ehjOzUpswu1)=2E6rb}<$pgjxq5Ehx*w4_)3=slOcC4rp84(j4che`yY-Jg z`U_u0_P?$z8n*6vWq#t^I9A;_vD-L{+&F%}{)%IToLbpExF@&MQ_F@b{jeh+CretD z@q_wq=EZLcIx@p5bm_j`5Otl;L~okQnzPngJfiHplYnB$L~*RQKSh&S5On|P6XboO zexpv^r9k)Ew;PWZw_o5sNWV2L?cBa6vkj8nb}87FuKWP{Jx(d$`my)k@8u2APM6hP zk<0nYyeoX+tyI5)!M{|v8=u-VDZ*{DHzA;1l+><8)Gp}Irma@kj_qrDB?$I$ViR|1NxOv<0Lz&BVS$sK9 zX7zb{bLqlPl;(blx+^DU5 zx{p-65P4&=X-yz#le{#*k=3%=_S>%3^N-J-d=xdEK+JB$97yC`;1DC$mgKH^MpQUrYp|9#^ztrvE+BtanRAg_T z6!dLwVSgU_nfAlCeB9>>@ZmqW!<`Bg_@V9-x)oizwbnd`;Gf}@^7ry?@-&|9c+o9S zYeKDg6sQn>?~D$*e35poN1P9*wNgt#_^-o8C;>kt$M+-2htuNMQNiEF(D@;JS3N^# znEZZ*stN_w3Wb>oA&ftGIx>XWy9Ekshm6R1JJh2Rget0ggA9KLl`^0Dle*nw-i7B0 z9YJ{SMY_4OGyAs-K9!LS5H}5VZt*tg_w=hji!BYu$9Z^#o*LKtBHnp~7NW8%z*#`O zZQEFExBC&G1nr9;--{ilyAN*rQ#}Y}IQp?c{+sz> zAh9JNIq{CowVz#Hr#{+Y_cnZO-OfM~{+#l^G(&#{X=M!FIO)p^p=A2~yhV@t`|7f) zuKw#Qi^&-)BN>8A_rEho%ju)|Tj1BO!{Go0{pL}}@c@9}0Sd)PVA#}%^Na(t1Q{=I zuT?7*D_Le=V4`EptDXR6Rf-oj*?g6ZqV+s*mlzg{3(ACMe-Hps8nBpBEo>!2LCkF6 zwb4Kzsg4|k%%J1}FMwi9*+gA}gw*l$WWPrwM*hv8dJEd{8l#fyZopobS?6JR(d3;k zp8Iz+s}s~y#{O5Z_aBq|U*+EYoHfXORw|jjQ)18j3AR&45}s_%hXLQ3GOJec664)EHv+7Xh@Xs{%){UYKwn`Tq~ zzM-UrK@Ews{F!f+$9np^fObYIfhg9O$NO zytsyErE? zs(d)~;jjnBUS{xeBlgnn_~rX~lIL40SYNzdE&uA!s&}UdezqakOMBg>RJ>=9j+&rJ z|3mt7C(znUsq@?E6-F~=@K%N{v`r~({0Iz}>SN}eZ#AU#njJ25%yuMW^XdX=b6k#s zzu}5FJ9_gl@=w0o|DowVlHA1zG9ivuls`jQ@ zqo@*U7OkRMqiPnVy-`$KP5*^}V>mM?l`3{uQp!V%ONWwJeH4 z^Pu)jhQq1~j&m3qVs&Yeji=KQf#WFV9;8=isxb&tA;EN$m0IBw#0GeRl{Nky;F$ET z27s^Q(m4G-3RhasY|1Zs+~J;BEVY^AU$)LXVp@=KdeKPD&y=>#3?l*8K&!pzCLSO? znF7h)PsoLR0M@Zx<69FH=rKRizQ_d&Q*LPi_UC^Ta3L!riHWke33z&%NMVS}l~S;k zarfYkRPAjoYWO^$@b%O(_K7FvWk8rut$l&Kp&~MHC>=BApe;Xz1O!w*`0Z; z@i2M}cZiv|!?9n=;P`v5bb`kx>l)0?z5*}Q{oXxeix_kb2xPvp857c=tByrKXQFq3 z7zxM9#^wPP|0?RW=f>f0?y3e3-YhWOX&B9q602war^LBW>pbvO;3`F~S9wjdEbtZt zzT}a2tNY_E|J0&Yzm}Jdg*$Jav@TSP&QGm|>|TqvG*S6FVri=Ohs4TElUm!#T!%Z! zYHpX=fM^kU^NLWCu7D9pt)Ov#bA%j2M&LGr5()w~mV1zY>=dgZ9VPjL?&OL0h>UQM zaGYEo*N9zj%q!4sW`LX+j0>}$B$X>l;p?Hjn~?p;kvQ8~Q!xw=1vEoruqNm?X6+pf7N;mLBZy1{d5Es`sebqm%yo%fH{*JMex{|*q=k) zyN4jghuCC*=@_qXwb8$ggqjiJvImd(cpx~<|4+qrGwT}09VeVrKl&piIbhCIcBKruPEHdtKK3mey^{J*xv0mk)i0SPw^N+yt!nc{en58;c zRr4@6CUR^;!-dPyQd(eRtPZ4P4+c|0WRp#Z3G_HjSf(9Ol+5L2les`xE#}am>r!># zVqatDW4#2Q_(0b13Ze&Up%U6vhuQJfwV7k^tL!vRki{Q3E*Un|z-x4drpar6xY;L}mWD=Mvu%sNG21p;>sImzu^(YRb zwsnXr>rO5V^!Kvful`cU-`&v~NZI56esnCf?}L>d_0)>-3^c&SlX=44oYLu8f$fvl zm4F!)QP#IKVK3J1djcH4KTJ;8KHsfv4Fr`uJJ~E4l*kX#rG7TMue=aLKf|LfzWgF1 zKC7C8h!X@SPbE!M(u((Lf@$ConifxQT{JUPsnBX!j6msX2dq&c8Ng*5ROEI9Fg`-` z5d&cy&GHnD83yrrz`?d`qqj(hEsIosj%(Q9NrkWs-nAZ0;81;Fk8X?o_GhBtHSCCq z!#bm?a5CekjY95z@M94gySPVefZ-M}uZaCdjdZ0mFin0Nc#cnZUG-7?YkO6P9^sW6c@6OI zy^~{sHE28FIn!<7wPU9|^4qU8c~v@NuP4+gfAu}EsHXr`fCS4A3_R|M(k2la1@nxU zncwuyWMy{7WTSDSHM{SF2K1X-e}D7)C*|f1WAYdEgk->|l3EfI;bbdL7d^j{A5zd^ zy7z)zs>elUjs{)-!a*yX^Y&T*^xSxW`x`0RaWmTZjIe_Ywv{LwAm(>}e^zoIf~oG_ z47KlR6`KDF`h;0{yB0pu_`=%ppl|3&&5yAq_&4$nyBW5qj`p{h0KIyl^(F;;CU^Zt zUPw>ny9D8L!M+#iF{afU)iJnVrWVoYlOGW zcf)mws6Nv%SQ0SG9WV@1#%|JjEPsKlqf_-VZhQu7JzrjWjTbfBqz|CQkwZ07M2gy4 zJ08Di+*JF~_v!jSxdqq1=1<4G?+_KR0x+EINBGgq7l(>OTHwrCGW)8he`cdHaJnNC z^ZD7IuTzqD9$gCq*}$X(l&;-ge%}^5_j2X8_LFP<^VfRm)FU^#GD8G5_|&#>-B-@- z*R6q=1N;{{n6w?_0EN!#L5mzU{@ofprzGrB0t`oxB@Xm?`d}%3VEdK;(c7(;+aZS~dWI)tVC<`ds8h586;2$ZKA_dmPGp2NSC^;s@ubd`r)~0N{3^fCz^k)> zQH+k$XCs-QxTcOJIhV$pTw-*Xv@MummL%FuhNH%bqjq_t_BEpp3)!SVl62?j&FxXA z1q{@M^v}_#EC1MW4#?E*iJR4!r^lEV72vp_?VUHa8;YTwQqgC6VsNU$I5pyXIu=Ya z9>O#px;k>D#D!tT!vo@WHRF}^#-pg7iwetPYsO<%wQqHfhqmanq>s>TsW3dpv`>x4 z@lV9dO+*p89J>XAHYtsZF;l{Q+P$d#LX zfSJs*n#}i@EC`=0l$*%Blxi&y0UIs zQvZ1>yD+KF6)mmxB6?f9n`*cjquYO|UEHs8k4hgmG8x3h%Z4SjZW(>J3VJ5T74AD7 zusqV?Xmm1U(8*=EYY&t-Bxzm5Ikm*wV&j}Ok|-U=z%JyfAxa5F(*(Z~jGw5+pIYf})~IYR(2Y9Qf#i%W3}>v48@VSE ztQ(3L8wTB*8!MNdM%NHYHu_Wlv4V|f^xO?KS}mhG=Hfkz<$0edX@5F(mqfpGRVR0$ z{a^EKUHiiV<|LePZ2_}`F`Zf%nP!S3!GiuQkD`Q0B#SyV;l`e^CJU$3fAh47WmHQo zMHK7RrEIeb<|Y8M?oOiidW$y0L!B)neI{;RmKWqyUtzndGkdXyk8qCW|>?_On@Xli>ER> ziL#>=>O^WQ9Y9N1iNwUEpWLoQ3nto&Cz0w&P^T-#xLD~j?={fB`~!BxWBH7K})) zjav4?+125|*XL+A`Nf3=OSAR)9-NhNwpHB3VxW8(xv{aS0HZpol}0{gC~20(^>>pY zmP*`cbL~aD&Fh~IKopu*xAGHou}OS=FE=eL;_!(JPn#)c7j%-W1F1#Bj2E=!?Sk&V zYpJlV`U3O4zWB+^X6U=M3-h8_wDqQDrYbg3Ru5tz73V6xm?oc=J~O*^J28eD7xd7I z7~b{a+RXg*q_^=qRu3L7N}AhRy&x|Ne1wt0%dR6UnD66n*7zI7=_(248^6KCbz_vd@Em)393Kcfah z&Zvt{@MMU1F+8(sdvPY4#gU`Ms+rxb{H0;*1=;AO6nPkO6sJ+tcgjWIaoxd*8rSpA zp|k6Kn6V@F{+yC)gKn9Az~y-9whr|c&e{i1zsOXYBQHNnrHK1D(w<%=#n4!hCdW?S zQ<;0Fggeic3pdaGQI_*diC(rhRS(WjwVoJQo%45H|5Xj;XivI4JxsuS4R9ek?aDhL z>8V#+)AD+(!PvOvOQ*R8h6OWfksP}Ho>UY7k?H}d0`Zg{&Ywt~{?X3S*RRCMs@0p=(-E+!WEKV9xed(Rd2x0oVn%!u@x(qpW`UNZ-^ zPAlBJBDIqNOq00j$zu(0_8fR>2$e9g4d9#o9m+qxc(w*AwV*Gx+S~>>**4`V#^cJi zDy_z&6JBqZmH%{B4tw}n+4DC;p&riD-pljT&!X_-`_nazhfJSyM2a8ir!MD|=HZ;# zu_Pi5&dZ26bG4l(%HaK2KV_R02V{;&M`$)i=$3^68j$wXEw;tfBNk2G83B1s-Ysvk3RAt*Y!O_*TP zgkRi+;B^@xXAU7Vp2yK54eRphZ3>+E zAaE1O*E@a89ES;MeXIbxZNL{-QRklKpM?7a#zSa|K95TH+c+Eqb`Jz8cvv=8`N!0? z>-dvoR>~W@@)Pzd=UHO4boO43MC$903PjhXwLR7`vz2ODjU& z4?PBEC3T7xo}dEDe8WgbTT5~6r<$!N;Mpffl5D#+eP1NF>kBz0gSDGZyl)H5G2A)_ z2e&hb!iyv~c+%mfKI*SRPof`ZHna`Ph_Dh1)j!cCyz>*MOc7s7lbYE3Dy7(ZZV;y8 zcuUjZ`++85OaZT&)pq^yDN8UTg}1cn)q2mX8x?M-)a!ti6kB=u=x>FvEO6uDQ*EOx z1O9uDYZiAhks*W{Q_+VWyGwEUbWi1HMH2aN%IQ5yqLC_wy&SyVZp|SF4z!USJ^CxM zdCxmN4q>?vm73~>R+l)9=4Z85Di$}+>p7K5(n*5Je&lYQqYEh^*8v(Jaq#ZT^53~- zzk9UDxjP!1v#Ps&f)$Il&XWvr$%YNJd5T+ZthWl&3;BNdr!Z@|D?in938{}%ds&?S z;5hWXQV6Gt)M}&yUyt9jqiV+Js5f%N*iXGA9Y16hx$oP4e>>dk%Xh1{0UM_t-J5(K zL3y!R&U)_$D!DK{=>Tl6)e))qmZHBqV5QrxO1Y9x8Euz2rJZj_ePy)n181rnFYgbA&L zcCDjtp>ai@w`lM52@LZm;snBpJWHm7+t10Dp55t{!pK??~DwgdNxqlE! zk6y+|7f2nd7a;GP2M-Pn4jkSZ_7lBZD3pGZ6^&K7d*|=nPY@Un2yBIRPo3wa0RhsQ z+Nn7Nj40F(Opi2!Jn5O}@$mm~?Exze^GDe#4V}mr^Vi+^j zC67VSNZJ~jX3q%sz@>qdCVWNQU0ACvPN*QoJ>o~ppd~PmSTHN?RCYMKn zt$0y$$a=ht-EXS>qmBbn>~TO^xTN6mjLZv!q*%V>B+}O<=Z=S0_ z*Dg=&$y;yUyT6WiowLQe%`^bL5pz!*RT%k3Vc|Q(R=$0Z$U1XFQmdoQ|t zO22RIE@xZ69YVgsjKBN#;Xp)uy7i!B8zqYyI8b->8wHJ7$!~2;pzW9}*}`Tm-n#ly@@bQsx_PK0MRKYuxF;>F~9N z16UuMF?5hO^aom#@!|K^*6KH9mo0Z6T9B7`D!g1Xm;CcXSCqCvDOE^l0*lKYKMk8s ztrn};=KUz@GQbC>w)x!lHG3SzPDa4*9#ADz8T*nJDU}Gi*Z`XlQb`ut6B;#;RR5$fi-S|s z5gi|OPsi2&MvtTy+?x3eUQnjL6O`@}exEAH4EjUEJk5&Af!q{(O{&{m`-n69&l;9% zwJ|$M!UKK;wP0*@5BxlZl|D^xVi&|AHi5i;NS;( zancc!Q!*4`cZGjXS^TFt?+Pa{2}+XqJw;#z-=ek&1!bEDuejnfJu2fkM?H#TZ9`D>fB8=}YtYzgzZ)qS^!;*zaDk?S($(3h{ zX96Q-4Zob?p__zMb*vPyC0h2(j7jQOKLvZ{O>@RuA+oV^T8t!4xU$ ziB3;^ZTr8-JBwg3I<5@wd)LCtc2p@fKiMy4mcQ%p+d(<+N0&+Tyy3Gv(=$1{;2lk3 zkuI(EckB37$g{mc@2v+BIPqOa*7uY(l(n%aGt zOHhfb6~E&P;9}@BBp& z#q5m_-#2AnD0+THrJlAVZ}>UTH`_c$ox?AFhQa@r3GBsb-;ot2fh^1}0+%^t&)Kt6 zH8fdk^E4}_A()2wVIg`H2Ex0rA#}uZtXz85^4qB0z4^dRD`4t30-!f~bQZzj%7Jf>c07*&HJ0wKSCaHC{?yAxutFekC zcno>@XY!!! z==mOZcl}y8Lrb(;Msu!Am5p_G_fm7kKyE*aa3KhL9g(nJbCmc*gYJ<()onS#Ztxaj zb7t<8MKkuTWo3q&GR^oYq+hTCp?9nr5g93*(H__gfao`#u#of|iv zzB@ShS$R()yTIRgPv2Xf&x+cz_{8PQx3RR9W*X*nT3GCCm|a`LsA!t&)K%Nu4v@o9 zv=+v}8sm6b&qK)AUSDc`;Cjh!CV0hO4hW4Y(`0E$rTw)ArV%PbC^#KC%Pfezf)xUB zBAQW@qj3-`v*m3v3+&9TweLJbB;>ElyxIgdnJeHtHV%J(5on#xF-mv7*ggt<-$5EgSm3Jrp~|@ZBnMAXB9sNc_*kb=y*9` z^WO2Jdw(Km88<|!|Gc6F{@zKXVH*C@0{&9#4Cp<2B+Z)|4)R+d@X+z@q|Wb<0^3V8 zS=s~}P`tT7{1+@ZB?%9K0whpi?+Q~geuNjU_}suE+_RcypGZbS0&}pJlIJz^smKa} zlg40vMy!#Jly_S5@L5$P!ixZgbu|9dn7{-rMKO&+iusd@v{Vc&ftoLbK%~iwqhnb! zkA(hC}Ctg2lZYU11_z2m(L4ICIF^mzYtI&m4X180kuHH--wfKp# z`*bs7)VhfB>N8x+CSSI7ioIiQG;iu#ZoG>nDSn8b$rY&CMA2x9rdck;k!JPc_^>3R zWtBMor68qZSU=cweTX)e1Y`z=9w9~5K++uUy6eDlEBJ)K5riG4y?RoI#NRa2^s;*; zXH$)Ga+g(emx~!u88cPkvE`M@Hu(dhIVX`NC9tn!C=Wrxc|;8!HZm2JEp*71M6^4_ z>ej^uMuBETdcb{kWJ}{DQBx*fQ4Ob*TdiC&fx;~?Ce;u@qbe32DP^Rz}dg3O2y5{o; zeDIyNH7e;}O|6X4hOX9ppwu)5gMkvHzimsNW297ILNtknG#IVT>HzWyI};Ccni2C? z+iKqy?f5nA%i`>Ftu4|vbgA5>4ftg!@K!MxG>wPG$rk!@%aM3xz_N13jqgxSWAJi3HJby7O?4RoPos%l@Bf|W&~TXOKJp|lLA7QBuZ7IDC`LLUcSGN zX6)--bc^@x0dEW7lRo)t(K1pV8BL|3I58Q*Q&-Zv$TxRc;u6X=?m!6;7<)WT;%zsd zyWi@`FNIPm8q_K^zeSILdVKW3q;Z+T-6FzqU>3vn1ZbnDbJk9;@L|w z5at38J>>Y92-ZlZ8M!M6fAqx%22RRnXi|LWlStz0H?qea)TC=COosFGL;C?{!flg2 zO%kQ~3~a8oyMl9WIAB-we%9K|+)vdB+F20QPLZG;9k-(fm-Lr%kUAYOYFC|E`FQ(>M;_;;i+Vxj06X7F{_WcYRePB5OM zOar1c#K)z_8BQDmwG+OC;^;llB#uMEE|YySqGaJq{S@qEA@Rju38F{dCD#Gr3&Q?7 z%8agM2-z}>5`8HMCs2ryVGoA{4@37BXjC;TyMU_Vo4Q2=5)T490py_<0GI_N6y?2y z0xxm{2t-~Z%;AWQ*qC1cd5t&8A)3?*$I3qplKVQZ)0%uL^eVn(wj^M&Ni20Ez_6g@ zr0a0X5B=U`H#%B0K0J==G)`A6;CXqYZjmT|o#=xY5}rgZA*`N-ThfcRz?B%xz&HQF zI-O^Cnsl|2?jaJ*x3gKiQ!lihrsx3 zCL&JUC}4GiV&ZeW{aVn<+P9V|35mC=5;WQV6(_a!BrbWU(2`_<(RG$irS*ZaXnDpzH=A z$x$jkQlEo?Ka^vg&5mF9jTbd7Uozu-h#&3=9pmw7T(VC#R3mZBCr{@d@(Ba)6RJ{a zZo^|VQ~X#AhTYHsunKkDmQMKg2}+AM&b|+u`ijPd+!7uOluEL+(#~@mrGV%mcM~c9 zYJ6x(76aqqFI@&Bq;6o^tRqd#(PI&bhQk@5x?(50pUdcnNxXcLosOk#0?LGF@uD}z zuli)d)kzL{C*RIJL#7io`31n^E4q0{fu}Madu2G1?<`rGtm&34v=~YEP(ytV4ziOQ zBcnV&Lj5|AC}|U63DO9ETCV5PQYjsdR^R1$zlXqm6*@w>XcJX$6Q3yG3R4a~FLxec?pGPKm?F!wN8x~C~da@x02wVgY4f={oIo%pjRKuAu6L+HsK zx$Yx5gTXZY`cqtsoZ%qeaIn+pP58%XIbe%hGs`WML&}&|kNHy0%y!82T+W=e%X~`D z402}1E1$}LW-2LfsVi^CCTEh43}tDz^6s(;mbZ=Svb`5!Y8fF+BLpJz$HxZoMq|Vb zv-%xN6MMRJYvi*h&JtQ8AR6*`;LY=z9sGxg(u=clLRaFfe0dH1BiMP859KpBo=r8r zgf7WF;mjtzD}>mjSy&~`Z9JDDHPkP&1J61O>DCR;+9%QhSJw&8YJ4NV+MqmP?|O~1 z^2S}hJ#^Fy{7vH~{`#Pu#(!{_sz~9=Af=siUs1LR>YzWS$-r$uqPMZx>v)ZbY}w9%zt();t+^lc@#RS+8*M}Jk^ z%ARSjE(ej z0RiT$}*-g~r`4(@Y<5*1x;RfM`$K z{#}L76&a6j;S@sW(P-5h)R-r`i*CKlx1tkolU@tlX6?A~dqQ>C!^QG$kt8g_779H5D;8R?ivN7Q_MlG+WbC3LXL!&x|euYZNw!3g_VBQod49c z|1Ga=o6!5w+n2xeeoektGUETJ8}g!-SH5od)VeexKCh&7vS*3@;W)YdDk$y)Dfe8` zdebKYKY?x`)pGeZNiQkvNzTWVq!0L^tos6GbN81Tl({43K6WveP5k7X{(8f2^+ zumhuo^V*<8$uUP*xtbaN=E}=Iv!v?FjW_4x9zy&7tWsl+-hAEX8~7gcXAJ^-;`y+% zmn~zG=iHWaiW&&!$aAi6MunW4rs&d40ZnHruGhx>a`n(0V-V{C zfzK+A#^d0{4ksF?Lbq;G08x^=4r|YL#mT9$g<+Y12{Nz}S{i1iV~B%_b0lxKH^uSd zDcL`!(yc>Ys>!g0ox;K@nWU&Gd5rA7duefpalAUt#gPb7QALZvl=t|x>JXJW`6~H- z*3Gt0yx#TY``bQtZeE-t?)bCGc+Iv1LWF2Oszje3e*L~1%#)Ewvf(&%|gkoHWAJe8CL>Ff7|#L zf-W%nIULyF8t^!W;aZLVhfN{d0kPzvbPF!k1Qz3%%HPS&jaAh0E3=g77fD6_FtwAK zJ`ECvIRGO=hR8FMU!+hqLxC(Q*W)eNN*)jVcDQZabg9Yt_35;Nf2J1FW+9^k5Y8}r zO2V!gI!MWyMtm~L;CiF2H`z%pxM>^Awv}6r-!ZBwI81`nm4 z+Ks>^yfx`MT7)lai>*=t@QBKYXvpYQ~QFq+4#+aD#|NnHVRB5EAHh zY>3JToVv;HJo!Qw3N(ooTUtUV2I}F*#B+(vyVJi#<*i6{J2&ZWH5jP3rQXcD_Tl!MY#l%9eysUVMo)rc?Oz?9&|7 z2}WW}vkp$TH=WR;rXj9x;^j!pT*SsLq~Tq3}{f`A`N&R(IKU% za)*@`i}(Zq)V^mM87n)#Ykc(*pFKTj{pV~c_|u=ZF!6(y&PBh2)}GHzQ{~T3mYW|B zf@Rqr7r8J~^=i=@BqWRhAd)h>2?*)|U{wSM$bckDj$y#GKZBkELrsXZ(NG|1La?Hf zq8NJ6_P!NH2n3qDhc1&_OBH1~2JF<=wW)1Y)~PoOmNAeAJ3pi{LGLAeIJ=VKMo zl(7g?xR+;56NS}E-UFD{MQiDveAhW31@b62D$jcsG(}bD((`)>qF!t`UBYKtIT7tr z4}E@f84p@HEM~#u3@|)I0Kq*8Zukj7D;)t)Sp%4Q5uL))DFZy_@)W5)xmrhxFMEt< z<4f)}c!c|Yd#;kE%B44()6owhHccTcN5>F5koD-#>8^UHJj>7Hrn`f~kJ`_5#r|@O z;$CgOf}lY;447Q{5ElZ4PACY>+U6>O>x;aeiB; z=ZB*yPuOt{Ce{zJQZO1N^M^hL2YAXQAKgM>W-5L+vzv%wCM*Z8WKFIJb1ybeZ%E$XH&Wc5&+^4LJCPpT0CB$0#{B=>4)8jLr4tg`Vl?U3)o68E zrG7?-pT^j|40CyMC!fO2vX3r1Ew83FCjf}NX7M)iyrYsD?KxOtx_WZjnN2OB@BdqT zJO16X)<1T7@hVm=cFfHVwQs3{>BytwZTmq|2O4uRt8Ic&`K#C4qDE2H$xLSr`lA6Z zQ=OZlX=cty z84_$0jD?&Sc#=IR`of`yb=kulK9@rU$4zu5xl$I}(G6)q#$Y@wtEs_|r$A{sp3W=Y|;08Q;hf^ZHY z)x5@4p!TgyA?v2O5X(kE0Fx)8Wb?ClR5XeXOG;?B0Lj_KGX}4tDTJk8g123x>=GdY z$YXJ4$wUgA4}^sWVZg@(W{Ns`4dLP57m)@t=eb}CmEmNjmk2lJObWPO;1`K|%G2lq z3Noj+{jJ1osy9@P9gM+x{?dhHkPx;}#6{U>`N!Mu)t*EvNDx*%hWbWxu5M<^a@M|}%hgC)4#`9Yuv#3tNA)fpC8a%Gn(mQ##4Zs0S+;m4 zRx2!}v=v0?u7}|MQPBE*RR&NRJZSYb;p_hxTafk$bSK}yS!Ev7qsebWosbl(x=pEn z)?^=hR88nxsHY)}NsAkpX*r0*3wBmQ+P|KJRM0g0Xpb04!BmVi+!Z7{9#~@$Qv^okg3BH0 zN6|CEPA7TKRCn)V0C}H33Y38MBKpy<8>tmceUjd<%YV;JDc8>RZ7wxRjVgI0Uvc^Ur8)xW zr9jLfAog|;Hy!a8?PWp6F~h6lik8Zt1Tuyp+NMndj`)={F)&o49v?6lPz!?*TVr_W zzN2SRAJETjq@d|7q(Ai`%Ci^v22s^n)t*2y&rz~UFsZUDDG!cb3?$5N3bQsNvlp{T zJA$nUfhqmK5vG9T?B&2PZG574n?KpAB+zr8VITw*5~z4(f4&Mqybf{w-~+N)XLg8V z7^#?Haig?Jp=AFb_9=HnNPPu(0Xd;-glQ=<6bzu^(O}vmWE!=TeAr{|)i4#Fs(!&0ls z;(YA&Uq&=cf`OTj>G#z{eGVHU=RQ+4nBth0Nb@#{DTn?$9^uoD7&-E(cr4m|d}lyf zwBjvY9EvUF2}^K}{FpfhE12EXoxA=C!v-l&{xMhS+f=W0o;y0y7ROAtM;I7G={cY9 zq`vKkhKdeLi|W;)o=TV3ArT##lv+pxD}yMC0ohswI1TknHBckXnXu!c{bn{jf&7hC z$S1@6^;L}O(!g-ak=;|&l^k6`Kv`L!%w+gkP6Qgkd|jFpp|rqw)(_Z`f{F>}I2~$O zN~9V|%?hP<9-_Kk5nrB6nzu>)Ukx-2!`LRu#rR+Nvr^>4x735GL}6`GHJujBb)B7>?!=aPj~k=jjY}P2hF$Ya_X0>RE`_GUD}a zGAlBGD&#-ZC!#CNgF)_r?DYo-k9FuPoIH)JwC;Bd`j+gqdBqa~3CgA6*NNm!NwM*# zVy>17zOwZJj6LfX68kdzhYXTuCy-(WWY#2Sajs2lE^19iV%GxI16T0Ag)sOo$BtA< znwP%Sq0)0po|H!!1dAh>V;(ORL$9 zl4pY^gGhpATo6+26k-oY;ZFXJJO)ob{z1_$Di{}^or}oEE!a(yG__C^JVi*k&~Z_r z%1)@#!%?hm%$R*@)+;R3)x{C82?|FT4CzEn^fPG7bTG*ZHN;~;34(BHxeYqiiT5G; zZ+JlZ?D3TSIMkIUx+osArccAO!A$cxxhWjcCWkt5F@zAv89+?uS2wN`p@$A<(PVNt zHe=T`XRU%kE9cAk6WQFLYx*d-wFSGpxg{Y!n;i8a&!F{`L^WS!h3Ub-sVOAFOlz~i z3$Lp&q&o#MBV~pno>F}?6CKWh?BN)NT`Aa*mj6_!%E4)rHfTH3=`+@81wm=V;c%lV zIe{JrM`?B;7Q4)}h8=H>SM^2sTyLIEJyzQr5q#HaGZG0-vyds#q>esK#(dE4b6YC5i(P^&^ z_p8GhJH80JhXp>>Rd!hs4Q=Np^;L9tU6}XG?2DPxvK5dqXSST(MBf<}`+v?|4F$A& zBYkbGP!4jJ!XZDPbdW(XiP_aZWu%DBbSnjjoCZxPHx?=Exj7OG@=Cq>n&6ABbAFfm>@W7yiLrBBK)O=?KDgq+Q?-ms)GK`ec~;kWn+ucI zI=KomF)9jO{|v|OQq5l&HkA-Z&6YldRRrS_jeAf`g`rbLB>JOiS#HpOl~KTsJM2E^ zW=3PY9Oe*mLx_G62l8-7tpZde@`$wF==jx)ew(iV7m#U9BUQSV~FI zRf1Tr*QguS$eC1YIa(;xA+;_$WlgkRKLB2&$dPYMpq}HM2$~dPb>fA zv+F8*dHv@73w9W0M9s{UY$4i$x9oPcsDuhikmD@!bM3ypv{T7L$a<@a9A z}>=5NgXsIZLQ+{-!$+rHNOV==Q9GCbNDA6v4gG@MYr^ zy0!FIqkUhKZ!eKtb~&@pL2<37wl#6I(;d;b^-+c0OSaDVNX7bB$+gVQ`>*>Db*cHm z=N2-a3MNLetvz@g+T+@{dGio%9n?lL{uA;%v*$O8H}=a_C#E$z%>I zRN~)mX@r*ibqUX^2(OK|FC%rJXuDpo6I9_9JS-5Q;vI1b_4zVtbV%xtHutbp=^nPM-Pc&!-vNCw^V{F$b9w>9scq%i z#!CP84X4Y|8|%q({Wk*EcW%Af8mu2KnStEi_6X}4zs*(|kx}YA5Z_~K=T;&Z0F4=Z z4~2cX=D<(v_lqnV{P}r6Ja#}!bFlXYiE6A}D7gI|wpv3EuLQjBZa~&2?A3=5t9^9y{iLITjV$MqW2AoiZ`L z+hcxv(v+;-eBnWH{}iHsSg?Ll%WVkMDE*KurbbtslMCNA9$MmU_+b^{Y%w#l)se)Y zlgbb}ILy#S-cJ%#wYU&{z_p(2$E+gG@!)vE6#*ba;^-9t2MGd z2}G#=;-Fp{3v!XX3YPg0o_qaWuT_r3#A5J7wjTY(VPZm7P0?)IvBb@iSP zqUCyK_Z`z0zJ@)26kvBI>>(Q;DUv<*FoD{WTDitz#3|~5F)bpMSosE@vKw-sIiV5q zGp2p?vVLEm`VM(fMb$9V?VakXCp*ezV~u66_ldD|tF9s){yya*~ zj%2`w=6`E0)~Xt6sG=*W08N|-w>upeZV1yQejz6M zs3aZuMf?Zy_a9BSzPy8)Fn?u_^s3`D#N67^HJQ^6uhVC;HHrSmmhiqyiZ%(tSz}c* z2l9EhTh_~FmiOs>9#k)lLcY}xf2l`)+q&Q8*4(aFa}t++rr&fbM3Ip32q8CeL1y^V z()pjLGz5pbnl;yR9shKc$- z$MyfU)9T#XDOnzkv~6^S*~rx_l$fe-Hbe*titINCmD(82Lg*GyU2S~pBydqX3BNl^ z5QI^_mm|k*S?ks*+WWQiZPAm1#pMS9r_V3G|E6*I(RKhn2 zfgRBM>`z?>!rv{o{G@kH!?9IXjo`1a)97#EB0CR|SE<$Vk_k(c`5ExOBlz!k)MYcN zh*MV;zaaRfxM}(8JxCgTF2H<(KRK;)|MUANwGGbl6)!RIzoO>Q5b0)83KO5L*$F-j z%Df2)xu;JLKtn@h40vS4YTj%9GphIr^LyjH`PH8D9F%4F;fJeGN=Q+14AYE~!F@`0 zbC__H3mss($y|v@;ZYl{&O&cCxF?5Xgy9oGW)rjc6XjEnJWBK4*?S;{ZnyMdksi3k zv@+SlG_gLVGK|FPTRM`*fa`{)EoO6)SL*P?Ru(7(u3Iilz9<+6McU1Uub6Mw;wVM> z=%Drn!X8-dS+a_1ke$6-b)eIpb6ui7MQxsAkbUL7^U4pi9BjEFJQg*6Ky$QBTOb@mTL!! z<~lxXUor3wd`M}Z_}2c{pR_&9D0ks%o9xm`b0tBdKA_|~vVOHQ(bvCa;Mm|aILymD z-wjXYIg~0)8=?r~wzTq;(zguEbIZN!C3dso9#sjejX(|v>YhUP%53=6$Ku`c9i89x z6a0+*bR!J6oK%>51siAa2$BSTT*P~) zd(@F1+_H=#msp-2Yih}0!-|)J2C1V~T^@hzUX8qAeD*QspP8sncmGmfc%c&nIehCX z>p1+|hP<)@I+v15gZh7dKBKyQK~KbfE(v}ey<4sxG0OZX%cO6mvhek@ouca3F$Zmf zi>s4;&hloKjLhh zEj8kNx>q=S6Uq7XVoO{3^Q#>Lk<=%@)*j72`TaTa*5lmzy?(P0f2T2IDMf^=`)#I% zVh@Aqg)JtEN$LXN%$cOT9N&KLnb&ot{|J<24H}VFA=!Nt=_|kSo^EnrsdCDPT!;vA zC^=N^0`sQTu_N5g8Qgxd;Qe!Z^sh8E;^v!3^v(~`%~|u_{aTUW<2JkRTQUQ$DII8h zLKDd?JYf74vkwt2n#3}A@l-*N2p9RaC@X&D}*ex-4kJ{Y5IgHFX>q(9ny!E&(_FaOIlHTd*T z(aoh9DDw)21*y2K_A_WFa-Buev{btJ%Bho(MH3Q=4sm8dW$cBK`7Sfu>L|~_!j z4jbhZaaDo&kw3d&DaQUb2o*!)2va)O(hFXD8|&9V z7#cFlxTHcvZGeHC4h=)(uMG=|r0RKXvFg0hknJ>~|IAN?cbChUNL~~z@TpUgnC9rT z*Aaa1w&E4X9*2~XnyU+HC=wen5E7Bd1Y zdE)OnTwcfMS7@8oi?6hR7@F?m!42NfY!Tw>OS$aS7wEZOaD6FNx>_;^C z^%s{(|H3~X`Vw zftr=d16#jnwWKdJc)6`!jnnamTw6feCC4Y%dh1OA^Aoq<-M5lXiXy39B2pHRXuL&O z>MiHyR_lbNC;8sp0XW#Myda7t#}%DQ2gfH*ECgfd0zZKhE7(mV!;rv<3O%!jlapnC zOqdc3xMIv4rnda?;u9%`0tOJ4;^2w-i#Ig!VjoC|;2<7!g?*f;#6pa4AV9v3mh7eE z{IA57x}50RVp`6mnHWbK5$AhKZ@(yO7m0M#J#hGP#mkih(G?v`7&RzZ zKz8$}4Zc2BU_uc#@SyAYqdj%s_P+Dc8f`DR`%q3_Xk+==s~*|rf7@Dbl3~)tx`@^Y z5s5WF;Sd%LqVGmON^5eJ0;=wF_<4NKb(H(oPKSQ(mm~S-!-<{dWVYgJw!7b#UniS< z@;2vqMW1*X=W$nam6@lp0n3{^kGm(N*8O8(5l;UZ0}n1|Nyr0p1l*DKtXt+nI}|9s zp6tUX--E30?K(XQ9+}Yn5&q}n+xZjU3Cf3M%!KH}Q68zrhbe~=)e7IXSfxiljx~2i z7IEC~Bv$TL1U+io`C=*5n;q5lyN%-GvDu+NsbRtbQ!ACXv#eSa&J?r$tnz7B*%*-$9T5KW9HKa+HTt4x50FBRhWXK)5MKmqiP z4+Z=rFnrQ(*&6ZY>(ejsmK3+cw?P1pFCuv%EYcm8-W+kuM0Ui7YgMC1Ctz_cPYTPz zNn4_(-C=J!BWum^I9DU!eqV*Bl4co8ej&#K0&I)BD=zGEmM)nr(&Ao z_iG|=f@An5@xy%yi5)R|U9R`@f=K)bk2ldEAePE6T)qo7P9I0&7Y{H*t86{?tzq<+ zi6>sg+mw0g+8h%!igtpAFb72Ry2GTgF^OjAEMGJdL>Z+SmD-7e$zNjAEoig9BHD}% z?4{M}B;80{rT*nDMH77xgu)Ain$7r{aBxjC%r8wa*%#pi5c{f7(`9&t&e7J^b9x?)3UMQmO!*SNdILHy)s zDQz|w##BvS;QH`9-p9R)hW3SDjdSH77*?0+B9L$H#SorYMblE27m`l4>KLTWaMufl zu`0!S6^OWK6X3f^zQSp{JeIv3)mcGD)QlfD%=HnE z4bl0WHAJ4#I<^!G4hjBQh4rBT^X8}cYmKd5bT4uW6!g4(?rFk&yS@4XDlqw`**qe-vtU2Fc><60}gNS8#PGX$e(iJ%^$ ze+ps{qRt|qY)LMoA&6?p9D*@$D=xk*~4dg{-^T0axhIi*v}gC4AFhyEaL(^+lE zkZqwLX~@NG(#nv4Cx}kWP^I)P~e#5M(}UyD<6Z4kZ+HID_0aEbLAmG+D}G6Tj1vUq&ah(1Z@+%Gd) zII_uJ`~z{quz&T*kB+?tR(*?ig#O46fHuS`S70OFFi@ZCH+k{;`hGcTu|NWTnkaDr z&ep%?{lsd6*Y_o$5fXns_L9vG(D)5e`3=cRyrwgzb#E17(+QQO9wrkT$Z{WK>675L zd3_VjqXZJ?W7edMfC&b4-8Mi)Vt6a%B|er9HQ)<_;KDm#aUYElQ@^1uaMzxg7LASw zmD6AciTIUuIl^@-`6&I%&ccZ zV@0QY)F4?ZME=c_ulpFAl4oaTXWtyn&f8FRC5M*OhZYmRd7u2|L&KYovv1aQrk0Mn zi`EjG_*Jv`WVmT`xK;I~z2-^+REyi@%q0*XV&;OV<~hBkeztROJRB#w8ONO+UD?4+e zu)hZ34nlhBofKc=(jaK@HH}{0j+E&su_qp=2G(1+y~w?&Rf1eH!l}ItG6KI$Q}gw; zS6kNsuggR&6Ofz}m&2BAsozq5la8rC9Y4^e*SNp7JV#Tu3|e?wR;y@nZ0zs6WCzJM zYXj^`iHgt!LAPuv=VA==^h$$F%m&`u9w1AV($iMD<$?zO1|VI46pM=vp2?%-M~M$g333_McYo`0(Fev$Z$6kCzrxBk7Z14rK19Yw^qc$ z&4A6w8r78UHI4MQz>ib!vj;bAqn?DMKUC;>vf|gaYR2+PiIX635Cl8LV@%Tze3Dob z8oH^o82dm<>6e+Gy85$edoar3A}PMy{3wR+5HR)!9~p?N%{;17bM5OS zj%;wfOR)C=Upk0v`rYizfq!skj`#YL3FhqpzUqez3kRXU-DqXREZ)One|NDdvJyE! zDoa_t;~#b_J){slR4_k`jxX_A`vTes36l2N%VGbpbzkn*cB2Q=RZdn#YUH!}{mmeaEdF5w!TB2!mDboC?J!gbODaRez@+ z2&QTYgusZnVF1wv5f^2stOzBv+V?@6-JQ7fegYnzYC<6AV64{6tYy|IL;$n(xdW&n2?{)T< z2%4^|`hiO9#}W+>m==`zhw#5V{pB2$&m?U8eN6A88?w#ILQgalip}{_g1mm2xi6uh z2PDAxe^*9LRup3Ae@~=_hccm~C+%@X6wKoje}2b<@*cs$p$OBNE%%%3hOhN=G4p;gnEJ5GhBd7kllFE2Ldfb$!(?n6;=#A4%jw9YFcNKsRMy@0@dbl*$ zbCfL>N>?6Ov7s6r$Jw!~x%ho|=Kp_U8vp;Em<}IxPB7rg7z2yGrTC_$lT01*EHR?1 zNi?9Aw!Tqb3qLjVpAxbOgK39lRgMz#m+32mPq*-v`$)ImfuX+1FqeL6NLch{+5KuC zmOq(i(=iQQG^g6a6chh7n3O9k-Ge4#@S_(1162YRE{}$yBa(%_&%`<>U`TzhPudYU zuNeUx29RR_(Fdmx>VN+Dsti(j@dGztsD8~}h=4F!V2}?^PL8&~)1+`+ZU&!s9Gq#; z$0~g9y;*kt-m032b+~&S-A8esZS2oBK@I~4R2vjeS_&})=am!7CaQQ$0CPGX+VGD1 zNZGBT2!nY{9cFRi&U&)n5MzFXpK^2+uD2lzO4dj@#(Qa!J`4y2E^DJWY$QhrKS+v9 z=sQXV4Q}m}a-bPiz_4J5 zDw@NB(>{!-&TL_thQ&x?P61C>a!E%`S8By3Mpt_6!HBNRXHuR?eU)`)%sT~Zcnu9q zWdl=6c)FyLiIrt-s!f)rBB5z=c&fd3x7+^_h*fTA(x6aEoY6Jga!;GEAYKT@e(zbH zLlz<423Kr!4T_J78Ct#_UyXZFTu^$aAF)r7jt39@P(c(C`;F5KMdaNWsoCxwUG@0S z{wqUnkBL$lL`NqFrIEi+&0$BFTEQQ^Anviuv7>D)x}R?kNYbrb;Xe;P#76+xMs<PAELH1Ud1NBFo0Rnx`mz|0hs&Z}=)cdLXW#pQ5!s}74p==um z+G~?ZxE37sdC*IjS0GmJ-HW7p}Hy> zI~GNm1k>E2D%6bUMHxm~FPGB?uc{3Q>3ZK@zU0+xjWM@)6KNiUhi4(0NOEzOdP~s} zN^WKWutltBxidZGuo|1cdg^EZDRUX0IxX#a8cZyU0}s%w3pILXwNuW5cZzop{Y|gT z*qJUpR%-zA3?3s`$)-OwslC>cqpZfJ9j8U@dWG-b_+vpV_!LS7E5&EZ<3>b>YAN`; z2BZs(;l9#P^|+$~3P22d-*ghDjS1X4KFwa;_c`OO= zvDB&TjuObVtCsa6d6lwj=4Gg|V^F(^n*Z=u6#B=K`Yr&F{nH`Lr@%6DDSq;9Cq!&z zv!f7ZmBd+7jLGgOj%(QwfR_pjzeY5_lui5(;0UdSgm$UXYlG5>ONXe6LPltCQ9r6T z`Ao=*FJlUtU_^7ngCfkU58Np;+Om(5;o=JrJea!GT%Bi2%993LuKSjMpGd!gULE!r zv`$swqyKwJsky7ZMVu1?af!43w9UaqQUn{r13OrZ5^Hrv!tSbu6;8AtFLq=$HYDbJ z{Pc2ozk9sW%4Mq1dcmKbodSJ3%N&wW5&d_7389d@^YJ2#zS(Bc6$oK${D}(gU5{<_ zOo`7Rh$n9swA}mSK;wvED1()Djp&^Be!&qq4E3>`YIkVGn6G{tx%v4BkeuDjcd&>j z>R3yX?~^^^p+j-fH9s;$Y>&NJX}PgUP^SNC_X+oYXxdfSB@O3l0{_7f{PXqqAc}ft z%8AZi;wSi%RERj6zZ)=C^~ppvA=m4*Tz3W(V|FMi?VDL}pO#%hmZ6i|KOEk}AZ%Mu zfDji~F1@96u~w-ZbaN?g4*z8u7(uG*))E&w>s!?nMD`r4E!qq~sf7JL+;JHv51rdp zw0pE<~eU=Jo)i3$;}DVSNUyFYW|or>eO{&b7!69D$g0WVqD_=^6bg`CnVu7ebzzgY<6KO zmazEQ^Q6xgdpz2C{W9^&bw^1t*FM|*q5t&hYzK+>;J$q9Ur+ky?_s3!?+J=;KgZYy z`D&&ft_U7n@>%wed$6S+{C2xu{hi$-MR7JBe5dOfqtWFb{+kzupBoqTfB*jS{7F_< z38siGbm65^;9|AHL9U@9(Fgs%CouyvSjCubrGmqO&-eR-B$VSal|c|C{D$0@fc_ z7it4y-~cPug8YjzUNUo;Ab4~JFuu`9AXX7~T1K-!EaHN}$Et}yMtG1TII(EuJjfOt z3g*Ic&>#jJFt>lwXzWKR9;t0LBZQWR=h>r_0DPgEyBdK+np{w=iqY>$nAO@slCDvp zc|?wML`+C+0H!8>!)$mI^*>S~sA&N$yMa-jtPsjV2qYI7yNt0Sv8v3&*|H%d z8Z-}5m+&7b5>4vtf}qYD6=)uHU{;qKRWs~Mw4PPx+fg5IP?M?P%`#9oxj@;>RyZz? z%U6t8-HhvG+**$K1VhrISjdwIe1g`opk&fenxxhr8os1x-3BCffBZ3*y21ku88IZ% z1Q`U;h{I_3M~vWnKMey0x18Z0hl++z zsk=-8e9@{KqDI$ad4a={CR(TnEzZD9sw}N0m5KSXsZ2<$H;q!IO>t|0X0)URtq$}> zgm$URl@i*~1PMGN^kN)Vdo< zo{KL;10LvB%Y@fQGp*@(BANizASNHKGlJA91IQ`i^sfSlCNQ(a=h;XLJc2Zkzv1ji z5s?&45d|Dz24YKm740{5#&?qBvFJ(!lr==6bmRVj&?v$x%J5VNW$|WZw0C@m(w`E- zC5uA~d2oEz!Aup=ZqVp$C1WK|L5>lao{x%UgF0`Dva`EpXDen|zD3=0KpW;o@ovmy zci{;RgLIpPw=Z-L6*LZ(^u{o|B!h0L)P4x&^#oicBUp;2971xU7&0iuF=6# zk)d~(^_~t>lm5ML5^AXKh*|4<186Q%f^`?Ubn%1qF=>Y1AWQ6i3oP6T7d8ffA^=h! z_~i120*by$)*a%)@^KqM??Trjj97dz9{!-mUh|d-M(+ZR_}>_`JKo{DJ3EI{&=$Q7 zS#iJNvNdXIHeyv=WQ*0O+%=%KC0eOplKGp!^Y9Jlx{j3ktgP+rfs1jIh2a+IGVjl~ z9PbvevL;xVahDE*?TdT!f^rRB(Uq34(l(pK zK{|D*)8U)Md^|YGm(&nKI?MNN#sT9Qh1Yo6>KtlH3V?c`K$3@{IXAIuW0IR~0?$S? zUNeMpH7aW3jSX$0rR%%NtCgO^DDe#v^3^DR*TkhLV$;}nhcxD&AuCop?_R5rw5O#d zg~hOmCU@5)_4=-0_za{Biyq^fHS z^--fK%+GR`52nkvX6kV#OflKlbae_2%K!WRvx>z^=KJwYV}~irtT9s6!Ep37U4GtgZGY$xKv z$s^84Rygx~-n{eLOoG}_zuqNAZDdJ!NRI#IBZ8y_^g`BvE_Bq^ z_Rj*%$5>_EGlTI^3_ZhVTTt|#E1lBS`o4{weakvomJPp$oe6v1K+8wzbiI>fva{V! z!BaLoDQRBa*-?%(WVN4K@^fbH+FS>HIyWt($Ud ztg|gX=_bXtt2Bkg2mr--p3F>htFGK1-~PnPOK-+QoZzCC7~j&fY3t!uw##~ z*J*Zo3oFYL`E5;W^#;ruVH1Y-#9 zcy@S{qxON-Z(#=>bu9ui!#l5*>Oxv8JonJ;YmU(iwSI^!f3xC*x|$@b1gaf36T6y( zz1>GR?)rppaU8YTSkHDRFU^l`jrY7i_IhRIeMOlTcM-UESbfuaEs)6L?ec7<>sqdB z*W_m8KJ##!(8s$?8!Z~)l97)eL^es8B+;2}Cn_CE?za{ghqo=Twm0_3MK`wPJWdnd{53 zloP09OxG(N60~jrDUX`S($h?X`iC1nEsKvINdIuRQgh}0A#}G;M22%1DSub7iPnJ6 zO4mVG+F3$7Q$l*=xZ_p>^O3O5Z2c~PeCH!}&H50oM)NoB!RFHkR|hRKe5W3ityw0; z8kt8Q1w^d21rYMB#3IL-G;#8M@l(XxHz!VLusD>y|Lo)e>x)NoO|OpneRs9m$=>^{ zA^h}{nz9EUwPu|%R<|!ow;abcFqSBf%$fAOQf4mtsK2hv6D)I!rW3Ga@TQ*gxXa|# z`@bkWe-tiV%qb)EkH6>u>0R8*ZkMK+KfU)^NCTuEbu6{nWcDcNmS(se*jvVT80%k9x;=1h>jO(ZOuFC4 z6RFy1rC=}O;`2jZ&%=hwtIv_XbNKB~yZD{KJH2!bKRWOp_ZF%;YdlWc9&~N{<@Ard znf+sIeGsMHk)*veDXE!V>br^1STig}xYR%8gHlkEs$alhW)Srjr}*|A(@wAcuQ44P zy~$vUI|`-KTTrCd-G1E3{ofda5cQ}KnX+K5rrAPx8DWHC0$WB3Mdz_~-?Q&zu`kgw ze6h;d0?0mC7ltne$4cg547*~2a#aU_5R7J&0uZa(Y@Zc!l{e6xWq*}J0hHv1&dP$! zNhNy({x~|LY6Uxnt(EXodQB8Q^J4#5% zIt21|OfH;4CSss{+PstasDs)jA)1#LLm&EdK6u$S$20P>Un5~4xIX#O<&t~w?84>S zRP3^bOj;`L$y*JmlnNd+4XjZ^B0PylU4z!i0Fk269Ho#!VeyNZh}GJOe8*WP(x1#|Cm*OdxUKf}aL-HVSS%AwIbMi9uls>Xx;_0S&7Si|W{sdHE zFbdu}_h&v*qfO=D>r*szkUKSjSQrdRivl4iwIN_3Y)G^*I0{0>F-B(s43RwXK7!NH*|r=R;fPe96EQ)!jxlUh+@U-V1r` zclPd^H|B9Y=K{BXg(Fz}O`P6MXD`xfr-s3oVexO-ni9<5%McEHPQ6kFF)LsH1#%3| zZW@x8hI-4+%*e=iCGkxMAPT0GJISmV&|j4Z$73_vd-XhL%{ z{Dq~*b64-JY~OsNMVm7bq4FHr_~T&&F$>L9I&Zt_ZG*F)xEH&SjMIHq<$L_o6h%w- zm?{ybFpK~wbuz$7&>;+5ry3ugn*bdOaRe5IG>l?EG{H9h3|_As;|1EY0GvQC3p|m8 z5X~{HCD8{~b%+_8bP3Xr&ifpe{K|a#$%~>=syrt;Mj+QNLy}h;>CzHM! zr6YRb!lfN;em0s%$NG!a87S_oh!_erD{e6K-`{M2a!4BM%Iv-})>p=tGBMQP zZZ|R3SC=w1oppnZ5<)frV!XR`T*BRZtVD!(g2~aUK(LD+Kwh8#1JV!#aC`=VGg=Gw zjHyj^FqZ?z_w-;SY>*I?Ri+M*y(%?iWFDGw#~Fmz^M(ORD>R9)2&Qn4V0Xu^31>jDb16> zB}Tj1ivbSTl!e*fdx94e?7wf$wdk`rmfn&n-vqsp`P%nGE1_WsO$v8kmKvq{lMI7_ zJ{f?z6p+v#D|ET5-#7Q&OiqW0+>u=<=Dwv|?TkN)P2=;be?<{txz7#X+Px>~*yPY% z?HYm#>MZSpW(}ZtUYAvunt2jQfBJ=f{B7NC2$*}UZEK$LYAK!mv&F8UBkQmrsf}S2 z+g2h6K5u+!Y#KvRAJ_sI;I+AVXXHKS19*5>;L{O)!fj}(^FI8dh}dvGRsH$iolWKD zb0!1?r$A~WxFi^-88(GO95)OSwuZE-=zxDfr}|sQ1%DgjUzcQmw>fYw`9qA!l`Nf& zNd_EI3)Sg=<&K`xFSGu>bm!F>tc<=qoCfsA5m)RKHlRUf5Qkwjz%@wCeEInR-YL2n zEBuJt-+J|)bO$reJv8?|Ygdsgb$dOo;24JXm{kbrA3|fbOX%HYQ-Lipk4hIOur->CgdWOBl-k}!5!-SLvad_fU zA)_^r!rp;_G{(TuD&C-IG@d*_%G0%HgM!ZrWDF$*kiz%kVnO5RW0LOZphtdQz2wbU!uZM zL5i8J(*7hnlWrrC&avpiqWn&m{)utg7BWGoyE$H7fh%>VsBjvC(N&oaC`vBn*6w+H z-+b7=gi-E)9Ys>wTSw6#kzFYb&jih>GNOfv*=x=5RFhQ8$f z<+QK)5LP{gS(vCaP({Vs1_L0+<3Ocu0Z^Hpb^14nRfDiJn%O+YNlud7J_?@NhM{c;M$F6Bxk0}NRZ>tg}8#MMTSS)ly62_`%TE`zo6Tj1>Z-Swjj@XM??^d9i zYmpcsiM(f+3a+npYJv#Cq_hv_ZW?nqAZQ*^HBs21W>LCaO-4linz4{%S5 zh8m=&%ifTscD!|_oKEX6Ss}RSSsE}qd@NJ1NS)v@IU2Ei~*mipIpH}g7 z_Db#SYlmCGFG`&gCeh>!FKj;hue1)Pygjkmz$Q04d6rujJ(N1Po(-e#>se;HH?VDk zDK+a745;*J3Gc{Y-Rt;H26(-w7da3oP@eoN=yQ1AV8kaNcjqV116O(I8q-SW8ktXM zw^{k2IPSOapOo)jZ;9s#<~ur?IA8vFRyPl23+`ed2e525)~HX9L%wKOlBe2Ro1+mavYf=gIHZ66?NG*$K zBE|hoLDc=E<%6yE!MsK>|C!`3;P((oT0l?efFMv)>!k$A5vMJbTm>prjXP~M(#*%@ zau8XdBuj}hniIJ00qT$Nwhx`_A9Fo=gKeV(KTLTL-pA2l&N)p>T`GazUK!3F6&gXYQuU-bk#8&e))XBgPQ z6zKl3LR~>eA{t?bK>^V)Lahl`0;Ttp3rR}f?L~<5c`VdXCk{ec9*6@G4d~nF>**qV7kRaVpkgjhASNE4E-#`9rGQ>bADz`CtD+>^n0mQU&shZMnguy)< zb`W722&GFdJG2g`T4#L!Yj<+CI)*o)Y&=J7>SDNRbd8xv4RNDpeAz^*T&Q)8@Xr+@bt?~C2~8|9{->u(69(? zS@ew^`Oo4PEiQn88EdKok9x=U({uDYKHD!(w%=tC0v+mTQHLoI3vMDCe)-&iBn-~m zUOEEUqZT%PInt2pO_7*=`ELtR6HZ!%ByK9b-^WIdv?sW>2e`_}ShXmMA!jrQ5UWGh z4m`SMh*1(vt$>((rAp5Xkl4@=GN=+D2WgX|H!$pkvT(=={Dtc%9y*%hwk*!~{B(Dd z^%pyXTM3mLE6W-?;YJzjdD)vXBv8xthjszP&X%d8LQn)^z9~7$wm)-4RzSASW*u1y zvNexN**VHNdQ|=|dALz7eC{-vwj3$x#G}U{WaT8L>BQx9lcv~-YhuQ%^^1g!C!&s6u_gd zAYLq@KMkq)*;$EI%TfW1Cl$vWGRzhcPecl4(E$x80L%smE(1f9fi=nmV6p)7_No2` zt|lj0fUUDlR!l!BEnGJts-j?p36rD>UiKkw!bJJUgyOY|hI&Y{@%X z6%{I5hD19k4R;TFi_!n;i^3b-V`d9P1U zIl{lOgXY$c-snx(hv$fci>{7R8kfpPSL*a@o;8$@r=sIW2*xtO`27AkF< zFgi*uUa~xHtc(|IJXj1Hha-%q|KeXc*($0SOFMxoPh{ zBv5f8cSg;k{X`Mm=@>tMu)jdHgO{5xxw{{$yMGfBz(?O7-cc!tRpn59T%|e!tyHY5 zKtT)wloEoec(u9q0za#Bo2sy4qikiM$9JFozrF36o1` z{|<`-5L30TS;5oQH7ICf<=|GO;e~Nt+A}|?un@L!)Hb|FFnCXZ?r5>VdEM$*Yo)1W zKV{1U_v~Q**||sRH6POyniujVmC7@n$}^3;HeKLbhPY?uy>FQrkPO7PtY?^{{?83k zD@UqkP3x@LVc&A2J@XQ4$!()-Q@-VgdFGdYD`@pB?5Q2E{Z>d`7hjX%*r@~6j3#)@lC$B26gDQWo z>ac_Aa{h{8kDRSlNd~*#`(El^w;GI8=*!Io`scYDoiy-AMC5vHZ6IT zpVuL-4oc^|q-pEtK!>R-b(3WErb6D&uDvK9xFk2;Hpgn)!)j}szC9o2OgZtym=4~# z#JRb#kaS&4YSsuuH`mqk)N2+UY9FbvHVki8sIa1k;g=?TbM@q}1zV|VU!{zaW8c^R zs&B18l3Wb&U4SUckxdz!+F2@}UnAn2D!Oo>?j9tQ&M@Dnp^x zRO0`{ZkKZ1@EYehR;U%zh@g!t9P~c1whFND9CWF>G&hv!%w*K(P`o7 zIk%NY#L2|3huhajxsHMBlH42gr~1Q4E9Q$Q2F|Z3r!l8K9CK zR+FqBIWRy94I=yIHJh6bhnq}&k!mLP)f*~ED5tbu^o7x*tGdyt;_qOL&V}Bip9F)y z`+bhW9v$vILR_4DC-{DvIQ26Qf*Th8+aa>xGy0E!9sR8j`(P+o6@xUufFB+I5GVQJ z*1Wt`^P}Lf0S2&K4pn-J{ANYtsWn5qM>9#0s>~3u`FA2^UkE1#cjhlT2hN9nc{swv z!aDj=^jh?KMHDYQpPWRP(M;til z$O?}}mYPnsJihh3NZ#Ymo#Sj>Y)c$hl6K(Grh_(cX?07_5fn~Uj1sbQV(Rk<{1*v*_E8-6 zP&SH*XUU@(%&mm-{?r*_rK@N7d@uwbaaeI|1zf!BlRtpg1VY5?YKXN4{c@O*&rkhd zxRe#AVX9wg3(flj%dKM0cU0XdB-}?O1gAx3#H8)CnAvcX+=U+tBj}{I{rx@KNE`yf z_x*7etwXlApC8V33WRbp;*EXKd?8q7`?6 z&0=_fQkf>7X+!n3Z8V5iHcv}&65qwMRd9qxF<)ZFIUaTAi5)B3LPKfI#3G>82o0s)yUt2lZ z)_yB*sWq!3|G7YcPe~|CaiN)-ut^@hF*li&OtzS^zVU`tp7L{Z9nmsWTh#DWb`}x~ z`8(PE^~m7dmxqgOj-Xxtch4)+)3ikfea%rROB{6?utqw!pFFzSzPh0skH7wr>enS4 zY4JTsJ2{BV6Ofij1F^6XEVQ4o!>$@;y5SvU{H&zUk>(on7qG?c$t1jQ`XptT$LVQ6 zc98ocNlA$`Tjx7`(YsE&cygB z&wKwv7C12zm}KD7)*00)fhfIIN6OIb>TSvzP<5}hb=f^HKC1|;Kk#~CyGd&) zwXCLYQt$bh$&8wS+)Q99iGeiEF9A9HJTs|{3Sq0FK}KcINT+F>t!;X#B=ruT%O)d6 zoKH0~XWlrII@5)IIXGD^!ZTK1@XGXD9q&(>&8sny$;9gHv6@YV{%#w*XAj`xae1%B*ImXLafX7UXipJ z7~X@ux=#NQS~nlgogKaxb=}T;`MR^W!`trlOxV4ibo*V|hS&QY#Xd|WUeZsjY7GAf z?&Nu$ysdH_Wu;(XO#tx?s-n{|b@^7Poe%i14@riCa#3xiik4Xqd&yH2Cao0`qgC{C z6bO1k8RzndKQbha-4wKcDEx`Z2o-kU-F&TC#frE?wF%Tf9HQZIqvNm)%a_euY|aWSa+6{<5sL==`;D! zRgoi5`BczMWB4oCqNoT*V*Zuy?x$|g8(Nh?E{{K&2HjIJYp5Y|m0fvf8~7#+k9kyF zIR-%n!g{R9_oP(b#T2+*D4-KZO-m6ozaE6qV23*WNCU!eO z{Qkc^mkQ-bNTm1a#f?VAMp`#Bg1m>yLymKVE#AYU?%8md@;79pV zc*r7#((=h{kkxsGXF#pq+sdRq|C1Y1)kYg4)>9h;{<(NkGcq#YuM@6i&z0G9`T_!X z_U7%?CsJ&B&!30?9A4M){rh8|=&d)oZ&_A<4<}UNT<1r9>&P`8$IuXQ`S;f`qMZAE z1Y|;d!?Wi&tGTANrGgYVi^}F{sa4>aD}zg3)Of+eK}y2sK|3uI#ZPX|+}W6REeTot z20x55dE}|OG1v#z#v*_0?7x6Z&3OzaXprv{lM?2B+@z#}dZ^-UTKIdW@PG$5X>(1k z#R0K8D4IaW<~}r4huMHA_Q2UNJT698)nk!v1@nl|w@Mnf>F8DHv9DH<7 z7|_3R(XLXvy~Hwew^!0Jnsg2w14nH*IK&zXpVFF?7pMFJlgm1mE}J)qzgx}C+nv(l z!&Q>P%~a(Uaz3*3?G9o|Il7#(WGE6H;)w-LInw!u)M+hUCv=0&a822C_D`;!i*L9R z3CK+IQ%7HZx_?`dH`1n62(eO(e3#%9ml?EbdublQjXgu{cQ}R$;5ceS zlXP`@$EN zTg|~*y3wN+YCPmSr#lp%v0nWcg_Heqn&$#4BUE~y;jgaF?LS0SE0u&lAb0}cb2e`& ze^uZC=97v&*M9e3;txjb8-KZ|o1i`Rd&%9%q@@KG9k^akH5(fuV&Tw?-kVa@2vPITGtU?peHNr~8m4t)uP*B-gj7wCd!|&~s zQOMUQ>>ZCLM&7*p2MikoIqlxgkDTzFS0@Db7E>a0T&M^`2T7VItRea3syuSYe7-cK z-_9)^xmf_-*@Tj@mk|}dQxLvKnYcW%3B3<(qiJf6g(=uyL(diSKV{t3rFQUsPAE5c zHo^F<*bFgd|RJ#n0oZ z&(v_L*yjK9he!ZhS0=ORGkf~R7Kj9VV<8y_U~;B{3dMKgz@K;d}UC({V}iyb8y zB+cu{aCynNfi}`s$6Yl`-8V_R*tt)ech$enzez)q<;#%oX$HAXBvX(VsA%oIPMCk2 z_e@Ad$i_C>(DMiIS?lt1)7gyEh4)R>xcRznj6(0%;tGzTWwvXA@ z-__M_WD_d=xXE$&%uOP4uQZ$eB1P3_=2s(HHExiW4Y{eSPVWcXpTV{VCY*ZELBr{S z$d?DE{0q=g&v&Kn7x{;>i4s3f33FQY3QnXKbZ1&9YJSEX+F0u8EiA{DWHuMRf7z(j z?&ehOZ@^V%qpCJ2TT9V>?mjG#_ zt)(|x&gF!i{Efi;;8dDmEQ8F)wOxZV!!UI+j&)dq_EQS3kG6C>@9trcovSPYEH%S> z?PtzSVg$$It7{~VJ@Mt#H^ytdXv`kwGI}L3TUIe$f_2o7ehk0@QF)OPofLShWE)BD zq(jJc6oA(YlaD3W2!+TUW#x;}F|K^O=_4~7pXi&iFjDucy!#YXIG|1N_o7Pw$THGC z8gmv_hNJW0?vZuPy@kXy^F+u=@((NSxDjh;YWdIJJmzN~dDnQp2gs=DtEM_woceCu$n&gDd=qde(hM&svQpaxCki~Ug z7uknPf2OTa2Uh?@9lW-cytpp}8rBY*B`WzrwJ<_+fhly zKJLq!!Nw$^h%}JqE4b*!CXt9T$k7oN@V*S~F@`gc3u_#yB-xG`&H>`)m3Hv4KXl)> z{|i}ODPHA}Cnbd8mBaGXAw-ifbR-P#HFDRzZuE{KAEFN<)K4dZ8{s|8{4-+D#Ra&l zvS;6b;o_=n{wceh3_!26Uk42Van|k((e^wv{w^NlxH1!kA|O^{H=i`IUEtUu__xA5 z1D-`qg*LhJ*&>hD4mUC}EakXtIx#g&PRdQ5GOYbr-XJ!zVG&5a}9FGlT5*gxobt6JNGo)>J+f z4w)ST#CMGV%JvrA{Zz(*r-hm&xRlRWud?dh=4V?FRpt?q}f6Iz=SDAQ7T^F1>^ zz?IeMDW@d{w)tsp7bG2|udapc>tc1tjUhzC0jv_?o1KZ8l6Y+4>Sny~C?InhfSjg- zi{(fujL5a~oDA8SoQ+7lKN1YEfLC6AlXWD+L9>Y8T2#&0StoGw$>!D_$nVS|#q0GCM&9qyk1NFVhYF#ID(H2twmrkK|1H#hLagZ)^M@m*_BX ztQsUu&}WX?SdulNBe}lHVyI@c<1+K~o^p?pJf1k^&Ut<7JGSubXElk@cHlN>Px>*b zEIt-f3@-DNt5e>;Bz)*^u;-qF8iz?s$~s6gz$Yqvv=jV{q)!{e`RYqZi=I4vLMkBe zMnHtLfUT0D=ybu(3T1uuFfHmS4xtx&BcvTAR5mCuY6p^wlA8xa$!94iP4E+cDT#@Dhbmgc_R$7j<$HhrMEmx@Y2QeXzs1^t-udE5WA)M5-JVe z%}0vs&deBwUcl0Hv_AkeJXyT|Xf$bt{!lRyXc9Bw3uzRDuQJ2{7GG*24Z=0h+cby} zD`?@IZ!ccB#Av(6W1px&xgbgBy2^Qesq4-H03lA<=;m{bjiJe{*&hu>MZ{CIk zqk=pbOcYuCvq8^X(Hs_pWx>DQD_Gd^nTa~zeHNK{-YYCYJYnM^OiupR_C2NnK*7Ly zjh4wmFPQD+boNVqbjt4(Oz+~vI*F;t`Dt*_%u|0lC}C^qURpUbn}R;LvY5T*>c-?X ze@^60n?p>g@!MHx)AE!8<8{F-i01xmF zXQB`6P|io&M-YeCYv9-4EPp{}^Ub));eRYFtO6nU$RL<_eli9Z(*b2T+w1UI3s3ic zH_}rtviN`0DU1{Dc<0_C@jj?8`vR_NQaZj$@xCtPzJArdZ*=^$;{`OROvD~he9-YX z@$$2t^|u$rHqa4{Gx0a03iwVH=;J#7rOxI>R)C34V3bZ!TwP-zmB-;)pk;heUVLzo zC~1;SRaF>+@tM0ZdvFO=Xs1r-@jy`Xbzm=5*o014Mq%jBt&kb2@O7PV_rkEKjj(O1 zh%=pt7g^yd8{t<}aCB(I9hLv64xETOawZ=Bbrw!K7s;3qOgSfrr24@<_rqT2M_66t zlY}UV1m9+D8h>9ZXV)Jhb5R=9G4Cbi=ED7pRV=C2!8vDDx+4*dPxw85OMIHCjH`ci+iLnBJ+6dbEdTw+bD0S&=#;RMj z{RU$;b?$y5^+yTGA9{_b@tbEG)louiwQjZhK4b1eZJTa^SwlfUHn@JFdF8HB+RIr` zujsGa!a!rCK~iFSMky;Tbp?{P1zo@Gcn<^z=6BL&9^TdFEHsVM<^mfESS2XBKI zy)&=9M93zMlCH~Eztjn%IO!oRX`kBuLGcGAJ?n^V@>1TZm zW&=`Yze`R0mK^1jqPkwBg0H5U(2f1f=(KFgv2AL1{F9^9L|c>5l_x_()7;CHLe=w) z3g+>Pv-#JB{?bg!(!$cx3jOlB!SZ&>^8V8DG5yM!!OB(2%H7h+UwQ<(Ap$!Ufwzo6 zIj>0#S1D6hX_r?S8P-?~*GL(bzB5t9ri}JB&qWz`<^XeY?iJGKYH^y!2&6!j2IKYj zG{x-;v?~`7tKAl2A8(%8MZ$gZo8yzyDx8lXV~#E+zCkC30dBWVAzc^+>J}! zOg9mky@rH1#Se)x73zw zyhK$V4$_k>Db+N0L6Hk7?c*_C$5BkwaNr60`xET66TFoZBF5jO?|)OK{ia>{&B%Dl z^8S=P?UZ}v^agxWkHtnu)<*pSaFM0o`H|@{h%AZlj`-%7WGimn=EB7mm$o0SXVQJUKjAIjq z^Nlh^b4bq|`__3UMhNmAb@h}c<9@kO|GAcszTwkao6~*`0d0--^i%Z(j*=`T3y54W zok~S^e-y`?LjC@VoWVFglYwNF%G}{3(a(E}{grv6Y0^Hp^r}_)<5|j4x92;K>s6uC zrO-uT;^ewdgfow$1I7@~ypb5e^mxMJ$};{~jjhw25)8(!zVKKyvW^{)D8%vlKJ zTx{)SM#T2EuY6U`v94Xk1FyFBc%{t;k5Rp;?)Q3M6!-g)ruwt(v8)$q>dg%o`?HnS zE69=N#;apQX9%N4OVigCQkA%tMARKY>19)m=OIn;^Gb8eBB$%}$47w;m>dWg289K} z3&fU>@WvP3LHK|bIaYni-dU{rQGLu`^`~>*Sq*^rbF2kEinUk^;>gXdKXd0o4r@sbh)=*)`rD>P~Jsheeko7t>^$%Yqft+Ii|>cST*_1 z`mlQTW6>c>3%Y+;i}0s4Db<^6U^V+;l!|ecXJ#Rdn3)=W_qJ z6@bli(uP54bJ7lCFFxtO7dbfT1S|3U?jqB+`Q1&m@6MZ2*3objcDTGf)kqs>bK1|5 zSA06aQ+seah#K#n4GGTJoDHK!zGow-;qMu0(EIp&OrFyAd|a8mF6L1WR4x`=)n5uNe3>z`y;^eJF1cFv zxH`OAfnoDrBYY|Cu2%!uORv{LMUJl5;Yz$W8`0W!VjG`o@vgSc&5mxi(*t;Kce3N` zZg=zZN^kdyYmaXC%Td?&2URn6cZYS`rFTb7S4VfpZP<+B+a{P80HzxZfGYq1;6eQY zAQ-7=0rdaE@BkwU2qWYHCKSy7z{0}vh=qmq0d{tFP7V&P2e=>Ld4QLf_sNqde0+Rd z;`~paJ{3m&2>gSfprEjjkg%|@$OB>zh>MF$JRteNvuDqqKYuPGBO~{K`~!-Lib_gK zDk>_f52&fBy?j7JLqk(j^VO?YZ{EDoLh(*Z;>#Pfw%4+s-f3%V>*(k}p-??NJp%&+ zV?%vJs0PwUtKIdr(fjvCMn)eVFnPf20dsS6iwCT%tgNlAZEbDs?Ck9A?HwH*KRxjI z^Jga~Cue78S6A1sU%$G$yL&wF?c2BS-@n6PFmG>fUteE;fB%37f*uGC4i0%BEG#Vi zfryBR$jHba4@5l>9UUDL6B8R78}~qbe0;(Ki4P?GOY#FL52U81rah4UKt@JJ<^x$- zS=s-R^FZzcc@O00=NCLs_%B5d6hBbWZ@L!Jq<>Z0We>r>L{9i8qW%n+&zrg5>8QLRc)i&B|HvCIgMq4oi9F3L)fCn0!l@#iN~@)T>Y|x4qt0OZ7d6Gu zG_ucy-8T*e&9x5e11T?ROaBk^hVsd`x*7ple;I)ghL;UhyA%0uiVTMvs`qEgO$Pnx zt1`Be2)<3n^fvzQ^X9+e2Kk@7S#=tJ+GGG0)TnP=>Q8(AJ>~xH`fPt?w6*o`UjWws zS>90nVqdfWbWz3NesoBxZGUkXFcQMo!?7MJIBl^WCc2fs9xi#gvmPOh#km3h|IQo3 z{uPhrZnHJn)cV>?$;YLnEMgY9D&e9wHM?6$4n3UP$zP@|w^LlV3bs={E_b)n{ug<( zm!D|aRLYdlW(K6{WW2nz?9b_t$nl@EF{LN>=abs@_ZPF~ zW%rkhF30y*h=3=^>y0>jQ=7fp4zdNi%=qFFKS#=#no766d2v4)QGv9L2THraZR&yB;Kq)z=t( ze?g> z%Dv+Azr$UJvKX%VdY|3?j)383L$Fo)WNA*}ZX3*$KRIMf0Y5$ECs&B?Yin3Zx@_&4 zq7t?!x~=%igS8hkDZPOB@8f?_HlymKwEG9%HJrwjhvx8@s|@PSpT^b=$Zs%DLf&yg;Hw}XW=9pXze?I?=m!=rMsY_XC zMHT!dK6&QCT3&1mP0x*R^^j5(RGIVIIfm#?dQ&LBEPNd|FqtcUQJ@)C_%=^+eFBazKFKgkho8_GLFj(n2_gI$sHBGS4PAE?NpEoxJ31V(W4{P3ea7 z2D=QcGu&PGN)uMV1L)Qm$vSiJTKpaRfhO%8+EF{o?Ecgeq4?mN0iBVG*xI2@UiXAv zYAQtsJrChF+3S9>YDeU^$XEEr9yh}d;g!kTYTM!qUn@IAE4-=yd`L`9fN^~|GImK^ zHNi)xa#63!q#WK+l(-#V!t{@a4wnH-)dzex(yu=PSM3d;PqD@~b*l z!UUVTnnt`nxql{ml2@qQ_uEQ{5gKW1x;5Bl8lm)*eE)pKIXhX&SBTx&iHHOW*TusXf^0#4y8joZ0lLn)?*Y7YrN?wPUx* z&1KC*)W5{i(hvHTkN5nZC7QSpy%9=DL|C{6vC)Fdf>_TeDH1b+t@s zf3A0cMx|$usAG4XL24-~N4y2$Der z7LPL+%J?S>w?ev?$mkVF>FqkTxe>U%yzmA~trW=z$1t5fNX1iE1%WzZJZ5Ez z-$3cFfDNQ3TteQNpiw%2rwsyi&jwN~p0w=EwA%OT>7DM~`{yvywOzqgS||sq#Vp&Nu@(pn0{92XQd^9=AwLyvkZM+YToLatg~QazORYNFGB%>5T!Q=^y!!Is zq)jyQ9ki&aU?NJlNOFuy4h$JcIH2C3?ixSV%$)!NEkD5q6?g*qLc0UKv8e(5%ILs! z+;Tp2l>END4Kxw|P05o1QA42E+-&8y&efZ7ju{>bq8EyI^&)<<=I z{;{7=^P!{;{$Hq|JP!Vxd{Ac>*w@-0$_0A(AdJ6l=rLw+Pyw8v4^H^iTaz>LuXJQ1 z7%MUc(BBpbg!w35gF4cIKP~_pVC-1GA1ZUPhSNWqjl$<@2={cNUa?t=is6gTLC-l{ zE|sCzfp#(75!lxec39AFS1{t+L384{(FrjEhm42|Oq)UHop2jKOO z;e9*7&72G5?8RN8gqlI{_D}H3HG`BylO__FH`Z&@*S3@q#om-3*H0_&>X8+wn<2TiCRktn|j+4D{P1cg`%y`K)KRSt$xxfBQ2;2ErK&v)Xa8RU5L^aI<6^ zGM-FlC?;lMHe|hY%h5^9QNGC*Rt-kuvQ~CW*A>q-)y>`S&5_^B5yj2bO3eOvo9jT6 z#}$zKN;g{=CzF{g&#fWPW8UVAc$AfRjtxyF^4)x%zgvFbzz^t5nowfy#Z^wrT<(X& z{Ak^RST57=g-Kp+dB$!9ska5`x*rm_a+0|UGTaLD6AS+e6*{|R=N1;0(-c({8WcAa zl&a?2i5E3A6g6?_Ro~`Y(-hQ+7c}b@_qY|OT@-0^ zCYE%omN={A%oLU&Xi5tPO5nkHeq5zHiKT(6rR`Rw^@XJ;G-VD0r9*qAU0h|?iDfTT z%cl2=Z*R*03t4~MijXwrSnlPwV&%)a<)DRf!lYlu((%nG=5^eE96{2R`5#La^ICak*E}WVZ|@;Qz)rY+}d2E=%)l~ zFn?zzbyq5*SEcA~Cg)yOJcZ3xuS?VhicJriive*<>na%GBx_dZYvEENbhVSJ6E3QC zlXNv`s}r7{GBdkf;`bZp<&Vy1nkTh1Sq2T4;@)?rI~n2~W3uU$=YEV4D`Y zkJnT$0o`;r*bRZ673nSAL9dcp$BnvZYPx@t>P?E8R%mq(@fu<_ zTXTgPva2y8+Ta`eO_xROK+U##trqMiD7hwXF=kt~PzSSGM+bLf>}LB3nOvpyV~O%wQ?8ajXX9)RD0XQNAE17#b6ax`@;W47_CL0|Adm4@_QHMQRh zb-!!URgr`;NkTO|bPd$>jCpj4=o(H3+w&FLv$R0Z({Z2ogA`A&qsjwY{cv9n0>8B3 zMDt++;b@_4ILP!iP$=XF4H!H51p9KQ7sk`aJlF0e0knkU1V}r@kmIzlL6aST>Tpnc zIrjIUUbms%*qlBu$vz+)r0D=kHnIT%`hTE&+pO3T2wZQ;Xg`m>@6`1P27Y}`2ME`mMGKXVD8=(Qq z`%_SJavtb$$Z(_rT4yMxt6uL*T7Uu{>O+K0pa$jBhZ>}}%fm6P0pZxFs)iR(nNVmX z0L$eByNVKU!UNs&7-+#CigX%!t2EwE*ZX;KATo3a2pQ_~XvrSx`)9KwIZjJ37>$V> za9`~Gu0OzBFxav+-t7V8mc}uq0_crl#$Aj}Ne;(gVnu={OTmsr_haFbP@>_Hbi|0D z?L=hEM5@9_Do+bB{ZOamMEpeyMe{e*qKL_MAl7UgFg3Y2 z1;$5>`+w;+4o2n-hty5Q=KRX!89lcd#UBPa^FZ~M23u`xKBE>o^iYrCUm^I@F|1Sd z`csjt6Nm0&sFg~7@j&t7*bZGC(bDXUP2VUTAiiX5?ZvO+;u+U(&{Tr)fG}v1!LQ(N zyixn9(O7Da0&qiLTY6Uf~$P6BYn$1G#|h86nURJuF=$7(g(F_PV&; z1&)agLr)k>KD%rAguuj+MvLS76cd9rFbs?U1Ef!Y7%=qoHUJQ^G-AY})DE&|tJe`UjVdFXI4P7ATPl#JE_ zW#om@c_Idv7J(-~DNSsAK3stljERTM)6rl@%tZ@JYNR)KRY!VtY^h2d0eU12;5})K zi5ZQq9{qs{gq;BXdaPwYFq0iX?T?|D-=LA@fmCfc%~XI8_w~Fc1i|vk+PBpOku8AX z8jaoR<~@S=+3J-?kACvX-Q%slw#zXJD^uT=^pg=t8{SpPR1g&8U7ASQ{uSO6UA_Ahd0@P}ZD+TsQ@WYQvpvoL4ZGXHN{#GQN5DN1+Psl#sh|z@ zZPW0r&TweR;Nhkr^t5#4PW|xW8+3VOy{83FWvn?n|`t`ne&&!EZ-P-CNSFFnx; zAz1h)XgRPzEjwr={LEh3#d-fyA>v$>@q**Y&GYxa32jebkDjZ)2TCrt(j63l-_8pRBN@x@Bm_CHm`LfcH%G4BEk0IPwtcs-54S+gaB9S&#!=Ex4@Iz ztendrz|9NBt7QALM&$S5_=wZW@3#p;x7jMSLg3J8#>*&$KRt|yK)dsn@Y^=Ko5 z7_-|SW>>LhwbN;TB6H4}HJ~9y$bu1QU)i6+l|S!FuYY0Q0*E014tzB9^GIVp7@-&z zOPx0atQiI{8PRtDy<+ZG7Q|?|A%;ZudQl0ce}I(Z6MKa^bNCj3Guq_^Fx#4H3v{3+m)^iJ@(Pm z=5NS9hkD%h^x}>yRa)*f2l3^G^%k~MTmh;u>U6>?ed06r*ZfiXG)-2T7+gM%Fi>bQ zJVS;uAL|>^^ISd;Pn`D_GUxpWKqwhXRUqCz`+KlB0h3LY4ni6@l7{U!;+7F@I)L^# zWT=_8zHNz@j#}R-L&RcS^D|M3{>>-ADy$K2$j(C|YhS7-a43C!Xm7gAw7j@DpN#!LmL;2>=pun31x$%F|2FewhI!nk$700a(AD#BY25JzsAO!8>M8iqn4-|@+Rz$r!`JQV zN|;?YFp0YHMq3WItWT67I{0nfkN_SMJ|CUW1i}no&-h>5f5@!pqG|Q9>5ZQx8~(>) zjYJOyAW#a%$3c_9!~9NfK_XkyeQzL=wq23Jf4|(~XvoN6kmYvUC6^4Bw0*Hx<1v`T zkt0xWe=Fui;S*6u#QBY9U|o{HNbaRpF|k4$1zwD1iq%EX^SMtRl|wrxrjI%SBSvFf zBFz}ZMP(f{Ma7lBbc;%A*Ak0L8&Btp%39%myTG@qz!`ERm5L0%0l_aI*$YfJj!Xbs z@MJpe4xh4*8sG&iipxUBC!B(fYEw#mKtX$n5Tvwfw8@I9B$d8I18QD-Hta!%}OvUs7z74H1X`>djH*v5{nqe{6z_0%ggvjGgR(AR4NSN zhXY&A+-B`0Av~31uR|W!A}W-48xA^NJZbr3l_u-V7lgqXi1%1!ZUl+($p;t2OM-O+ zq{pQKNSdw!P&(5_X3=(l2ZZ$K^)fk$1Av<6G22&;F5oOY2oq&D;GFZ~9_W_Fwleb( z+-0DbSC%F1>Czx?GQuLC^qs2n{_vDpno05#M#`>(FRMJ_9V}4BW%nif^C}2=76&|r zm08N%feGJ?15D)Yz+ooXN9M-?dIUz`_UH|vYP`|Vs-)4;Q~*@^>2Lt2F97dEmWraS z9TO*;z(5p$r)n&lZ^laEU&Jj)hT1(e_wqruk;7 zTe$jQ<7P+8@i2pAsR3-bm^iR&pLaZ8>r14W2J69s`cv7I;rJ%>VjLP!(N{ECcGn{L_f^PK;IF z3u-14Mbpe5T_Cn$~-7vD%?lQDMzc+O$(xf zkmq24kqPQ}liKfO$TpN?6#>HjBe#BqXr<)5*itkPM zMw75q6&@h*C4-ELsaS7y;B5-WB~e2~CK3NO)WEVV9 z)hZZqF85oq`A9JM_P3pLMNIdhCfdH1e#})l+V1{8dYg9P%bx>cWoCY#ytK&n6O8YR zWn{TYHBCF(h_AU|H|tB4xmq>2xh1wma6{y+2%v+tRQ+wyjHUCF)?Ip4o4LZdoL$>y zImfaL{nZt+5W=7LOTlRecu=HXifd2iscDD_$x16$dTs0DKxZfJDYEUOF4?W4w?$m< zL&s-|`RDkoSy6WI*E0>XLaf>FrUk6l=|)M4K$jwSgZV1Trbkl)u{pO=@d(vn)l2Jl z&qC(}tj8z9BC4aO+zR%vS)C5b}T4^uL&xEVs(FFR6Vw~VoB-WJw zl(JJ~%ply@ime%+v-Lv8)3U87iqtI8+q>!MEv{lYH(xBZn4G;G8^kKCBzpPQ@^}G( ztt469OmxS=0|A1L!vH39Bl;>sn;U zN{q7wd>t}-_BnB8aZ9B4>xfg!=Y%ZDxo50jDhZ?}EtGCwML%ld!@g6Y=U#y|W*2{g3?~)PD&?ADv720C?#{;fS#I;VP3;BhLMG_CZ$tkZ zh1?3+k1N;b&C3QNRx`EB7VRs|%RVc((_)VFiau1ovA+K)VL7%)yZSOVM7UQ;Y%uvO zj^HF5DM{#5;UiFwO#CLtbbljSifaE!{grq1W1CvTa;En9yqX9ARCH7V#xne>uwR)m z{;;^{vr3$ij*dh2)Sv^^pe)hn!?pMYjVi9qLZK4JZ)Dj6sQCSsPgs*dnm_Qb#dB`k zx)yHPb_=fR1X1Ul9wh_?BPrD@Ln8E~@tuMf_m9L3Ul zvl2Q#=0TH*qY&so2sgTF;I1}?v>|q($-A=vDJPB=8Z;&$jk6ehAA*D7Aw{}~3w|U* zP8NvUMyK~#rVae;*{2rt9W>H-*kg{Uyt!vOL&5s_lc3hcH$H+0$RD4eyNT8*?i!j$ zv=l>64OrU6s^k=-WK(B*%#P6~E zk{gfcF((UpOBRTO`nn+MyRlnr6WyIr&@IsxXdwvtEZ@7Kf?<8Gp!h}6!c@Tr?xTcs zz?|Wr{3;02tx`zY`5!)SFF<GJ-FRC0@6%meA*U}GXYQpJ|Kf1 z#N6jCtNZMU&NEIrIK7NY43A#`%CQ(EOWQ=qu8g5Mi*B%?pc<;|Wb@p6GDwijN2E6p5Xo-9m`dtmmV-xyFpJWcJ*Aq-o{ap#RGvN;{DS631J!~rs@}dRica*^ z@ALQQtL_@G?i$R147d*sWL)>c4yX#c$cLJG0DN9yT_uCr0|0;m^3@-?rceyMugN*H z@>U*f2e~YM4kcP>JD;YaRAR)g1qa{5$a0Nc9-ni4jS`L|v~H9+T5j7{eK-2S5nkt; z92kVDrBUOkac$GqT{nimq={h*{v%288ubWrmFTQ>}bYE;u6)%(^{DqO^7E3>yABq$W3%pOpum}Jm!#MZF>LZ+90A+v%46NdWi)E&ff*8k@3VkXyAvm0@ zw>$pbZBoMz=e5E_wCgw(rpBv#c9rV4YEzTStdj(XUeqPyv{PE71e(H9QyJ;xALwzP zznUC1oq*847X1|?L_P^Xs2>YTFDRok@_`6lefI^&s(%G(g{5BkjuTIjtH(^s8Gt^8 zy;3LFF3|~f`Bt^w)C8jyk6V|_I+aXC#=o71&;=AwC95Q-fCE$O$UX1#(r1I`f78N- zpCyZG8Sak$O~>7$)+E^#!@I_XaoEXNL9*6+h1rtOX$YQ@SEEykjV83x<>ca1XD;# z^`4UYH0C695C;W3p38N`t==4CEueM{3NA3hi7{KqgW-OEtb$kIB^5Xj_YF5jiYifB z$4`3UgKgyyE63nc@bJ{!!pR~sO-Da=2dyt=abgpihB-fRxDd9vxKvNjNyQQ5An1vsW2Ghw{G2UUq(?F1p;H{TsDQnZ@-O=K>7k*F=6`!$L6T5^FlHlmHM$#DPcygamL+mOomofRs0N&A@RHjw!9Y zyLts{KMq<^r4AO%MF{)6N4AlQWspjEMNJGKcqzuDBsD@vN^WC*Jcqu2pOI}5Lrf%$ zkl+lPP$mEunvycDACAX779KfTDu|X-ci)sg)v6+>VQ(^~uO*&6 zE?yI$h+#4eTn-8vA6|+Y(0KE?;k-Un>s<nxn z1%2gJIP@B8bfdr&vuS)?;dS(70)$s`;zg?1R!RnB_tRHH;THOc<(<)>0kf8^K!38R z5!|STUG5G8Q{kOe;v_i=OE75J%V5J}F3!^uxb@RFsIgsf^8q`@3-rpKBRhmc$FNM)ng~^SN9PXoQKmv{=$tj zqYZ}4G%)vpzyw5nFpOmL9~=L|dL+aA=zkB8DU*_+<9nq$)>06+Vo)%dpU zGF=YKThhKB4l69B8v*$1z_4aEvX(5b7Z#A6SUcRk{I&3cMN2k=2D_$Q&QJ&IbUs z%s_`D{+omE^XjHtuYD6CWUrYhDvr=c^KM$~d)YVu$EosmT9)YfhLTGyYaO;|5%kL9Ykq`kdH07@($D-sv!zRGs*)kR)b_}V zih+_xXT17zju&eJSQ9vu#|-rDwXFL;8Hg&F*(<~ao<4IIh~y9C-~NR6G2z03pZhuM zabhLkXUtyK7ChzF=!`?>#um45V=oR2TY~NU?z4>!+YXR|V*2ume-J|banoA)G4s#q zPvvaePnlzRpNj%mTc7i%7pdhHvA2HW)8NFPz&#c}mGpV?IHFyg_7l0uPw|jbu5AJR zpr_u%r&m&}^hy^Q@lMO9j~QJAo-qFW-4I1C0J<7DV17}c8xSPIa$-p+03vW4adzcZ6Z1mr*+|g z-s{kr>o6iQ*Y)cN?62|VuFiNjhCZ%x(bt5D5P-6Z6F^)k8%DEfLN z^!s>NI=WRmX7nbV@-~D0HdEv_OX>ER#LdQ^uWuCVB;N);{~`_KX|nWjgN_)sX*Q9= zB^q8-_sfZrVMr0n$CdZT&0Mdntn^GO7;#(e1q+VF@y$5szn*uX>%5My}J{+<|2lHZS93YzQc(-h*zDz%h6uvLS(TBWd z(XB*=ZO*+?p%#wi=x`cfwd~a!=sLTUYY^bZTBBnUae;dOg521gjgl5Aq=dOs4)w*G zY~p-L{Zx3k1CLl37BLOOL871^N^!v-{) zr9Ve$-l=k7P(79=Bgd6NTagc#w>$ccriwz0mX2k2jJDAn3kCFJMh=CZUAq~B!GC$M z$NtN9t&0KpFT=JxakdW&YQE-;#BwS@$*YgBAOVy(a0eVL3^MO7pl%&WlEU@gpuNF< zjXSK1OfS??CWtQi1c-hCG@-r}9z%0@&~D?2{Ncm8+G@0K1>mWbqYTzVV*`)BN}kIq z&^mn?0P1V1%GhOES9XG3hDtl05$TsptG>T?1bAzPc6Z|giQ5Rs|1Y-g`=9E^k01W) z497X}N2vdJbyREH=e*(79DQdUV?r_1~Ey{_wr z>vsJQuXAp%+w=8!+#lglawAY33oQTUZRejo@0$^m0UFWZ1r%V(@Pck%=%-C!ZheQMbIfdO#GKt-P>0x z%S~)ls+%dV9mDuXUCHSy$vkbcFD0L44&c2T_NPA>e_Wo9S<@`=+kC&Zwu5s@8{CBv`>>n$2SGxUS z9ORP|5Z|CUZax*dt-^W=|Jo0~O&$B^?VHcx-Fa_IjD19!ubwjz{Vx$gQL)>1-4rRj;E+~zmZMvY+-wnr?{uer7MfG=aIamh=`H| zym~?ccR^J!=Q4o>5sF|s^T%GpYmNJye@t<~LmH2+vZocnAA?osaEJDj(0OjbVXZ1^}Mhw)2=NQVS z?1pVV+t&JUWoe-6c1MbC3-hHbAQ@w~ipO*lH!0_wtjHZyq%$M#RQbeZfNg`R7PBymvqQyHbTN-x`d3@DHQ|i~z}#!#2Ii&jJ8^PC6tQMElry zlf5<=yAyf(z;xb!e99h)I{$hWqI_3Cp=f31LqXq@zgI0{FF1f*ZEHSoUW+*VHJ8w6 z+nc*!cmomc7+a5|r~LASh6-GI6Z7H6z3sYdarO=?{mM2EX*8r0!!8ilICh{hW)Nx$ zIhhX~-BrlKAFnWQ{>FBv7bX%M;~iI#CuoN~HWAWxUbRD5E@N|d51IQuJ01BU8<^6Y%OtqiS|fxLz~@F_#Q0e>wl7RPpI027JD5)cZrl=wa@J(6D~Locg1q zD;MYQAP1~Rf_ZZtFLjUe+_udKuWD|MNchYyC{6P-v|9Jx_I*J)b0jiY3(IIApnWpw zecW+-Iz=y>Fiz`{NdzlP;0h}d)jkO)Z))EZc36@Wzk*&B-&m+$Ar3a&J@}mS%p|AE&av& zP~cGSstMBSp6UYlSb^a2x8FJp3Y|QVUl}yPUDIC~d1I5-#n{NLy73^GEcwYqls>T7 z@osO|hg1BRhPOWT#x$d|G`!8vKT(~`)OGzCmsiJOqjl_E=8MPvHA2R#X#tn{=ffGHyEIR^XKqP&k#gQNFN3#wQ+6eSxk4O`*b{U-Ze4jeY|E)dLs<~#iQZUhrgyuLh%(qbkX&l zQ9Ys<-kG=a-vIs*HdT{u=STR1C_)a9b`hWsCf&-KRyjN^$nHITxD-t|l2+ji#x*rc z-PnO3fAn9tif!`Ncx7|-`jeLx2ayjomY!ckE^SwSnZ0`b*Gy2(SA81_SmfeYF62fB zSs4HBvB}C#Rn~hd00`81TAunnChS~c=wfJ zwT?gIfpqa4QB}eup+I%ziy;H(`qf*;8(P!YZ7OGgj@wOl7+~Gd3Ap;B0?-h)GMTi@v;~(Q#&)VGL5i? zS}&Z(WvWW-t~uHFyjiL%G%6-zr-#sG)DHbD6;uEVpmo7zh_8DLLIw%w47)>#DD<$$ zPA0SU|DmTrYXx}jRRUWv4B7{dme9d6xbf<73;N+I$XCqQ{==vlp=1^vlF*-_^%JHJ zL!7`B9F_*h+iSq5>2}5r#Wv!^C~gEOpJ#qjZE1+|FG2_%kX3 z#|YxXW3u2HX~At3E;pQ}o+^WmoF<=^>h^n1em+$I5sKe(?DE{<;&(pf zBb0f%<_X+5tMzrnUu77%+U45Qw^@>0xY%mHRK9T6gv)y+i7uK%iKzFvE$DmagQ+xG zbTZqQVFXMZK5i8ZcwQec;l4y z7z2e2d*RUFU`62+FJTR*#uU?+iF&(9l*q<3QRt1^yYtqX7_!iv}2=KdKh(W&TWdXE~;S-w)ejg%4 zb!)z^?#~O=Rr|KfHa3DkHFO1N54IFv8{%6XvIuC={v+Dnb$Md8rM-SnYq!Phl`{Jlh>Bwb#S%& zD@M%R8)UFJeop6LXDa)RY{Qyj+ScN=<=gu^l4L}%78r{EC_Azgf3PaEKdmPb8Q+qb zBJO45&2<1RoKNnU&$!uW)VXU^)G<-oH{lzQ<|l2`F!+3eNvBB|mb;wRdKMTGU{w8O zVvUlaWzc@?mvWN9(0xXeM3+%KjX0}7L|jJ%Av0>!rCwbZ!108Kz(@o4-L6zv+)#A|dXqtH=X{w7!ErNh3 z{5dFzM9T>X8o0c!Gs>l#Rg?=-$oB~YIz*vgA>@G01xvB z8)FhryEIt;=q5A`PiH{)PLgg8K^caA(evhXdTeB*@YnJ_QC8^l(A?GjmE#YsW^xwI+?rTBL5*X35(o#tZ)BvNn zn^8;H%ST;pd8Tr-Not={#E|(~^I=j?O~s1}WO=@QObg8zVh|Q;0gZF_Ujs&VR(32z*I(V4ZE)Aas66(`pU0~FU zOH#ObkJV)ev`XYFIMC|ozH~``>N?S|rrU_x_L6t579PN=6FDxvevPK%Q+~IR8N&Xu zh5$uci1mbz%A4H_H@cf8NsTvo7jAl4$GsM`G|j?S{2edOciDEvhL-Xj->pF4Bnu3V zI7BH}sxg@VIKj)G=*>TPOU_!IrWa?ttg~H#Z`Kju6RBPl9#`}=vb$rRX~mApQ%2;Q z0&C`|2W$zP#vN$c$5w~m?d$^!JTF-2R~1|~Je7DqYoh`68JNS@qGNm(EIbQd(L)2> z^8jhz_cQCq1Rt(LCdUg*4pxtj8$tw*w?yJ*4hO87sY_z1q^>N z>S7orr%3O5w0}`SWKoe9W4J|d0pZ^<_v+9p`+k4sVqln6OnxaoEfS|Rf@lOoS20{z z!p&PC$RJ*XlLs0Mu>7%5{}grE`Yyg3kLv>qtIuljpOGl3Q5^Kq=f8WrOJ5(W4kmoo z;#+|fh#AFC=0^{Ku?eEU2d$Brw1*YppOjKBM5l4+a2hHnU!0{+0}!yKPsv+EZ5v!icKdgglL7#EmjHr=;Z%3`PJaAoO98_vi2B=1xlt9&a8QXsk&7X zRdo9LD?G!5Hn&ctmam|8yC0wQDE8%}ikbkzb$N=*L=>~htEQUb)^Ddbr4 z&4@>S%z~Dk4__4CL*^!GvF{8umi_J?z*IHhAJ3h2U9=gX4tR|Cb3Dq{cT255`wBq! zgT+BTk1wEC>W|Lgz@xYsmC)-wOLw%c4>I%v!3egx3$|U`zfwaK2g2F%htBlGPpf8k z$7JvCdzHOD-(ju$Q4wEew8OdG>Uj8y^T}g}cc)|HRd1d3%Eu)*wow{$DCqpZOQV}_ zqdhd@Emt40Kt-LVf}drPOC07tJ3eF?S&*XWjQc9Ks-PqI1VjtKYXe&Ld%%+a%A0}M z3Aa!9BF+~QR14G^#UBh7y-&lQif;V=)4I+8ng_AzXdTg=bQfqWx^oOR`G&Gw85;eo zf7HR4NTQV{igLc=8XRym;2dE8OJ%09cU}mj8{u-K*7hLnu|YrG)!cjgL<^lT!VnNr zeAWpPgiK~>?UWt~gfbQfA{G@7##VP5GI-J~$@nyT3A`x>rua%|m0#`$LxnFKvV(x(sQ` z(i}wVknpthP-bF?c@B=iP=m1gu$_9+9t2(yI21mpLheT7*)mU5PCh zLokeO;LTiyZm}yd&`sy#nD95PevLHdx&zr*!XFROg1VO^y{o!2AHg#4{J^4(<9c?~%Cwe1#83Gi5w`FQCz19ayt3TCiCznd} zDO@AGNn?@gjs4T^Lh4>2L4T%JRjeXq*f9=f=TCcwvunj+6Q40D-_eAx}Se}sO zhef(4)unRuW$LQPN)t*EMBHeT2;q}W+sH8QBi)AlFxDDZs*)70tE9#s^Aefx=B?Er zT6Jl{$?D#@eWD_dB&;vykg&;^P#vtAIvF0>SP7P5QXv`&Rjo=9;Wu#8I&C_fT{?`2JlqS?BRaF1WRBU5m(1q*X-_g9 z<)2dx+kYtW>;9?78NQhNf;;Z?_{F^&+=bp;;Uhow z?)p{Of55oLjwj!_nEz<*el`}uOQf0ZNXl0VjsqBsaQ5dc>wlE%1YQZiJFx8 zANedzIiGpACE8`t;8)07xwp--TK*?J7o1HDlk&~D;bdEvWB~)4E7v?1tnC(RcHj6k zTq~-kwK4DPh^nh&Z32$6im*XL0%^{1kUkuflPlI|)g@H{vpLKvxwLtaN%GQ~ZPYI; zqgiidt>pi3>9Jq*3>(4!{<6ML7*hLr4!a2Kc8(bwCFYCv_KX#B(eOd&wi!guTrv)m z72gftxprqBm}<3Ny~?f_Wz%5EaOM^nu^RI!@4Yp~FFm!b_|yGsqt>>|rM*3S!R^np zAgx0DYE(vjqS$P{T0J&juOgWJ&X{0Z-+tT6jObpzekB2_ES&N&hS+Anuc*iFbvjugbm~{ATSiYNt9OQPdVOHS{^x&OMiFkH(0b zT@m1yzsyIf-gLSgH62zl7`mCi_3ON!-;T{TQ;*TM{@l6r1S>8x@HgV4{|m>kRfOos zFlj9H$+EkQ^tFqprf9d2Xpyon+yC zlZZXbDh?KqOz}|NIGMS7W`mkw&_qQf8Sw7Bf?x8{Vrd$27vqQ1IN70KEyG4K{8(xY zA8oFKoKy`*dWIVq9bSgqG+p^ER5DzL|6rP!B#W*_j|%G(j4TSeD5-VQbt0xQG*;DD zwiw!jlcl(i;SpFj_7{EKtdEdciUAE+C@?rkn7jGp>IZuX6nZ64c3eY{&o zIy`9$+^~xmb2BG7v{bTDvyaOQRwF-u;uVlk8B=IN=Bx691%!E1(MEX%b@FwH<{Tqy zn*@i3@bke&_Ll;zU(;y{+#t>HA#u~3TdW1|r4rbUT^aI=N98}rurSWO|HTR*Je#43vnJDB(OMm`f8jF= zRvYv=Y9L*Czo$8OJnz=-eNd92smOieOC4i2`dV^_revZ!EV|g2U8i&wfOn@_5JiF_ zD=mZD86;`fT zC}IjhF4o1iHQAcb=xaQ}6;b4=E?gL)hZjv*_Y`9NJevd@ep!%^09`hmipv0Lc|UTh zT<1o<`_Q%}vr#XOpit#$Eo)WtHKkFgvB=F^6*A1h+F4>^2!524ZkATnZs_#chw-jm z)?`G5(|7S9o9)XF9)Vj2bp2g!8s)srQ^<#6Mztx}yp@GtjUAm-&Hl+?+vX3}k8Hp1 zhmDHb4s|KCbx2&Z=NPd6B|m>>+NxIag0IQdN60QwmUfP503@PZ4N&cU%^%iKPM?H<+anSWWHID{hY5)~Jt>mqE zm`6)@nWnqWWIsJ;^&K=sbzVUyhrJJ%8W$R^TTl5`$(Zz6P-t{yc&}I$?z$0tw-|*0AGtrYA|>w77DTruESb?M6B*#@(KuR-UkuS z9dINOZj7T63sT{8o??!f8~AiNTlM+FwXnH?RU27-ssPdW;ZyeKk?7L6bn!n&a^N=-NbwbO4e%!VK~?$PPmR>3KjQThdHd z`StX8?TL7r5CAO;X8tx!&xoaeNuqK>!tT}~A5Npq%~=pybjk@2Y24}AtLPCVmZ)H6 zgbZyEYEZos&6Y{euQk~06tM$7Zpk>&Aaq>>yL7{of8Kf#X+@~>Wx#$7u z-{>|m^%|@*%6jUUc~lzuZv=Mj80lS!#Ng@cE3wmG5H-?(X)a(9!g6fJ2qB`z(-}g@ z4C!X5H{0S`$FguYCjDt9R|YV!3CdxlXEYL1cgIO>K(q)n%A3gBQ<&5mF2oj{*!~5L zAijuHi~^qjB^Z<3$(}evztD-5&*NKQ+;GVYr>o(oT%H9Hn4Z&sIULM5?h0^U%H_OE zC6s$h(7NmV^O~s07HlO~P~V(eERVZL5X`eT7%uTxvZMNrAjpTL2~OkJmLqb8)GdR0$E0Ree{ zMHUB45aH3)Oc!_QA}Wz7+E4>5J>WV9Pm`5k7T}x{1%@{Nbm8C+sDm?5$}ZFsSUIH! za^=+$139RCoVZ<>wXj99*8{9<3!D`|SZ#{1Gc%-BDoa_GSI^0bY%wv3sffAB(>{|t zwvfstDj|lI9$5BbiI7I3O#asS9wtTM^DQ-qi^|<^D&zTbot6TaP1S)d4a0nO1 z--YpjtUy7@(`u>x+?M(q!u4!Rf%lsd<2MOwlCs#GvOt=07?tM*;MP%SN6S)T|1-h4;m5RyuCX*=&Lx0Tvjq z4bLVbdW%ona&ra$mle;lmrb6GEmXYFL#-%{lEqU`ZCJZUAia7lnM1i! zzlp~eVy`SDXB6VDxG>_Y=)MxYF}x?>4Z7NmD-f*1`2^{tf)vr5Mbpng3};I)s*fa5 zNwC1ntZjT*sMjOb;6$cJIZR)AaFN!(c6!~bDyQ6&sr?w(c-|6sF!7;Vk4e{X*6OlnU%Q*(@ z&BJ0t`B{jyGlMns%xcbFHD`2&U|pZ-=)KmmLu^^q^`Kh6d)f+9{UQpg&U*8byb)lh z#0WRkHnnW87rVE&$o?PAQ|~v{G~IXn_XS)>6*X7x;G|F8Vib(51O1!lpU|9oy|ZzV zHi3>s4oyaC4zUI^7J0GXarZnG31JPD`ks8c=*zX_^|Qd@+joD&b6@*KH|;UAkSwr3 z#?qn~L?t2_j%6~yGDm`sWk-^C9$5aXq}sYKtzu2r27m=YM%E;~Q32UR2vm8R8PXj7OjQUq4tt?j3eI;O{2;!mi1+M(rD=N$c&qA}skg`vD-yNSFb%U{;_^d7Q zJzL_>$dzTR{0FL7km*g^M$(%WhCVD)$01K5U&3EDqU(uo*ok=8(k5IEhZv53!x8_qn#+Cbz7+@%iG9G zEGsoVFLS6EJF=V-f>BpJOZ1LTM!ezTTfQ-_9IsTA^GZ2KpfBf>ZL$F+3e4xXG*1iJ z|Cs)Mdt;Z+^g|N%3*_QSjr5a5D?5G@RqOMtO4N_{wLTk69a7Kpo?SM0rEgG8u+SoW z6&0zkk%qf~2C;Ok8*(GH*!msAYA9}X=W_gx?3s?rRIM&Isqn{ETw$U8>l%qjQhrH| zH0QBKeK9Wn=VgmGx_&!)&!M7H8zl?A>{2fJQ|$e>V-)mME}m)=xIIj~*h}u}l>Bh7 z*ng!LyrZ(G!)}O*``2#-yHc+EQ}gJ}2=-AyVodQZc0);z$Tx4wYXYi&@Rig467wF> zPbw)!5P_);IwmstPl$0exWc5rq${~dM{M}C0vL_o|w~Kaf83kcEv{dk#QurHVj&4U0P?jQe9{v%v`Gf#j`?1HJVM;D6gbSY^C;b zX^Ts2HbSeZ_1Asc#3r87f**|)c7+m-}Q#5isc}^=Y^I6GLJ=Mmhk#6DYlD=F&1t&nI<}ExB0z{ zR_7bAeL``Z3*SV4UpD^jIaQC9RI`^?&v3JzQM@ql`P_+7s0sT+se@u2` zZ_U$%9@o4L!Rn8EiR-#h+XHclwR-V5F%=uA_B7e;$%4Zp1gXcf3C@4HDM@Pp#2K4c z9nX>a_+x$GfnZSMbE~$yQI9(M=&2u4r!|VZqq5 z7QMF~eB!MKkjVz?)^?_)jGhU!FL#QoV{{~afNEwbXHQA>1-$LhH~HGKci zlhnaDuebdT*PpUow{9wXe)Cy>b6hgrTXANV2nGA%g0%84jjz_!r`}(ma)M8N`ZIOT zS?BIfqP~aA*-IoE=A5jiL2pdc|D8S_oJQT4VShaH;*wbzWvqn%sN=P4C)>h|txuuV zeSH~?G)?_Tn(2|k+A%`;Ht6cd1KM{@#3||Sew6jGZvj$ zhW9iLhGB+Jf$=56E(kNkv_p;`*+A|2u$BB>tkPJiyRl-av4nCkw=7C+yOu27ES>Z~ zJX8;|TZx8kQic1xwHMZub=3gtEN8)Cj;^3-DZ z2aVQ8A-7Yr*EXtBf4-W0-P%S)e@MRp$@jmKw-bnHOa2PjBEk-;W6+@89)UUF= zUizDpORLKSYs^OeK2AUEqy;h2l~=pvNsGsA<6e?r4MbYM4OA1Jy0?bx^~73#2lVvsyz7cs!T18LZ{ljJ5&4W|1Z$` zG3e?w%KsR_kFiPWt5zdgBCLK#mwnChBGhIi8zjfz-b8t}m`2PSC_1q)GWbj(t-Koi+l?~pEicIyMdrO=sOQ-EFd+DMVbEEDi540b_VLU zblnL`wF}<0841-Oy-8EVweDHdOV@f9oo`+1HMY6W;omkSc;Q;_X8m1_!Jn|Q;1Tvz zPEQ1JljMG$;+bV=>yCj`E9tnkJoy77>a$XBkPWrf)V07M33-R<=x>X0L4=Fb1R^2a zF_#RI4aVbnEx0-@fG8q}fGSZ(k~vJE#6&SHG&tn>g>O3d2?oGdeK!n0uFyTd8%1Vm zkym3*K2Mz{4MT-ozS7BZbA>98~)OzgUtEhMJ|LBzq8zXKB^f}!AT-WbXuO>L)WdutQ!zk)e zVWl-@Kd|IRf2F3Q@}27c2nxnhe|*AW4i}DcA+qo_nhnDlL00i9b&O`5iXSebBGXg@mnXkeJ-k0NviBnwYIQbEqNVzZUP2 z`UmLJgQ*Kf$J7e!?@P0N1@t?;%`^Sxg`=f?*iXFCj|$0^RP+l5KMeqBbsRc;8Lnq) zNHmxJBFu8;V?aAQOL`KXqNQN)e@>UYfXbThW!kUvjiw5K$g4(=gWg2-Mx324)qMj< z$7Svq8ChQe69;z7#TssbW{bKe)0jQWM}Z10?h&F^pE-!~#%}1SN-JB1rX^B$C1cHQ zqN~*2!hK4*f?X;-+1Qsu^a;$rGpnw^>y4`UDEd}m)q6{~^_Ajix1H7+Ph)@cm&Ff< z$t-4OlN!u(E7h5i`t$q^9tKzV*C(3p_K9C}CJBg+K_eRVMee9vOq@~{%*&4m@bKIc zGJoF9)cfYMH-W-FeaLVE(3(-vMixy&i7xcf!G3~A<7)!~TQtyOf{0rq20T5)xNHgG zz+$QND|hM(L3{C?O7DKH{}7HQ4}n>ytJ{u`8=x^qU{f-Jm(}wQ^)3k^*g^HvY+1F= zAoC_j+=Zxu8HU}*r_&Gr@1S|Sca*B_n1gxUSB&VDito9EWM8eM8&VA+QfJy+ccajB zPi(f?XO_9u>=r)$Lg)%InYL=$vmrU}0e%-IyfVPVY3@a( zXv7`8W+-rQ_{7KB}C~`%7Spn`(wSUDxibEu5ZJ6&M zm|fe_l9VMcL=KqkVSWV}HZFt8a~&bUnzA4EOL5bR{h;(j(fw z6(W8C=TH5^3JgZ)btcpLAuvBMp_nF0_c?x|koVX^ zDhsDEGl4QR&~kvz*f7UQK47);3#dw4f{vI3Rydvyh+>2-GNj=PC>_e%VN-*Fcl*LY ziFfOwW#D|LYli`lferK~i7n@AaQyGL*c2`F(4k64{I1G{=ps94>>x16v3-;ToE-vOInfDIgz>c9^g_Yq>Esn8(>Bv zY>S+JvE?pG@9Y`>6f*Fh`v7)S^Yp%{>0yLr?Fap;n8_^J6H>>Tu$+ql@W?4g{?%hF zf8S+-){NlbO^4c$%hBtv{X#O(PYz+AK?2R|lcW&GUK+}N3 zd`i%=cob1y=oxd=h8fRBhAI3OzYj?!4c!Y*$$zF;ewJP(tXPwlReu)!iIDNeK(B0r z=2CLTCCu&mvFMvZY9AY2b3Wcqj!w%c;{J>Qs<3KQpqSgJr2kh#dwQ1PS?mMr%&-{) zZW|yGZ!)Oukqjlwpd8Arng<%`C=%Z;NzhK5YFt&$3{F=Gv+%w$4Nqh%!Ss)T{&U_o zAPfzeAabUV5Aq2-(*c@`3(FMF&j(5SaU)Fq&+#@g4us8BJ-#)R7DDVx!y^jPrC|yd z1p&J$P#{&$Fqy{CulzKB3X@D1~V5kxjJ5XLCyR2Pu$JbIX1cJkZ zeJKE3xT=(DsI>D9Nz)$gg(?G)OJN{TYKQPh39>W|T`5vptAZMMbN8t|a`v1s6ZxMk zR;m4}Uw9o+vBeHNj49ErLNypNP5;cIB9zzImwJUj@s{kN$4t!TY>`Sr*EZQyI+^oi z?k)PFKb&uaeJWeKPxG#%@_4+GA)^8WfH?6~9CZ~{q{^*+FWnBnpps@ix9Y?P$tNoI z!m!#;5y4GUo&O*^cLpLg3g_&Acy3g*`ucEy?xAH^HA+yL0_<^bijrByl}g>?f~mb~ zd3eAR4CBIrqx{GDSQ61*E zRBxt+vSgz4s77zoQA3+WFZPc9OijdIUGx>M0zy$}t-=0|VHBEO$c#qamvtM(^NqLO zs|utz2FcyK{1XGbzEi9^mZ*P}XfV@AMc`rFKwJz4B*=*KS`z3hA1|0oWSW}gSu(XX z(zUn=JPd!#26z)S3e3!yq1@=>`yf0|8%^^s-lkf=CaFZ5#~G;ig(45HARlqGoE$SP zCx%b1DD*Wo+v!p-%eBs=-+8%56FQenUc zC-AN9S26d6OYLX^P(TEombPGjw@GwRSDL|MIv|3#+PT$)Yhv3cI8ckC4>EeXB>Ztw zH0&D4!t@-FYA_6SH@_to{I0b9LzUntsk<HDwY-E1yVc~~ z++;9Ren|``AkwGzwxKbFV>O^KvF13u#yHALanmr44yQicli&LMPdELM%;K_K7l7o{q2pVq5^2bpn5^#f5CF6055e zllDYT?c{fZbDvq{xh0C*G>kYl^-{2ABenIT>tbbi@-r7lG${^^a2$C-LWP!zV^AZm z?0xQo&r>d>>t_0)yIwGT=u4E-DzPd`H1c26WzRJWy(*{8%?x1O9o5_;b)4=Jd z>iObZ9a(k9(|Pwj&EBZGpzbq}SE%!)X%i=M2m9d~o|Ot&x9!LPqQKbn1C zojS~{0Gmw1uDuq11>$spvLivZ(ljiUuiH4KgtA`al|bylu$Aj`kd|306M*1kY*G0N zCNnSo*H!a;d9GD~ejlSO-mOC`hhbLot5Nt{1_o|`99tKtK#TfAGwDNP>E?>8i3@Ua zR2P-0&e#FpYpkBHFm^Qx{$zzEC?E2#RLEmRgJgN%?Ikb1{J@$;*&1yOZ=cJnrAvrO z+pOiB@`beJy@|Jk*O}4Py!+|&_#=|MpSuNbfdZ=9Y!E_M5dM@$)168VUO@1FVueKjE_c+&dUbtep}~jEg15)IB!Mo!2iAH94@CLhq?^cc?t$ zDGtuaza}WB1DX%1P}_?4j;5ABUTj%%b*pk}Y^^47P!g z=^lU7O~6BwwngxWGz%a`S}!?}L_ENpYAgQa8~Z(XvH$NDwa!QR1F_qINV*+-h^B^H zfP8GlC;fzXKhw6WC6x-Ut;%E@Z-wf0l4=hT$;$J8O zi6a|tO&tV;>+VyO4sYvydU9|Sc$lDlkS5+A6La|Y;P4;A5lHGtt>AF}eZn72$`PXd zi1zgn{ozry`B84%(Sv>VZ7Z==es()LcK*8KMAGr)Jd<+4y4^4|*G)9CX$FY2gej3Iy`--XhO?Jhr{B6A^@;nlCzmdNE#*By zM~s@h6C)ap85fw6{EoWTzLa%3rknd^g*X%vEL^kES6}mAy?m-!dYb8an%8-{ID2Zi z_4PLDhassa%lwDKIDgPa}|@;i^+O78ms*$_V?MqKmLbO62t%etQqw?>%V+x8!HZp zu(vgqctLEu?6}l^1B3^YQ>daKH+Honel20n_JiL4L%mtLxpqjoE<_1`0QRs!p2Npk zD1=Ke_00{|bw;Elm~Niedjrp(X*P~2CZUAPGBFbHoZ!tNKo^$qD2$hwuTyyn=l4Nw zj|2ZJzrU~4yUi^j%c;z3Qm?HH6D$q=Xr5biK@HZCZYg9`3mMXJ+iTJS=tGqM^0G&W zjssLOSL#%Aba>3{jLxrq>148mQyxyDR1Tl5o;_7t<$(ig#3%*a-<8M4#_kz zzpz5tZPZO3pF**dRdS5I8h$^8KBl6CY^)6Ah-Lb1{PiyJGCsz&!S82#E^+pMe4k#) zxs_BRX2|T)oVk#79KHc;jk}+&+pCOzyYX+BE&hg2+zPpGJDV%g;eH)}6AO^tP|s^0 zO!#W~1&iQfJ~t@&A=BM|Exwudyb{!D>_2xS%m(`RR;2l=LgS=*C|`cJsD88?X?t40 z5RTA2P#l?2o}7hvYLpnzk&|^8RJRcvwmRu|9Ahb{55=Ap_x0`ujS#%KV!m{G^W6ON z=EbF$MS^}=Q1|^0C7!oY^+k?8A+tSdUCKbJF*jzHWD)Lvty1-HQVt;GoCA`!p|q8Z zAH#!_pkT*o7j3-_7nfvnY2~z;MDVEP>m}*0;nP}-Ci0pXSZq=x#I%BgW&Wa4 zt2vFd*;YZNK3_RHjS)@;p`1qpGqoc-op9C#GNA?h)HrrK34{e1QkHK_P*Qu z-tUQ=5?u%8r!GT^7nUO~>CO*XLF^))1vigYrmA8vo+(0kttYd_CIfsVKofsHT(?Bu zV;OF!aI%*8-jf9%(DPmqI1j5vVjU?mG}q+cV%Ym!G84Iamy<=B6}I!|j;coV6?JUv zy&gwI&L%|O2)q)v{W9`xAY}K9zZ|k*xuo}W^e6xI@9&k~#J*rrT}ouKPXw_`RumGo z=oYrDjPwDiuc?x>{Hhqkb?!Kx2u^*-Vy&Z{VSvqmkHRpc#IlM zyI_OPK!01j#b-k@{VKzzelDIj=dnlucjd%t@CLqC7tSIqmiU`VCNUve%Mvq>rCxhj z&89tooFVw=(Kw^0`N6<*D3Ij@$^qvC197KlAL5F+%kbfQHMaAmy;kc z?|Qu{dbAtWs;57}v_xQ;mtTWeX8$>`NsTQZ(H@pU?Nc zf4KjHb6xLquIqhX=lOU%Q-$@a#ps;hXi6#Ex->??QQ_qP^FA#VL_iu;ZyO(2hau9# zJvr|AT`)Arxozw^h1&7!;wV;#_crs8q$TT#fJ5~jwr>b(b&)>aw27qszHt#OIX0`l zl^{BRLk`jo|4^^{AKvd_w*5QE#J<<2uydwHKFQzg2=ng#bbGDJb4iOyy>z%$=-Gh* z#omg~)cQ_$#=5T}nua!Ys4Xwl6}-HzWb1C7s%OWgZ&!eZuHa~Q*;sv60ap?jKqn`o z&6FzpTsIZY^AQprKxw11Q>82r{dsmc#=MrxCg*p+c8t1pcRi-x^g8jEFhlD!grJs= zoJ7Mu4}=&DY%3mPnF_Wmhlu(CioH`=V88nF)SJ32Z3U@}+X!WPA-JCTt3je`LDh$N zDgDFyinT8Jjl8qlE~@Lc^3Clv@^5|Oy0-_Pl`8`=mlI7rV{%>C=4#~16Bzyw5@oB~ zv=nO^*b=UeJ?8GHyWR12EAmSF7vj&hh2K}5CbFHYj<}v6Qa{^4tn5wbB0K6Y+eno0 z&*x=v=ZjoszkID>?on1`N7rB50Qsx4y}rtwv=v`HoL!t=6k1<-A)D>E=KXYCyF!DV0Vgf&Z4En^;3 z7sOSMF>Rk+{9h|ZZsrBb-UX+06}A`97*Ja{KGW*Ad?nJ{Wd#9ubyL7DMQNOSRmP@q z{WO*yoN*h_2r$m;0ufwbv`|2!NX(tBjFwhSUKVJyT5+^ECP9p`RK>m(=10MQ`i(`=a)oM_mJY4c|o3;!gyoRpxn_Hk*f~r+2+n;5dYA^6jzGs6Lmn= z0zfz75|k$^e5I#}84*jy0&7K2lS}1^c?%xX?v9U$25DCu8T2d|*FiZmnfYCCMT3Xy z*B`eZq!l!j7{x{B)9#!r$kALg{bx6XyHy$gEN<7uLj9exvqFg*ZXQRJfD3d@IoM#YyNb4Jh(|iHE z7eX8jyo@sZA45OsmgOIGz4UYG7NkP$aye^C&dZafnYCk_t9Ev+>e6x#v3r2U=AZ+5 zb4!qN=p?Hg@(y?=#^!iDUG^ZPzQk>p1${F6&;0&urR#=_h|!SYi)0DLIWB)W>k&xH zkHV^(vX=KwK2dibr05C~nC_PkeO-Q0C_r-Ey!}4v?Y-J_k6EZU)woa(%}>{j%R(6cA_LNkU{vm*n@Bl;YgDQQC`9~VuZt_+0^$F zFN82hn9|Eo60IiBQhg-41NsXs=Z*kqQaRLsLL_42bt&+6BH)20 z8tt!$7~K)zju|gL-jmF{)UPK9Kc_Sxe5!MVaDc!~zF9aC*v`sVWC#)g`jY!K=4TWa%+o{(K$1cVzxCJyks2bcsO#_33Mu zF$Dv`RQ92S^V{);r2}70mF3yrIQJRg!?Tvx4EW++bJ@MFPKBcE$V89V7o7C$2jDm3 zUOa3xw4Uj|uB2~hHfZUikHn`f=e_Yf)fXCg1F#O+Ra}TNOHWwGXG{)VsnQQjd=)qI z%I}d*mdu5p8ZYnS=`zP!!(HF7ju}*hCE25lK^eKBVz|>?73lgC7^f-_i>qE@rEy9s z2eI<)C+?e?pq)p`odK(sPGa;({XnV_>-mOLlNPAyW5!YSiV8m;~^y7F_Rv(MzECcHa;^ikpnxzCh3=sMO5HG30B z0`SYXXj#gq2y*GnwwokWPPeLZPbv zu9E2gTCp-&vk6(V%UW}2S#z3ObGcdn`C)uQKfx$uGWKQiCyLr-IFm{10W~FL2K*cq z{Ai8-Z7qB_E^ufe`goKN12Z^Qj4|o|xHRhZDix_efw@VNylfrTG%YqeA*+=pR<5_F zJGtC6DknQ8zmbR?oCca~l=Vj#m`p}d6O}V&)iSn<{L?R=mOtTCsm4?t?b~j)zhhdl zZGhTUmx6pWQ-y{g_D%@R5SY=|ikIGYKJ@6S9n0=f%Qk#8lW}n|}eeq+q?PG!}Cg}pD3A!C`28Su|rYaRB zT6ZVVG66c`1Z$^a&LM~uFEmj%-N()0L~zbaYYw0eIrv6oa-{!|7I}q~;^Y#`s zv(*Fk=+JqWqldNUcl35JOn$VAded zzRo7%Jz=0b;>y)q60&juT^ipUK?IO>7iY|xo1SZs*(J?jiT{PA%&7;H5C*lx7r z+G6#q)Hbcf_O}pFJJAQ5zM)m8TSKWi>gvAKdfncuouPQKF9 zsBrIT(a|ImZln>6jfm{aPAeT$H+=;|p$0lS?eu5c+0~?+LwnAP9UhE(AC`;&yOui; zIE+UPu=23UC<3AXWDC=<!Z?#KT#R>3^oytbT&C)aRbsueCdQ+FZEY(xYsYVOr@@^C=+HT)cn zx8ArLy>>22Qd(kVndi3$)IS$~|I_hy+FI&55m?Q7%Y?GdMI*eB23}U~Y!|PsKR7L0 zO|s1q9~nEaTE0;RIp(M3Qz~5G&7J0Z*HBvL%r@aws^C>hTAAus;EL8MV%pj8@)tUD zxw(xq&+z$r%lST_^6?~D3nm!*cCc}3h2A5pmv+ECGI%|b@=}#pwIVhznr#qYUuVCO zWq)+XB?G$&)Niqe!mut3w}MLZ76fyR5${BmBAf*hwKuOB2vqMs;=@2`tRSEEn{PhY z;-cFYJn!dyw23P%YaZU1r`yiozw(i?#To*m>5ix0hj`GzBq@n{lsiOLh{gPSqME=} zZ7#p%x`auvj2b~8ByrB1zU1{z859tFEd&(WjBS3H1RPY6Mf(%x4Ax zB~ya+2D?-uVuxwv%7<2=rKz$kZh>dU+qWV;vn}tHJA4pkOAtr? zOtoDtlPQ*vZj>-2OW^2hbw(09KMpFf;+K>Jcx&bx6lIeG{zE!iT$jv95=k2LZdLS53ySs_{IA8ES zGN?flWKSR%d4M!AoT)>_z;*?eP#9hKJ)uvjz;Q# z27MRS_XG6Puptkds83(u>W_?<#GC+>RZ<#b6}<5~(0!HlCBXA07dGW=^-lRJ1`WMF-g?rO_hCLX89wmWvMpkPc7u-o!gzk)1jgpuaOP- z>%sH@ZAu88VLR<<`#TBuaz^Lb2i6 zS;5HBivouvCYyUEmTw+&RLOC8H{EvGzVQ37Q7bJ!vLCcnCWwr*`P6(gUtmT3HdzqkLks$4M+u0?6pcg6U&qzeH;!|k z1d71#(U|V@yE{>T&J<3q%Q|oSs~Df>Iwt^E%6qC3+p7Ak)28ae{f}S8U%`1xI-~_! zRTuY=PZfdwm|Z8?hTAG8C*o$PSY2eSMM;}IvTfyci=*vHHExTV&>f*~kmR=e5;A^R zy%Z74eWF?w+u(C@$Uu6u|J029%|z&=rH*kzjG#e@H;PVADjaEyawwNqek1a(dcL45 zrSl2?vOW!r#{;l$={!I5ORgBycIhvkcsgNw$$p!2tUSYv^mpvu%@19FR}9m|)SMiR zGB3m^9);@A3<-4(t#V(aCTKxEz6922IT!0X6wVPp(dJV`PRXjb9~z{se7hB)LzU_U z>~I1{Pi_i2-sZF%@o!S8A37Z}lo`2)C4|64aR5#kjB?Sza=_!6MRYSTIS8T=N--3k z4HTpSw78xkOxT$x*vP1o5hv{^@A;-stEu*DiCXw)>iWXdu8D^)Z>n!R)}U5nge@|3~~w!TMS5(`bJ|zFNto2L<8jC%qZTj2h#t zW`M-{kVrUOt@^rnKZuVHQlu|{!+O2~?f(bV=lC$dENWUSh+}03J2tZ8!P^sh&*Q{n zVA6$wqmM9VCPL@HidKxCtyR!?yC;!Gqr?@s}D}6l>4Nkqf^Y5nLLR8Qjj>q0xc2_+! z^{qnLJ{nqG3?9_Cx(W4EDNXpT-Y!B7$`qnO+Ognr$J(?Q$Ib$|>~KZ(A|=`tD0R|y0|n)KB7=8t@+!D%804A<(1KH^bM- z@Q7iX3;AucGPD%MF-6)C&|8*J$_O)y|1Vbi<`y?R>_+11umIE4P^YwhH|-}QRnuqT zgQtHOTBbSvnP<;gp#Rn_yxnzu657QMHG28)jG64GWf?!1bGqUl4Wy)$MlW1(G(HAP zTCF;OZU|DRdImYZU#q0sBQIue&~PMnKejhT-JpP~n&jr|WrMt6A^AU2LU~CFBcdR0 zR$6q`x`N(b#TCxDNs!X`_4#6UB|VXHY*=pQv~94~kkOTazMqp-m$Xb0*nRM#w8u)}`^DFeS z?rARTpduyOM5qT>t%tIQd@iE<%Vm6|@tC)mZO&^miE|}8V^?(F6|`h*p1Vh9Qi%WVVmC9# z^{i$vIKtZ1Lxx9rG>u)%DxN(|%}k7*h`;X3UbgE~cYeixB6ig_$9^7tp$X9*2UaQv z3t@Eb^O;C`HKi|-E4#XRo8@zx%Gt{>`qEdY?szFx@qfe^p6Aa=xSE&Ga3~@5ib`kg zP&}IQmR*mFTU|5b#mxP_7$Y-jx}MabFSWuE=@w}Vwkb1qs0+&Pt)w+<6@?2BIvX1{ z9L{!iO3JwxWaD2G#Al;ael~2FNr~%dm?TC1%%{X{OASlP78Iw}$o;)yg6Vh2|AJs? z1YY%gdELpEPik)VtFT>?%BeT7p$|{`d=Y}xd}+ea%HgjgVlb8R#&fpCVX6`TQC0^kV~1k*;GCL<-~8Gn{Oc&HwZ7o1Z?N>zSR`*3o%XfBzoSb_Nyp^Vq$l`C z4DPx4s=2E|#!(zQvx#Bv@|nzQ)R0mJ?c;`z)1iTQFHQFUWKN&C0eP0BG-zMzuw{@# zM%vO4f63<-dEvAiWySyT|A3kGb^e7M>sVe4f$B{6ZLaH9kGd}Zz_*wgTy(S<-RzYEZBtT;d;Sd9J194;1#ro& z_d~hhY4vG|~!kYpoEY2XEbxVRvCBeGq5 zI#4$uW?Uolmv`q^DV=jMS?{#xO3-ijytU%ry^qiO-~Na7RMV>RK)nRmqjdI!I7t)?9mGS$6me#|0Dg0dKM4Dl3|qIvotIL zKMlKDwaCD_5qg0qc-T?8cqfPd*#i)$n+YaAF^=$p^|)Atu;qTvxQE=Qq_mQ|;7 zAo%5vcT@iQ-(sH0f_iY4eT@A_!*a~fE&M|cuJ!rwR!qvguozDWtQbCh{P&P53cHu; zW&Ekdumu6I72)Y$yGI(7e#BuM)mNDA9@iP({JyOEY;Yzky+PsQj>lHF(bB|G;pbkB z(3I~N(z0QHdJL!32Y&Pne!H27psGW^!*I)5P>`6&q!#qsVVT~s2yn|CI9=YX5#BY% z|2Ug;W?h5|KNQrAmnK}I7o_0TJn$Hg&u`to7?*#7iG0<1O~XF0)q%)BePVpQ3@CnL zs{Q06^l5SG10GYjQ6@4o2|`5)9jqS z78w`V4?G4zh5$@8?W{6h?9BL6?+LWz(|J5JS|Wz{kY9`q3o%a8;$ZB81a3mIV6+Z6 zn=^d%pxCfcuxYvcbvj`lT$Z=GcDbG(h+B}vqz2AE^ggHUZIAHL zSzW_xSOaF2@n+zZ@G7E__c@hS=JoG6ySueMTeRU&re3D_Y)uHGvANGbBV zoCY4VO2YJd0;H9P#)%o>mGbmV3c6xD8Bhh?GqoK6cvY${lMEf!VR1N&5%p}9@t;1U00Cu|Kaznwu!xo>QOP>Jm|PAZIcCgMFgmuu}(9l|y!#F_`zMIm7IdXv)D((GqODaN9;}!(E&x4j)xJb=}~KJqqo@iwBCJ`1(qJ z1u*Rw9G_KPL?I|rB0fYTNAAO$;nc0cnIWN?Iz6Zhn+(8Ctp^Wa$)RKr+n2g<3+{NY zEj`!x@V{G8FSN_CeCqa{J)c|b_!|b}Ix}b;#w{ZhJfGY1 zX(A}nq~_j-u|gW)fqOkKmc+nFSHQjfFig_5b3Su#$9`t)&gu@ndON)nljX8o>bVo7 zwd-m?DX>V>W4v0yoL0GfG2;&=nR~}r=`7QGX0+w^ui3@K&`V|<)$2%zJfd$Xl#@EU z{KRYIre^i?oxW?KXDXFLKjz+;!C~TNi;Cj61HJMvEA!->87HmMyEU9GaE1_Y9WMba zNO8rd0#a&tK?)<%sel1kl5!<5l#>xdpOI&J`Di3xgpWW*$%|UHXBvsm3P1Pgj)|0F zbn3mxGK_sApAnOv2kAxwYVq;M(mLHuVr(+__WyI=EnszzU?e`H{s9`?;4K-Q)JG1y zwNl}8g9gx-8c^{Ta|6QK=lm-2c);^j(nxY?j8#0x@FVGiDR6x}qUVvG&zIMcGUJMY z&o`IG_~ApfkMvj{BgCn)Z}xC+*%NiOA5YRWO3%wQGtWVy$t;36h7eu7(!imtz-R7+ zIU0hl`?WXYX*1)KC<#F5%V);NUuTxt-l=?f&yN}~pos6u9JdAnf{*nmF7Z$qo${tv zU^Yt{VAw%MxCSQzB-@b#-M3|Roc3U;g!kI7S^5fJdp+LDT13%2ems9|Gbre-OwjfV zp&4!b>~hdly7(8}t79L6KFyicvkzt7k2<@cqgR}^(u9SFQ;y2b7pziW5aXmIN;->zC@9!torI0W@=e&Ml@ z)|Ff`N-KDE$ZJ9^V} zc(o<4_zu)|AEvpl(;^9y=7O`nCHoOzO=$4DCuI*9;j|>kL7h-*gC3TE_JJbfgaiR1 z!_oFzc%gPz#6$^Xcr8C$cuh zbKOuVLC~*mZ)RR4z z`l;X96NOI{5PEpS+(p)?Hn)|*JGqL++28fnf7C9Qqkker8J_Sx{NZ05B>g0ZdF{LK zolwQ|c)3seQlDF#B%UgijBt;(vY>O3v?R{+iOd9Y)UBUzY3Yrt=Tt99Gt{wN+vI&! z!0D{BbXOGX;0JRwY8LF|WOCL0`IRq>l{Q0-&JR1hR}O8}Oo}2H24~abQQ`jB(YVv6 z_V`raYWnulA{;a10F7eZ=V(4|ter=jrc&P{F!9kjl;u=h|{qpiK44eM6 z-lSco-3Y;Ox7rYQj=m`_4U+e!rrOYWH0{B@af4s@oy=(h+&N|d8YKhPC1qp0G0Ohp@2MvpoaPbQ+bBXnnZ(Gcxoy< zDUNq04o1vQva*C<`eA}+84$Njw0`|s!tsrfDFZO4Nq7LPtZm`fyTg-YY zxj*_Pev)adk;qJEaZ5TYQUiATGYdO(63}`0uasdD>i+N4@)vJP!l>?zmF8;{y;gK$N;H$bz$chlx+5!)84qkQ{~)NPf9?(?{rU(6papk{L(xeL zcVm7<`*j~D{+qbV)Bj_kAao|`Emw~bCdYQ0dAFYVb2oErfEvBB^*v-X32)BQ6N1n9 zJt24_*3j!IK*>+ZbkEVh6`P&==@`)I`Iw!Q_tU%J;Zb@@PrM#9Qx#glkmu$ss1q$! z;C&1{xLCHOzUaY~_~}NL2wRTopFvblMZ%5Swi;RQ&EsyXIpbrfd*3O1URIPd-W-|nVG=ro!xwpHMyb&;(VdD3<+_Gw;D zo9ao#&u_fFPdhbEP|oi<0!})4Vmq&&bS0d$#m2UO`{VfdXUCu5pd*_L-)$cx$BMU} zX!o2vdl&nB&9?6(@A>DG7uWOK@2p(QT{-{rgv1foFL2tAj3Z0;ndHZISez$0o(Jyc z6zFqg>vK5POhK^m;zPvt)PAJdyEm5a$a!(YC8xtxaoWG1UF*EwY0}3#oIx|GBgsf+ zP?|pAS_t&fon=fLyu!|SMk?hDWTZiFDav*1;NFaWyx;~%w@~lrtKA$i{X1iObN1qM zF@H-o1aepE??2=4d^17j((H<6sSpF0P1+ghmXtp>DT#m0(E!>zFhd~I>EORm=9w2 zAV@Ef=mo*LX0C(AqQk=-dU!BvC>iFn!lAfgYJnF$B}f@XuYD@zdT|M>Tfq_Jd2B8k zoFjB1zWI?BSlbf3n6s{j`uFMF?VsoW{d^xwxe`UX_$V39Q8U0Ia#d{5A!eHdT7ts?Bp5LUNel?X27Sag))NUW!`K74Ey~mG>Nud!(pl_C&8JcNfDg@FTc*mf+ z5Gfj(QC9VCJ?{c6$O#+P>-{!gG9Wv|+3Xbp!^q~UgN4`Aj7zvOJF&MSnTAbK;0*Qa zL^QhwsD1rK+)q!vPbB3mrJ)ZIz`WSGt4h=b?2mPzAZppFz^E!}-+B0+>TThhF^8WQ zx}yFG--`Qf*%kShKQeIPssH=Vn*veIy?Y}8PhO;k_2(oz^Z?1${JDDRgZvB>1s*Ft z=qtkqYJR#2xS@4Gjx%64QFDeuVUf$qo>XAP<7z6@2&7?{hU+#Y?To+zXf=5~@dX@E z4sUh??5Hub6u9Utx2c9_7E6#qOb^{@WS|W4USTBlBsZTM(q*Kb3aQh~Kn#!lo^j24 ztMW09V_a>cG;jQP_b0tf>yRRYY{z`qsBrgs<)~cW!D$cIs-OEz(Vto zJ-<{KSCjAMmeyvA37!^p+U1Y2?{#{nw4J=dIPGEk5I04rzV`W)dnsg4=-yJ;TdjNJ z=fAzPeW`r{v6}=K#96H?;TUKK621s$gr@_N1m$AN6c;PFd@UWyoJ~wfxOELqhoe&H z67W_GS94Xs-SJ#Od;to8rUsdqw;eQ6l?|C6@&Pfc-4CR7)O;>FEg&}RpJEKh`Z2u& z8x>Zs*FXO4n{cb#`$_`-sNSb4XKp*e%*?>aGdW5ssVBL`;NIuv=T!bLErY^~7R~zu z!4rQ^59F-?I-z|lDkM!x^zQlI`Qii(J5OZ>2ExdKAE;R!Id& zVx?ZIfYrk9HHWj7b7o6wDtn#W97T~Op&mfB8frclW1sLGO3RSGtv2A933x)eOn6s3 z*XI63mszV}(ohoPTC{&bD`~-S1`A!f1~8e)P!nw@Hais4*751V$=>sS!lxRuZ_i!O z{(bWEr4CG~om2<6@(!=&29o~lFLGAoLzT#vZlC=9Cqe*mQh@0&h`Aj%fhZvxRbknPm{U=Rb1LTrD-&e?P_a&Ai}B;j=6O2A(n#uL zf;E42enHrvlv^u-^K3)pvnJ^Bw$Wr@Cm$PU2iy+FPH!b?8|!sG3kpo~pyoV)YwUmLIl9r8}tqVcB0j zp-4_#5-(@C4^QF+rHm&RN~J|>nlyK+txFrvbh7KF z=UaE3Hf$Z5Xf__{64&W&!u1g&Y*TptQki*OQb1RD_{E>V?(sr z$9FcK(dTXqi>2#F?dqa{(5cn<3b!LVxLwwAZXr)4tW$%o2+GP#fEu#mdS^QJ#=Em= zIqYy*|KsVCpt7|cPm*wvXZ7?)L8@nnE8!)k-|bs`S0z82y}^kF7ikyIK&xA4Z0rg1<%;Iwq|fz!xc>1nL48=6kBj8lL%X$l%>u_K7-#Rc2CuLM6ks zGtH^bJJfv~|Jfs>pi&~-*-1~`_WAC*;)f}kw1aA*ufG{2g{|e5l0{(Ij=pNl`#5HR zPS7XYs+us*q<#d#DM*!SO4*cYAJFAq3-sYR54@QhVsv>Gc;&h?@^bfOo2ReOh{G#44g%$SO;iW-1#Mn|2QBF;k-*p_hNvS80@<>!LOevu@5FyaoM0;~$~ULo1oo zq@ha(SM#Ei3neL&M+V}ur-BpIy|lu9*@OG<1wU0Mt3!qR;{m(}yJU#Q)JtB% zt%twgF#T4ahF}9sf`xYFKmD56z7~u!E}s6`{OfrRWh1%%W|wXED`dI{>w~*|YMTaK zz1I~ZZ=iL*#r=vc0zF*n{3P&=#<^|9n|e@5TfSGHnp-9imdvE@zQ4mvzrmAt{DPM9 zEen6L@sa6UW*+L0l%{E2`vnhcv`W`C)g22#iPYtNN^mqPS*V4CQ8?UntBme=h3X^8pLqGzPrK`cz-EZJM%O5|2 z|8*y^p|YuAy0qBre-ulq26m#c>O)&5tp%1d`u|mIM#=&~xGSm1zjMLjE!SZ7*->B| zqgsC*HyP#`^1l6>*xofvhLsp*)kfRupKdl%6YOzILX^Ami(S0!+4X0a#4?6WUz@$iS24frl6)mLW<8AW$G@e<(O2DDm#`(IC5mHHYMPj&s)MJNJL( z-$mmHzl`D;>h#&!LTKoTpc%q`clB^LE7uJ&+)#lNQVupIbG5R98mvTl$y6h-XnLz? z+cuY*7~5;Wv^bID4vSi0i&%I(4|N`+7bv)KU&sWJO&XU6@CLqanT$u=nRY1WA zkYnVQZ5PCdRKp)4?;CWo1Gpr;=e?bftL>3@=3;It4&LyP;$|qG~QU(1muSs0Z zBy{4YJlGpsnSm~T(qgqURera;dIGUWDXa$QZs@L?WTU9z<*fXxG^v%m(AOdoPZ8!g9Ry~BfKPH70+W{DUwNw{8mzsO{N7n zCg}%H8av-pMf8VqjKC_INem;PJ73-OUxO$JK4~Mn@B?b6!^lg4nGj>n?4DRj$$!4Y+eG)-^BUQ~99VfKU1enTxeMo%yg8I|2r7DcSf-!l#cdMe!Qx$a#qUm& zoH+8*D`~UR{?B*X^NRbrm#UNv75ice5eX3zAZuiT#l&;bz18YTxeP}X=G;y72C?&9 z(N*c7ChKMrfVRZt!u!F+KTvB&BR!8u>=U_3FlQ?4{(TVo;~7*(CQ?QJkI06&K) zB%H!H8E$6qqbX+HFdnMI2~`{8GK#+JGOuiuEvE0Ngzm+=4x<3lzVl@nNlJm^@>5L+ z#XUHU?Pyy9==3Pi_Xvn^b*|BMXb{2tYga?g z#ZMYIaFCQ?ZpEz}GLpmf6t6FMTnF7N*fYQW{&DaGDf0eXSQbxI!LLIjM=I;9$k5(G z)T4-NDLj(h5ehF38U1+lzU{q>gZV?st>tiz(SweWkK&kC<5D{PLdoZ!CXsgu3}P!W zx`mR{U5>Y49-rQqdTlT4hZo07m~?lEx^qLxQE`u}oP)r(C*Bj-&Kh!mc*2XsAHzPq z_~ppWdDbogRjlyDI1!1JM6C@XkA567`i&AN8Zoc8@+*hg29IoLekAitFc%}%f1B&b z{Rb=wQtn0lDnVaC$4}{S)lE(7=5!TnTYuY`uY&v+G`QRV|NWF1<*PAg2+`R9UzEc0fv;4&9@qeA2F zt{r=@`+DwPQBJZiQ_EKW!h4qvcUM1z8uumZrxS#)=V9Y5UR)#*&T&<2k+uq0aYi^nhvZXFTJzQ|7z#y+^?Dcj>dNqD*IW%lnJ{9obDZp=V`z zt~9ygr+KL6f-Sctp!eMDGCr=^?Cl(b3ZQ2 zxcKhnqa0j{AJY^^fIa`J-nrWA$*5L|j-g4DK&xof-sHc8>P?wQtz#0qTA5I<@W+3Z zBRt-Y`A@lMA^-hrzHRC1E$+otnZ+r@z?yr>K4vs_clqn@6<=Ws!;23$W9UXR#NLFh zMuuI9^5_ZLqZtZQK${_0OhnnT2A+VP*(VJbco-MP$OD1?=!2w!KjW>AI|uYc2`G|9 zx1VE~-0mL~n(*kUd29&% zR><^kCXV}=R?kF%!Vb5S_rjtb!Cu|pNL2B#$5S!bHn)mz*#r&)Q6@j*-iDGwEWm8A z!WzA0oj7dkd$FBqwYRCHuWqqVf%4Hn^sEu;SQJcH(7h|9Iy4L;YD14;QLG;xULZMlqBC4?gN{c6;<|!kFpxgcU6-in zt>LIe!uJnvhhwdmGy~o}_;xz3w`oi59#Wz2C&^+gDz>h@^|v>NW}@Pm+zBWj z635t|nNJC`ZqH+N|IX%M=APFb8HMLIoBc}nqB#QYUUi#)vq|55eg0$B{NJtj34iB< zF$BU$>-ht?p0

XPIi^TfcgPD`uN5yO&g(YhycR|}HkIb$Hc?G=dS?Hg=LXYwhq#!-zm659L zi_*@?Uc-@B2m zbqRKp6k8^Z{$Uv7tQcBVx| zW~L_R{Q6M-yneEU2#bY$UQ|{DVOHEHE)%w%PErtlL=$ErzF3`#;X9wN)<7&y9a01b zoxeOL229X{u1SafP!-;DcrdVytlOm-gICbcw%&RinRSawUKt8iM_Uxa62QWyc?MR3 zsX;-<5eG#F*#n%7`_W*gelt-5U~`fuo;UCpTXrm9<3Fxw4Yz=6#nTne38%0hUfa+Q zudVGXka)*MXTS$g1vzy(&AqxjsY+R&w|_dTl(sUD(p8s@%_N1Brn7k9UMRAE2ykE3 z_Tz-msxy#ra9UlRM!>D>^R5u~6W}>ah{ji8Ng#M@jh}}veh6m(NIbaD6rvISh@QU4;BVP*;RZ;%kY>qr(*+?| zXH#pRaojY#$>B|q!>wLj zt{5HS+f*RctL3G;>+0&(fPBZ_^-C%U{Vh+n$EHuY&OR@z+mId)?F7WmogWs3WgM<= z@F-QNQ{p^Wp}akG6VAMb`n;c+wA9fqNCFgzu#%{LH}F%OTObzSPZW-pj4f z%ih;T0cwC+D>b;KhkfO$Vee(w>JJ#Pc`z+D-;Sv2upU^y%E5BQ8 zuUFiyPp({oPeQa}h70D5tJ+^w9;#m%t6zn(UzM|8O`>02y^(9DRBqaMeDMyLef7o5C;a%1SY*vt+prpSdA$cN6x8()ow55Is zVZr|}!jk4_>!QuW2dcwCasBY~V;rK&Aue13%GrmiXETli2jstEgqep1$BUkH4~gmz zLC-*1K@G=X4gaAWmJA%AEdQ)z-y^uz1qFb_IrZO7`A-WhF(Oh@pzPyv@(6;m{A+zWXA(4Xy~uYhfIK+- zY-mi0*dF~@6LRXhsgvv@Zl$QJT}EBay>1gozXU0V#+aWCrF-;=;s#Jb5ok6iG}s0a7~n5O8ziD# zFsDDhKgvFx*9HArPuFM^Vc+UL+fe+Zs}lm+ClwB3xW?zEA1ATrvAf=?ZJ| zD1G82KV>ya8cC8Ba;DTX8)f?k4`rJz3Uipi-fDpl5hw$jT^`#uT)LGU!ZRF@L$@}qwESZ_JZgrmnXHU_b_>zc#U*^PKP z-TsBMvKdQXiIz+hf>!W0pQ2^H5uK?uKIorXy*Ph2@)21gzC#x|9qpyX<2{FE)yoF}j=L0O>OwXHRd zzq&X4FvGB4FSIV8p#HS84>F>~OCZA9Fcx5RJl_ez>}v1z?RaVHTIKKQ&HF0}x;6;C z3K!Z90WHinPAHBp_X?U)h8~o4Oy3GeQW#&?@y+)O%?oTjs%`yk+x$|DxiTuain##2 zAY>{ad*0F=VjZSS6E4TqyASFtqfR{c-NZ&*F-DEs;dp3ESwtO2yNrJF% zo9JMhShycEb3g=ptj7N{)0jAmpeZX@!IVwkl-=HxBzT85afhx^o788a0a}NCVTb8p zhxuWrrol8?V*?w!!_K|SA+^h?G{CC48f{<*k2QeI7~sp^A8OvqYl&cp1a0IdC7`)0 z0<$MtDbB5Ah`o@`_t>K5%<+3nr;aj|uTZpQj7;``Olm?@c4O$pe+aJ6*NZZ+%w))I zFEoI1XtrKV1ZPiOb61dBq^moy@>MSVPRzt|-?s6<4h2Izao>8JOtU)W{A}V9Y4SSa%dI&) zaC`zNGqLZ+B4Y@Y1K_`NPJ&m*#@7X{?gA%X#=d}9frGOUfpLdGQ7br1?p+C9Z{lh) z+9@I9kc4Z$2STey#xHN>R(=DAZk7nnFhy@`;{r$HoAJoogw-gbP?LS6N&RD8c!dN+ z#N0Tn@1woc@frZv!LI4)4b?~EaQk0E7&Pfintpkp!W1@_(QVjEX7-PYF zYz%ySvKdx36z)(+)l{eyV20ECgq%r@$^zlDwLjDnM6$DOlUpb?mufHjEKj7`h>LaM zfNHrRLWR^US%SGi{V6Gt>ZE}kCG_bWBodYZB1%tq0*WF&m1qcm7_4$J<2O6VnAzmF z6OR4U`ruGbYx^K_@X5r3y%@KxwZ&?_JQMEx=#Riv=4L6|?UP%KJoiL+h}aHxoXuMQI`VZnA0k46$k(17nUp*~q52|wJU5}6E;hymkQ>M~SNt;2&>pH=>mi03uh!u*O)tAxtW5t}yw!MDtd5tU$WiygvU9yZ_ zWZikibwcO{oNz1JZ2(eUyJ4?m5NPOdsLp8A?^0%HBxl;da2v68BN1R{(J3RaW?+%N zS7*^<<=LyjcZG6q-@<6`cWpU2wczj#NP6k;D7a6_GX@O6VWI^p^C|_SwO^Tq9lU&t z@Z>?=utBzrgx$Dz7I#k!5y?8=v?zk>hKac4;=JqStmhDX>_;?LdM z_zSjByZ21`YhiJ(Q>YCa5=55q*Zc6VPv_DP=@T<=zvX(!Up$Wi(w+j)kJG}MA4+@0 zW=K!j$Izn3Fpq(tNmKp$pvXf{z3Rtk*r%8;$`PoSge7HEDcHzs{-P#fQHP#?em^BA zJy}qGN85~yla7t&LB&0#UW85#0aSBS#dHS2>gafQ?N(Ty^cA#>#RUw)` zlV?M9+&Hipl6(mQ0q_94daj{)?csSPW_p6up65ps$Ykz!0 zHI~e7HB)YLOFfa!?{RZ>d`mNxE&dyW$@Y$RCSNXz-QnbpPW3+{s^I^YQH5mqZyD9& zz<5c_0%F(-tkk@qnJ}OZVRIASM{F&=)LA6A;zcisttJ-upRkAFxLa*87c%Y+2(tmW4Hk`xh;+602 zXr@T5%JJ>T$+AY3<@(CK-BOLkd4^(Jw!3Doj%4XtV zy3%IyaHiHr@(4EJd@$K>;sYFFr@b7DiSJaz6i8w02z-=(B=Nsf#>(zcCa@9+&*o?z z{0!Okz0B{W2!%tqMf@uF1D6ag1q$YZu%KyP?q%?Llk$G(*<7E71ghyv$Ape>3({>1=6UP)B1B6k^gTtr#* z#`8b!Jq0QXT2SH?INI^~QL6K!uuW?YB6cIW7ZmEsf6SG(F}Iz!mhGtb8w*5ot$6l2 zR2w17GnU%?0k7h;cE8>*cS95WWbGNxp>yKUUJg%d+RQvz?G$!QVIBBn2Vxui2ukku z8c4oU`w7+ZE3gukf!IfxtO&;{vsR7@`^Zc26}y;EK^&7pqjK}0j>_-59R)o$XPw;* zCmgei0&i}y8P9*6o1SrmYC2c&;B46YMc=rVOu~tBKp=NKmktvH@4JxUOuJlIv(XQW zz&D=5?qFoZbAy$FsC(4m;xN5yjxoyHfb~#@4&Gh)w-}@xt4+Ocx$l5Xvl=kD-GyEO zCz$UjC!AT0t^wY=YKT*hnRr1^Gvby#BwASDykSwXk9}E=+4jWt-J9>g|NVe_qS4b_ z;AR-iP*n%jWG?Si{74>_CsGF6vD>_YwmHTg!+PC)vmGuX+(yC*l)ac1{qpT{PS2-h z+Wx(;p@o;gM}dtN@im+UbX7ab>_*lF#HjX#5hR7cEbfA4ul7UvNeV?l+YPT;?T-T@ zh2bdfMs}$VAbur<`%K$|9$OtqEl7r-R@{S~i{=Zy?PvK2{3T=W;>CDna#iO^M7e_~h;NGrg>Gu1J>yN0ESCCA=2$<{~%a<*xqM9HJFE_K{9 z__;bX(%!o6k3;SsInVyn@ZBIG{Gycf-iMx==M+Rd^hNW(d#_C`pMpMkPrGECtnka8Z za|(v#Vb#Xk#CAqYjhL!2q#`;1bCR@eT#r8t3-xTXPJQoe)#@!8R z8-e+`+F^+dEq4VgQ^efGAb!F@4 zE=_G4Z_J*(3>(+6O`roImLIca8~3$MAF;m6?~!(E+pP}`)efiJ;7$DO<_-7C7B2Z3 zcgo5Qm%P}{aTx#MPixQ|&HtPqqhQ>ISNo4SFOKqUWY^|iVlZpSXT}}$xPMr6*}~My zcd+Z4`%BFq?fKlSo0Uxnak8CLRP zkI!S=r&DVg(d=MPtSjGVa%~wk1hXgiG9IwSwTxK`bEM9eA8^&Rj63>pr0+5w^3AqP zC`CEwd88Y;PiYd1fHh;BUMk)p9*LxsU~|X)_P$c`5k~oN=2I{o%c`}`{6n0;QE{y3 z+B%yF=KRQ~ov6gM&J_xCm8w;oXwWK4xVEisfVrD{nJ&J@wXGcp z^R&)ZTzso*Tfgw(0qrtfexGgIcyRZqOIf!wntjMOo>tV~=Rb3*omkqtuFHu`KQq5< z+eZ1t+eg8C9jXS}!Rh23;HbQgbOr4azw-`#X1@6o2il_+;Tut_yh*47?KA)48#80R zO_}|1_W%UE!^^J(Ij@Le9u+p${b^FpWajR}eKLKFDnJ4^FJZ>PsuT<7b7h{*G775Kic^X=l7 z$m=f4`_t^Nhn>#%zup^f3x~g^{=SO_>sW%fry8rD4<)`wIEE;t+ZA#43S3myg^zAzi1k`%Eq8?l2FX&@VEf)sfn z8+n5i38x>5729tw^LWYi$gHB9_L7juaOop7f zA`%l5)6>&)bFyo5gQtqkkE;|Oo8{g>@?em{3rJo-#GfO9RHJ(|H|qA;Ou{J z{$IKH7nlFW)&Jo7-?;g&-2M;l{ul252M_-{fBzRA|977Lcb@-uUjCoF{{MLU{{jAg z0tW`X!~e4(_v;yhUVo_ie>UXu2BS$ohY`xw<`2iws+H;w*A|Q>v6_vfFJEVmr|}}I z1`gI0O=gJ(AQ1hlA!jgBUou;yoF|td*HHT38*+{1I$2n*rTtINHZ4ugyCWI$O_l3y z|Ggo%-5Y|*U^v!XvpX0=A)l$xQoBEzjLYKP+{hswEXEN|tk_zAJX@?*W;ov3aJpD+ zHX2M+pL3Xo?7gr)(AIRh*%g3Dq6BKb-W`f#Fq#0h+#XKl$!96Gx89#F)!A)Mw731e z-0B5~lYHp_ec%2z%?>g^(9W6%#Bh4EBx32Wid&bcg9~3pR%to(Cm|nLi(n53_t>=#R1kacqxr zLa0lRawE7;j{aq&Iw?-I8So@YTJ?mV4CP~*!_)^2TaiRqcYGfyEpI$IDFasz(4Usq zFW8<|G#`|nR)QW*POG|L7|yEuaO}=%hN#QVYR9-w&+4Y67|!eGG}}(ntb44peuBF1 zEyQi}p%+Y0oToF50dJ7%o9~3wD?7j|XL!9j_0kmz@Au#;dOX2*c2n zU-cmIoL%*zNi$yeVf`~I(mTpbyIA{uG<;QR)`4#`ICZMIATza;p{PD>n37e5{FWkY z&i;0s_ptnSLh$d|?W8Cy)7_K=uEX853{Az|i~`U3-K?@S)BT*fmc#wLwpGRbg1*Q3 z{Q`#w#4Y7TtykC}iIafKFn8z+aZ6!Gv*lho(x3R0A*>pSH7%2~LP-cKV^*X{@ArF6XXn?!*I?_2JkMK}t zkbmVm%5yA_`0vo5@bh)FFH$}!tn83D{!L8Cni+0eu_U7$E3#-g3HrT<#CwH9DAdullP0c|ps(uJ6G8S0rT_c*UHwo1d1&mg*qq-|MiOpjL%pSv|hR-)i zT}Xwjzh%cv@o$rd6bjjshQ}=VZ&Ris3OS2p$8Fiw5>$Biaa)dpSmS}Qv5cnF^fqlu zK(sgr^hIjaq1q(6Tr}?wsTnz5uxhSLf)ZG{2mL`d(C7I!3xHfK3M)6|kAIg9r&uhG zJ2Dl_f0u(6Su8;#Hyx&Xmy0)EEX6Z29rfcbj}*B?Mp|wrHkC8~MbIBZJ4KG(*aUIo zV`%1Oi@)}dntAi*Lo0-%Hg~0+jO%h!oElMR&67AdQGh?{&#r(%{`(T;$Wrwpx%pDv z`%>-kQq883`N|*nWyZ*5+JkZnwW;^z){14iiz5q-t@jnqk!AXaa*M4i-zw!5>Cx3k zXN)6%9;e*PxwAPXhI541i&6-I%EMv;pw!XaG3vhuY-va!a1k<%u5;b=k-j z*3$ATGpP^t#flZSTB9oq|2S1df-CH;lZ)%wrwF-c@D~N-29`ldCm-D@2sCH zY?@xjV5J1zEYP1@W+8$MWj^ZcclZ3a6M$0f3#;%?s~ntCwf`?K;O-6?n*Tl?hCqRY zcYd7jDJP~G2iv;vkXS7uN==Bg!VX5-V;`+jO_&za>dr`a`wK<+&kVcm3`e3Gt4*6G~COjuNtZTCOV5PMOcr`eH8dwGc z;JIFlB?#=hv5(E#=joWJ`uu+RAg1{3{$D;W*^r*KitZR;n!$CL)QTsnY0q=TN)7oL zT~^%bd=3YDoWa8dCba$-s5V#PD)M?j6t^x&qAgKq(KaATu`x9LRu_!us4oQL766eJ z0I9BcZmajQvNYjtogoU%lHWafRbfyrX<_vFly_Q%x5t{M3y9YIvQE0y1;r~5M5*7} zcy#mw@tyiYkZx@Pq(y;*+2{TQuUl|mJd>l*pg&$w4v#8wv=rH22v-9qj&Ycv`2m+v z9=;H%4ZaBA8$}mvZP7YpR?#jkM_(A)*L{|zE)h}36}#G_5! z+chJKFEn)(9Hzns1k_*q13Np{#aN=7>`Okhcv0x)U9y&xY=I!IPX@}TLW|z-0@i%Y zp3!F9(7&^OAh3FU8-Ue6%|R6ogJgpkRoa4b0Z1axMEU))-h%1u^8HX(LP*}3Kn?y1 z#B~Fs08;`$PoJ8*DeawaE(QUp+0_>o0;qoJpM9aA$^0y&vjdIRd|%LL2jMIM2v3Ob z?{GXn)*l>-JrGi*On`U9<}OBr2bQhwP{L@s^;%w+3&3P9mzE?adS4y-Loc8e0D$LD zCiOE>5|Z5+h|LO7#A-jT1&O@{z$AqX6NSKGg?J`~-bk+rI046IC9}Rg?5<)Hph@A}#>+;@LhFQG-PW~7)cK|8P>Wlhd2=j=T zwqWDj>l=**cUupAjN_L@1tbymyLtd(80(;PL3~PfVvPBYk_{lnb4IBCZtNKX21xni zT_I-iK=v>G45fkOaMn>mgG{1=lC6Bq7+1 zb@sP@h2Vu3Q3oS8nOi=x@k*L0Vj&}WIy!qo36lD`Yx^}V{(fxqN@@TEz&Rt5hEIeT zQu0E;e03d{c12_L&eDcR`Ucrw6#6dej&+4fBMqdfhTbPdTcHiJJoHJF1j-q^;~JyM zZH47OMm#K83wAl9z?$p^hVOFQtzOxrY=x_cLUqIGD)K~VSm~%*MIgch+j&B|Jfg9V z4W^f1)8>C>(Lf%<0l5I-+*6SphXI>QQ9E!zR#BhZ;K-8@*R?|cyD}Kk95;GDNoPMh z3_B&xV*pZO$~kEu+A0L;eMzE$JH|2DTFxUTOA`3a`ZtMjiAp9cy&uV=@w|&VK;qDErk{huW4*ma)R+~LGrI7rMb0ChF8%W~{_kt_ZcBJNdS)ss&pD?}U*M2=@% z5?{JBPI7=w^5rE8 zrZI#e8nPh(lCd~(ap_N?jZX1#O(sg>v-=(Wo1D`69e@AMNu76!;Bkh<&n4&2?M=x>luNd@ zOm2P5Zd^!@l+|s2u4TQpVmyFe9jZa&kwQAOEVKBb!=)by8rRT4cFTY&PTfQi0H_eYU0ezAY6EBHHop_g2t_DPWye{sZ0anujn zAbQ8&y76)&`O!a0l2c25;FQom7yiUAlIJf<Ug9ILZI6Hq-s623@WV}p{)?ct8%`z8jYYvX{EXwzY4>v22UUt z3$Y3{t%mre#;2vGa;1h;ua^2Wf?U30^G7Y?D!3MqTnjj@Wf!Q+fvtm+uj5Ut3k)lz zIVoH_sb(mv6Bnpou&f)EtCvZuFSe}5DXUj{sgEA0r$lT}*K07PZVQGNWdLC}ao zWHvWu>^JHWG=NQ%8>R^aMP<1u^SV~dmO#`w*&=^B_rRW5oHiQziDz!Bi zTR`Afw+Kn;(81++v7I3{aRC_4Kr>iiGa?XE*=HDR2c!XHCUF6&Sb?)II#X%C%jKKX?_2u4I{3Xn z9%=3r%57F!I^?Vn$~NB<`$6diz{UIa42{gOrq)kgjcCRlM*>~!WgP_;O|vg4b48hU zbP#E2?(SX?I_?l3p6vt;AXUuo=d>J3(J(AP`a_uxghCgkeJzZB<5@UxP}-A5G;c~T ziSaBnNUNK3ttELMKwz(9m)1+g3!-}MCGqO94)-3F2b%IY;dXW50$f;-far|9sRf-_ zqMc}@z^;#MCsd9?{o+bcViMi&oU~UMk-<8?V+fyLPr$oo507Ym9rFd@s^# zQ(77DJ8h3J(!kI1YEyk<@ZM^_*V^F6O7<@WW54o2N4=p4P}OfiQ^U2PSi#C@!QsT8 z!)Y4B$)Mq+^5OK?;fS;0Y{3y@#*zG=Bb4?d#h{V?vXS!Fk&x4oYQa$>hSB<;qhIVs zn?a)zWuu_iQQp(hF2OM-hOxe%W2AOtL!dF-vazw(F`u!zQrqHT-5NE-@ujiaiS+R` z!K&4@@hyen8HIv5#tKpS#_jY86Tt}+`jYvv8lAF<8^P*L!O4fU%Cob&1KaWIpOauv z<^Ag<1XCGMXbMKC6xw?V;jI|HeF}xC82N1q!=MOVXc{N75ZikipQzwd`!q3AKGEAW zc}2|=sPtfL@<58_I>&w~g##uxw`3}Z;1}nux#zh$` z<&lPE>nqhlhE+tX_2&k42CK~(22B~OpmV*p_0=xqie#b1RD;EC?=_l-)uHya>Vmbg zx3#kUwJEUBdLh;NocDT;#rjhFx~ah0i~iCY(MHF~`lasLj`v2X;>O<}bw}$P2LU96@Ky=Y zHiqE}mf?1e_cq?fGJeN);`%l*c!`vFCtPTU(r1a;p81Bh?@5%Vg$#v{~Uf)v!&ngq|3kdD2`^;+k z>~m!7>w;(WH})Cc_Kk&SOob0f3=S+irmZs%aN7^;g{K|C2dG4cE*(>DhKI1;haZj- z@Q;qe_q7l2)TA%*(d~y}uW};T=V&|qC~RXqV&iD}^(Y2qJXZL4O#e7BYAiYPxDRxk zjxv@BJ_Zq<H^nTS)-^`XSkEgIGxwBtJlPvqo3Z-$fChl6r1%_ zPB(W-6A$3^>&zSatWrjnMP{Qb*7t3iU*kNeOQfB*9ILm&m$jlKcPr_)@rrjmj(3Yu zceX-z3Rz=vPFG)0_f$mg1&!`Cs}_~A?#CnU^}p;IzTeAs-kdAk?mOI?UM}cmJxnV+ zJpX(^n|!cre{lISX=3zO{qkYX@b+u;UroioK2=q|B##?E{{~*p1^jvhI6Q_;?nP`q zegQwmu+Jeqia{X_gV z^W}KX=q<_TZK>*brSmOg<81@=WQzoxCk)d?LHcGwq1m$UKYr>PSLB(H9cX@70($mv8iOxxy|Z#$Uw) zVWDEF6f-4KRQKf)nG8AtKdBukq;ffI^rfgBDrE|JgQ4)%kCbyIBZ(zb)j#%X6*D0A z$zrm_0ues(2h#pA&L0bXe~QBG9_fZ*|H;Vf19(?g>Vv zP%8Ii+Z~7^`5aZArhRQX5J@BwOsI2XK9VrJkx{y6yIJnrf&d2VYBQRS7AR&(W$519 zE>swFK7{f)X>@46JD&67m2cNnd%wdF>pwd0^hZ`DDt^1v=+uSuq9S~_`g$^7VKkU& z@ba)V%(duv!RKLp+}@HUon`p;=zGz;j$dkb7Dn*ua_i^AAxa{Nj0=J8FGtBHX$Du3+ zOT{T5oUu1EAdYKMuOh7@;5Le{^0Qu5o~56&Qbv)GeMCV7noC_JXa#Fr>6DO5Lqp5r zK410lwN69FssMXd>rK60)4*f@enJnkpkB-5HM?QGt86 z)feb`U5BRq#5TL*u|~bGgH(T;oXnVb48AQ&p0DXI2k{tw$8_ac`hMBZvsrthsA=@; z9U70m#FC;~RyIeH%Qy(va*4_(&wU4rk2EoldF&Ud z7M(aX%a(luEq6Z46t$r5mT69v^_J-#2YkvIUSJshBd%XKt=4%Zl+V@$Ne65;g;~M6 zl0|uittUdTno;6Re9()wRh?1Jw$+2wdO|g$QUVUA6Pj%fO-X&v0-s)>8aJCR2Ugdb z_aQM<%*iGMoV!=o+qNnc&wn`g<2FS&43PXL9PMck#$52A_z;%0QPZd>>7UOFx=sJx z|LNF?e&FdguSGKQb;0O&``FBjFy88t)1U#(qU&MC-*qoo;)l%u8lSuEaB1S(-8d_s z>;1If!k346MIGnIWgive)4Icrlk+y%_v6c6n$4r@QR&XZ+gYp4gZtIro%?@xi?a5f zP6s=8Uv3YLcHUlKvwOfFXQ&f9UucPJ5Evy{6sFY94>>TqnHWzDLDSA3yN|SvIav$^ z#V&vdDyLEyPaLDsHjqkUyI3h%9LLf&h$(P8&k*l3K8|fLS6@!1WAbO>4x8UXP~<5- zcoO73HX)J{xiywntd%(opC_P(N|$Veer z{fP{uv?u-~D@P6+<@S=+Pv0_(q8J;Og*8p}#Y#XqG4^vNrv*K3fSg973v;=f1>-t| zyv_nUQ+>S!GYiGY3YAh)Cl)138rYN180VJ1nbVS8k4B-7PbFoN5`{g7PjQ_sF3djP zlA9?ssr(yCT=A?WuK|VP*Tg!iJx(ir6@R5~jhGN;ZdUx;pC(-<;xf1E4~6PdzIZFe zWxf485CNtt_@UG%LvtOmpr=mhGsovNxE*~q`=k=u7@Lc&xG%}3D;Mc_7e{n|L@kD| zDi;->AH#Vp`zb{=fjqW=iE2;Y1VJWcB0id{fsXiVsv7@Ae38T5@t1Kt^_;Lj#gg|s zDt}5P3z+A_6u+Hd=HP2kDkYRk)SqbhC2LgN#FQEIZ) z@JrHLf1XISOE+^mebVEzRc(Hxbfi}ESo5aFO&@chamsn&KUVViHs4Troi0Ce7KYij zKELMCT?RUTb^*;{U4AD?GQ8)n0!`Rgu`d%Cb&n@?%y_Y|T_P&HT>N!-yRW*x(d!4S zVst@Et@@#tw*$>wyKx+xok`NC;Rrl>2rI5!SYD@*obYmq9ysQqNe zOfYXFL&xVX!*tR=fpNc}H{&F-$w{Z1Dbptp%H3W^k2jf-X|WGUqOAP+Q!Y%-((*^n zoqZyk(Bdyw%1BW9O@djX1=Hx{h`|L#Qg;M9TlBJz5w|PRX!=2PMauZ|=i9W&BTGJ` zh>33xM(NkD{Q{RMCf*NqfP2Ct28h(DclNs+WL|4Y8n)@k1-v}6NDbL9Kgtps>$TW2 zj;kG0XU*^LiYD=GRmu|P3LH;MRFJhas(w^fxHlM>5S@Z1QWt(U+*iD(+8H1wF19nD zRry6~o1l8t^m8|weavJGF{drZe|xB7A#kv)x6pFw9|J`K?X^#j> z8k9(^64ERUk}9<{N-LoVf^>(pG%TUgsdRUD$Fi_=mvk-P#dALQp7S}MbMNOK@9+E1 z@5>AfF~bbQ%)-Fq{d|2T(zLL0EJ7ZXm|@y(L&5QrIoyZkdhwRF=*}qQM&3r{OpumC zuVd+cNvW0AD_(AL^~Pi2gPMC3(hHy}j}V@tEYd{lxS9BwA={(Ie5%*}FEJBG)Ts{l zY3sbLCcViH?HBoJ-^c|e%s&Jlw~xlZiL5-FO$6}sKk`7WA`jGmNx zv()mHE>6On#?rK%SntBNjZ5nex!%na@=yAEpFarTKQ=kJX9?U5keH)TnwA;*Z0+T$ zF61c4+c4~`8<{IT*NoWaAEPta<&rta6NWgRIfWjueKA-Gk&!_VNnI^-)wyfaDo$Ai z^{!l^adAxdpcruTg#vWfYOMt%EX9vZZ;5Yu%bd+d0>G`MXcD}~erNLp2FF^r?(S|M z5$K~f9n=kHuO^#_-^hTR3>0qdso-HzZ5N!#mwnpLkM^@Mb|p}Ed;W{}viN56!0DbW z!;v#{6FtnZ6VrZSQ5uRVr73nrh|upJ8uGS>nLlibUMXDh2}`tgrn)a=|3WJ?C&g6UY4 zD?F`h=XPtr5h6SBU`af$CIT#0RNW@5w*9pHd`-ApuEw9azP_w_`ECWkRCN6cfP)!} zr%t%jvG!_&pDSK?Pi5V;FO`rwH`*LpLOiV65A_?@(DmC#xb$Qp+b@L?p28u#K;|!r z*V+hX5yI$~;jB5(JiOZU&muUio=jxoi|uZ=1fd)8b)%;Q-11@*0)opgpp-Fgd=iOQ z3V<_I4b^20J$<;slMNp<8mPU*ueD)jRV5~`xDi5t0@Mwp5{=uY62e~9d4-q-HwhjY zPskXE6%V>A0J;MJ-P#7yq1-i#nzfpmwTGH@=9_i*n)Sdf`eZEz^exZ1T3-Ceh1}Z~ z6R#H2h!(RiE#^fnFPmCk4YgRzw^;7ASR^!S(0klf1~D;1S;su?Ni>O>ih$Y$DG4Q| zn}T?#37@TF35I%dF=MG3HZ%Kyn9#}~23`+$dJhk-HcyE*FO@cL!#1C{ZN6S@ei3c{ zU)lnS+CDV3{g_^D3*KuB`NxG^I9K~eiS`JU_DI9_sJHDA)G}{arCq;(-V%B~+!he5 ztFcq@%Z(S6>JoEEkd|3*kS(i*mPxBjN^^{Ps2WPLY)iXxwPt?l$SUf{ZtBPx>d2k% z$lL442X_{bb$+Gq{KnN;DA8G@(phZSS@O2C)T^^BqO<%kQC(ohZk+vt#3h3@5>+YxT z9^mR8l;}nesdNt;c8|R69`))Ti|8Kz(mhesjcDqg9O_2ScTeqgPh&P($a-ezduF+M z<|KON=M{SQs?8Vs@c`ed6_yrh-85+xcLU(2Vg^S>9wR&E1->rGlIMX+I!&VRnHT2Tn(yq*i+mlRO+Da71ni=6>qoewu}T+Wmey?15X?2W~SA+~FR$D>*=~I>2Bwz-T+b1sqaKCwgwfQNN@|f`4oCs-9^;L#`e6IcvpJGMJ@Vs1Zp6rF#MpMk#Cyava>Oik#JqUqW%J0Z;Sr04 z5zGA%E9_D0>!Yt3M&EFc+DNLu*&kL>l_%Cwo!f2Sv>E0M8s;h%)eQ3Kc`>Mk?#6p0 z`9ueM%Tn3w99x6zo7?U=9km|x_W|F0Kv&0~SXV?hgJ!TVz&*yEws z$HN%L!@0*lN{&ZhYdqLc_O`}Wlk_1$`Z!$ge_uT6=!}==Cg6PTomh?S;ynJ0bRvae z;uH78XUT~#suQV36KS>+>E06=krSDz6IsO*+07Fxf@3lw#do$)X9$G$$(!*;&7*o0{dGnv!90edp0U1#s9u$@o3ap00Hb&vtp>Tarcu}Y;X(;>>6hRA$ za0ErPh$22fk>JdblFwWX9zP$Ro`R2`BDIiky~$yu;{xJTa^_~*3}wj-Rm%+Z$d3!T zgBd!U*<0kZw;5;e@XX$onx$8pWiXy)v_sD_{dysnHp@~nd%tCtb>um1&2$11vE?~T zZZ~ssKKo>S_VPkbZI0V`j>m59kO zo_TSpc?q?7Nn=A{_Br)Py$9rT6l#OgCG$5d=jBJ{6&B|e59XC{7L>^so-i&vR{0dXUUp;={4ih8=fT_sin7SOSZ;K zc6Lkee3tB^mK@TS-j^&nlC>;3jVw7YVrH+GTyad_E@BR^@qQ3U&_5GM>L0F=7W4A* z`SOX0iGhWUh5sQ$lABXpP*7T0T0v3ak(LxixE!$IQbz(?RUd@Hv|s4GFnnS8%G}LR zFGF8tT>aUh77VSeh1SzLbyqnrkw;g_9hAzAq^T!`JADZ74-XHIkB?7EN=i#h%gf8F ztgLKmYWkHr_V)IUkB|RDI!^pfIwB?~Cx3?>k-x)^Q~!>3#E{3|dB?fmdB^#Gc*lib z!6WA7@5tlQAIanL|CV{g2*`h^$IaiV$IDm$2|oT#J?{KbJzl=`C-}JgFX7{#)Z^tl z{u(|W`~`eG{A>95+eiMIKOX-ze?0jw`Qzz-%^&|e`*{9e+Q;8M_&Wl5{C5fD+rLX7 z@BM#6Acud7K&D^_1=E`~tTIUU0PK7qvjK_II;TC1u5L?G$hdJUYY{w9I60ZjR>`S@A;P{Myj zAp1#w5J(Mg4*vQpk7ZJS3H~Vp`S_AR`eC!XT@uJo4F5zRZ{8twh!Ll{)8>6iAf?ea zK%@ubok^a}cO1k#-39|V%y zOF{iV38Z?xe`UQ5u?ax@3Uep`_;Umj#H*zzy_16T_5=#?9 zAld&&AUCiK>#dRhf*}zfYi_tu)HsQ?TUPpS z1d@2;YJwZ~!=sxu#UF|@)?b>^Flk2G9lS^ z!#g^izG@EuepA@~K_E#uNh9=EcpwhtX0(S9op4{yx|_&Ps%|(_-8+PY0)>PCU=3QD z*dycxIgk`k)^R&@!K+emhVV$bQ!XBKO~dZ$b^G$3cfm;SQhpNG;4*#!q=vnwHoo+- zyXkoM>);pA!W%crhmsPbYEt}4`kVfDn1d|HG9Y2;Fl#+5GjjZk=OSV48#C34KO(?T7NvoB=(rh z8c45M=eC)yPn=*1#AdH_NFdP15J>c?Zyy1L_4K#-8}<0Sw=Ynq)2NhIiz(yxpOekV z$e~-JjEBtzmT51c`dBFpj)jMo#qVIHzK(}!j?s~Cs&TDJw_R`Dc;09NV@(DT6#(u+ z@FSa@FsTQyHGoAQkG>9YH{55Z^y@FSZDWQ(-_yNfngM66-q{5%QQROFH`j9}zbsR8gEnh9H6J?9XIvu^eFbid z2R=|J)>RqbO*Qu@TX%;H_o!w^=Of2#`@ltRk8O2Qran(jCgwv5`&(Aq89v{AA!4>0T0wk#ob&r`~o+ROt}iIi7@Pu?87Y2%ZY8XDC-Z8 z`>-nTH04`AsF=W>MEf4_go2=fG^T-DW1+~@K!*ZY*QhrOB#3^@b=WWX;i%_$SrEt# zG|yz!#|)U40kG78UQpOX#lYsF0mR4Qc2a08p*rhmsSsm(!b6OCED5oQF_k?GNy4_T zDg%0^18~f&JbeL9W4^yYY#_%GwUT}pZg%2+LD8yV(aoS6Wd~@C>~#+ z^9}2_>#RINCllns3F-r98yX=PjC96Ze+8do)nT9)^4CO&Knz z-3$hTLx)PgqdGk?YBR=iI! zYRL?bU)IJZ>lY*ozW*W<_vJCartstByA$zZ0m;n#338gLYVT9|C%)Wad7&H^BF>*m z7?Ap$Kh5wYToeBbp6RE$%;bBTX_hBx*7zPKCtq+VQ<*x_R4CKmSEM^-+1PZX+ODQP z4M;~DOr-m~&+vP1?n-ItUhz@F{EI(jW;lQ5`;rX$xHP+pG|7pyh>6U^lT2yjOr6yX zef+Gn_gNWn&p%CM=snKJJjp7c%m$ZaiLzw8tH^X<`9UBjbczBpOR_RUC$cdFvL!&P zHqNL1BqQN{PR~hBpSfmxK**QXtbPoEjLVJX&UNO?DAUZCz!1oe?8&UOuDI;ExV+W4 ztcAGDCH%ZK%KYzf85mzarr))`NJop~96Uq; zab*g=V>aPw0h!iUo10%7CUVFtzfvPUTQDVyJWem3$iIg8%INs*!uRV|zz+hMl>Y5- z^^!okoP50L(!CgU-TQ#i7ENgy+Dim>G_3FNkE;cbG9yK)5#*+owUik}-7 zJ<&2`4K3E}1gRj3WnUHx+}C6PB&Knflo|oAYiep`7waNQ#0W~3A8Q(Gl^7Ce61agj zVqjo>Afq+tZn8hftt7j+1h!V&y}_$FgL^H~)A|jE*!hfi>BJ=%FRCjvz)iZw6%`gEfe~97YC>53hvbxq)Cjpi)P` z{Y)4mG@jmChd>_`Z2}~RmT6N}^dP=|{-BxQ2q3_SNc55iku~UhT9vj;$zUgdNf{nx zi$Rr`2jt4QWZ*FnfI%k4g!AIG()RP5ga;2#;HW4ro!!|sry_BI( z&*pxeu`lK~EEoY4l;>YV-cc9rjrr+-`I73QjcRYR0w^$_*Izjq zI)ZHF?3c?;zDXtdPWfi`5)Gw%l2`9kF`dqUDJKMB#@?Je}bb`@qm$oK!4di5Z3U-e; zbtkKKk5zR~zJg6)2&7>5G3`VSM-K1D`_NB` z?7!&fr==PAjz4fmXJGE}03#edFcvVtf*k1S7+|Lvti~UFs5AKW@gNU;Fg;+9A2|r` z7!;-%+QaX^gXp|=-YEtj;#3%_N+^`hEqhEeT!4>Jki&+Lht=T2Y5~KV$YGg|VO^RL zKKzmAIwKddBgXI%x{e`iiy_>gA#<8h_3n}A)gddQ;WzM6)qs)r$kDd8Q5Tvqcg)VM z&e%P<(a$GCKGkD_kH-Sf$IO?;LWRZ!n8qWV$MH*OQ zkA8tqWHV1>At!=cCh}+y_Be=dItUvnL7=q%Y0 zkJ~3Mp#!UzoGiy&FpmK=%O0DfUb@TgotORCM+0h>&5_H&mLs9GE6;^iA~uJkTvjyU zD{+>?2~#Ui&sUQ3hCT_eis`JTZ4PE6uJTu}=2&9d1gj5e*1l~H6zQ(9IIopi4ph{v z-9fI^Z1&gDu2TxFH(B<#xU3Vy*E{n1x~A5F=j(k_y#vA<$J!esy1iqG8#`4SlT$rY z=#3TX%~{=^dELz!r_JT5?$w%2#N_6tOZPVI*6bt-88Ed+JhPj))mF82X4!LKnfKsy z3$(cfu5H6{-Cm{M-sIoL&!4_>u`Nlx^UGEbp;f-9*3N;#4&_A^_4Lknr=6OFsatwz zB%R)OAII;^R=s!f$L?=Uv0Qvtq1t_z-^+G^;ue|WO4=oG-aYEsmDt?9d4CEjvLIIb zP11EpS| zrM(Xq;~p1BbjTxPj^lTV$5C{Mu%u(tz~h9Fqt{7?w$+D57stsVhhU+TL*0|K+Qr1_ zlR&zY%%m}1lGE4dlaku;_@vXBiqop3&Tn-6*?NbyuE+Hv2Va!Vn)8>+YR^K@8>c-N zIem2Jt^DUh`CZ+v=bnk@6IRQU)93!^b5!s0tOz{Xx%FQBV(TB3g+U0^HpM)dlM1F0 zasl6bIxq8|1d`BfkM|C?e7v9!YmnyfS`5#d`N@UOrM&c#7u9M(-wc_Rs31>+_mcac zuBv3I=IS=bsjjKz=~TO5Q>ncg#VnCq?82p4!>(omiaVIG3A$*1lX=|4_wF-~Wf_KO!*8-orFY&m?o*$UG%@8jJ(OcB zjbMJff3n*r#NJ9@D9;(a_ePQ?tmwP^qiHWrMXbRt^iCU#UIeF-(Bb??KK`ID1I@y? z3`NS~BBwSTCSzl%}sP%3swNzKOeM3R?-o2nvT?~O7W3him zRHpAqLTrZ8xN2Nx;CuTi@2D?RTFk5;JeT)H5LV6DM34whEHZeQsNC@5XByblM|ES^ zXoQvz-=d~oRJn1ybn3A&{GAJzNh0RE|6VD{ld)p?p)U`=St?xOy;*wF=2x?f^t3pM z%?FP(Bg${dOk5(TxI~)qx*Sk~H*jM^L5yr}%n`+Ow$kM94$k$fdef15+JoWACD|bcN2f|9s z=I=7xjF(Xy2={yV1^baniJaXxvB*6`=IKb;?#K2wN;HuzGuv&-CmMY65%;w%(Rey0q?Q2PBj*-F)tY1^CIFH-Q z!uBQ34CN?ZPh=iZ(VEV+7_@pdd1$^f5lRn;5UD5TarNeYbxs;TcElF-b;D-;#UKT& zJu2i|B+<0d1B6hwC66O~|J6Q}YGOGks;HZD!|Y?U<}i6kaW2u+O9Ov+W2MpP;0=zD(ZNXzadsw{(Z^R*R)w#1vK!b4Gd~m(%%MMa#8h#qWd==un2TDCX{FuY3DF8{s_uVMcANZ7u>TpaLh!p* z*~K~k6m8CXN_@tuCEt%d5*8$%$96L9evigXUp~Nk*kyzsi|s!XewcqV#N4j1d4k#` zu_v}iq<9zZ9cLm$5!vf3wVDL1RuLtc$n@rUt8x`?n#CU1uWq~dxtP*S_Fd#aB+gpu z10gj9tBD-=!COsH8uOCixFIX<{mg|pbJfwv;oO$BY=dfbSnouBafz+|Yxv8C&A3tD z{r&vwRIdykMU6H4tbYv?f*EljzIEH#8K=-#^eDzpBo!YNOU7GRL`NZzQX8f9)tawE z5XB2T?_Tx8Eho@<@yJr!!%AB!D~H3VsePQy@cSB%4`&5NPBxP{sn)H44Y8=Khe!3Y zk=EWH0%nLrW~y%sV`|rv6@aZfJRGlH9}6YS-Oo8{y}9%{Odw#M!PTJcNuq9KenRyP ztGO`s^*3AaghkF*$K6}THt>)KOG439z3#M3DI_|LUeYJ{!={<7v&g|JbOVe>MdMEG^Mf;ASKAS{7vteL` zz4Dui0i!eX_d%Ms?;!I+tB&tpMj+8wMX5DAWGQ_r)7%Q?;c9f;_>i0Z@)@DVF|sx`@!^lEtQ_k zqKWoiVG`EO0+bhGY3g0&I}mvr#8(*LN|r!TBcLMgWJ)c5;4Xvy?i-4=bjXe??uXvP zGH}+UzI$r%T5hMh7GI7PbY_C`xYnZQf`m_B(dPB!(-4u<@IL4iPR1iX{_L%a0?Xie z3D${pqG~6PuLHU~p>AMBX6WJEm7@=}o16hSDgk(cpj$Ce#1o-=1yJ!eXfZDoJTF{E zTHnuEe=UM$N~?-|$e*H#p`Sp6i5El_0lzCFvid@hBq4k&9_tsfhB5yu1k`nFYj;}x z>aoet_2n5LCR4G|*PyO!e{!xmVu^+ugrbeJ=5dIS(9EdGrY z{8d~rqZZdN;F`U}0H1r|4JgrM{hfLVmYl{<)>SvP#UR#A%6ruK0ExR@(0dW$8=Ot@ zLrup5HMrVh9~X?_8Cx zpORVjCn?|dMtN_lY}OvGA8!}aWF zSD8e0kQ-ZcRbG`hXmE|tt7+X+2dVmWe^~Et6UYrU-GyOo?%`*W!w+;+)f9p_H~Q4i zl}RH-)U=_GoS(^{QKORE>eslveu_Y6E3LBkv@CJR#!V;XK$Dfq7$Z(Hgs2Wuojlj#*{Dg}@SeG@tqIYci$wm938d=u zzR~o7?ewAT^jxIgY%b!VvrvmZfdhOL373WMBP)seQ5)kxV(k;|{|SL)ocV=k=9<(D zncB>C;~DZiJy3}r;6P_%x9)slnrlIe@&H+jt&iF_;PIaMHwol#BLN&Za}e^m2aI!< zBLSP^bO#228syCpJ*t|Sgl+?xDT5Wm|CT_`OWDm!`^?Kk&C90EKQ5VV7#Dax1jE`pb@nI`*#VXv4NBk<)RiBn-Lnms1daIDs9eW zanbTG2&CG`;yYR+^Ss5UHH$BOmK-sEOZ^>zTy`U0c4u7n;92&RTJ};~_BLMjv0L`_ zS@w%s_D@?5C|Ul{vK&~l{Jv(<;b0lLupCOh62`a^&a?7SY9&H#CDM2$%5EjvXC)?T zB{pp(u4E;?WhG%`1-`hFc(9U$vzmN460rIyaWTYY*bVT5T4Mb(wfrqC+4u~rND(he zg2+km7d_6KQupZ~40jpt(%-#v=k_f+x_>at9~P62j*jIXvmgW_#mOoD=#hws$R)>A zPkN6F8@t)iGi4ZW|#lF z=JNl(w!~P>p9Gh`qn7`#Hu?W*lmCCJO;UX-y{t`c{C#Rk_1Cq@(pzpz24{b_Ht7Ih z|I6BBET%SD#lx#iWDfZ`YFR*pwt*!6MQw7a&j&9~l<@gc14S8zS{na6wN(DEYLji= z9BL`}Pi0cc5`T(XKE0%tN7xTy{&j7#fz+j~k@^nvkJ_XXS_AaU0qm!0lM)S>+GGcd zp*z8pia6={AF1VUwaG$dOl`6dPZY0##HH^ispWrFo8%<1fOrz{K;3bFidwQ^^PoVS zMJX;m|5Teq;82XjUUe+eBe*s|MQ?AE>I=X>K^#Ne!I^geWlS#_n92tM8O+JM-m{I^du3~DF zcL6{wUQ9?U0aKe4cE@L|8wZm?0RWOR0DdyS;zw<=tf4Uwd{5&&vAnKjT)U8w&1nje zwPLC1eNvFUqae7khZP5{9J&>rerrBP5EyaC0+i)%5)`XqokoN77UH`h%MrddrKfKEO8Y^8OKFx^~i zedXPOsmX5~%T}YKJ$B>d?!(Wmi*LtKPeY$gYQLNQcEd=Vdp!%hSek@L+Pfu?_j1~o zJ>GAX9|)jC*Y@fg1y-XKfU}v2pswfDJD}-`W#5qJqB(WnuG!a9L!V$3zeLf|l+|-^ zK|IOJpjTZq>Os2bZ9fkCx^J9Ihr4{%p0Z;AEL5~8E!4o%NNZ%5-?a`OzX8;lr+=lk ztp1QqEBJaBfNWpd2{Rw|Wz=Fi>V5hj!KKVLR?6_}5?rg>Zm^0{$Kw%9ZShSVlQkIP zMt|dZiwTSyf_2jxc;6bIT;Kje8H@ZDkN|=ePzSnE06KwS-4FHb-}acn_2k6NS8jtI z>BDZKfH&$q^0qxl0ImYko&*H|T1<1Y86;N+r04?%6xfg`6B}FW7^!<0%2p9bxi_APPLIJAD8Q;$*CIKQ;!r907<(0qEPz)>z7ZMq_?J zI}c2=&`27q_0TEc5f+y(wowSvSLH(eu^njdPibUwq$5v@;=b<$db+t_6#>j?Hvp!)bFzO zc^rmH4RR@f^_BvnRh=>M%sGwVV;LKWY4~azI+%nMYf0T2#T&x60StPS@_~|xaG}{%cbDcR)7U*aAwR$(`amibU>-whZu$k z6NeZBy9gy{XaK3D0-v4|24XTsYC|JGF@!m4gvIUy`!ZrHfmI@O{{+`?Zwz*rrEA?3l#Ojr-<0E8$IqAptb2td0{a1-K90I_04;or9g-ar8} zOk=(rCrG8m1g^v=u9$_lhx(g*+Y`zdmkwvSQgu0wp&;=vLON#SbHWgT5GH}6fP&q zrDr9PtmAn=EOs>G+o3D5Bjbu=hXxa{$mC`~=aJ=iDJzOttJ4-3J~Rj@ZGD~c^F#j6 zy$&fiCt^$wVj9L$N}}LVzf~xIvzX%TKPr?5_FS0SBxP#3>F1b|6oJPtM~_pCNk2WE zNYy<_)#uk#$x7kVglnv(2v@)jD$-s}q$%^K@v^)y&I*OarQKOgvyV%E|2V?hJe9ER z^VpS7A{FUqFU<^}#~#j_Y1Hr2gjh1n-)DqksAY$ZKTGy zWi)=IW=Cq$CAG|YPoBkpk{(Ezp~at(#h+cInJwLtW%D@8&OEznBD*H;c^Q9}ZB}M2 zhFZSQ0h8yb2V@3OW`_ji^ik#xOz3p1W_96br}5`bROC(uXbqqEjA~|mo5-El%v&_q zoQ?~vc$~8|k+*r07aN%u7Ms~qk-7ao|A-~`JATIONzO5bTApT~o@AYy=K~!J@J=(a zsPZb~3W!e&5-JMTH1kQdzLLvj{34J;=7^z|U-jd@?#1QO3Vfrd`g{wKb4TkNOXW9T z2lTfw{ybKy!iSDQ>{p0xli$nH6!kVl2=+-#-}BUA4<@V zHQB9`(o{=J7l7->niicU)~BT+_e*i8H0>Qr?Fcj}NU_jmFd`I?0~0z$c@b8WW;O#) z4*|}VC2p1Fy!Xp8Rm)PbD-wqRtbL#l*)T#B<{#%k+PY}60uTfR^77Y=iVu(NEH9%f zO#Gn9-UsB^1_`wQ*#YHtazIu97DquD`>iTS=$F`HV3$J$oE!L{&gwoIP<_qKC1D># zt6Xtz3*=DtqeTHJAXQ)2Km?)XmhqMAa^ET)HNRB?D4=#EP#94t5TYMGcMACa61MXJ z2qC>JRk9@m?%%3Thy>1@0@$p9@7G`))=t-;wce*7JFQA)`^t^VdTPwnV7A?8Jd9)8 zql?cc+61;&38O7|g?k3WM}c|{L2L!Uhz~H1T(%mz1EHZ3w8i{K#CP<3uHt2vQ5GW>p%kn!21Ot4u}trQxjSS2wVs1 z9sxvhYQ)c4u4pyAC1{|6)IV`5BXO%$4s1xZhfygvqum56qniQut;?fROSN)fW|(V$ zz8Ac_4Z=?4mV~VlXZddgHFpGRuer4_#scLNfM;oSj%R?UXE1;2qzMGTpbPNK6h;a4 zzSh@<$aao<1*7f*S+8`kD*JuZZm&7Zi)PiVKCKiQ0kRc9ZEL_l=7yTewzl-LrF$(Lp*5msor~Ie_1gL*lQ8le7{PW|{BY-zU@s!B z2VByF_|O_v44k{syCB~SAj&BO`sgV7*blT}?2I$$E?&=IM!_k#Y@B!BI()-8(h(ZYm%^;UfF{jQTuTIe; z_@E%NPyjgyWh)e+8IsWXCayCigRIw$FN&%tqKq$=r5WaPyrh=6a+lQd=m)jj_(3g^ zKd9wN#gO5|&=V4Qt^iQipx8qB!oJS8IkJwj_7G;e(osXukj=BkrePkK) zavt+BAM>jobI7`+mM>Q?sih9fCAH)-zoeFAS(nuE%gQCSG`=_S#d!i?Hjz<1@r-g* zKRZv!Vl+nx5xFt(xN_txa-^sl@g!@a>Kp-mi7=-rDHkfMbDrE-xvWh}b(-rrBARqY zE6|wAhI3Sh4stBlVib;?)UiMyktm|92BFb1He?IU)UuGeROVg2%kR7H9AF31B4APXi(tI7g)L|yx`}!i6}zh=LAzI(nNg{47E(mnL}pv z2YvgdGegZjO_7-0jGVcHHoYc1%P6eN;4;gysdKMpmOW924YP;4sr5j3jwexz+hvYl zQH!r;P8h8zgq{=2(-ak+m(tagbeVrltSMVFuUG?9K+iw5ggp^nP|{sctC`nGT#&9= z&=#K8MK6fZEzl)y=uJ(Ut?!n@d%9asoiVGeLnk#`lE^JI?GS)&TS#adoHU4`mfY}d ze7Zrx>20?2ZPKKHUqp5obau$;25uzn&{XeGC-u`_?2w<&G?=5O?pQ6{cKuEY|IU)% zPp>peDU4*>nqw8&1?cSZZ1r>KO+9d(;_F=$NSfiezbitr*V8>T&$h>-wWm+JS77m7 zo@1VuZa+eBU*)1j&2^t~V{dn2SJP@yyEk9(bYCi@$PB)xw6$+&H3zFbV4*nx3mjN- zELry!hzT6Nb=@-wnK2XD6An3a*FAi7e(0vO>_Io{oj+@lbYxX|6sT7cd~u{rbsU~w z9HDp2<9wtXg6U`u3x_N>}hl#UKB5C<5> z1-}67{Ew+6ts|L3cykxENWeq*n|*@uk~a&el|kJ6B_6|CZFt9*wq9yZSR&cV{|>c` z`U`3)7vtN{qKg<~Gc5bKq*)@M`44KT_0HrE3UdnnE438yRjhn8Tl8U^-{n5ca-pLC zAJlT;rlJVZ*@^jVUisZezfsHS(ExO*?Qo-(l?Xe}8O|lOB#{UeKF^XkOJ%{1jGU(MV!PXgg>aIlEjnGM8j)aqK6>)AJp=z6qfpYZ#~IvCnYEqhFZ$p z_N69j#SwZ%0=?>gNiCDS!tdV|Fx;voWeB{amh;~_{nNC2MM&>@^~!PfN^o}Hu7CBq zl_FY&Q;~1!3))7E$5#G($HTSxLM4$4r%grrT>3$2D2XK36G`rCMI8?uwYi?kGNqE` zNHx!2ZF&4?q3D^CWW|sq!`HJS70j#q$;wD-+g=qtZ*Db7_3lDtm{l|PD4!Vv*;5@? zY#t3J2WORM1{i8Ne$Bs|Oz{V`1jRakRJo*>4 z|3NMJMSoDsle|l6**JId@@uOu`>SugQjXe%8FLW%CvyrIYWbS;l3L>ASXLb_I&%I+u+bi*>m_AFJt)8t*bmC;`OQK-=~O=Ait>ta z_=kEib%kGfQr5tj8S2eJ7*1foD^A%S>hnk( z!^)bDnZx{*=tHih@HSi6atQHJs(huEl4LiR4bTC9ep7Qp>fu0lz$st&=Qzo)4@-8W zU%Y)mEsiD4HxkDAw&(@z6;ElQgB=d1y%)FkK{BG`Pg%XV4DYnRk+LZdQnh|&NRR6! zBdZq95>aHxc(t{yq&QOzFlfkJ-_pKi^g4+0nh{H^r>ts8IM>U{=al`!Z0aL#BEK|! zq8!A2sCDp^Cuh$Hau*GfHz3~?EQ?q`d^eIecJYbn_F`NLbznF0co;WI*2Vd?UEad7 zFb27245`1_qZ|A&p_prlPb*f@HZ2^!LAW3=6D#Y`Qy9KqWJ13a+be;gmfjd@iG`t- z2Vu$B-E*Q>HKo1Txq^voO{p-{@*##=>SL&7dCZd_#jwvb&a={@6%t{=dwvYuE2K~2 z2Iw%_V znyI+&rdqrTz);Hzi^%NL-BtB13bn62Avs3Q)3E*u;o`h~CkxxPBNV0jMt5Z1Na31J zYBYvg@`vO*t4`?wUkcU}tJ!;V=WLP2YalVyvIIjdjWE=*BKTXRD$?k|Oa5+4wYTv7 zoFyogW;cdfMq#L>=pzMbm#0oyNMmz@Q{M5OsJA)$hDRl)TBajWr9QhGR!@Ajw#~wV z8qOJCE0oL4>vEQLFCc7EK0I1c9JL%SW?zrUmeVwTR9+x)mz%C!e(U6y$^{_=hFbFM z=N-P>u;th+5s;H<8I9a7<`~(I*PH4tjmux)5IPsoeTkz{hq5rV4EpdG>;9WsBAh8V zok}e{0gZ+VAxm$fV|^luphg<@X>W=yIZ`T>rgZw({@30=U(6b7z}qx@jR`8DDdHKc za+@KZW?jnU@7}d~oNb4^BsaX>8rUXjIUW{9SWP?nuH8=M`$q+GqkGTt+vjt?QDr6= z1zW^+j#a*KuMO;nVA*$3v2l9$uJ?19*mvKyC=8wsl;G%v8Q7L^Hf$#>xo^bw0(WfB2Mo0w$u@wCDD=jq7nkfSVW?#ahFVHusAU-CD+7+mv1Yr~uVFN*MjY{3 z-F6467;2e|p_V!rYFQs=VG$CEK=Q1W*2C3ahs5VD@EmGksAc&jwY0@h%N}svyC%zuNINyJIs6C-MbVE2!+rkpTjb)ivI(V>tqGw_%COK);`2 zpY2|mF|9L&`kZruuY9Rv!1EyBO1Px~BASPaAJu6=ajts#V#X|R1x3}{yrgC7c}P83 z^hGIHsc+v3sndW%}X=HnqIq1W-<`z>vQntDqz) z_0IAJ_gXp2(IUP6DX7;#*;w6o&l1djAu!%i7OLl z7HpKAY~)S=OGH2)w1J*AQSr~$&EJ*aq!ztL7@!_VaBE0x=`%npfeQZ!#A)gYIfDwm zl1#=FG9T0{2R5UxVG%*3%KHHic%eG<;%eFRAo(Z?v_Pxw{vdialhN zV7c0=~RavgYL+kcDp?Z+>uPykwV|`iR*t(E$QVFhuZHzJs9jgq`N@us1`piuz(@y z)pg0psHghIY{MCdJ-IzD$D>iOt8~6+ zbFT-}W!xtF8`M%6J*0Rq12i2d$9@Dtsd)O4fhiNb{3Y6}hB~XM@oD8nYMsE65U*vz zt`#!RtLGl8MHu?%L8jV&-Kd}3w*PNZ%R55-*Vy{6+V=6pc+LbWOWJ!~;qI~j5>BAg zv%A*$4B#zquSkO3Pio;ALoLr4I>?tg$X`78H>qW}3b%dVBji)|+)j>eurl5tRZ}N* zgxG?is?dBVr@}Mt4P~BvPt9&mEx4!l@UYIpuzc z7!IqQH>tA)5J?Vl!M(Uu!6ayIFOutCuIHngKU14jg@s~kxNVG9OpbD>sz0+(e@8^D z>fK_ms;EvwOxxAQA{b!X4d(71m4-~fkfVRAHi;;)MU;9Y$}A9{Bge0>sm3`s%yBiw zd#l4ENA=dnO(FH~u_r#4jcU+L{Jq-buhbGb7Kv=qQGeEaMLh#%2pzUSAyoGfwb+x1 z|A)Q14vKnT{6D_?Vd*poDM6)Er9@H$X)%bUkw!p{3Zis3g3=`@C5@zXgXBs#OCurO zu>3xYC-j_i@BN;8?w$F5f5UrbKeIdg&;Ik7o%zgjUJqviZ0cbh?okb9&0%4WzqU5{ zYij8+wi7zGn>4nkr9E7)GsUYN+ppC?A6k*3}la_i|+Q`Fco%{8oM~6B(1iG=C^+;0fQ3h>T@5rUz@qe^7`Ddx+ z@7E^vX%r^}XY?+TjiOg9w}$8$kwUcE7e$cbWSZB1TbukRspTKmCef*-;RwT&INyU& zOap-Sfe6tAJ=QRQHKq1HU7MVF*f3+>J7e*EYRPFNMy3r&)y5P|Yi#L1HIjMq{o3Tj zUrH@GO`bIj2y4$;H%vdTpL^MB==Tp(OVj6AU!uO6Tp5`QsQ3cS`Z2ZSn|~)YpQtjQ zWHg^_GoRu)pBgs*K6yT^a6Y|ZKBIR&b7nqkYd(8)KDKu*hVdai*+QPwLcYpEfzd*t z%|emqLUGu_$K-{Q!iCa?g|gm-@|lH-t%XXg#VWGJYR1JHzQtOp#k#ePpz|c? zJPA5ag3gnm^Cajz2|7=L&Xb_?B;7)W+3R(KDRJa8!mOs#Ja}Pj2X)T<%M4e@{DKAFrUGmk|*Wzs_)i7d8I=I>SyMpuAkN+g)1i$)k)SMud{@?b{{}T(H_Wv%1Zu=xl3l ztoQ?lUUc5MORwzT#n7KZzIrWqc{_ZEp>Onr@I~fD4_9e}ADf=T9;8)o&QOi3gX+IIf)Z^y#3#wa_VtUg(VQ z;B-eXbWZ#pL#Mex@*>`i>O%i9hA#b|!qA(Uti<5-$GJh0c;cEOeIs5ksE?F?4F5>E3S`x&s>)oabjm?$ObDH!gy2FaWtB5jzz;(56kO>13c(?&8UTdo00^-y zj8^Hlg-!x@2DL%LUluwSpvMcHq$>|?Yp-K~3!NA!A#kD7>3E?N1}=2s7(5^6))Bx! zt*&(@SHZ#z-7$Yz=U9s^b6QHv!hMd|LMGQmc3$dlVR)zP zVRQRgH{jbZBoK@E9?}6V7ph>Eb1?k9A<)>a!mKcH#*y;A$P{*e=)LU zk$MX+N=gs9L2K|>hkC}S1PjJTqMom6_caV!6mG}p1!tSJ1F)e0g)6<3eONufih$tL z0f|cRwnhL~41yI8cyR*+B*0z}aG?rv0YVtM>EH=^=qs*_#~wO)6@;Y;PjB1tI<^~@ zE`%KP(0Ks~5X{zvdgVOXZ`1*lY%c70^cZ1?DLE5wY2(b{NB5dqO*;D{vDXbSzwo)d z;f0XxJdM5up_I0c=7*d{x&Ta242Y+zfbOM!NCnaZ#inH6)~C;!1B83PSghcdIp!k$ z_A^Wnd~lM}3(i3Tgw>-x^jM@1Ru$foG5lgY5T;C2&+nb(ZT4W!O3vsP5*_J0i{%B9 z=x5cumOWjUw%C7DAb3R5^+G&$bdUYI5xnaeoINODXeSW4O-zLwIO7FO zH$DQL^lK>|uy}wy2NitvnNOrLQHpf1fT=ML0t4LR+_Uv;M7#v|IH6xW!97mQUAQZ@ zKc$i_UR4l{k}WpE%aIwX9r0RiSHok6*i6;^(sMWs+?DQA0ME7?!?{3!8#ZzaVxk)W zKzspR;9iaowi14(+H3yE&=+3}ulvAuZE?oQLe_ah?i)RnGR2f0c#88Ljvwho~{C(pMw4VKcv~=*X~mTj=L)cdVf27pw5-b0EBP zKKtR}Ap_A8z2Q#hB5r&!^*D!~;e@fMV=1}NhC|;xgJX;Ndv8OjeBhV}7k_LhCTcc% zm_;KDWYL2#5kY7b-3T{|_FCA5=W&4UtB6#<#2I!m2*`>IT=4?djp6hli5`#5YURr} z5DV<-J6uE0aMoOls2fo1-PUW042iF|bYprHV-2~dYOQJ-OM+_!|^Bm+z;REVPj-OV$Z`$GINhcc)gAJr(~zt9`g<|i$L}@SPk)Y)5r!R?WQAz59@08TvUg1kRGD%dyOVChHHhPgP zFpwls;>=gN2OT$CR)9CA5WR~_Ju(tUUINt^1GZ_%g&+9fko%w4JBexWi^!KkWl5)4(62X<(#(5 zrAQAytC4|-%B9`UZ7t4S!~1Yanhdnd<8W{>cc?u2X3l7mpvOS*2HJN>5zxH zS4#7Q>?}C_a)hb!Z}^#srsql6=1OowK;(kP*W4`zhKK~FxU%I?hTx1y9~@)_p!?i} zzc9%TzFS(E{~QXVtHc(om>H^`_N_3m^J$KTgI+m33BbEu6+TxLZ4F&ws*1ymYc&Qg zDM3x_;EZ%Neaa;RcJMR)m2CcyMhzS6)@oY&x+6L;Yb1jbFg+0GpaC2v6*7_7 zFghP|>fC?}PHl`N#hJrOFDoC{Q;E)G|Qs+Tpri-tcie-~z5s4HLNJgmc`RwH6w{G{w7vsfKL ze4{;e^K3~z-}O`hyBsO1j|)Q;INUbty^uSgwk}n*Q~K!*W&;kS8sLU7ExJqMc;IjY zT0XVutu>@#Kmy$Tf^PX^bGRxy3E^D;&`F+!|_7ryW@q_2Y$3 z`FZq0r>1(Z_FihrVvdU3U`E^LhZn6=lQ1~K$Iv~#YbQy_*e;|OBtQy_*eGCCKSH3?$qd?H^$h$cY{ zojvYLRNw@NpF?4F}`DDv+5JNv*F`toz1Tl0h+Jz6JV<3jU3u5TnV<3jU z3S#JSqacPp4PxlDqacPp0%GWKBOr#}17hg3BOr$UNejf#hd~Uzx*WvNhd>OyfadGO z=pcxpCpvtcBN_xT^q7&aUjqj~3_V16d4p(R%W>HsoM;N{KNwwhKU{_o_XDCU_F5}g zFZ*!btUN7WAt3G}I$ANOSv@Vci8@P2PvS+PAl!yxErjy5)Sk+va?>t?156?Va7d58iKfG&{Bl zziz9EZU!uW@qN<^j&vqC?owv$3Ultni5A44-@9{tFY#r5veTYK^j;cqPmIo1X62Xc zqwUVB%+tPa)iv8`LE?eM7VL2b)9fQf`lxz8(zReIPmCNiS?! zBQM_R)*u-t?0|w%-k(!?D;Yp58Fl~5-DHJW5f4gbG=~1(Xt;k>zbTmEcCzNcnqg}s z@1vPvQ{^S~LW_|K4=UBKnkCjtAckJVtP)5o?t97fbdqe?v}R3+Oc$eK>|7@rFbYTjU8@yy)o58saW+*v))XtN>3U)UgJtl3?~M5vY!U(O$?8) zXf=1NCh7yuH_F+u>1MmtQqo5EvrpzXW$HA>Y3>hx*ex|_+o2m zq;i>P)Mgz~B6EA2Q0K@Ib$ED$ZN<79fx*E)XTugy0wFiZ5yw97zETbqtzG)~IdNer zABTS`M}k-sb~zijK7F}r|H@6So204+xsv2M_9i#?2+9ybn0j@WZ_zxP$`w6_pPy3( zTVKePzWDOy6`5Ygj36P{YL}7>OG@GgS+?xX)a+?y>JAZtj?ydgmq84@l_GD^T!b!G z=#>0bG=_f7&j9s7?o4IbPl_Oho_8B-fjzf@{@q5Nk_55j*=u5^XHPeuJ>!91=*%?# zO!wwy@LdJ;LT3@X;hEbPgc%CJh0a6V`&<^(q{^!3g-+=G^4H2Y4C{GSwN51|E8Thq zE_CWmE*5;2_X06=!(eu@d;H-bhHffhUf3p-0%GVEhv_Qa8b#nj=TEr{y}h>@CHb|i zb=aOEp7eR}Yd`0g$m0W|HG4*$gA1KwC4+}OIxg6Z0<6w2IlzTZa;$lz@i|X{2R`JF zcLsg98Ym`wHQI{xU+$0W486R?_*}M zX#9o&HN9(`;5BpA=z!fgc2-am1FVV0ham1~w!G*cp;S&DVt{IG(o z)I4u8{h8e9bJo2Rd1Ia$*FQ`qmwxS^DZKuuoVV8QQRR_m#-l21CVS3m{98glr4y-^ z{nQxw;NYiEOysPOo4FceF0@>oEqmg@w=MMavp9MAMym|Ju=S@qs^yz?@Mpp{RUn4G zRR&_{&x%0|{aG%Eq3>j(G4%In3_TIV(4QxO82Vleh@roT05SCa5D-JRdkJFb2R>*F z-2;uGyMP$_p#vI2w+1nE$Dhy`x;Yv{kLV)m@aHt-2;A*(K0P@GMUfV#!#EKxxn@WV z2HP|oMTBc?8WNLN;5~sQ!mSL5k6KY?b8tYoGvbezFHW(!$09uT<>6MK|E;B%Wj^i+a?B#lh4uj!n#Z0zdl`vreAtp@`?n`W$dzI!QG>7bnpEIq=K-Nt#V&ey%JQkm=T^O9{Cp zPWDOwz0m38CN0U=$?N~r;L<$|85xzeE9iwz1~(Z6o4Z^wAclU_(|GDbj_2E(NiU^8 z-k>bu2+a;bup0Ll0yUjs^U!GyYg2CcT8>XCjFHw3^{I{f{X?cnYVkplSnTwHkL-}4MaVSj5>8VRcw(|t>7QCnZDeB(!uOTUq zH@@5+p}3!r7Mv={J9#IVRVsAJ+NpIme;esX#9>`{WIUo{3L}@(>oeMJz0FV znbsD|x>Q5MZDEB4c}o`h;Tj`_fkovCBad7(1jmW^pVsqQ&IUyfceUk(78qEH#mdQ@ zmkN*XT1q&RX{WS^dR)4{XnDDEp<_k+Nm-|Y5#%tn-6-x^REu@?1d>Xpt}VR6J#X2; zSasBTemi1!b9od(jT~AnDu>0Ty0rM{`mq+r5wxeeCE)7?$`+TLMWuQa_~`|kMbzRd zX5+wRMhKnyUt#dAE(^s>;CQKdVzbl-hdL@o>H5^?5+A z6VN0XHy9jD&C9^`(Nw`^ZOw+-kY?Z3r+1MnloZ#HgE*i?3pEg4J$&`@%jYld@#WFA z#27_oMz-}ytVb`;8C}cvZ?_)Rj#)iuxW4?{z+r2BdxLuJDiDRBxVn+h$ZsO~eAlaNU5bXyYo7p7zb0c;T-U}P-saPz? z&4gP#D$N_&;xnnH`T999dN`SP`{TW6OKVhK*vOLOQt3E{#`BKS!p%Z{%hlNBk+0EX z6`R|YZd6t-XTp(~qF<{|WodeFm3>svX0#(;wAvJon)vWxr(Q4gr+`x5NtzVhTJf*N zFJH#oXW+kvB^kH2mlZR;W4+t5jla6t`K0Cw7k`_D{DT-j;%VWR-5oA*%n8JYN|O99 z5`yA3L^xu<*gf9snmud%{tVlUvM5zgt|epUBP~bNbZ zsKX^0BfAj{@9pwgm9H*ixnsmmqV@bD_Cas#1@YeO;;?6*H-F#}EjnhYmV4vYfs%d& zlhmGGyhvc?ZT`iFZ}#&tJhoFRVXH5lo(Zen*c!<>4CJ)vwtf7Z1#(a6( zj*1fEx^uO1ZynPl_2a>is8mqJl@(FC94M5Unu=MBjoEEi9|pT$#i)mCp(_??B__!1 z#%>GXCW=+%RxvfXUWvyL?H9Y7Q%Pj+h1d}@5%9!13p>qIP2c2l_8^*?0w8-TF792e zE`UV|^UHx$QyX~5>AKV0bmO!I&cjeQDo@og%>g{|7#GW6Dq=S%@B0j!)TrxvD0;)h z5pFC7{%ph1>;pH1N!+F9VBGRIUaQ?;tP_tAlZeulxC8RKvl zKas`Cqce47AH~)sZoX2gLtKZ6BCDCiT&44=F45JH3sqh&J4=)3Cc05qGT<$+apRok zg&N(PR~IGna$K3DB}<+IyZbmd2_%GCYbkmBg@tORn{J+7bY&^7FJ`$(K3pMNCK0kD zDK#9xtSPY~;cOs81#5EU7Q?vaUwv~!GIR%R6Da3~R94WfS%jDCrCaXQQf8V>r&FC_5SbJiXFO&X z?+qz!>LxrHnNV1R+c4pSDQO;NH_jYa7UWGam@93Q3v~{ZD&FO;fG2~y9J13bGVBQ8+4J11sRCLP);eRvT+p&LWc%Iyjc28ghu zmpj4d?GV?FMHf)~{(Pyelc%lgW*e&eep`=0Tkq4hKKHi%khX!uw!!?ip*m2iXd9Vo z8{KFdgS8{iwvS(GpWtbqyxBf=zkT9BzKTG;%^s*(bmeXm6AY@YJBzz-Cl!)-tMT9y zqr1GlzdQ4W+owy-Ev*2XfNY{Y(AF(q?cT8y(y^P^v6tVmU)OQa-Elb8f!gRef*~NJ z2q*&r;6-3aB4El0OhW{gH3HiMffI_rO+w%mAV8lS$GQXDDV@6{&(`Gng&pJ72F68y z*y~}L26OpkbKDgkiAahL2@?0U#MbpiSE@Ew5Mif@b*0_>d>*rtjbvE8x)r9o6*s$YWA-SK_S|9UxqHl%-&gKYHtbQc?ostn zR^@Oz#n8>~aj!0>OK#3xP@$$izln6IUGglUh@s5gszy2Q&tg4phDmNl)^5fgy(Xc( zrb)eK1-%dJd(C@#Ev9=dH+vsp_F0kk{lw7sn78kVWZzTeK5N518|%Jj9(}f{; zOwT|p_*8Ba9+jl#8=zJv6l+$M72Mqo93!RhKk|zZV|1pN{IKeqOO4vI=P@#P{;{h9y z%EI9%+}??~5u`k$isa0c;?|!obpA^W-AK20O1{E?C2m5<-#{i#Q#NagpnX(7Y{oQs z#;owq7CIScAM?#Vk(zy~GHY!#YhyF}?E8gIRD-dl=L~LzwxPC>QH8GY*I9>uiJ|w- z1K`tk#Y-aF^$XdsO>7v3N(ZS*BF&NTENVd#8j9?4%4lONo5|B_tsKw42P z=}#9ru@-X37IGOEKJfkNLg&LG&-qfD`7)xp(m!43R9UPyT5PacZ1h}g3S0b?yx3g0 z*wV1r+Pl~`v)I11*nwq%)!w`Cl>p~hW&gv7=eOn)gw|>3ex}ziUA)M~%6jcGw*(K5 z#IA)EX6RFyR})D86Y&5e!yw6yB(-~Xbb@;$(Q zcnq*_6v*}^DkS)uczL)4`1^#0hDJt4#>U1bBqSs!Cxh{4NlD4C@n?H`dv9;=;4f$B z$Mbg>b};_@AC{m0ONKi^n0@uTv-acp--EG#YeD}T&F6nR_(Y*l-!-4Rr&%?dauRC2 zNG{68Nawz-_oKLKHr$l^uJI+EgfF$shr~~>neU}(e)^Eq63(sP95b*Q-xe)Ec=zeQ z+kCS8|JrplX<_|)&F7c@PV>o%Za&R^Za&rjPV*^q+)b`)kN@z~)os?>C=_f7X0@dvHn7<0(iRo(cI|&8Gso`7Fld z@(wHva^!hZW#R-( zYB}Dww(Iv`@Xe5||nO7HI5z#>D zvB^)zeO0S8TDd{mBtI)SwA*gmo)@=GFv!ZiTYW0|vf_Ze7^!4*aHN!=2tg#2#Cr>ax@z7`V}G!}y|7Rs z-JRLIn!wrf(UK7d>;8qPMnB6M5-B@p0xRUm%8VEmQ578K4T0^n^W#W4L)uRxp{H<) zt1hlU0P}q$&h6qFa*-K&9%$DitF^~{nqOJpXb_tQ<&{XLLkR2kCn=e2j8If0U^t@* z!$+_KblfXp67gdMFR#^7tq@0qhhehhuwUe)TaVkPE+uj*NPfd^f~PvHDd-6kx~h%I z01?msirQ(s8b5F<;$Z$Fg1t&(bPfC9U_nd7MWL{45SCFjlUV=J@E$@Zr}S{?1EyTJR_cATac^mtN8aT8Ly%^JVq4`+)@CY;RS*j9(D-JYdW8ZpjTYA6!s z9D59`6?prQ%2MX$!PKpzC$tpwcu%t>9&?-;6MuN6a<>VtI5!adb{%QM;Dyo?Bwmjez%Bw{KtLG4?32L}fH-gjK`?@V%g(ms2nc}^ke*|>()i?x zEd<*Nim=jR(1nrZK*+6dkhh2)SZSHua(&QbCdmCW$zF~yebeilPiN-HeOoQw@=X78 zDqWY=LTDU6 zITCvWI75yQI?Y~~Q*(C)&(5L zBkZS{A#Bc$8@&LtE^PXcJS$4yR)Xjt{)?d3|#>vpb+Fis0*~sgq`;ZGaCpnH+?lB9e7v|uyI2$ zoPj~5@FZJkHBy`*C%a5dt5Aj~s8e?t#snGoT030ko zNw_VTDHCr9CL&VbUfzo535zK#j3H&kB9}$0>~{r|-WeuFHM~7tl6V&HU5CuE%Fddo z;+r_x`&NDLEg9vzZz{XawPZC)F~5&Vrh`eAFH%62{US~ZNm?Str$kNPgcpLTXqEkP zV~UJfvXg9zVp_829$IBj_e?d6O7inf4lql3Rf1O8Ur4<_#hSv|9AnLz8h5O+-@;0B z^bJwiOH89o2b)iphBV*#G#AaI<$@V?>KVw*^tUgP6QkZIn`N}` zWguiVng%_?OEPjOGy9`52YuDMSc9sYGlnR$CIqvhdNQB*zVDOGnlH)fFw1(kmloKZ zwI-OIKcCf%mmMXWy;qVQYnI*Po88uoZa$ySXOBf?p_|XrWGwvDn&am4-e8Wu?{V`P z9e>s@YxTJK)cu&-JD5wS@qtm!?*e`fQ|SkGKa@91bUFv9vR{9}wf{|Jf5MBOg;v?^ ztgb)IMXT%&&BWzCNJi(&mKxuR&X(KHSCTVUpvno^0#xh@xJU}r@pJD*t1}0MCV2ph zrW)iqu~`g-$sPr&r3L14Ia+?|I(F(NRO)8;DgmrPz%xI9%nD%50o6+=xfl>K1jn(mSyP3QJ3|EC!&$7L zuk5r4f`GVZQ1Tpz9V#7Qb_O<*OUqh(3(|qShwu^&;B{!2r(emOTvi%YA%hi!ARd^! ze> zo4M$H#c_blPm|SAl57p67~uU?8pCsb8J5#?+_k8#9+ ztbP3_>3~KU0K)8{V9#3h{7Nf4_mE-uudXDlWSRXiELAX2e7nXfs<3cAq9m~J09{?1^PF>32m4eunCt3?s(hY z^M=@$!C6RJI5nY+&SBzez}s8RYsS?S!;Mb%6&W#L`Pm#_U!r9WC({MCsERW2D~Jx7 z;)~&?<~E`#Wv}g9Uig)hwZhx>+ddf=MOcG*I>3@sKF1CjE3NB|fuv=$VJ*EM7ShF* z?+ADZ$A)~$RYqV7e-4g90ELLAVFaKAb=*}yt?-#nA(c${0Sf}bYz0t`pwvO4o!uej zBB-*{bj56TUeW5hqR_<`+eIJHB{rZ zdt~u@K$TteSY_w;>ro%+VQ&Gm&t5wG-UnK} zlv_VwkkZfrC_@0Ft&GSvRgieiZwnw90NED5DLi&&HXJ) z{TLNUU2-G=3aL4RBoP^xWE?;1I4)*1PEj#lppNug%EbMePc1Uhmpl$OpLoa3C+2bU z37MJT7MYx7nB;MsoG_desF)l{niN7!_D@fWiA_VW*9ykfA>^z{#PBaOs?Ci8(UIk8oD*GkJFA?qI zpvq1$`Xx?r98}p!MCKFQk)XtTje;us0;sY(j)E%t zB&f2ZMnIK)2vpe}M?jUm9aP!1he4IS8m+Pqfhv1GT4f&sRrU@lFq9ykE1>>;4aPBZ|j?4F>?&e;#D?2e$yp4A7c>^7jv&eaF1?3SR)p4|(o>_(u< z&eaR5?AoBpp4|hg>?)wj&ea2|?20sN7qU^^mvq*o9M+h*x>+mNL`K#)v%9#@uk#77 z^Eh=qh)ZqOnz`V(ZXUNDDmW4_vMzEoBj$vpYhS;wvGLe(Ba?DMu4BXc>qdFz#@)&p zKBvvIv772n2+gt0!GlfRj^+oVTM`PJ*E@1=KH72&+`2)$X+E}*RX8Mgw54)>`=01_ zlh(FD*4CYu+oIZA&TlGQMR!s)c04P)EyuPmmTviE&-uOCa6H~~w_Rf&G75#31AIXHvbZyx*5iW)m$+dn`&`p_wQsPAxK_2@7%@bFpoVNCns z>*d3-u{|u*#t0XRT>Eg2D|fyUrHPNqT}HhnI$~uzYPo$>_~2;t$Pd+j9)>SF8_4=dN7}iWhgsJ16MQ9Q;<&pYqxTOe&Q{wGW1E zagxz0KR2K0DlGR>l#*LAUhb)YL!Zzbgl<}nmOFfFKD$B|wBw@s zSamAZF`hBVYwkUr??E@8R4jIZQY>#Upyg~S_`E-}B>1U4V5F_}6aar