From 31f4fb790d15ae1084a9b48615fe6fc54a4af4f8 Mon Sep 17 00:00:00 2001 From: Erick Friis Date: Mon, 4 Nov 2024 17:29:15 -0800 Subject: [PATCH 01/26] standard-tests: release 0.3.0 (#27900) --- libs/standard-tests/poetry.lock | 546 +++++++++++++++-------------- libs/standard-tests/pyproject.toml | 2 +- 2 files changed, 282 insertions(+), 266 deletions(-) diff --git a/libs/standard-tests/poetry.lock b/libs/standard-tests/poetry.lock index 8655b65aa7753..95d28da3f7dd9 100644 --- a/libs/standard-tests/poetry.lock +++ b/libs/standard-tests/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 = "annotated-types" @@ -13,13 +13,13 @@ files = [ [[package]] name = "anyio" -version = "4.4.0" +version = "4.6.2.post1" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "anyio-4.4.0-py3-none-any.whl", hash = "sha256:c1b2d8f46a8a812513012e1107cb0e68c17159a7a594208005a57dc776e1bdc7"}, - {file = "anyio-4.4.0.tar.gz", hash = "sha256:5aadc6a1bbb7cdb0bede386cac5e2940f5e2ff3aa20277e991cf028e0585ce94"}, + {file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"}, + {file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"}, ] [package.dependencies] @@ -29,9 +29,9 @@ 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)"] +doc = ["Sphinx (>=7.4,<8.0)", "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", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"] +trio = ["trio (>=0.26.1)"] [[package]] name = "certifi" @@ -46,101 +46,116 @@ files = [ [[package]] name = "charset-normalizer" -version = "3.3.2" +version = "3.4.0" 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"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, + {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, + {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, ] [[package]] @@ -198,13 +213,13 @@ files = [ [[package]] name = "httpcore" -version = "1.0.5" +version = "1.0.6" 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"}, + {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, + {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, ] [package.dependencies] @@ -215,7 +230,7 @@ h11 = ">=0.13,<0.15" asyncio = ["anyio (>=4.0,<5.0)"] http2 = ["h2 (>=3,<5)"] socks = ["socksio (==1.*)"] -trio = ["trio (>=0.22.0,<0.26.0)"] +trio = ["trio (>=0.22.0,<1.0)"] [[package]] name = "httpx" @@ -401,68 +416,69 @@ files = [ [[package]] name = "orjson" -version = "3.10.7" +version = "3.10.11" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.7-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:74f4544f5a6405b90da8ea724d15ac9c36da4d72a738c64685003337401f5c12"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:34a566f22c28222b08875b18b0dfbf8a947e69df21a9ed5c51a6bf91cfb944ac"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bf6ba8ebc8ef5792e2337fb0419f8009729335bb400ece005606336b7fd7bab7"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac7cf6222b29fbda9e3a472b41e6a5538b48f2c8f99261eecd60aafbdb60690c"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de817e2f5fc75a9e7dd350c4b0f54617b280e26d1631811a43e7e968fa71e3e9"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:348bdd16b32556cf8d7257b17cf2bdb7ab7976af4af41ebe79f9796c218f7e91"}, - {file = "orjson-3.10.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:479fd0844ddc3ca77e0fd99644c7fe2de8e8be1efcd57705b5c92e5186e8a250"}, - {file = "orjson-3.10.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:fdf5197a21dd660cf19dfd2a3ce79574588f8f5e2dbf21bda9ee2d2b46924d84"}, - {file = "orjson-3.10.7-cp310-none-win32.whl", hash = "sha256:d374d36726746c81a49f3ff8daa2898dccab6596864ebe43d50733275c629175"}, - {file = "orjson-3.10.7-cp310-none-win_amd64.whl", hash = "sha256:cb61938aec8b0ffb6eef484d480188a1777e67b05d58e41b435c74b9d84e0b9c"}, - {file = "orjson-3.10.7-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:7db8539039698ddfb9a524b4dd19508256107568cdad24f3682d5773e60504a2"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:480f455222cb7a1dea35c57a67578848537d2602b46c464472c995297117fa09"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8a9c9b168b3a19e37fe2778c0003359f07822c90fdff8f98d9d2a91b3144d8e0"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8de062de550f63185e4c1c54151bdddfc5625e37daf0aa1e75d2a1293e3b7d9a"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6b0dd04483499d1de9c8f6203f8975caf17a6000b9c0c54630cef02e44ee624e"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b58d3795dafa334fc8fd46f7c5dc013e6ad06fd5b9a4cc98cb1456e7d3558bd6"}, - {file = "orjson-3.10.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:33cfb96c24034a878d83d1a9415799a73dc77480e6c40417e5dda0710d559ee6"}, - {file = "orjson-3.10.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e724cebe1fadc2b23c6f7415bad5ee6239e00a69f30ee423f319c6af70e2a5c0"}, - {file = "orjson-3.10.7-cp311-none-win32.whl", hash = "sha256:82763b46053727a7168d29c772ed5c870fdae2f61aa8a25994c7984a19b1021f"}, - {file = "orjson-3.10.7-cp311-none-win_amd64.whl", hash = "sha256:eb8d384a24778abf29afb8e41d68fdd9a156cf6e5390c04cc07bbc24b89e98b5"}, - {file = "orjson-3.10.7-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44a96f2d4c3af51bfac6bc4ef7b182aa33f2f054fd7f34cc0ee9a320d051d41f"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76ac14cd57df0572453543f8f2575e2d01ae9e790c21f57627803f5e79b0d3c3"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bdbb61dcc365dd9be94e8f7df91975edc9364d6a78c8f7adb69c1cdff318ec93"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b48b3db6bb6e0a08fa8c83b47bc169623f801e5cc4f24442ab2b6617da3b5313"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23820a1563a1d386414fef15c249040042b8e5d07b40ab3fe3efbfbbcbcb8864"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0c6a008e91d10a2564edbb6ee5069a9e66df3fbe11c9a005cb411f441fd2c09"}, - {file = "orjson-3.10.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d352ee8ac1926d6193f602cbe36b1643bbd1bbcb25e3c1a657a4390f3000c9a5"}, - {file = "orjson-3.10.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d2d9f990623f15c0ae7ac608103c33dfe1486d2ed974ac3f40b693bad1a22a7b"}, - {file = "orjson-3.10.7-cp312-none-win32.whl", hash = "sha256:7c4c17f8157bd520cdb7195f75ddbd31671997cbe10aee559c2d613592e7d7eb"}, - {file = "orjson-3.10.7-cp312-none-win_amd64.whl", hash = "sha256:1d9c0e733e02ada3ed6098a10a8ee0052dd55774de3d9110d29868d24b17faa1"}, - {file = "orjson-3.10.7-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:77d325ed866876c0fa6492598ec01fe30e803272a6e8b10e992288b009cbe149"}, - {file = "orjson-3.10.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ea2c232deedcb605e853ae1db2cc94f7390ac776743b699b50b071b02bea6fe"}, - {file = "orjson-3.10.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3dcfbede6737fdbef3ce9c37af3fb6142e8e1ebc10336daa05872bfb1d87839c"}, - {file = "orjson-3.10.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:11748c135f281203f4ee695b7f80bb1358a82a63905f9f0b794769483ea854ad"}, - {file = "orjson-3.10.7-cp313-none-win32.whl", hash = "sha256:a7e19150d215c7a13f39eb787d84db274298d3f83d85463e61d277bbd7f401d2"}, - {file = "orjson-3.10.7-cp313-none-win_amd64.whl", hash = "sha256:eef44224729e9525d5261cc8d28d6b11cafc90e6bd0be2157bde69a52ec83024"}, - {file = "orjson-3.10.7-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:6ea2b2258eff652c82652d5e0f02bd5e0463a6a52abb78e49ac288827aaa1469"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:430ee4d85841e1483d487e7b81401785a5dfd69db5de01314538f31f8fbf7ee1"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4b6146e439af4c2472c56f8540d799a67a81226e11992008cb47e1267a9b3225"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:084e537806b458911137f76097e53ce7bf5806dda33ddf6aaa66a028f8d43a23"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4829cf2195838e3f93b70fd3b4292156fc5e097aac3739859ac0dcc722b27ac0"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1193b2416cbad1a769f868b1749535d5da47626ac29445803dae7cc64b3f5c98"}, - {file = "orjson-3.10.7-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:4e6c3da13e5a57e4b3dca2de059f243ebec705857522f188f0180ae88badd354"}, - {file = "orjson-3.10.7-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:c31008598424dfbe52ce8c5b47e0752dca918a4fdc4a2a32004efd9fab41d866"}, - {file = "orjson-3.10.7-cp38-none-win32.whl", hash = "sha256:7122a99831f9e7fe977dc45784d3b2edc821c172d545e6420c375e5a935f5a1c"}, - {file = "orjson-3.10.7-cp38-none-win_amd64.whl", hash = "sha256:a763bc0e58504cc803739e7df040685816145a6f3c8a589787084b54ebc9f16e"}, - {file = "orjson-3.10.7-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e76be12658a6fa376fcd331b1ea4e58f5a06fd0220653450f0d415b8fd0fbe20"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed350d6978d28b92939bfeb1a0570c523f6170efc3f0a0ef1f1df287cd4f4960"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:144888c76f8520e39bfa121b31fd637e18d4cc2f115727865fdf9fa325b10412"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09b2d92fd95ad2402188cf51573acde57eb269eddabaa60f69ea0d733e789fe9"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5b24a579123fa884f3a3caadaed7b75eb5715ee2b17ab5c66ac97d29b18fe57f"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e72591bcfe7512353bd609875ab38050efe3d55e18934e2f18950c108334b4ff"}, - {file = "orjson-3.10.7-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f4db56635b58cd1a200b0a23744ff44206ee6aa428185e2b6c4a65b3197abdcd"}, - {file = "orjson-3.10.7-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0fa5886854673222618638c6df7718ea7fe2f3f2384c452c9ccedc70b4a510a5"}, - {file = "orjson-3.10.7-cp39-none-win32.whl", hash = "sha256:8272527d08450ab16eb405f47e0f4ef0e5ff5981c3d82afe0efd25dcbef2bcd2"}, - {file = "orjson-3.10.7-cp39-none-win_amd64.whl", hash = "sha256:974683d4618c0c7dbf4f69c95a979734bf183d0658611760017f6e70a145af58"}, - {file = "orjson-3.10.7.tar.gz", hash = "sha256:75ef0640403f945f3a1f9f6400686560dbfb0fb5b16589ad62cd477043c4eee3"}, + {file = "orjson-3.10.11-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:6dade64687f2bd7c090281652fe18f1151292d567a9302b34c2dbb92a3872f1f"}, + {file = "orjson-3.10.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82f07c550a6ccd2b9290849b22316a609023ed851a87ea888c0456485a7d196a"}, + {file = "orjson-3.10.11-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bd9a187742d3ead9df2e49240234d728c67c356516cf4db018833a86f20ec18c"}, + {file = "orjson-3.10.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:77b0fed6f209d76c1c39f032a70df2d7acf24b1812ca3e6078fd04e8972685a3"}, + {file = "orjson-3.10.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:63fc9d5fe1d4e8868f6aae547a7b8ba0a2e592929245fff61d633f4caccdcdd6"}, + {file = "orjson-3.10.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65cd3e3bb4fbb4eddc3c1e8dce10dc0b73e808fcb875f9fab40c81903dd9323e"}, + {file = "orjson-3.10.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:6f67c570602300c4befbda12d153113b8974a3340fdcf3d6de095ede86c06d92"}, + {file = "orjson-3.10.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:1f39728c7f7d766f1f5a769ce4d54b5aaa4c3f92d5b84817053cc9995b977acc"}, + {file = "orjson-3.10.11-cp310-none-win32.whl", hash = "sha256:1789d9db7968d805f3d94aae2c25d04014aae3a2fa65b1443117cd462c6da647"}, + {file = "orjson-3.10.11-cp310-none-win_amd64.whl", hash = "sha256:5576b1e5a53a5ba8f8df81872bb0878a112b3ebb1d392155f00f54dd86c83ff6"}, + {file = "orjson-3.10.11-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1444f9cb7c14055d595de1036f74ecd6ce15f04a715e73f33bb6326c9cef01b6"}, + {file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cdec57fe3b4bdebcc08a946db3365630332dbe575125ff3d80a3272ebd0ddafe"}, + {file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4eed32f33a0ea6ef36ccc1d37f8d17f28a1d6e8eefae5928f76aff8f1df85e67"}, + {file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80df27dd8697242b904f4ea54820e2d98d3f51f91e97e358fc13359721233e4b"}, + {file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:705f03cee0cb797256d54de6695ef219e5bc8c8120b6654dd460848d57a9af3d"}, + {file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03246774131701de8e7059b2e382597da43144a9a7400f178b2a32feafc54bd5"}, + {file = "orjson-3.10.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8b5759063a6c940a69c728ea70d7c33583991c6982915a839c8da5f957e0103a"}, + {file = "orjson-3.10.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:677f23e32491520eebb19c99bb34675daf5410c449c13416f7f0d93e2cf5f981"}, + {file = "orjson-3.10.11-cp311-none-win32.whl", hash = "sha256:a11225d7b30468dcb099498296ffac36b4673a8398ca30fdaec1e6c20df6aa55"}, + {file = "orjson-3.10.11-cp311-none-win_amd64.whl", hash = "sha256:df8c677df2f9f385fcc85ab859704045fa88d4668bc9991a527c86e710392bec"}, + {file = "orjson-3.10.11-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:360a4e2c0943da7c21505e47cf6bd725588962ff1d739b99b14e2f7f3545ba51"}, + {file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:496e2cb45de21c369079ef2d662670a4892c81573bcc143c4205cae98282ba97"}, + {file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7dfa8db55c9792d53c5952900c6a919cfa377b4f4534c7a786484a6a4a350c19"}, + {file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:51f3382415747e0dbda9dade6f1e1a01a9d37f630d8c9049a8ed0e385b7a90c0"}, + {file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f35a1b9f50a219f470e0e497ca30b285c9f34948d3c8160d5ad3a755d9299433"}, + {file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2f3b7c5803138e67028dde33450e054c87e0703afbe730c105f1fcd873496d5"}, + {file = "orjson-3.10.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f91d9eb554310472bd09f5347950b24442600594c2edc1421403d7610a0998fd"}, + {file = "orjson-3.10.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dfbb2d460a855c9744bbc8e36f9c3a997c4b27d842f3d5559ed54326e6911f9b"}, + {file = "orjson-3.10.11-cp312-none-win32.whl", hash = "sha256:d4a62c49c506d4d73f59514986cadebb7e8d186ad510c518f439176cf8d5359d"}, + {file = "orjson-3.10.11-cp312-none-win_amd64.whl", hash = "sha256:f1eec3421a558ff7a9b010a6c7effcfa0ade65327a71bb9b02a1c3b77a247284"}, + {file = "orjson-3.10.11-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:c46294faa4e4d0eb73ab68f1a794d2cbf7bab33b1dda2ac2959ffb7c61591899"}, + {file = "orjson-3.10.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:52e5834d7d6e58a36846e059d00559cb9ed20410664f3ad156cd2cc239a11230"}, + {file = "orjson-3.10.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2fc947e5350fdce548bfc94f434e8760d5cafa97fb9c495d2fef6757aa02ec0"}, + {file = "orjson-3.10.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0efabbf839388a1dab5b72b5d3baedbd6039ac83f3b55736eb9934ea5494d258"}, + {file = "orjson-3.10.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a3f29634260708c200c4fe148e42b4aae97d7b9fee417fbdd74f8cfc265f15b0"}, + {file = "orjson-3.10.11-cp313-none-win32.whl", hash = "sha256:1a1222ffcee8a09476bbdd5d4f6f33d06d0d6642df2a3d78b7a195ca880d669b"}, + {file = "orjson-3.10.11-cp313-none-win_amd64.whl", hash = "sha256:bc274ac261cc69260913b2d1610760e55d3c0801bb3457ba7b9004420b6b4270"}, + {file = "orjson-3.10.11-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:19b3763e8bbf8ad797df6b6b5e0fc7c843ec2e2fc0621398534e0c6400098f87"}, + {file = "orjson-3.10.11-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1be83a13312e5e58d633580c5eb8d0495ae61f180da2722f20562974188af205"}, + {file = "orjson-3.10.11-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:afacfd1ab81f46dedd7f6001b6d4e8de23396e4884cd3c3436bd05defb1a6446"}, + {file = "orjson-3.10.11-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cb4d0bea56bba596723d73f074c420aec3b2e5d7d30698bc56e6048066bd560c"}, + {file = "orjson-3.10.11-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:96ed1de70fcb15d5fed529a656df29f768187628727ee2788344e8a51e1c1350"}, + {file = "orjson-3.10.11-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4bfb30c891b530f3f80e801e3ad82ef150b964e5c38e1fb8482441c69c35c61c"}, + {file = "orjson-3.10.11-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d496c74fc2b61341e3cefda7eec21b7854c5f672ee350bc55d9a4997a8a95204"}, + {file = "orjson-3.10.11-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:655a493bac606655db9a47fe94d3d84fc7f3ad766d894197c94ccf0c5408e7d3"}, + {file = "orjson-3.10.11-cp38-none-win32.whl", hash = "sha256:b9546b278c9fb5d45380f4809e11b4dd9844ca7aaf1134024503e134ed226161"}, + {file = "orjson-3.10.11-cp38-none-win_amd64.whl", hash = "sha256:b592597fe551d518f42c5a2eb07422eb475aa8cfdc8c51e6da7054b836b26782"}, + {file = "orjson-3.10.11-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:c95f2ecafe709b4e5c733b5e2768ac569bed308623c85806c395d9cca00e08af"}, + {file = "orjson-3.10.11-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:80c00d4acded0c51c98754fe8218cb49cb854f0f7eb39ea4641b7f71732d2cb7"}, + {file = "orjson-3.10.11-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:461311b693d3d0a060439aa669c74f3603264d4e7a08faa68c47ae5a863f352d"}, + {file = "orjson-3.10.11-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:52ca832f17d86a78cbab86cdc25f8c13756ebe182b6fc1a97d534051c18a08de"}, + {file = "orjson-3.10.11-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f4c57ea78a753812f528178aa2f1c57da633754c91d2124cb28991dab4c79a54"}, + {file = "orjson-3.10.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b7fcfc6f7ca046383fb954ba528587e0f9336828b568282b27579c49f8e16aad"}, + {file = "orjson-3.10.11-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:86b9dd983857970c29e4c71bb3e95ff085c07d3e83e7c46ebe959bac07ebd80b"}, + {file = "orjson-3.10.11-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:4d83f87582d223e54efb2242a79547611ba4ebae3af8bae1e80fa9a0af83bb7f"}, + {file = "orjson-3.10.11-cp39-none-win32.whl", hash = "sha256:9fd0ad1c129bc9beb1154c2655f177620b5beaf9a11e0d10bac63ef3fce96950"}, + {file = "orjson-3.10.11-cp39-none-win_amd64.whl", hash = "sha256:10f416b2a017c8bd17f325fb9dee1fb5cdd7a54e814284896b7c3f2763faa017"}, + {file = "orjson-3.10.11.tar.gz", hash = "sha256:e35b6d730de6384d5b2dab5fd23f0d76fae8bbc8c353c2f78210aa5fa4beb3ef"}, ] [[package]] @@ -493,18 +509,18 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "pydantic" -version = "2.9.1" +version = "2.9.2" description = "Data validation using Python type hints" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic-2.9.1-py3-none-any.whl", hash = "sha256:7aff4db5fdf3cf573d4b3c30926a510a10e19a0774d38fc4967f78beb6deb612"}, - {file = "pydantic-2.9.1.tar.gz", hash = "sha256:1363c7d975c7036df0db2b4a61f2e062fbc0aa5ab5f2772e0ffc7191a4f4bce2"}, + {file = "pydantic-2.9.2-py3-none-any.whl", hash = "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12"}, + {file = "pydantic-2.9.2.tar.gz", hash = "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f"}, ] [package.dependencies] annotated-types = ">=0.6.0" -pydantic-core = "2.23.3" +pydantic-core = "2.23.4" typing-extensions = [ {version = ">=4.6.1", markers = "python_version < \"3.13\""}, {version = ">=4.12.2", markers = "python_version >= \"3.13\""}, @@ -516,100 +532,100 @@ timezone = ["tzdata"] [[package]] name = "pydantic-core" -version = "2.23.3" +version = "2.23.4" description = "Core functionality for Pydantic validation and serialization" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic_core-2.23.3-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:7f10a5d1b9281392f1bf507d16ac720e78285dfd635b05737c3911637601bae6"}, - {file = "pydantic_core-2.23.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3c09a7885dd33ee8c65266e5aa7fb7e2f23d49d8043f089989726391dd7350c5"}, - {file = "pydantic_core-2.23.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6470b5a1ec4d1c2e9afe928c6cb37eb33381cab99292a708b8cb9aa89e62429b"}, - {file = "pydantic_core-2.23.3-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9172d2088e27d9a185ea0a6c8cebe227a9139fd90295221d7d495944d2367700"}, - {file = "pydantic_core-2.23.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86fc6c762ca7ac8fbbdff80d61b2c59fb6b7d144aa46e2d54d9e1b7b0e780e01"}, - {file = "pydantic_core-2.23.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f0cb80fd5c2df4898693aa841425ea1727b1b6d2167448253077d2a49003e0ed"}, - {file = "pydantic_core-2.23.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03667cec5daf43ac4995cefa8aaf58f99de036204a37b889c24a80927b629cec"}, - {file = "pydantic_core-2.23.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:047531242f8e9c2db733599f1c612925de095e93c9cc0e599e96cf536aaf56ba"}, - {file = "pydantic_core-2.23.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:5499798317fff7f25dbef9347f4451b91ac2a4330c6669821c8202fd354c7bee"}, - {file = "pydantic_core-2.23.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bbb5e45eab7624440516ee3722a3044b83fff4c0372efe183fd6ba678ff681fe"}, - {file = "pydantic_core-2.23.3-cp310-none-win32.whl", hash = "sha256:8b5b3ed73abb147704a6e9f556d8c5cb078f8c095be4588e669d315e0d11893b"}, - {file = "pydantic_core-2.23.3-cp310-none-win_amd64.whl", hash = "sha256:2b603cde285322758a0279995b5796d64b63060bfbe214b50a3ca23b5cee3e83"}, - {file = "pydantic_core-2.23.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:c889fd87e1f1bbeb877c2ee56b63bb297de4636661cc9bbfcf4b34e5e925bc27"}, - {file = "pydantic_core-2.23.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ea85bda3189fb27503af4c45273735bcde3dd31c1ab17d11f37b04877859ef45"}, - {file = "pydantic_core-2.23.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a7f7f72f721223f33d3dc98a791666ebc6a91fa023ce63733709f4894a7dc611"}, - {file = "pydantic_core-2.23.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2b2b55b0448e9da68f56b696f313949cda1039e8ec7b5d294285335b53104b61"}, - {file = "pydantic_core-2.23.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c24574c7e92e2c56379706b9a3f07c1e0c7f2f87a41b6ee86653100c4ce343e5"}, - {file = "pydantic_core-2.23.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f2b05e6ccbee333a8f4b8f4d7c244fdb7a979e90977ad9c51ea31261e2085ce0"}, - {file = "pydantic_core-2.23.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2c409ce1c219c091e47cb03feb3c4ed8c2b8e004efc940da0166aaee8f9d6c8"}, - {file = "pydantic_core-2.23.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d965e8b325f443ed3196db890d85dfebbb09f7384486a77461347f4adb1fa7f8"}, - {file = "pydantic_core-2.23.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f56af3a420fb1ffaf43ece3ea09c2d27c444e7c40dcb7c6e7cf57aae764f2b48"}, - {file = "pydantic_core-2.23.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5b01a078dd4f9a52494370af21aa52964e0a96d4862ac64ff7cea06e0f12d2c5"}, - {file = "pydantic_core-2.23.3-cp311-none-win32.whl", hash = "sha256:560e32f0df04ac69b3dd818f71339983f6d1f70eb99d4d1f8e9705fb6c34a5c1"}, - {file = "pydantic_core-2.23.3-cp311-none-win_amd64.whl", hash = "sha256:c744fa100fdea0d000d8bcddee95213d2de2e95b9c12be083370b2072333a0fa"}, - {file = "pydantic_core-2.23.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:e0ec50663feedf64d21bad0809f5857bac1ce91deded203efc4a84b31b2e4305"}, - {file = "pydantic_core-2.23.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:db6e6afcb95edbe6b357786684b71008499836e91f2a4a1e55b840955b341dbb"}, - {file = "pydantic_core-2.23.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:98ccd69edcf49f0875d86942f4418a4e83eb3047f20eb897bffa62a5d419c8fa"}, - {file = "pydantic_core-2.23.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a678c1ac5c5ec5685af0133262103defb427114e62eafeda12f1357a12140162"}, - {file = "pydantic_core-2.23.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:01491d8b4d8db9f3391d93b0df60701e644ff0894352947f31fff3e52bd5c801"}, - {file = "pydantic_core-2.23.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fcf31facf2796a2d3b7fe338fe8640aa0166e4e55b4cb108dbfd1058049bf4cb"}, - {file = "pydantic_core-2.23.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7200fd561fb3be06827340da066df4311d0b6b8eb0c2116a110be5245dceb326"}, - {file = "pydantic_core-2.23.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:dc1636770a809dee2bd44dd74b89cc80eb41172bcad8af75dd0bc182c2666d4c"}, - {file = "pydantic_core-2.23.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:67a5def279309f2e23014b608c4150b0c2d323bd7bccd27ff07b001c12c2415c"}, - {file = "pydantic_core-2.23.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:748bdf985014c6dd3e1e4cc3db90f1c3ecc7246ff5a3cd4ddab20c768b2f1dab"}, - {file = "pydantic_core-2.23.3-cp312-none-win32.whl", hash = "sha256:255ec6dcb899c115f1e2a64bc9ebc24cc0e3ab097775755244f77360d1f3c06c"}, - {file = "pydantic_core-2.23.3-cp312-none-win_amd64.whl", hash = "sha256:40b8441be16c1e940abebed83cd006ddb9e3737a279e339dbd6d31578b802f7b"}, - {file = "pydantic_core-2.23.3-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:6daaf5b1ba1369a22c8b050b643250e3e5efc6a78366d323294aee54953a4d5f"}, - {file = "pydantic_core-2.23.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d015e63b985a78a3d4ccffd3bdf22b7c20b3bbd4b8227809b3e8e75bc37f9cb2"}, - {file = "pydantic_core-2.23.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3fc572d9b5b5cfe13f8e8a6e26271d5d13f80173724b738557a8c7f3a8a3791"}, - {file = "pydantic_core-2.23.3-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f6bd91345b5163ee7448bee201ed7dd601ca24f43f439109b0212e296eb5b423"}, - {file = "pydantic_core-2.23.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fc379c73fd66606628b866f661e8785088afe2adaba78e6bbe80796baf708a63"}, - {file = "pydantic_core-2.23.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fbdce4b47592f9e296e19ac31667daed8753c8367ebb34b9a9bd89dacaa299c9"}, - {file = "pydantic_core-2.23.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc3cf31edf405a161a0adad83246568647c54404739b614b1ff43dad2b02e6d5"}, - {file = "pydantic_core-2.23.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8e22b477bf90db71c156f89a55bfe4d25177b81fce4aa09294d9e805eec13855"}, - {file = "pydantic_core-2.23.3-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:0a0137ddf462575d9bce863c4c95bac3493ba8e22f8c28ca94634b4a1d3e2bb4"}, - {file = "pydantic_core-2.23.3-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:203171e48946c3164fe7691fc349c79241ff8f28306abd4cad5f4f75ed80bc8d"}, - {file = "pydantic_core-2.23.3-cp313-none-win32.whl", hash = "sha256:76bdab0de4acb3f119c2a4bff740e0c7dc2e6de7692774620f7452ce11ca76c8"}, - {file = "pydantic_core-2.23.3-cp313-none-win_amd64.whl", hash = "sha256:37ba321ac2a46100c578a92e9a6aa33afe9ec99ffa084424291d84e456f490c1"}, - {file = "pydantic_core-2.23.3-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d063c6b9fed7d992bcbebfc9133f4c24b7a7f215d6b102f3e082b1117cddb72c"}, - {file = "pydantic_core-2.23.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6cb968da9a0746a0cf521b2b5ef25fc5a0bee9b9a1a8214e0a1cfaea5be7e8a4"}, - {file = "pydantic_core-2.23.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:edbefe079a520c5984e30e1f1f29325054b59534729c25b874a16a5048028d16"}, - {file = "pydantic_core-2.23.3-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cbaaf2ef20d282659093913da9d402108203f7cb5955020bd8d1ae5a2325d1c4"}, - {file = "pydantic_core-2.23.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fb539d7e5dc4aac345846f290cf504d2fd3c1be26ac4e8b5e4c2b688069ff4cf"}, - {file = "pydantic_core-2.23.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7e6f33503c5495059148cc486867e1d24ca35df5fc064686e631e314d959ad5b"}, - {file = "pydantic_core-2.23.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:04b07490bc2f6f2717b10c3969e1b830f5720b632f8ae2f3b8b1542394c47a8e"}, - {file = "pydantic_core-2.23.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:03795b9e8a5d7fda05f3873efc3f59105e2dcff14231680296b87b80bb327295"}, - {file = "pydantic_core-2.23.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:c483dab0f14b8d3f0df0c6c18d70b21b086f74c87ab03c59250dbf6d3c89baba"}, - {file = "pydantic_core-2.23.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8b2682038e255e94baf2c473dca914a7460069171ff5cdd4080be18ab8a7fd6e"}, - {file = "pydantic_core-2.23.3-cp38-none-win32.whl", hash = "sha256:f4a57db8966b3a1d1a350012839c6a0099f0898c56512dfade8a1fe5fb278710"}, - {file = "pydantic_core-2.23.3-cp38-none-win_amd64.whl", hash = "sha256:13dd45ba2561603681a2676ca56006d6dee94493f03d5cadc055d2055615c3ea"}, - {file = "pydantic_core-2.23.3-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:82da2f4703894134a9f000e24965df73cc103e31e8c31906cc1ee89fde72cbd8"}, - {file = "pydantic_core-2.23.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:dd9be0a42de08f4b58a3cc73a123f124f65c24698b95a54c1543065baca8cf0e"}, - {file = "pydantic_core-2.23.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89b731f25c80830c76fdb13705c68fef6a2b6dc494402987c7ea9584fe189f5d"}, - {file = "pydantic_core-2.23.3-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c6de1ec30c4bb94f3a69c9f5f2182baeda5b809f806676675e9ef6b8dc936f28"}, - {file = "pydantic_core-2.23.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb68b41c3fa64587412b104294b9cbb027509dc2f6958446c502638d481525ef"}, - {file = "pydantic_core-2.23.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c3980f2843de5184656aab58698011b42763ccba11c4a8c35936c8dd6c7068c"}, - {file = "pydantic_core-2.23.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94f85614f2cba13f62c3c6481716e4adeae48e1eaa7e8bac379b9d177d93947a"}, - {file = "pydantic_core-2.23.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:510b7fb0a86dc8f10a8bb43bd2f97beb63cffad1203071dc434dac26453955cd"}, - {file = "pydantic_core-2.23.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:1eba2f7ce3e30ee2170410e2171867ea73dbd692433b81a93758ab2de6c64835"}, - {file = "pydantic_core-2.23.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4b259fd8409ab84b4041b7b3f24dcc41e4696f180b775961ca8142b5b21d0e70"}, - {file = "pydantic_core-2.23.3-cp39-none-win32.whl", hash = "sha256:40d9bd259538dba2f40963286009bf7caf18b5112b19d2b55b09c14dde6db6a7"}, - {file = "pydantic_core-2.23.3-cp39-none-win_amd64.whl", hash = "sha256:5a8cd3074a98ee70173a8633ad3c10e00dcb991ecec57263aacb4095c5efb958"}, - {file = "pydantic_core-2.23.3-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f399e8657c67313476a121a6944311fab377085ca7f490648c9af97fc732732d"}, - {file = "pydantic_core-2.23.3-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:6b5547d098c76e1694ba85f05b595720d7c60d342f24d5aad32c3049131fa5c4"}, - {file = "pydantic_core-2.23.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0dda0290a6f608504882d9f7650975b4651ff91c85673341789a476b1159f211"}, - {file = "pydantic_core-2.23.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65b6e5da855e9c55a0c67f4db8a492bf13d8d3316a59999cfbaf98cc6e401961"}, - {file = "pydantic_core-2.23.3-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:09e926397f392059ce0afdcac920df29d9c833256354d0c55f1584b0b70cf07e"}, - {file = "pydantic_core-2.23.3-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:87cfa0ed6b8c5bd6ae8b66de941cece179281239d482f363814d2b986b79cedc"}, - {file = "pydantic_core-2.23.3-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e61328920154b6a44d98cabcb709f10e8b74276bc709c9a513a8c37a18786cc4"}, - {file = "pydantic_core-2.23.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:ce3317d155628301d649fe5e16a99528d5680af4ec7aa70b90b8dacd2d725c9b"}, - {file = "pydantic_core-2.23.3-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:e89513f014c6be0d17b00a9a7c81b1c426f4eb9224b15433f3d98c1a071f8433"}, - {file = "pydantic_core-2.23.3-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:4f62c1c953d7ee375df5eb2e44ad50ce2f5aff931723b398b8bc6f0ac159791a"}, - {file = "pydantic_core-2.23.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2718443bc671c7ac331de4eef9b673063b10af32a0bb385019ad61dcf2cc8f6c"}, - {file = "pydantic_core-2.23.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0d90e08b2727c5d01af1b5ef4121d2f0c99fbee692c762f4d9d0409c9da6541"}, - {file = "pydantic_core-2.23.3-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2b676583fc459c64146debea14ba3af54e540b61762dfc0613dc4e98c3f66eeb"}, - {file = "pydantic_core-2.23.3-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:50e4661f3337977740fdbfbae084ae5693e505ca2b3130a6d4eb0f2281dc43b8"}, - {file = "pydantic_core-2.23.3-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:68f4cf373f0de6abfe599a38307f4417c1c867ca381c03df27c873a9069cda25"}, - {file = "pydantic_core-2.23.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:59d52cf01854cb26c46958552a21acb10dd78a52aa34c86f284e66b209db8cab"}, - {file = "pydantic_core-2.23.3.tar.gz", hash = "sha256:3cb0f65d8b4121c1b015c60104a685feb929a29d7cf204387c7f2688c7974690"}, + {file = "pydantic_core-2.23.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b10bd51f823d891193d4717448fab065733958bdb6a6b351967bd349d48d5c9b"}, + {file = "pydantic_core-2.23.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4fc714bdbfb534f94034efaa6eadd74e5b93c8fa6315565a222f7b6f42ca1166"}, + {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63e46b3169866bd62849936de036f901a9356e36376079b05efa83caeaa02ceb"}, + {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed1a53de42fbe34853ba90513cea21673481cd81ed1be739f7f2efb931b24916"}, + {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cfdd16ab5e59fc31b5e906d1a3f666571abc367598e3e02c83403acabc092e07"}, + {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255a8ef062cbf6674450e668482456abac99a5583bbafb73f9ad469540a3a232"}, + {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a7cd62e831afe623fbb7aabbb4fe583212115b3ef38a9f6b71869ba644624a2"}, + {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f09e2ff1f17c2b51f2bc76d1cc33da96298f0a036a137f5440ab3ec5360b624f"}, + {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e38e63e6f3d1cec5a27e0afe90a085af8b6806ee208b33030e65b6516353f1a3"}, + {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0dbd8dbed2085ed23b5c04afa29d8fd2771674223135dc9bc937f3c09284d071"}, + {file = "pydantic_core-2.23.4-cp310-none-win32.whl", hash = "sha256:6531b7ca5f951d663c339002e91aaebda765ec7d61b7d1e3991051906ddde119"}, + {file = "pydantic_core-2.23.4-cp310-none-win_amd64.whl", hash = "sha256:7c9129eb40958b3d4500fa2467e6a83356b3b61bfff1b414c7361d9220f9ae8f"}, + {file = "pydantic_core-2.23.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:77733e3892bb0a7fa797826361ce8a9184d25c8dffaec60b7ffe928153680ba8"}, + {file = "pydantic_core-2.23.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b84d168f6c48fabd1f2027a3d1bdfe62f92cade1fb273a5d68e621da0e44e6d"}, + {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df49e7a0861a8c36d089c1ed57d308623d60416dab2647a4a17fe050ba85de0e"}, + {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff02b6d461a6de369f07ec15e465a88895f3223eb75073ffea56b84d9331f607"}, + {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:996a38a83508c54c78a5f41456b0103c30508fed9abcad0a59b876d7398f25fd"}, + {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d97683ddee4723ae8c95d1eddac7c192e8c552da0c73a925a89fa8649bf13eea"}, + {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:216f9b2d7713eb98cb83c80b9c794de1f6b7e3145eef40400c62e86cee5f4e1e"}, + {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6f783e0ec4803c787bcea93e13e9932edab72068f68ecffdf86a99fd5918878b"}, + {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d0776dea117cf5272382634bd2a5c1b6eb16767c223c6a5317cd3e2a757c61a0"}, + {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d5f7a395a8cf1621939692dba2a6b6a830efa6b3cee787d82c7de1ad2930de64"}, + {file = "pydantic_core-2.23.4-cp311-none-win32.whl", hash = "sha256:74b9127ffea03643e998e0c5ad9bd3811d3dac8c676e47db17b0ee7c3c3bf35f"}, + {file = "pydantic_core-2.23.4-cp311-none-win_amd64.whl", hash = "sha256:98d134c954828488b153d88ba1f34e14259284f256180ce659e8d83e9c05eaa3"}, + {file = "pydantic_core-2.23.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231"}, + {file = "pydantic_core-2.23.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee"}, + {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87"}, + {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8"}, + {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327"}, + {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2"}, + {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36"}, + {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126"}, + {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e"}, + {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24"}, + {file = "pydantic_core-2.23.4-cp312-none-win32.whl", hash = "sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84"}, + {file = "pydantic_core-2.23.4-cp312-none-win_amd64.whl", hash = "sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9"}, + {file = "pydantic_core-2.23.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7530e201d10d7d14abce4fb54cfe5b94a0aefc87da539d0346a484ead376c3cc"}, + {file = "pydantic_core-2.23.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:df933278128ea1cd77772673c73954e53a1c95a4fdf41eef97c2b779271bd0bd"}, + {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cb3da3fd1b6a5d0279a01877713dbda118a2a4fc6f0d821a57da2e464793f05"}, + {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c6dcb030aefb668a2b7009c85b27f90e51e6a3b4d5c9bc4c57631292015b0d"}, + {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:696dd8d674d6ce621ab9d45b205df149399e4bb9aa34102c970b721554828510"}, + {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2971bb5ffe72cc0f555c13e19b23c85b654dd2a8f7ab493c262071377bfce9f6"}, + {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8394d940e5d400d04cad4f75c0598665cbb81aecefaca82ca85bd28264af7f9b"}, + {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0dff76e0602ca7d4cdaacc1ac4c005e0ce0dcfe095d5b5259163a80d3a10d327"}, + {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7d32706badfe136888bdea71c0def994644e09fff0bfe47441deaed8e96fdbc6"}, + {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed541d70698978a20eb63d8c5d72f2cc6d7079d9d90f6b50bad07826f1320f5f"}, + {file = "pydantic_core-2.23.4-cp313-none-win32.whl", hash = "sha256:3d5639516376dce1940ea36edf408c554475369f5da2abd45d44621cb616f769"}, + {file = "pydantic_core-2.23.4-cp313-none-win_amd64.whl", hash = "sha256:5a1504ad17ba4210df3a045132a7baeeba5a200e930f57512ee02909fc5c4cb5"}, + {file = "pydantic_core-2.23.4-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d4488a93b071c04dc20f5cecc3631fc78b9789dd72483ba15d423b5b3689b555"}, + {file = "pydantic_core-2.23.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:81965a16b675b35e1d09dd14df53f190f9129c0202356ed44ab2728b1c905658"}, + {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ffa2ebd4c8530079140dd2d7f794a9d9a73cbb8e9d59ffe24c63436efa8f271"}, + {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:61817945f2fe7d166e75fbfb28004034b48e44878177fc54d81688e7b85a3665"}, + {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29d2c342c4bc01b88402d60189f3df065fb0dda3654744d5a165a5288a657368"}, + {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5e11661ce0fd30a6790e8bcdf263b9ec5988e95e63cf901972107efc49218b13"}, + {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d18368b137c6295db49ce7218b1a9ba15c5bc254c96d7c9f9e924a9bc7825ad"}, + {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ec4e55f79b1c4ffb2eecd8a0cfba9955a2588497d96851f4c8f99aa4a1d39b12"}, + {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:374a5e5049eda9e0a44c696c7ade3ff355f06b1fe0bb945ea3cac2bc336478a2"}, + {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5c364564d17da23db1106787675fc7af45f2f7b58b4173bfdd105564e132e6fb"}, + {file = "pydantic_core-2.23.4-cp38-none-win32.whl", hash = "sha256:d7a80d21d613eec45e3d41eb22f8f94ddc758a6c4720842dc74c0581f54993d6"}, + {file = "pydantic_core-2.23.4-cp38-none-win_amd64.whl", hash = "sha256:5f5ff8d839f4566a474a969508fe1c5e59c31c80d9e140566f9a37bba7b8d556"}, + {file = "pydantic_core-2.23.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a4fa4fc04dff799089689f4fd502ce7d59de529fc2f40a2c8836886c03e0175a"}, + {file = "pydantic_core-2.23.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0a7df63886be5e270da67e0966cf4afbae86069501d35c8c1b3b6c168f42cb36"}, + {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcedcd19a557e182628afa1d553c3895a9f825b936415d0dbd3cd0bbcfd29b4b"}, + {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f54b118ce5de9ac21c363d9b3caa6c800341e8c47a508787e5868c6b79c9323"}, + {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86d2f57d3e1379a9525c5ab067b27dbb8a0642fb5d454e17a9ac434f9ce523e3"}, + {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de6d1d1b9e5101508cb37ab0d972357cac5235f5c6533d1071964c47139257df"}, + {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1278e0d324f6908e872730c9102b0112477a7f7cf88b308e4fc36ce1bdb6d58c"}, + {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9a6b5099eeec78827553827f4c6b8615978bb4b6a88e5d9b93eddf8bb6790f55"}, + {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e55541f756f9b3ee346b840103f32779c695a19826a4c442b7954550a0972040"}, + {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a5c7ba8ffb6d6f8f2ab08743be203654bb1aaa8c9dcb09f82ddd34eadb695605"}, + {file = "pydantic_core-2.23.4-cp39-none-win32.whl", hash = "sha256:37b0fe330e4a58d3c58b24d91d1eb102aeec675a3db4c292ec3928ecd892a9a6"}, + {file = "pydantic_core-2.23.4-cp39-none-win_amd64.whl", hash = "sha256:1498bec4c05c9c787bde9125cfdcc63a41004ff167f495063191b863399b1a29"}, + {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f455ee30a9d61d3e1a15abd5068827773d6e4dc513e795f380cdd59932c782d5"}, + {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1e90d2e3bd2c3863d48525d297cd143fe541be8bbf6f579504b9712cb6b643ec"}, + {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e203fdf807ac7e12ab59ca2bfcabb38c7cf0b33c41efeb00f8e5da1d86af480"}, + {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e08277a400de01bc72436a0ccd02bdf596631411f592ad985dcee21445bd0068"}, + {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f220b0eea5965dec25480b6333c788fb72ce5f9129e8759ef876a1d805d00801"}, + {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d06b0c8da4f16d1d1e352134427cb194a0a6e19ad5db9161bf32b2113409e728"}, + {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ba1a0996f6c2773bd83e63f18914c1de3c9dd26d55f4ac302a7efe93fb8e7433"}, + {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:9a5bce9d23aac8f0cf0836ecfc033896aa8443b501c58d0602dbfd5bd5b37753"}, + {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:78ddaaa81421a29574a682b3179d4cf9e6d405a09b99d93ddcf7e5239c742e21"}, + {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:883a91b5dd7d26492ff2f04f40fbb652de40fcc0afe07e8129e8ae779c2110eb"}, + {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88ad334a15b32a791ea935af224b9de1bf99bcd62fabf745d5f3442199d86d59"}, + {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:233710f069d251feb12a56da21e14cca67994eab08362207785cf8c598e74577"}, + {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:19442362866a753485ba5e4be408964644dd6a09123d9416c54cd49171f50744"}, + {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:624e278a7d29b6445e4e813af92af37820fafb6dcc55c012c834f9e26f9aaaef"}, + {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f5ef8f42bec47f21d07668a043f077d507e5bf4e668d5c6dfe6aaba89de1a5b8"}, + {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:aea443fffa9fbe3af1a9ba721a87f926fe548d32cab71d188a6ede77d0ff244e"}, + {file = "pydantic_core-2.23.4.tar.gz", hash = "sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863"}, ] [package.dependencies] @@ -791,13 +807,13 @@ files = [ [[package]] name = "syrupy" -version = "4.7.1" +version = "4.7.2" description = "Pytest Snapshot Test Utility" optional = false python-versions = ">=3.8.1" files = [ - {file = "syrupy-4.7.1-py3-none-any.whl", hash = "sha256:be002267a512a4bedddfae2e026c93df1ea928ae10baadc09640516923376d41"}, - {file = "syrupy-4.7.1.tar.gz", hash = "sha256:f9d4485f3f27d0e5df6ed299cac6fa32eb40a441915d988e82be5a4bdda335c8"}, + {file = "syrupy-4.7.2-py3-none-any.whl", hash = "sha256:eae7ba6be5aed190237caa93be288e97ca1eec5ca58760e4818972a10c4acc64"}, + {file = "syrupy-4.7.2.tar.gz", hash = "sha256:ea45e099f242de1bb53018c238f408a5bb6c82007bc687aefcbeaa0e1c2e935a"}, ] [package.dependencies] @@ -805,13 +821,13 @@ pytest = ">=7.0.0,<9.0.0" [[package]] name = "tenacity" -version = "8.5.0" +version = "9.0.0" description = "Retry code until it succeeds" optional = false python-versions = ">=3.8" files = [ - {file = "tenacity-8.5.0-py3-none-any.whl", hash = "sha256:b594c2a5945830c267ce6b79a166228323ed52718f30302c1359836112346687"}, - {file = "tenacity-8.5.0.tar.gz", hash = "sha256:8bc6c0c8a09b31e6cad13c47afbed1a567518250a9a171418582ed8d9c20ca78"}, + {file = "tenacity-9.0.0-py3-none-any.whl", hash = "sha256:93de0c98785b27fcf659856aa9f54bfbd399e29969b0621bc7f762bd441b4539"}, + {file = "tenacity-9.0.0.tar.gz", hash = "sha256:807f37ca97d62aa361264d497b0e31e92b8027044942bfa756160d908320d73b"}, ] [package.extras] @@ -820,13 +836,13 @@ test = ["pytest", "tornado (>=4.5)", "typeguard"] [[package]] name = "tomli" -version = "2.0.1" +version = "2.0.2" description = "A lil' TOML parser" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, - {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, + {file = "tomli-2.0.2-py3-none-any.whl", hash = "sha256:2ebe24485c53d303f690b0ec092806a085f07af5a5aa1464f3931eec36caaa38"}, + {file = "tomli-2.0.2.tar.gz", hash = "sha256:d46d457a85337051c36524bc5349dd91b1877838e2979ac5ced3e710ed8a60ed"}, ] [[package]] diff --git a/libs/standard-tests/pyproject.toml b/libs/standard-tests/pyproject.toml index a3775ed9b3010..14515955ee572 100644 --- a/libs/standard-tests/pyproject.toml +++ b/libs/standard-tests/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api" [tool.poetry] name = "langchain-standard-tests" -version = "0.1.1" +version = "0.3.0" description = "Standard tests for LangChain implementations" authors = [ "Erick Friis ",] readme = "README.md" From a3bbbe6a86ca4af3d258940e5cbb9455cd3bbdf2 Mon Sep 17 00:00:00 2001 From: Tomaz Bratanic Date: Tue, 5 Nov 2024 23:54:26 +0700 Subject: [PATCH 02/26] update llm graph transformer documentation (#27905) --- docs/docs/how_to/graph_constructing.ipynb | 120 ++++++++++++++++++++-- docs/static/img/graph_construction3.png | Bin 0 -> 171696 bytes docs/static/img/graph_construction4.png | Bin 0 -> 154289 bytes 3 files changed, 110 insertions(+), 10 deletions(-) create mode 100644 docs/static/img/graph_construction3.png create mode 100644 docs/static/img/graph_construction4.png diff --git a/docs/docs/how_to/graph_constructing.ipynb b/docs/docs/how_to/graph_constructing.ipynb index e9b6a014177c7..79b9e1463f4a2 100644 --- a/docs/docs/how_to/graph_constructing.ipynb +++ b/docs/docs/how_to/graph_constructing.ipynb @@ -44,6 +44,9 @@ "name": "stdout", "output_type": "stream", "text": [ + "\n", + "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m24.0\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m24.3.1\u001b[0m\n", + "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n", "Note: you may need to restart the kernel to use updated packages.\n" ] } @@ -105,7 +108,7 @@ "os.environ[\"NEO4J_USERNAME\"] = \"neo4j\"\n", "os.environ[\"NEO4J_PASSWORD\"] = \"password\"\n", "\n", - "graph = Neo4jGraph()" + "graph = Neo4jGraph(refresh_schema=False)" ] }, { @@ -149,8 +152,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "Nodes:[Node(id='Marie Curie', type='Person'), Node(id='Pierre Curie', type='Person'), Node(id='University Of Paris', type='Organization')]\n", - "Relationships:[Relationship(source=Node(id='Marie Curie', type='Person'), target=Node(id='Pierre Curie', type='Person'), type='MARRIED'), Relationship(source=Node(id='Marie Curie', type='Person'), target=Node(id='University Of Paris', type='Organization'), type='PROFESSOR')]\n" + "Nodes:[Node(id='Marie Curie', type='Person', properties={}), Node(id='Pierre Curie', type='Person', properties={}), Node(id='University Of Paris', type='Organization', properties={})]\n", + "Relationships:[Relationship(source=Node(id='Marie Curie', type='Person', properties={}), target=Node(id='Pierre Curie', type='Person', properties={}), type='MARRIED', properties={}), Relationship(source=Node(id='Marie Curie', type='Person', properties={}), target=Node(id='University Of Paris', type='Organization', properties={}), type='PROFESSOR', properties={})]\n" ] } ], @@ -191,8 +194,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "Nodes:[Node(id='Marie Curie', type='Person'), Node(id='Pierre Curie', type='Person'), Node(id='University Of Paris', type='Organization')]\n", - "Relationships:[Relationship(source=Node(id='Marie Curie', type='Person'), target=Node(id='Pierre Curie', type='Person'), type='SPOUSE'), Relationship(source=Node(id='Marie Curie', type='Person'), target=Node(id='University Of Paris', type='Organization'), type='WORKED_AT')]\n" + "Nodes:[Node(id='Marie Curie', type='Person', properties={}), Node(id='Pierre Curie', type='Person', properties={}), Node(id='University Of Paris', type='Organization', properties={})]\n", + "Relationships:[Relationship(source=Node(id='Marie Curie', type='Person', properties={}), target=Node(id='Pierre Curie', type='Person', properties={}), type='SPOUSE', properties={}), Relationship(source=Node(id='Marie Curie', type='Person', properties={}), target=Node(id='University Of Paris', type='Organization', properties={}), type='WORKED_AT', properties={})]\n" ] } ], @@ -209,6 +212,44 @@ "print(f\"Relationships:{graph_documents_filtered[0].relationships}\")" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To define the graph schema more precisely, consider using a three-tuple approach for relationships. In this approach, each tuple consists of three elements: the source node, the relationship type, and the target node." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Nodes:[Node(id='Marie Curie', type='Person', properties={}), Node(id='Pierre Curie', type='Person', properties={}), Node(id='University Of Paris', type='Organization', properties={})]\n", + "Relationships:[Relationship(source=Node(id='Marie Curie', type='Person', properties={}), target=Node(id='Pierre Curie', type='Person', properties={}), type='SPOUSE', properties={}), Relationship(source=Node(id='Marie Curie', type='Person', properties={}), target=Node(id='University Of Paris', type='Organization', properties={}), type='WORKED_AT', properties={})]\n" + ] + } + ], + "source": [ + "allowed_relationships = [\n", + " (\"Person\", \"SPOUSE\", \"Person\"),\n", + " (\"Person\", \"NATIONALITY\", \"Country\"),\n", + " (\"Person\", \"WORKED_AT\", \"Organization\"),\n", + "]\n", + "\n", + "llm_transformer_tuple = LLMGraphTransformer(\n", + " llm=llm,\n", + " allowed_nodes=[\"Person\", \"Country\", \"Organization\"],\n", + " allowed_relationships=allowed_relationships,\n", + ")\n", + "llm_transformer_tuple = llm_transformer_filtered.convert_to_graph_documents(documents)\n", + "print(f\"Nodes:{graph_documents_filtered[0].nodes}\")\n", + "print(f\"Relationships:{graph_documents_filtered[0].relationships}\")" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -229,15 +270,15 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Nodes:[Node(id='Marie Curie', type='Person', properties={'born_year': '1867'}), Node(id='Pierre Curie', type='Person'), Node(id='University Of Paris', type='Organization')]\n", - "Relationships:[Relationship(source=Node(id='Marie Curie', type='Person'), target=Node(id='Pierre Curie', type='Person'), type='SPOUSE'), Relationship(source=Node(id='Marie Curie', type='Person'), target=Node(id='University Of Paris', type='Organization'), type='WORKED_AT')]\n" + "Nodes:[Node(id='Marie Curie', type='Person', properties={'born_year': '1867'}), Node(id='Pierre Curie', type='Person', properties={}), Node(id='University Of Paris', type='Organization', properties={}), Node(id='Poland', type='Country', properties={}), Node(id='France', type='Country', properties={})]\n", + "Relationships:[Relationship(source=Node(id='Marie Curie', type='Person', properties={}), target=Node(id='Poland', type='Country', properties={}), type='NATIONALITY', properties={}), Relationship(source=Node(id='Marie Curie', type='Person', properties={}), target=Node(id='France', type='Country', properties={}), type='NATIONALITY', properties={}), Relationship(source=Node(id='Marie Curie', type='Person', properties={}), target=Node(id='Pierre Curie', type='Person', properties={}), type='SPOUSE', properties={}), Relationship(source=Node(id='Marie Curie', type='Person', properties={}), target=Node(id='University Of Paris', type='Organization', properties={}), type='WORKED_AT', properties={})]\n" ] } ], @@ -264,12 +305,71 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "graph.add_graph_documents(graph_documents_props)" ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Most graph databases support indexes to optimize data import and retrieval. Since we might not know all the node labels in advance, we can handle this by adding a secondary base label to each node using the `baseEntityLabel` parameter." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "graph.add_graph_documents(graph_documents, baseEntityLabel=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Results will look like:\n", + "\n", + "![graph_construction3.png](../../static/img/graph_construction3.png)\n", + "\n", + "The final option is to also import the source documents for the extracted nodes and relationships. This approach lets us track which documents each entity appeared in." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "graph.add_graph_documents(graph_documents, include_source=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Graph will have the following structure:\n", + "\n", + "![graph_construction4.png](../../static/img/graph_construction4.png)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In this visualization, the source document is highlighted in blue, with all entities extracted from it connected by `MENTIONS` relationships." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { @@ -288,7 +388,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.1" + "version": "3.11.5" } }, "nbformat": 4, diff --git a/docs/static/img/graph_construction3.png b/docs/static/img/graph_construction3.png new file mode 100644 index 0000000000000000000000000000000000000000..3d89b1162e68388f3e4be892b632b644cfb93f2f GIT binary patch literal 171696 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
$MN9?sbq8$5XKj2_*rK4orC)%)JNb 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%0An#B}5rTV|*koi|-JY^i(=5@5!s^KQ z|F6~YmTRq{QA)UD+VPW<3AK1!QLSV)Q>|pq&8(aUWvlPMRGNj~lW~0V>C;fO8%JJV zB-b2c-LJaz`(ipMyh=!%TxMogvJNaOl7XkyH^7QzT)pftVl~18iTPIUV~7QahL~jX z^72f3;g76ILXv(-P$6rZ^6|y><2GNUg~LH7feAHR)NFgoVWxcP4Ok_&=6^ZzIbg(n z4K`Wq%<@CuS)L3j=>pS;4ik(mC^8;UsC3@zBQ?4%IBk6weR3QE*+2?Jb4FtyNVI-D zql{q)$;m0OwEg+ipOohjZ8?U{3<3Vkng>=O#l}k$rY(Pt>`uN!EwYGVwo>%}+)5dV-6lzl zK{y;gNp2GbeyGU$xTBW)Os{uz!FJ3CXBZ~Cxwg{*9R@Fu zcv)WbB8o%9+Bys7wx@jlY?qvx%t%A?m~_FUsl8n+Wk#c}Zee6EtXJFyvpqNe&+Un} zvB@vsImo*T6Kcg`+@M{~dG$khZ;DoVZ5tQ=GTGTUf0p_|IqkyR%T!%Oz=NN2!r~SN z7E{q|ODv;bokG!8QzhiqcQV&16f{+nK5ugyEI(IqRxg8b)1g7J**|`aKt$48FB{FR z7Ow3e?lz2ZreqBN*W)u{&?^XSGt<(3CyyC(p9ijcv6TV*=#t#$s1fIoU40`Uvg=T} zS7^Si=?xUU;Q1>{W9N76)Ze@XgA3q`aXx&?o|D*Cq{aeqrjojIBxhH5Xl!gs#jvKx z-mxF2vrE6d9U#RvTf2;6=;!7`zsiJw(~R?fCReGK%C&MTcYR0QjDpB7yRU3)Zg%bP z4W}72kB0Z^%6E6jvAQGE-#rRAHXLgjbMLL4YLE!dF5MOMcbN|o48)IrJs2L9c{NaY zdYB_aV{g@Yva$5pi2yc&-vKX5T4Jbsr@xQ(V1GYNXN=O6Sn@8Xry~A;zmG>;;#eXC zUi^U;v@3MZ%hMD(c0Mw)mU47_ukCUo?O%rcv09GKP^E)JGf*~yc3|b1=Gy0nUcKKR zUzX^CT*skj10ka&{pj&dQ)bRm*ID_C;6i|MN34&sBqd~QY&j9enk)d4W(~xni3FD5tQsRaj2&H^7kSrF~TQ)sa;=;))eUirLjH@5|i=7Trz;^oUu>!Y}#QJLtU zf6}_T6r`iq(}?@x?SUe`2~zm&!0G+<2wdd<`#qsb%=K-gM?|{ zk5X;d9s3dfZDoP$y&gLp2a!B3Z6V-m z?b`Xi_uQLGVpL2m6N0UHU=BkEUs_q^f+F`0#D$FaihBtfytz#hpaW|GrQ;D)r`sue zrtux*HRsycz`iw$9m?6pMbngzut^AR{V1?+dpqTih<3io`=%qZcO!Tt+cW-Oz#1s+ zWnR7d!d5!1kermnVB3HP!KSJ7F;k5DA?fDUUXFJUq64nOA+uhCg;9B7;R{Yjh96F8 zcNDQ6oN$mk+L623@xycJ7YqR?LO4FRlx+;FufEF2$Qshwt@v?M(tB#Y7K>6%^XC7! z0C3kSy=vWmYiZ!kz0K1rbZ8ZOMp$Gq^0c+~XW`0PR@+nnZTibh{>sC{sB2fQ3HNX! zWU!FK&IJIOfw%S|zI7)P_&J%7rJMFwRSp)Kv7glvWkC>nQlzremVly@fONYzx>PpP zc8+a_hzdcL#i|ip#M)@jS9R*NLfG9 z6|ti~*Y+Yy2PKovI20NgoY2!lNJL23V{Fmg(Sa>gsdQ2xlr$ITrVc!l;H2-U;S3N5 zBHx_5j)*seu8*S0)R$~-)_L-a10gZ_2yTo2(}9eORqflA#(v|H3g&)2NqaIzq|#?R zN>9bwjoU85oY~7HaSa#0|A@+++R}1Ou=(2fv_h_BoI)`@GaZk3IwPaxKy1SHwo+(V z7^VHH2l8{|=03NUV`H*CDL^un)6?AMr)E)7I%~07gm>=Dq&z{$?fqA9vCplp>mGRs zFHh#uk&W%n?47Ncl@7z!K*7|CLZt$u)(&4P5360Aix*9g_q`b{uw*!Dq$AUi=+niK z9CShZcrLS$POuo{<<*!S590{cjk2esq(9T`{>KK!IsH?FRJc(y(Crm1E4``547<&{ZFupEPx zt{D|gMjbIRzLZOz^@*}MY=?(OI@A2Qi4Uze-03Xa<;FxuhNJ%$QONNF7{Ifp7D58% zU%sYoE-Mp^@iX%n3@DXN3two?Pd0ohB6Y4wH;?})yZp5ekdQ4 z8Ho>LT}?+{`)M#WHEs8V*lt6nCUgWk0o*2=gf~QwhMgO)$8UfUT@8RDp3I9ENxRe2 zOtwa01?&O>(syg#g3Ytm<2>I~s~^I{6!5od3QVO-p5~)~p9b)Zv-w6{HAIfKMW**Z z7b=a|H<+{4v6>GRb-zQ7CYOK_AE)g@si;J}7;SS~fI`H$FQ(2~PU`o1t=d_5wtt6gJC{fn}9L;lacty{(Ely8=o`>S@1!r#Uy`R#!sH zpA=)GMAK-I)Q5v3C3*RY)#nILGS1uni@mk>-c=)N0+KIeY!#{hu3q?W=_vT)7?;9E zrgGDSl`$rjV_~TnybW=pQCw_hyO`E$*I0oHdyM_A0488qU$<)XihLcZ)6C0ea^>C9ynt*pNMtc@z=AU$7Y8Y3nGt7c3W*H5C1 z;#T`4A>kX~pS61kIIDE@{f9##AsLm$P)9Hy&V3jRe1YUJRvIEAimbFWWASItn3)9C zgF59+`?!_xu6SVsPl(|_FWVnE7N>liCQx9=A9z1F3G!Mw zNJ149iy=x(dukTdYFPC7^Kt4r9g{kyr~>L-LOh5YPhOvjYB?;_fv@Hy^DlFn&)VGF zRe0$B7V1e#a&kL4x$zHhKH%i5voyH+zpi~YzgxbV?X?X?b}%X`N5?~BrK>;NJi5%m zWDR3%T&`apT|{Lrb{ZBmTcDbCi<%VVzxx?{K-oj4VnMoK99?4HEt)|R4^Q|TMtA^9Ax?Jx}< zo0dO=Xe@-iZq1#ooxZ3oIti%1I&aLV^a@uT<{1WKl2TCC!X%z4FCrNv7Kd`;4!2h_ z-@SW8L`0mCn=AL>0}iHS3hdSj3L>z0 zfrFqAz&I8JxAJ9N&GXaxpey#rNF?`$y!l93?*It}Mb?0TH_Wp;I%d^3 zS9OiXLS$PNQ?p0DMg)D|-Y(4WFnJj$#KmP$q#mOeUQwp+iE98A6 zyj3~o6N3R4&)E2hUBPCR2f#Hw&V2tS1DZ3>L_!SxF9UVvknjg zo&n2Xsq>b$al(qh2`uj8chhS|4z_~l2iJ=K-2FVySN#F~i^$@3p|cCp-}og&XCHg~ z&O?`|-r;-mMXAUIqy|N1CKl3pR|eCih5GUHVV=3e>To(_D9J`ijI2D;&0%gJ&Rx#H zK%3OIdiB8yDX;EVCUf4(qc&;-BO{YvBDLE;nRA!~1yct9Oiog}frcF5%$DE5)W|@q zoI^K0v%7uq-V6zo0Hd^si-Ut6)87@+{#~K3@25_hTa?``q}_I7Zus*VW;sHW`=QJp zDh3A0wCQIi*wYhE`#PD|pC%^g>Jk#&N_;Dr$*YH*_KfD)7;|}RcCr+)+1e;MrjW^A zb)2EAURV10$n}8!9F)6JYMmyOZ~+lOeZNC?q|BjfR_tt`lAXuR8|I^cuUz<_hqC%> zOvm-DM{!6@2fX9Ri%P_UG1UCIt+(Vn7o$0!23E=fAS@C56~i8&S(BHv3Er}Y(`-QH z`mY2g`^LT$JsTDc@S@q!y{7~dt(u3y#i{9O@f{FaVLsJCa^v8A*4bNYYXb%A4fBj! z7ab*nJB@oxuw`*F(1F3b)*-wwI37^Bgo7^`>XX6 zq6cM-AJE_1ugQE~GyKDmxDB$l>ScDHXc@r@!OY)JLNpf;rq%kJ$`DCt9y;i+cI^`S zVhTQRiw7Lbgy7EykGGo90rY};szDeo^H>>p-GJohPcSjvvFpk$&d zC=Cm_kj4y{TfNwJE}R&*(*>K*uV0N@<_YrE0X2fhd7v_ z*cln6f%AXOoNW1jFK6sLnBgaOD0e?ndE2~zeYw|h5feSxwhOaHwa#{-9ahNPjypL= zM3yNrNKR2G;R6cW+rr!PiMRAo1KTqsaZnI?aW5phYL<*I6&peB2Rer)?W4lL0FVl9 zYHI!(9i7qfg);c^oqqvZ1#p#foZSvwpgBHnf|RFcKif9d}j-8j~x9%mRz) zlFJw|2n+(T&wifY2h>1c)}*U@Jt>cH>~D+yX^C4gb*vyr)H~!yyyO)q*4aOn(^1fl zP9tX3kPIefS5M=cLn|+pV)cN!xOC)k30uXyu7m>E{dy6rH~{9SW?#X|2`DL3c(e4h zFsG22-X+K7!g-MdL2`ca$h~yV?1eiqziA9*6(&ZuFxrS#L+LmHDG+P4s~TM^#B$!s zLJ?6=uu3=sIlRb3@zKhMOLBX{!rU_(CK$Mp_9ap2XODHPER9=h=Ret5sqqZw(xK3h za^}lVjVAf3EEqeA`Ouy}s_C0&&XEqwf9^_bZfwZsh`O0^vzzU)&28aP2r;rGh!=4@ zyeqxEY|Gv>G^7!{{gZ1;-|COqT^>*8sfq9D-G=kgw(TLbYAnPe+@}wLMAXz;gFrMS zShicRtwawC)7?ugr~e!2S)F^E_>YrkJ9q8ls!pQo7%rQuqMmM`&y>xzmFzxmImy4C zc-@b0IiSFIqf$H=Q=o8zIq&pjqz^>6Zu>`y>V>rl9+67~_v&^g;)^-{j=KRA3`MJu ze?jY{FBt-|m!OVr{a-xu?|FnPr#Gi*VvBgM+;rWP8;ok3N=U>2>6cnM8`(7M~MCFr+eY z*>n;RXOMB&*cCacXxnCO9T+u>2~6^^5D^6@fv!~VQ+ ze%F&0hv-9`(EVAw*jHIj z%SdNX-uEj=TBr3?5(M{?tf_=vYU-9`c18hdV3Au$ zp2t+x>3&ExxEC^VKkG9tkO1guKmTVUcgmv7ByH=Ui*8NXW#o0i!Y6@(=#^2o!#-U} z*Z}gtQ@66lZezP*KVPY@U!!OLv%S%ge+|_`K&K z1HM;Z1YX(t$&>yTbhcZmh`p#zx1(#ghnzs4sJ+X;Wt|+9US!<>C?@P#wu;cXl*B z{0ykOTMATDUeaTB$;#DvZ;`1WFsDFET{$Ibny}FV`JX?Rq4@6`LF7g-4!yTJNfUqx zilDA58JwT*kXe%ZduAv8%RRxP;Vn}!T2DPgMs_6fBBELX`mWj7R>{q*A8&!q{TTYTqyMnEk#`lvAmb(V+uR_m_HIfj% zD?zP5uE@OmFMhSV+Gzj3lk|6aJ?}X70zv^`0PX}-Lej2n?NQi7Lru4;!b21REh*VK zK8S#~HLq2i>tzg9Te>oOmv*|_HweqXgh@aEAqPF01?G9Gq2HqK`PD7fE1j>F+x`6E zd*0>x5R-A}ex)^;YojQ$T)u6vHu%zfSi`dNJCy662ZIOF)zw?#y5~tIIh3bCcO(^K zE}JM%K+rn!?F#suh5pQPDVO$9O*&g8g7a^-Z|WYwm~Aq@yL|XBLC27oRWp7%iFSl@ z`zb^NhW4vn;to;Laju&|$_))d4RLO5rNNhX>Z=hzf?|{q$`O)?!zB z%<14^d*@e)Aw?**B@wg!9EK^w@bRqoJHOKE+^*9Mq}RJ9k;LhRg-W=i&Qo8e)PVwe zv`VGYz5t%uVV81d=ESx|RqmCiE;Y^Y`MTj?7D1+JVrdae3rB*1QQ)QYJM0;~UHkvy zQ8KD3PWU0Y=8yijlW}lKGF<{=yZvygRqBCGgjsc$s^XZ-%P zE!^#?_A_$2S*Z0ukl=4QiH*Qx77PI2@#Gj!smm!s@_ATmgCBwOJU^#zi zC0{iwUrC7}LG2c@9uo%yX!MP`ZSqE(hyU?xMN1v>81IO@j^Ozkc^WsOL0t=&34&by z&6}_Jd()=lHb88daB-Q-2N-wp*{QhmiTcntn&GX}A zVb#dY%uf5>Zy@MEgtYjdHQ^RLKU4_Mq{7cyu(mb_C4F3+4;RZh2oUi#>+5o3qa#{n z7*k=oh{uO>ZYtt8&VgD;S=(P1FpB7giBNLpC7fuuX&<(hGmI4B(j&XRNOqTD-Ujy)?zJWt$Szo zslC7b?eFXZ9(o`b($xioXP!)eq!}ysy7>3Mq22uB_159VRI*4(h2;7(1iP__gl}z6 zPr_2uV3lu_IE+M;n_Y*c|W`vvH+VKMnbl=o<3ymFt4D${&xO6x!Om~5AfA*Yi=CY;Ym zR)??HQ3ow+QX@rElXehdF?X>HX+9|Hn@6{Npdgy*qUEgco)9ls!WdMks59D)^Bwa&7V6|_>f(hit4P)yD6!=+~427+GXtp=wio}aTCH0t^)mI zp{w)ZFgi*KLHx)czz)2}L&}Lj2QG(|T>SrGyTxB}VOBN+(Z@pg}e#HD`GwE1OH3ap}rhVckH2 z%R?pCAbc86t7Mk8k>YVA2_9hzXqL`}yaBTEi_@b&1iF{YmgtSn;qnD`r>&utyQP2U z$LB8`!y&$dBkS&&gDKL05`La&P&5!9kFeyw)6vWUn%w>z6?#0fdMS^R(%fLst9-Q& znR_S6E#uBZ(mY^pS0axH!m%BBC2n`$_I;PR3J40(b>Af}&mfQiK^taf3|U}tHL|ci zo`^`He)%&naPG?E+JY=P5jSL$-M&8fE9>ESxn=Jck4@E9xrF_W+&%a!qEK!@0V>g* z9r`kmIa*CcB!dWMZs_UhIRHu*KrbqjVAt~Ew(n;N1h}8%xcBY3vZ7XALxZr__G~MF zKiT1DH;G~+A|6m#POVz{`*ZXYW**rYl7lT%;jI0U)y0@+{Pl+$tJ8(iH*fw1AUv4` zELQHc_slo)xGpA80tp&~N{jlE$8y-2@BMhZjh*FESYR!udbI9~ zEWwNJP*sGUUD}UI(;F2QwOJQ;=$EzYn1!eGF|~fcK|j3n$!P!E&vDvM(a{g6nF+mQ zc3;IA?eB&4_D~vrtAF4vXkB-GMuffoW&nxW9!>vRO;o-HT5?s;&%p6C`6nVBBv2VH z_;nz8bZ&FYpPP$FjG_jY5x#w+COVoCVLdq|wOkuwl zFyAf{oXWRv`?{kik>;eN1s}c69M>4R=sJ08+|ar*Y@O0wIefM{UR6W+K-m4JYsVhW3S{ z>0yu&Ynjx*hC|H9sfWBifRh^`8&_fOA>~)PfnLkKap3`YppoG0kYFqM4;^erZ6y|k zc`;QvZQbEbiWju9F07{~9l3BNw~7ambR|_Xz52MQ`1KDFB*6&@Cjr*a0L3X-1ZZnW(B9E!| zGZ`kjxfcL`N+~(4?IThKUaxB^=mms~!5k;Jr=S`%_Cp0k6erh;hIT^`Ccq9XEo5#5 zxy-7{k##}@ibf6iJ1WVu&W<09JhB&O2aXOUO}P^Zxw{bzk(uypasgO5g4IQw7dn2) zI*M@4;Wx`H?O|h=5M-HUEerW3zjl{U!fxOsT2 z1y|tb$kybLM@80Oruvh)DjULSROm2yTU zq$HowXu0%|56Q;xcUN)tux#y!-y3O0<|042hy+m*;Hso*6>>%Er;l2DB@(MTR&)@KiPEr)DF zf^J@R+0N|DaA}e}@&_@<(zynJ_nSa3h=-w3xL;Bs;jHfNiWq9`&%Zzk{Sx$oA1b^O z0a9Y1a2W7A@G(_-^O4f5VI|YzxUE-QE6rxwTeFl`2Xq4+oQ73^Mt-Vx`LJPe&jv;W zqCc{Nd3rP?z&cyC_#FoNa7O~sPj6zp7HF3$jR0Q_h2{l*HD&tbFOFKIJ!6yg6*^C; zJ@Qc;jdIjD!XFqflc#=Ufn=z0C==4J2~@KV%THD(otoNxa1YeClUx3$Fz0(M<|3j6 z+ZSuIUfx2rwPqi5(y(av=o}zt-OaLCZy(Dawdb$a?#V!w2pFF9^akx z9-idTF&wn1U!CTL;rqLY+F({!BC51^ zcfb$Mrw4adrqAR@HW2I1?Z)9v#?fgdiXqr>>#DiLQBtE&hLT7aQVNEe4ASj!-rbsh zol*J4y@uMB;eTfMztX4e`OQxv7zx?waT*SlB)BA7y%+@xH4E;)6JG!>;9CGOEap;8 z&u=fqr_{39L6z@eKn;pCsr3FvKr+~f$w_Sob5wqmlpI0nYjX5PjZ5hPjUX#>b8%zd zVUD0^RHfEFNNUJ3%*kdppwQ)+m=GD^g%=#eCI6&Qeh{R#*(6)$`K;U3`#%gxjUKAC zsj9y8kgS4Acf#rE!nXo^w*R*l05xH+H7tO*cpm=4#}MJEDc)uyOmN~9lzU)-@i&l1 zq1SNx4g=^rOR!=7$@UGJSLAf-SCF_oP|JSABW&j?yaAyJy>a2b+Rt1cJ*iW+_QrZj5TJ9ViUN{Q4_R?v(dPQg z?9@n~4js*Ruy<4{8y$0a3(P%wLT-1C+n+6aO!zX;{O(k0(UT|qbfHyE5+$XAAK9+@ zL$|!~iN^iIPW_7E4ysP266Hh$GIg68``L)- z455%|O^pgB!dihvJfatce;_7F`N?mG&Y!3(MYd_Gdo~Ui8E^I1g?g*(FvsEA8oOX? zV{A?i`OjuXjolDLID!(R+pa#kwBv|H7me;V3l^ha;YGaC@v-ObIwI?i293cgDzfiRi}P>DP6? z_UY-ZyKGnQ&K*8t`$&C5t^abd+Nu7W-4;Ec>_|%B zcB({6mhd{ND-=R*)u4%S)}|VB-b7DdDgGH1fNzdw9KN}xx8uKtXUHV1Zel_hHz(lD zVp+{n9gd<{47b#_1ieCenYp;caRj*KFyhxzX7W_uM6XTJhk|RCpq!`(DlVI zUJY_u8buF`dO@75I;Y#A&{MQ)DyJO__I;acR*YCD=*uf45}vc$u;sdlhgUMb9{9!7 z`G! zT%0oCSVpBz^h^=MfLn~{|u>WCW}3~jCL>5>YTN013$(U;I;x? zLnt#dX6^K$*Ycb2YkW&Y1bi+}sR^j^OCZ483&|EhoR+nR(X_W_$^flNU8&7X^3T}) zW98fbobN5273m+D?q$f16UpP)bS(@IbK2a|_8%)t@+P%5`2x_q6-LB4%v=>*nhl|A+VC;8m&1 zv>hVh0EMncD?dtbNE~^}A(j08-!Deb|J8e1aN}%DuVF2SWu12&jw&y-^3)GTS!fq9 zkNopIj@am*C)l(!l)>z;!`(AzoI(b(?F%l_kfa>_+A5R%c-3cn-l+Xp9yEUsPyJ@L zs@mYm&{q31KTFv?-FliZWlICGomoPvTPZ3D%OD~mgLqXm*EE4W zYij%N)iWCqVw0C!T3h!&9HGRE)n$OHO7~>7-h6lp)hRELdBCiDmQ#0Gs0&*@HYir# z-r}fBO7=Mn;BF#rQ#Fp_evabqMab>Fxnd<=mpUJP4-Yl} zf+}mDd-OLUFN9j<_j8WcPkgNkTl1gWREiA_svy#37*a;haG=}!0V=vpMX*Kl?C^Y) zTt>fLGl$LF?9p!qX-a{?GWnO3szK)7Cxbbz7lRgR&x#(*BP&k(nGb9wk$qB`{ed)3 z0$UBt&9WHbZeVXT{5g!^$qm-`@=KqgY)d)A><| zD$Rd82!Rx_s%>nk!jUfee9y3RkJd#c6_2+yg1s+2avxQwqnO+d9dk~Hau-H=r7EfJ zOP7gnM%SqoSTVA0lt(5}#`OJ`PZ~TX@X2$X9vLIJ2dsp|-M!w*L)ljczE>$YUdJvA z+3MAcCqd$m)_Shi5O zTDkaD?GbAWt3FvS9koWlv#AsMyvV{LbGO$YkCIqvkdazC8T6&JRKY888S0!;N2yX- zOBK&bHlNZ&2L4jzs9y~p&RJEnR-ey#@8*cXn+;+I_E-crF_-b4e+`pddp>>4<#m#D zY1WH)OLnrnwJJh(S;Trr_PnSVu1I&WKAVaAz?a}~(y__O+`clxD@ML6Kkc}wTIxUS%bAxd`?7_u1C<{&-Z2UoHBaeMhvP$cGU5 zrA%M`@job@z7S|Pk|ehzO-p+k8=I&xa_BAqs#B`h3trX0mdU=CMx(~xGdT4EeTd&~ zPA9CQ9@QM-V3NDu#Sy4Qtm0|Uw3R*klpylie)f`AVRUI6ngM(-^ZB z%2J#z1vn7}Lsu@X1pCF)XWX;+mb@3YM1sos#$j;v%62S>x{&dvyM6O4K1{_ITDTSE zpvE^F^@NpPYnOP0daI6+HQ}%pO|^70_IOnQo8K<){UF8#HJqBf4Udt@4#NC9^8P>P zr)TvSKKlVe#}P!au~OQP6daY5O5N83Oz_LCIOC?yTVM;${kvokh08t%{gb+*qExh) zDtpi5B(=D>;fI{Y9AsZ$;`4V#ruL%!Q0uAOSlya3VNv}wHXZj|q5KmerR*PlD?jD} zKF<|@*CaBR)*uDnTx6aW-e1B;{Lghw-132VNc@0r-3Q+d5*V-3LD`vs zR{26{S)R6egrLgb6eMi0qPlOY`q4*jpWtnhDDpn(^av@f(SAtgn)U$arFPzf8yKO9 zr7|;?*0KghGov?o|BlG&neSpib@iCEGDvhzf@)n~8|t362R1SmkTC9Q)qJw;^pN}EA_4w`00c$dP1S4J?i$YZ=R($|W@fVbR`wg6Jz%9d7P;4ER^9gT zRt%qZSLi7HS<*bOyy!G(?+l*yWzC}tqB}~Ib31gF@(UY|`1LEVs$@^VWZ6j{TX*YV2)mbQbZ-2e0Z%V`g)-Yw9fC zn9NmhYiBbde|LSHT*H;#2E|6Nl~bAGAu5e8>$zuwjk3*nukv@F=rKBB{sFP2I=zFj zZP}FZ9Tl*R^DI26^J-w{{0@w9cYOna`T#%TBmx7~;Ft5=)B0$-dKO9-F4yVNl=z=r zi$Rzp1$pmeVd^Tw#^!K;JQ7dGYRz0J<1@z%NKt%D5`TV!63s4=#ZL9Y& z>^v*|%Ok%U%O|aehYHG{sDgT0-_oWK?NxZ|F43B4K_ohM12L!w>|$b2u~yNUX0-6- zE8I~Ma@CrpFuAXVhxxn+vTJAE2IGxkaJtv<@x#wv(eVTlM*GU+bUsLO?Qa41w+^Ai z?G|~tsMnib+P4etF1Fc@DBDdw8nvL`CE7acrU*=2W&Y1Po$LMag874t}0 zKrl)W7|xVnFDcrp`Xr9~P`u>#O>7#{V4WcpTp9~Q^)FJeEc7o_kab(+)#OTsY%qeU zSPMossE$6j_jd`u{N_3B4%%-9Dg2#R{A;U?;OY!x6(0WlOv9-cJ;eN)sewhK2ROlW zL_v&}Ttmaz#Z@Vv@oqqDC8>!cw`y>t1B|+h3qr(roc~namfizy(L)>FZC9Lf@1$-| z;xY8v=st1`;qg8`$2_OZWvg5CEW^b303a!_|wrka73zP zV8Dsy7KfqYC(j>=I49m3H_FXv<6-h#uLb)>{quE!E!pwErAtV#THTzgGo7y5yC5PW zVtOY!^7Rx;oP&!%eWV~KPeF}_3+o1CQGY432RhN8UtdqNTa9_oqcV0brm>@my;j_NzS7E%IpaQj2*YeShBXL; z7H75zh0T9y&}~;9i|ux3L+AN=3m8lCDRU8LeeHw>M&Hk6#=N!zZCLjMb*(W0# z<>A~mZ^t}#@%v{Q74&Xg`>&Do78>TsB0FAU@B{|4z9yKBTmgk6-r!^O3YSu8)Iy*y<{DW4zR%w=QOshs0|~IRM&d+$+RhZCaC- zCi=)9g#mW90b2z$NF(Uki>7ZTTlj>B6WZMGkt60P;A4LCF!6Gy05_ri-}F|xiUL>u z9&ZgiHaAVyw=(5$|EybgSxwujj8~m?DUh?vloV1x_ z%x|QSPuR=$S4&qvo*`t~$=hGCmc$|kUl~c2#O$?h7>lX)(@qgoVLPyu5 z3eP^i25~vy?G>dFK7Lftl&9)M@Ht3glE&eSMw` ziv;=Pp1U10osC!>(R@AU-ZgZijEJV+ZN@|;afp6J(%IWUu~;HqdUX5L;gkMU7n zrBy|nJ6c(VB3lL`R{eiEiylIwuu({ zSNYX5%@LRF6AJhK=QecuDvMO{5vg=^QQfpr?6|UBE;?1|`?F!u&HZ~^@;4`5NTfuDN|>^oMQPAY>fAbX1;(32O#@nPwY0~dX@(&_SP0mZ(fhc@O$ts z`dohP>pd5_}S!^)P9rDqs@uX z{6D>=n9z3@I1kLi^p&K+=XI^O%8Wtm=tnA=v9fSuG(;mkJb%H2keK7`iD%p z1!DBr;LE1&aU0qPFl}Eg7!0?HI~FXId{U%`eDs6R(*HJ){-3{gSZ+-vm|IwB{@6MZ zX_N!c1w+qXTs4k)PXl>&?Ggj8=vJ4kFB5V`(=SetCc|$WZ zUv7SwX>@i{LGtpdC*Fl9XqFxc#yNb=O?!9fmqV`nsq1%DzD9X$V4k63N>;{}Pl3dL z)9~;0{*4`}ses|>^rU)W;h<=d!}F>9K~#!;%F3(vB~acXhL7p~oj%sqEO^UGaWd~G z))*ZHEbGGhtZJZVi*cRZhh+>;!CBoC@>Jh>tUJV_S}5IZ%^Q-!J;CQ7B!n&CqS-r@ zLauzxr}&Co`!fjbzfm(Hly!M|uxIwpM~moz_Ugc!EcnLlr+ubxc`y1{#eV+k zo4<3%pTNq+vAn~e6ffls1QNx0){qi!sFfgFGT>?-a%%{Y2BvmwT^g_1p9ar$&Nb|B zq$v~sJ2vyJM9gyP{MhnsYUSW!gQW)A2T>sdOvO+ReG2N>3{NW?#`ap#eAV%L(sgPK z`U`QfgMYS18oB$~e;|X906-(3^6}+?O{>wWKJkdhrO)aCa&|27teER)`@SNj=4W%v z;Pf{BI-uAZ_bVn9Rab%yKG);QzV=;n|0fa>w_dJzD(s3rq;g=0`P3MYi42I2dIh$P zqqnVP?@srjs*39gJ3l1Zaf!5j64e|d-Th2Tx3>ibB1A`+ts<^+fK&NPkn?*K`R4q)o*wN&t*s>1_lS; z&4JJpr*XXOCfXBfOk!x07lkUW2HQ{CVcj%x#omZy-e>N+qLPDX4!EcYfebym#sRo* z0sKDP)FHNCStC=_oz|0Fl{8t3ZdgeOZy{G?&_=L+!%DJ|%2w8t?9cf&NiV&}8H2}x zWV#P23OFI_oZM+FD?{Fmgj7|PbD)XY&PIC4l`&WVV(}NKVuNS0NX%_u=XcIhC}`L@ zIAA}B6bUhYXlvs92{(g?@)V*yo!W~n=x~sO)0}}kAt5|tjtcq!Qe@_vD3o^GraZ(_ z&`lkqV*-}Gq?Bv8LkAY-B(q%AFBKw3kWG&HF7@Zvj#xoqm~_Z=+8Eb5B3{N`&$J?f;gP-U)Rdyn6kZDfj4HA=)J7XHSwl9rKj&ZbCSp1BhCJ zQ>3vlF{B)C@SdNid|`8L&WF6!@HystI{xNFxDk^p1DB{8{Ehqnyy11O&D0x?50pZm z_Zbb)j&LYE3$JTVqO`WmtGARPXRH4`z*EmI@&~|6VSpi|zQVWcXQ%oYG#J1_w1t+n z(0eEyQjvc0@22GtR7<~xJTo2FyG{6K*$;N}>BNMf!vmZLYmL4iI8fa(o`U84{z!C=_*tvGL1a{tM9y-xYEqU$g5si%u&omKcQ4&v(oh zulO9gJ_eE#5G>06A|KIWkE2IUKPni;To#(cW8?R=cdA4JPQEpnx(e>UKWInCY5bTR zQK0YteSx5gN8EYSr@)=2UZOB~1Hu_+DqlY*60Xt8U30f0*)t~6dNj_WG~^z?m*R?E z`d`o25czTjg9%fsmSVkfa`M!FYylS(D4v$ftIL|uD?yod`Ny;E#@g_NmT-T6>HYBx zv#jD`eNpsw>%#;bsi*J8jv$Z%t?f}IjnKG9al{++XWF-M<8mpE4B3YbF?Wq19k>7P zvXB9>_>FZ8brTTTB zQ2BT=LT^DV#R9_Ud_78-k<06p6CZa?RIA}OdELC!$CmP8IoH!g|JRv{4vuIQUOUra zA@00V^yywKnWU80OEU)YVxr!bf3Zc`S*o~a`bN}!MA2U}kty5fC8F)@Bp@!+KlPk- zJiLLg6vBCvNuA8ziAd^H1e;6{mj2hn99*CL^dCn{Svf4o$OA>pp$T{TlAEtnvRzIz zgk=$|R-OaG(MSIhp(V^nl8Lvah{12Fot(A9?CKo*-nyn%IVe$x7AI$X#Ockxg+>3O zZmRivC!YO5ha6l3`70cKv0KL?Tm%qd!8iUMks)yT{;~0by#8kjmLZ4hJ%y2Z|lbi+)My9YCEOtgfLf>FjvKXgwkKcEK|guFS2}G>H;Z&Fg8K6^YK*_Srvab zw`5q~ecMSGB+=_AmR~UEYXS058W#TSUn7n~EQc+t4267qe(hKy1{^KxKKW5{aB)GOJ+Lt7tFZOdvwh1HE$!sQL6u{> zp^RI-iDYGIl%mQM z2jk0U56t>1j-T$z20K}}2M^xOOb>dU-OQ*GA)fXeBK%lX4vtef61Ot-@nM5O$CLu{ z_}6-g2zln|wVQy@O8*UctWSHtdiFMVHm;8pi_S`@|I~BU*VVmB)?$jD*gQDNHtTHr z%(BDkkiXh+?U9j#ET65dIaXXDs28?Z8P43u$IP2LGH=NZ^=xvO)OGyX?#L$_gj` zbzzi#jf5xjEr`}~oAI1^8utjfOe)D@b*)dIC_n-aZBloa<6*gYsloiHqn4YY)AuD| zuW7b)HF=Ac!cbLdUwdiE3bLVd$QfDwgT4%0ldU@+SU92nR?3*w z+%f8E{vpJ6u@Tjz5elOhVAVpxq->}@h83}{AfuBs0=taE9eg|g@k@J*RNU+7Uw5t{ z=G08erz!W#$!mSec7w`~25w~0`#9BaZsqIPGbj{B^mYvN#C_bxL)y7XSO0wtE+FS#t8M3 zAJ*d#)-`!<9#udQmGM9Z>ljb^5Vi0$Wl&>$9>8!XGpe`L=GYurN8XL^LrlK@(ASxju+4wT;t#WjvTHiH{Cy)rM4 z=r^-PAAd?Gz1dtNi|SlKw9YdLN1hZPXhj?t6*8c_sB%-ZG?*TA+Uu*woFyrkPs>pq zZ7JKYc@C2#*=WvgBNt<}m@f*{s+g`||+QP;ZliDGOJrEUDU=}uHtG6QpB)WHa0%%xs$0lj32 z2HZ{^K4!^kiBG5+BoicBqDdKK^vrL6x65BfEJj&O44N+k&3EL@mmx>W@FN{rQHh^#b@Hcp5VH5?MDT!ha?43M!8Y(^2+2Ht%CkjkFrtnXua z?E35X_T{KDZ5Pk|@J`ZD>N%pMnBL{}2vTl)1?G63GFt}XhimtRPUtuz>Gou0e&{3%;dWtls^$3s@9g~w@S1z%!yhYQ(IHmGV?l}u1kMw ze|gd{-x|7l!Y1H;P#_Sr8R?eWeQ8Hr=`u`Kl2lBS&FWtQ;=wM)>kM;hj#J{RW6}9H#jwN`Ad|m;Mv=4s@;^zwWe@l2)kZPrvV!(w;`a$lNh?9VMRD)VH@N(GBS@>BSn7dNqlHPE`9*y(jsWl{;v3(CS0w< z-CMXEtrLN?G3x53i&Hrq!yYw9m8iN$KZuIB-(($`U#D1pDkX^!S2SnJOBc%e<*3lU z@}6~Nkb$#IU1hpx|A36H%B1EA7pc11>uAcC1dx$eit`RqzNww0TqK+^*5Z%pp{S#} zB~Gu!OET#g(6dwT#NqSfs+*AKVNKRb4p#Xs8B2T~`)5qLjVs$#Y}jub5$V7eTiKX(x=oq#7nF*8 zS|!{ZUim2~dx{=V&_FK5x}$bh*M6jNob`o=mzMH!aDx^QzMc7N&g+`o_|la7rA=5) z_A?(d&b?7rz;&N)PUgmzM$FPBbw4;*+yC?4UHlH5E8jdXdvGd*3AGZd)~;W=cz)U$ zw&L98I1&*;6~&*3Efx`*7>+E@X^XrDQGKrTnBJZi(1>q$u>Z9VqpX=MNEokJ-jCV4 ze`btc8W3Vn&4=--I>~h|e6^G(3p*GXr7!52b84SbXY>$p(r_`WQY^2=9$kelL`1|s zq+{X99a+fh3p>u~F%uZ2Uu)N)(s7EMtI)~)+F9m&n?Qn<;^Ai`BWb%c`~(Wv$zT3n zAnN8$h~}i%y2e{e?%jyiqqHC0VV=Hv`u~I}m!UlY+vViT*@7)7kuLAEvyE2LKZD~g zt88TFSx}TT)~C>egh7+KJtxV&fHLamTZgDE;gb^8YP_U)*rBVZt0vQRiU8^O z=NiW4#n_g-N`UEPgVf0?zl(^pYTs==shW_Jh22s%!WsRd~Cp>26=iTatrZU9neBf>y3BdR_MagrOZm zymrntymskz{}2csw!=l3>X*ASN&ByA(f;)AQ(;^2pEBiF9E6Tty8gMP(dwI~e=+If zDIK7!SPw44x(&Z$V!*SegEhb%r3!M(@r(abBBXx@9iXmAge|#3u9cgcs|`GX!=*GA z@hO(rg5Bt1e%^1MY3EwC^46s26`X?VJ1|+__589DuEJ0%r@)`8Ymxaw^hX8G%`F+Y zWU;EO&vbU&zPi3S^iPUB_{BptW&7#Lxax31rn-Td8Ld%PCq1DNz%<&DUyT5A<+K$q zU)+C$LyKQO5SgD_Y^H*i%JyIlivdHJy+A4@#4GhdfZxJpJ3r#to=aK{Uv$8W(RW^~gSWmj$c7Fw(?%8<5 z_2WBd`}nMDMQg_S2H#C*y`26mhx2fC^OHOsaj-5~o7vvQ7# z{8cR%p`(E}mCeRwt4}NH#kXo#R0#_uKIxQM)l8j@jqmq=>RG-obXjN6UU}LgelWV_ zBa(F0)*3C~!kRENeX%^=VYHMsxK+L5RDIDhoK;$^@hEO1aOu~Rdlx-5%)WYuHlrE! zu2=qp>JD@RwWawYHkGIDsH3Ry{b`@=ha`YaM(pFbc*##%X^-`fmc`m=NG@R8QBfNQ zDqqWe7Rsx1kbrAWesPDw&!E|Kau*vvPGyp>JR7|~>g(lj`Tq2d_zy1_8a}^)721Be zU7D-OOJhi6U%}PZJ4)MByf6Edp-WZmC5F2H@Fi6w93zxECLW>?VC^}i2RfmMk&04? zNv^v^_Wsst=d!hv%reUhDy*#?O8PbTta2FC91vKAtB3W__{2CojLuJYmlk)fef z=TLXDd@J^Qf=`_y>|J*K#h=ziJI2Yy^pt8%pR@7$%;~y$Hln!Lq`h!-qL$hXf~Li9 z3>gucr|q5w_Hts>X%DPcF;OkzZ?&$HTx9lZV?bZ+thSO8GUO2d;iF)t_2*7q9QA^JfH9 zX~_QWYU6Ton?d7Do#<30&|e9jpQYi@;@*=)l(UyDUle*Mb@OahuavnjFTYM$u6Y4x ztv)+RTBE3U^cdnv@@zfZ#jaT3GvWOAj|=F`q<{8w%XO<{HY%EDo%3R+Mlf0EGTJAC zQow%y8-Vw@XLXT*gNs_;8tpP-0W0tGoT{R4U=Z{BH}l%=;CJ5GTXqVc+8bj*t5238eu3M{#CY|{dG!=wf{s7--4x$f}@^R zaqkLVR|P2_h4fXCLH)ial}i*lGtKLrh^j~q<1}6*1Oi0!AM#os_MBdkxxFCnyXBv# zy~7{WoP$$)*;T#K;FMdv8E|?3zE3@TYp~?IaW{{j{<70qVFFI2MD-CEdXtTJ+;8|& zIY_}Cs_E9JR@-;+u<<9qWu=p3l?}2U^>|UZr!$O#S!cp#P1TEyv~WngUV{T#MxT=( zArmUnQKF@0-yz?C8Mm;;%;fdBJ7g>`#k_e&CQ-6IWP%w+_JVDQ02(+7{f_5Oi>fD+ zxI=zCEDl~hd?lN2Z|t66zqNr#E7R$%V`-3^oQdD2Xl0@H?!KGDp3&M;Eh&C|y{rrYeU}czc%3xuOfIyxNbdrilTWU*J8v zrF6*?+|!+fEVphi-l|%B$f{OpDObSb^)xz>&zX}Q`tKvUv$O?7f|Zr~&iQ#?49#gz zVeb2&K{GY}&K)fwdN3-80>d>0QDiWi&Q3(>rcCqiSh=Hg}i(cw2_|v zkLF64gGa7q+0;#y0Hk`3z^+!Q_TdhpXm= z+_pCJDDi(m4M4qv?6>>GoYoax^H`u1>SD0Mh{Ui=b5IkOdsr=2HaM8u=K!x)qA@YS z3)VgLx;!Ccs(-7b@{skjn*sKD(CW!-YJFTj&C?H zrC>{0j=+TH?<#%xx7?!cH`#k%2;tUTa8gyc;1@MUN*kvG4uLUIQ4NUqq|B{Ps5B_s zC+^;e&VhO@MB6a0a-7kqPQA9_Vf(qrSIaRpkaz4^we&z{;fk0tZspJEs;dEai3^iV zm*0P$*643qLeKhyB|;*)IAjnSg{hXUELWHn;q$eT8Na9qs1e> zw{Il=P(`2otbkI@wQWCG=Akw;Qq_kc%9@`k_ z({&Ur{+kR>QKu2!egbz+6AX)3YsKm88;`ys&J|7EbRLDNy7b@lg=gD$dQ3iQzSDvy z$cOM~lwQXXpy>Js_iAxnngw^{Qb7vW6 z`e3cv?x>Cf<){DMK5u)PHi<`Dwu^VfLlN<#EL-IYi0?F-27!|273;T`a z8VW5?ftz$`i+I+>GCl1(Y5qnbXS<1pHd#>~F8*JMlaxhQczENC@^cg_T_hxZyz_T9 z{N>tKacIwTZK5m}_iXryq9!sHXp;~SJtb*>1C7w<@O?fblpUXTPHtXbgpVA8os&;# zE^v2vaHMwoXeTE7iK?Pj2BSwss?6uV#LR9(t`jh5AwtH4ortN_wsYn?v5>pM61HYW zP0jeivgvPuf8kAvi>l4JHFz5&sz$ctg*;26-c|KZ6$bT(#>gBfwwC^-7)4*yE*%zx zvrL8(ao}3;{IabeHyi$P#@;wfzRzMWmWzcgzg3Pnl9G^he-oy|9At){)zN8XR*7pH zbMFp24nV{4ZLJ@;?R-abd9qc&haeAdc84yfNHZ2GQ?ppVhqb%i1X{=Fuvn-y!- zz5uh;D_T+&S(R3yOvQ;C(R<@AXcFsU*Z7=TZ<^UCr{ANK)LWN~dtAD^dLc4xC;2sS zjn^(oZ|-NN2bdCGytvUo9TiAjiqp1t^f1bK{L+Hp()%jq6H#Kv*3k}5qPL80En3cN zCz0>qIG{=NVTDBBW{4bz>M*0F&&E%W-B>iv?SrZOl2t zB*GASJ;NoSj(_QT;%HNxz)yq5*^Ca8LUT+_DW`R)Z6T0ju$c}8)A9@=6_k6lrJFOH z#rT%J_gW?(NAW64&QDVPZcb3#e2?g)EWy%xKyMSH9Z)g7O;k4AgB8@j5&__YM__a5 z)lK4r#6A==e@)Rvl!Xn0X|Qy$X8vg#^JHDoMMKIb_gNYFZnvw$?OReAOJqt;cq-M- z=z@=f>a>1TorZ$pVfN?0G22p@W!oH6zv>L6L>8};oCkGyuYUyro_lMjARnj!r^(?S zO{8mqAPGFnA+i54v`EU({zYu@bW!i=a2A}qOxUHSb^4@tr2X7+<( zT{m>&;T|e;zn9rl4lN#i={3Rjr%>p8l>j&JGo>V+b?B7qV3~9XJi{ncdk-ikQ>;iUJx1)ON{>7$}I@&ux z$&4As2~lWd^+)M-KyO`ShN1DZf5W7qA_a4vrt`cl)@X_pTLItJ>6_x(n>iy_D>mS*R4WZ#5az zQp?<2dgR1WW=f4a;9LAMVYR;URSy8h4)q5fIoqyMiWO$hPSadax=EK6%yb}rg#(dy z=tSn0&_R*&j~^B$(wSP1YFdmv-Df8VZ#Sm+R#mL?Bu{(q!K4+BB0KPGB{TaBW-&b?#i8A$5In z5wNj91#Rb277?8wWiw_cDo7CzGJ3gXN6Js~t{vlfGnS9|FlYxMG<6};9KI*d(3+9K z&dEWQ!0$flnmL&wU%$mw2F{^Dbafkew)%iM=~U_Bz~xG%l{qn-vU$!fVZA;%{DL4V z-k~c*`!s0!IKgQYvV@Z<2%Y1~fz3t=mL0|&h?^AdQd)USR&*+vLLt!y~q4bm& z%*Z{#mk}Ed%4zh4lLa$7_Z3;sf(bz8JMWJ}yLVYZKRBhFjvdWK8VR-Rb4TIafvjm# zpK00=UZQJ_r`-B2oCc$;PFF8n)_%9W_jD+Y4z>dgU5~mdR&EvgghK@uA1hjC0jc%z zr2I-;s6ZBtJgLgn$nqNrbfmM3Wv~DAIp<`hhwi-`hSUc_Pca5d^?adrs7(c}TpKdj z{zZI*|3NhaZmN50GJ04Y$g%mc%G-*1;3>#paqjDGsX7-N2bwAl=6kxr%q%=NMrz8Y-Hnn?*X4nWc63P((f4nx0_1$-+3qq*DaGS+2+US6NFcG zIxxEX`-+6^(E`sEaH9z8L40|IMzA4_atjeacKaFjqJKl7xs1}f{XTWCrp`-y{ZzlCYh3NWuoAZw+6^G==lfj{Hbx9ce9U3pgpP9WFiB6ky_ zwK=d-%IkEx9_z3D0Ct$svf^0ajNj0LXn(xQYIzMRArYj~;0*?dFalSun>kw1yqio2 z>fp$V=7w2O&Ehk(7r|8Qx}0x^#CKL{g@F2rr)j9b7)U5aj|8wLyVb+478r`>(Y69_+{gF80M<5n6Uky54~#cQ!E{JajV8Ds1=g?tU*#+DUoyxg>9uXI3ZR^#4!w*$Tyal5QALI;6SaAlvC+=LlTZ%_8V5{;<626)n zxo*j*=oB3nNSO0Ol1T@7qam;nnkkp0y?j{Wa@1X0UH!~j{P4y--b%f2Ny=yeqw083 zhU<??%q0HB zUGHVBd8wPFj$gtl!o%jLXwqdipPwaq!Qk#E|In$nfaJetsylxEYs`DgBlIIpJjEB* z5w&qoAQ3@+r(-HT3H!3lpS8hu)W&yi=e9&xoitcNyRW_$yQLfQ++@-jQosyJf%JG8 z0d*;A z{2uoS#YMXR8v(zUg@%V^NRObJ;~%yimi{lQ-ZCnVu89^NJi*=FC1`MW_u%gC?iyS} zkPsX~a1ZWo!2$$#3+^s+o8)=#_uW}*7X1h4K3%73*WPuiihy!sF168`c6JdcJO0&n z{R_APSy&3~K^|f+osEQ!Mrn0@2j16E2yf4nrQ9Hqs7k=Sjvg(3b(+AR8xc=DlN`u& zs0HNIhRrXq&%X&)OTRD9G83r78wQ>k`0t(P0PI4e`ybn!C$}gDdZm4}a2q@Ul8!VnMj>F}ALQ?`VJ7=Elg(dB8(bafnh+^3SSxKM#GkI942E`^Yi;Af} zez?>J2*&qijZU`MrUj1F!*AP#x-hd0-h8^|i4!P06d+H+g{S5j$j;-+{ z$CyH~1;>XfDZ^&4ga6^wBhZ_q$~MEJ-o2!uR@I|SouY#-PG0GtAHfn!Zk&ec6;t}Z z;3?ccKO98_C}Dq|7_-MLAxv<$Mf#hufOdjkSF4M9TQ0fMH^!Wabg6e@mvC=&mEJb) z)vVvYnl%rOsvY+ulG>x#1pRqy;oGKY$yzQx)`9b9+JCN@_ckHXCd^^$9FPy&z zxWQ~h$MT?2p%ve>j>o&un49*OQroNZ#&*kv!icBt+z#+n0f74kv7*M9Pj8pgKR-P3 zbyk2MI@aEKjnT%NRU$K8r%06kbtJVE>p%>wemj<2?HhCaDO8m$-Cy3nkWlw)G*Ca! zFj0w2Who{bmI@AL@tbzx_fdYOE&4{7(&I6lAgTqEO@qvNkgn@}Rw}sY1qddUQ=RwE z2DJ140191Nn6BX2gW<2!j_WM8*qyoKvMZnKDZ_vWgGR8;^QqxWNYB)L;;26}e?e9S zkcf=7FiBf05t~!zryho;f3il5EsYPR5cA10{hY*=tQKElL|N;QHpxEH+j7 z^}pIKDQ2bB@9Eu$V1LLyx!J`0sK987>*DT7>$PnMymQNV+Iq{3q_JzjQ6w3O!qZT3 zRV{;(=Y8O-%`RJX9aY8r<0yyAD--vBFc8Ht^KfFt%ar^u(_WK1|5%{%e4MqWH_s^_ z^KzycsDIjYp4v7sweq`U0(=uVRn+kS15_m#NBSDvc`v}}$@eDKLVJ-?g)W5Z{T}%G zUlCICIVat#0le4jad>Q?LEa_Y+IRT8;ewfmFI+q8vvXjlYG%ZL$o;qlm-2Moh*eVB zZ-If=T(O)9rL0wmT+Kc+*KuW;MOo5e{4$Z9y~2=UFUh1I|F=Un;p2}7#JU|?sIg9Ci5%o6B&|Xd|5$orSI7N82$fh z0S>i!amRg@7sdbaT=%4Z?IG$TI#A^G)s`>YPh|Ip5Kv+zmU2|lf0`6LHr8CHes0~V z+C5Zj`tvfhHjBHg?)K))TA411Bn$L# zd@DQXcLYXwL_|}6hKi|aXp&|1v$qkUAqfQ6YYm{@g;iRYR5DhXjiQw+>@?jQo+#ev z&-|I$?ztIjy|MKjJ;-rvx0xgMfAH@tjAcvu79L$XI`DK@aJ#SUm_WII%+)3tc#*v} z40aGpnWt-*nfzAu&jD_mjwFULlJBZzd=3(l(}JV6pTdtP^~6 zcKI;ACG?rn-tlm9&Le==mgvJ5Dcdb{khgq1bHj`%!MRvQr>z0((V`5**7mV=i{JMBuXl0E`ko_6#u z(NAy&tu0<8rtwoQIcE~lnDO{Bqob1=W2sspVCq;Q6k-bMNb16yW9q=0r?A0?v54U+ zkV4ho8jLFvI`TA_d&~S5Tq8lQjjNzoNKIhedC|wg;q_T_9jA~Y{?&ZlhRlC^A8~in zl^x`Yk|hx5yXu9;{PL7tjne!^k&B-be3&-EPEQ*rgRb#!m^o!U1P(bld47y|T$yDL zV{|P%ElM_ORzYlB2sML3ests_4hJbw{3S=wP`~SS!}D3}aIhwW{bC;#$X$_Ck#XNT zN_1r3jr?>H;%KE61rCKcXsbuUI!rY9Q^BCo%hM=}msR}Q^Q?_~>qcr{pEzzDp7ext zM7Pz)sV~S|Vc;UXxJj!X3ZfhRpu*CN*7cEoG^4lmMlB6LzKux3B*S;Dyi5cnj6rno zhszUXJLVDbcs9&>fUmBIODTWgA93_6t;X22E2*bUaET z;eNE{DPUm{z>rNRq#2E_xxO3vS2 zSE2g1GTm<{H1}RFXN);sgfbT@)Rs_SG7E@M@o;o$+lFUk#Zg$gJW6N4ghdFY$8Z~8 zD4vVvZ1oVElxR)A?U z98Ko~B&=P(AU5!g-Zpe3Z&Pk>Bc9A`O<5Fm2Yml|+O(vKqONoL!h8QgOZ}v^LZdVh zmtZb*_TzY`ray$MKO@MNyi26yKHtMHf>jK zKXEX`UH1>|JDXeNw!0k~r=~1gZpWSvIc*V^j$m~wVl|XA9Y|=s2bOiwzfa$e0LAor zffEdivwkHTXkc!Pmt1rqu~+;7BUd&)Hii-Nh239ugSITZs2l78SE>)Uf$#aY&G{FT z_pfyu9UFPN({u-U@wG;a**R{%Kcw>17y<5cRjf{D>zuA_4qU`OXP)yd=5?onDLQdv zp%KD3MWLi18YRMr{$H3c+#c^xIy(;2yns&lXgTw|%0}#*5oELUShclvt$V@l=uqzj zEaxXhhKBLx_n&9AVW)y(Mt`9;K&0`Ojd}7hvX-b@QDj!EbP~8ULpB;Vyx|&e!@N)w ztZWH~ZR@ZobbS2nt+`n`{QhaY)1=3&iQl2^tX~Qgv{ICi*P|LY(|4vfKw|`#)&Uzu zPX=rca&ma&|1Ai98c6s70smkn0%|;JlVERV)ant>NWf(r3=N@t%!4?%Jp2pGT_jE} zeEZBwLj)(-UboR`rEv`eV(Q!+@ql7-Y`+SK!128fy+jXLAC}hoqjVm_g)J0xeUm6YhjvS8+zY+O`!q9DUJiO zT7T6SQrQPm9Q=MH@r3*1GNtRyPt4By6)Iz(Z=1NB`ihA}2uA2DN0r>5muD}&7C{9l z=!l&nfZNoe%fIp~JJK5Qa$H-8pD=2*$%MzUAb5mnb_xT!h``~KFf+*N;quh&?;0HF z<2t>rMzoUwM6s(ZiGvDenpi-KvRgbg1>QvyZ4^B@d^|4)L?tCr=InLAUa<#Bu`vIZ-REg(w=aSohs@Z1HkrwP=z{5*^KIAyhS?%}qdwkHGr4B{Y2su+Vndpf zqCG-oCdO<+4t(LN%*q@ozEd!%a5Epuxb{{d1AI^~!u+x@ zyWy}30@e=o_TFCaes%A@OYfIY!9ZJVu?l2A;|skP?W4tJD3G$A-f~`0OkRJIhRSmg@-CvjXqDMbi;`cIP%JoN?b|n z_8o;J_{XIbzVR=M#S+ z`@gPoYbpQLTcA~Tz(F!a!@o}+oQNKe8j%l{FGwmT&yQE3>K9ERgwsp`#|V`^dpjvi zgykwrYvE0Mqstyl!H2^9_asGRl&A-w*C zcJ+l}Z}Ktn&WECb9G@~Pl2LxEvS+wKGRKusMo18}?F8nxd{k0kWlD6e-geI>{#pKisr&YCZmk&IE)0O{T`yD(Y zU%gO%XVJTxYjgJMHjB&I-go_iO8Rj1AfmzDjq&d%s5uO!Z7S(9n*{a{V8jA@g4^?de}9ulGcaCA{CzTbo#; zqQqQrGPw$@-+=kVi3@`*gq^y@|N0JcI@Z6T1+)9Whjf{|kuR6mN$u5fq_5}}&wT*w zBkLQ6eyMZ~n48qOtDnj#J>SWqqAFt8OjKQ+%8U(9O%?{2F7rviNLcx?^QB7je9iM^ zYbib^rgvFx&-i3n4h@F{C1EhsbTEFS42!|(NQ<~!gW=`=N$70s>#Wz#nqz}@!_Z`Y zovbez7HdiPuKDiB=qMRR8>-n@7TLgde1GFwISi=n@r19*ZPjnefvuYbf7myB^56w_&iVc5aL_p0f{pYMiy89|BoIC{6#tTifA6%Er# zSCh1Sx3?vOhsQ1gsxIo$%>9@glydp9k$*qD;f_)0fTc-P!!};+sS)!-q-#Er7jPo# zK27(_q@#h2*xA{C zw5}Da6r6w7b?DzNnSLT}HE*Kgv>&Evq{SVlsiAXsl& zOC77S-3JYuu>&51T3$To$nI)*$gZ(0_Dkw0IT5ehT5)Da@tRNHX;WQ3=MyB8f1R#pXV%D{eK^EZrN&9T>t=#9xMBP$rU$??>87?$K~nI zt}ZJu5Nr9oZpo-|spe=afyMe4ruL-`}s+ z0xEGoXj_*B$;B#0Je~xC0>Mk~omy9%xC!sv7HD3-AW*t|_}xe7KcBCpCx(PIGz<}O zSwJ7YD@HI0R<2y)>As7>#J~szI@sSszLN|^+uxVOjm49ele5KmB7>*&`2zSsb#;Wl z@LJHZNC7t!O5Y9fz+MB?HPz!s$jBYBvGC06-UfAVsbin8&s99i0V!P5OinqtA8BQe zdF6c0GB*ne8nJzsG&hNnnNlAlM+w9Hne6M|;7Cq>P}sAF#q+xK?$Syhb=B_s6Epgm zk&CB4OAJQ&5GYu%Ez?9l$1^DIimB+LD77ipe$6z5C*HqugsJE^5JS8UN zuO{Kl7~@K{U@=;4yZ_Q?LmFYqc03^X&Z?`XQax6FBP0H03{_VqF{BI2^+HiD1#ymofd zKp-Xl7h1t5uV!Xp@}X@O+&J2Iv_MT(hWwwU&OqfsSWqY{kyHXFqnsr@^WfR10-ZSK zmIwT+!#NVL--b6J!Ty+K6AdBF9WW7z>kp~3%wYb?kRmIe$&TjQYpnuwW+8bwk-dEx2 zai@h`gaE$xD0I}N)-*B$H;j7p|ImUT+d;0(GU~pMcTa>*>9CeG?AkGtfdGN^f9RA} z11HQ3KH$*dnKgMF$kT3bLJY0;xEnkC@zcyR}J z+uKrnFr~$+ILU;nG@O>5ecwlGA{oLVVU6daplBmKiNRPsXtp;J2pl`1>K0-J_&jrSt3l?4 zg)AxQ%KG-<&5MX>)B72x9<4R@huDOIZf^qpZ%%QumY&+pt(*lvmposhxl3FPy%b~U zelITPEe8sLot|eFv}#-#2v5GB)>Y8N8|{bJ-<==DKfm*~J(kU^;(Tmi9wkbkjr%^< zw%tUzcDz~Im8D&3V|#WSEI?FBrDmbe2K%U#1C+0=HWCPZZ3p2!bQvF+FL9bIq`HHG zWnQo96`|B7e5|@_5pJIq^J(#7?93;sR4bE_UE^+kTizliW&<#_QCpyeGvYJvUELY=q%AY%|S&wEo zk1D<|7Cf&I>*Lk#t7_kj8QXKmq`*HZ*nMiGKmgE>^H z{nF&-7oX+2KMx*zMbwmc4mnJWBF;PBQ>NgUwrFeleKHsk~X zRew!g&^q{Ah#staP$Edhv5+%b$aBX60keMxU46Q57qSgKFh{C1LFnNPpQjxh$jtJ# zmjT%KFRfQl%eP&pPSZ*b-3nZ5(T{<*q#6P3uycC8L_yzUYQcUlJgXD|HA2t9RQxB(0b?|lx{+$20D$-|FAA_GysB#R@OL|hUSOqeOL5)sjMv6dKLb} zLs}e^w^x#L3K?NhV&RP~j6ae|gw97sl*qg?dRW-f2?N_+ zu*D7U(y#ru;PyZ`0jo^{4*cg+e8ts2j`2+@%le-k+hg6~Zbd89+;8&SqePhoCv-ms z-emHI=d|CkkAIb2$_i{NM!jvnCohjvAfo{y&TcF&g-k`>IxSY)sZP(PxkX zk;+9pA?zgP1Mr(}UA&k!96xjzk39IGMS>>t-=_6C+^&p|94vK9%~J}pqCvqT_oPo3 zO)48EP)H#^9{fL0{iDTjZuybjvQsb0`9mid26T6mQU9gWD9>@(iha|~-+!8CR3XxK ziZO&1(_{egK)Hh%9>qPt69N8`iu-j2stI*-rL2ODp= z1ovw?Ogj^VY#5~Fh^$jX8}x3=;%~U5VW-131_0E6vm9V?-?NzBN!yLv>gXJs$)E*X zBn+}z53!h06Bt<+_oiQ{VtyI%%hEk*_j#NB>}LIk#0wR`R-rrv118UT{-B`Ek;|s% zup*<$L)Q68IREL`YAu39LxT|0usy%Wl4Mza|4ZiFn5g|vEqo*9l@UdGDsGDMC&GY3 z`uo-n2n~!$fvad?&Zsn|PrCNX+i8*GDup$^2w`0AKKXx|HqAQ3Q`qZ#=6eduqGMv# z-2i1}`uoHgiG%e+x-W=+t=k^7=h>KWer5s7J)}d5UR;ysotSl1l;P0pKes$z`dPktA$Cj(WwZUdtlDKRRbvCYLMK!zbvZ=t;rcYn zg|8oPou^E3PHbA}>{R%l`Dgbb|7GIPio3DA6lv)c?;Y(?KrR*drQfuG)jl9TNEV-0 zyhCvrKE%&`M<2>3*AgSfnTBW;81@GKb%5Hb2QYq9`7sus1E0D52|j5Wkp(x_egG-! zO|0Mf4vv%ln?*B=8wed}ZJ>Vo^u}`((LG#s;R!oPcE!)R)f_IZ7Mbb&3|l0H=8qE# zvb52&Jt;7BL~roNKJlL!TqJA~PDIS~x*v6ZsHjv7=)mfYj4b{>bmD$ZL2KE7{F5y? zW5kFpUD<(NOj{ez!2cM@%-j-A9Zo-UyTz(6mKgf5dpclmUamBESoU*u>7+7{_zz4F`qnB=bHI>>t zkE>)dC9|)a+=7U!Kw)i{c@Z&Ly;E&Z6RQHPp{vZEPvV`XjC}dfIu}yZUNuLbmCk^n z6Za>N#xcmOp!IY1Dn8449khaJ7=24QgQ_`C-3pr%)x^x?$UlFq04y}4^{%*H3pIy! zwWhdzQElY6Bdb+@KCAfwyPZ}iG6yz7gZ)Z~^?OSg_vNt+&IgAC0-=uCFE#zO(n}2v z!TqW$^j$!|TJZ#XwiF=qhUizs1@gmlPTmc6buoLy31s(@sHi6JBGuh72iLlnF~oRk zT7F9&a%zi@xHZR+tc=(iCe*{XZ*IIpdFo|=sK>S0VVl~erXSW5?V^Q`pZIM$&#@E@ z?_pcRl}qq4dd+lyYg1zIx%u*<%xP~&6DHeBL`aM`yX{&LB-}n5{lT1ywo#3OiV3K3 z7-pfQ7Abkt+4$j@DrFNR8NN>umtKMO-_q-&22>5b=DX6#V;EkF(#^|>Ids@r`LgC+ zVdSB_9LimVZ@%zp15G|Nq+p3~a*ltLd?*qtQR_MO*y@YI@Y<{3at1=D$SzcvY@6h>ntC5@$`lpPn>)| z8|#L8WOX0-sW`i1jpk&%&@GWT%<3c01e`~Q2hG>p((E#8;m)wy+Gcc;%-{n~>i%-i zwD$o(af2kjm=iC@Jh8-l<6t1I^{c+pFV{O40tx2``U9ar7cStJuAl$y=~~3|<89RM zVrAOIq$GIL7BopyUUc+3z9`6P#GgUb@3G>O;5%IjB~pwDobKcGsC&)P|gU#VI+OS?OEG7pQbeD&B~{ltD3P0KjL8^E{PpUm~UJ+pf86VD&rXxt9(xb*os-p8$e zU$wbjiT`br_r@jalk_*m_y~0~Jp+9xi9(p{)qL5lszOj%etUn1!~6y5WN zx1B%O0*UG17eQBSpl5VMdAS`W4Go1#RfHgG&Fn9cmv4A+iNj{7&=A0j&~jM;SVff+ z-H@RixxKN$-h?N#uct5))CylW5t@z`>RP8E(%L8@{2RA6H+A9^vf27^oEDl*eJ3H( zuy8_XL6eP+9vSC=1(^2q$;`Lg(g2(fFy5M2&wGdbXSM)bS}ZH2cBA0dwy z>Zs5&G%!U07)31^O7rsY&csyLGr_7E8gr7f>(^Bd+Q8L!aMAbgFzxKyb@8;k7$U+Fto}Iz8Fn6dfASFbym_oWk%nUc>RzYJXTapLx>>;XE{EW z=$`Z?8&mjJ=M#Td6-_A)9aTN`jIPZU{}mK7*6SpvDR6a0QLR%k-{^?~0(SU%prPNY zMYe2(Bw%5QDYH1AX_UH;cwCqCnWO;ba6xF_43gv;jb55spHFoY#MsOgDW-m<yGT?*CX-B| z5NSYM2>*_Ipi;WcJr$D`9inRV^k(>=rj?RUy)Rl$x-W*gJ;Z!ea3I|MFfq*&npkP+ zdR0%6=3*jS;$@+3zR6hN<)zWm=^06=Pu~;VqOjg)B_FY12MdbD7l0Lu*zNk_Al|}C z1Y3Y+J#fXDCG)huR3-Ea5jK;VSxQ9(4H#hfLGLk?fcFZQ%Te#N)qf|yAJwelkmFmC zsk{Rd^3mEWT`5Hz@MhxWnJ1P|;QPuJk-*o8h`?J=X(`ZUsW)6dgmr76kxw&Eb)%#x zr(24oBZ0$KV+)ufa6JBb*zC_*ASl487fGw_&Zd)$SV0XF+n||t-IN+WY`&z|SbHCQ z+t|7aYw67~0}BgXeCwRafWj@swS)flf1(x=tlsN-l1Gj)+BZoUmxL{=?gfU(!@4I` zs;31x)xS&%K3SZ*E7PfGErPAOd6G4v0z*=JLg{Pl2jf%C!pwo??nCI>fMrK}IjF21 z*=*HUx0W6)n zko+D|!@K?+myOWdH8E@Jw=WlcAC!x~1_}af;Pws?1W3<+tX_oqerv+M@flG`=o%Wd zUax7`9jjfJn3;(`)A1^n0W;j8a;Jz=Yw1Y#l?W^a}>OE z9I}qJe(m!qJv~aLz%?%hrK-{p^WN=)RIWoWnOAun09_Eq->-|d$In?vnaULY$t=#( zp1k6U9{&#sE08}iDg#(9KPF~{0hGwJolnaa6<>y7N;X7cdXJg063!@vVhUhIV2Ka? zm&EkYt}&aL-~ohZ&|0_RoIVXBvG480_KUKtWD3EGl27;c49BRXycD^~QMR!85F!nG z6CIt!MxIGBZrJ|)t{boOyVEzTUe9aXUPeM7qv-)8Ap4`()#IJun)s4^(rV8Z1ujP% zNYT`f117MVZiQb1?!@azDX<4aNighA{5<9WYiFkk%yrvkQx6H+9qUB2whs5$8=#_G zzYpw)HC#S_ucpBXa}iH05M3aZ@F4KgGg{RJetr?Ls#g&aN-Zz%7#cYsxbn*VJtgsYgQJC`L+Tqktx5 zlxNEuIF+xofR-s(-)?g{t_Y(?$b`d5C^&h->dRLz8+NVKxxJJ+Oiocfqh8vl#V!95 ziW9x*A_K*w7}aZ^HI)LAbIjKOs;oWV8F(MN^Iy(j+^wY<0{!bM4Q6@QP3(}Hk~2i7 zXZN}zUV;j|y^G7syI%Z#ou}jE&K}o8q#$Q4I{4C0%A~7JN9%Xt#->7ytYvS z(FG#N1c*k3z~}(r8UVlC3LUN1*Uh>p*wo_}NG1&QMSW%o_+^Gj$W2R`5Le6CzbC{DCSD272aq#w z*L&bJ>#a^xUGa{9AaJ~+evGQf5IF#c>tMC$%YF`ZcR2`6+^)EcDxJ@cV4ZpK&)1mp z@hj2*nJ=iz%Ff`T8#6yBhDi`P(EEb!>HJfKinewzAWx$R-1){5a=ePJY(!873PBETYN4QS(`o9>84#f#0DDM+IM@tnf=D z6FfYRTb*QYtxE)$hl%URQehH#IJuIETAvdXc`q-6>s^{Vj!J3M*aJRuXA&UWZ`EL{%D zi_4g=r=HKW(z$O=*f+~82Ab0K*bA%#Q&I8k_kgcKLED(mVaJus3Rk;_Re9C9pzCXQ zuZsxjf3tbQa937rL_F_aOGDtgI4Ws)ImpYfGv*gjN+NlEeh@IRd$N zzFRC;?GB6qcC%(3DJ=tmwCSw>SXy;}903| z1*$e1;D5S^F5AF@Zfm)C@7H1ao8n(u_C@4=7#3SOYI8$Kl!Rks~y?~Y4eX({?}i8WaT z-}^e0m%F_|V790v!LkENGQfk`U_oo&1vsKzYfPEKiM5_m9+5*prWF#$C&^l|eRy?a zGF$1YU5wd2b7O=sVR?Ijx35|yAp5}nZ`(=_nr*K4m;0TKbiX^_!O@F80<;CaBK;mm~><#S<1SJUFv(Mn95c4=8su;!BGz0~s=k{qDXfli) zo3)J)QZDoZrBmCFNKH27kD&M7g)ti!$54Nq3})bmTEf`nk4d+$=~z9(3=k$(5wB{ zI=jTlktisr*+))Cyc~=j90~|!nfwyG7!I3B%P_F`+^Vdj4gu2gbV7mdjuCn~`(2IL zJmju(ehwe=$4hEx!uLc$WDio zoQoeMaq|XtEFO2$Y-SWsuk%)H^WE*7;e(BSpcM(Mh1tgU^fZsVOaTQfhL=;iQ=`4) zQ^aNDm2YJ41gJP5`P%>m9b=egEFwMa;zW$$R5X z%4OeEe?Y8!j+wuGx(RqXxkVw9EIO>LjVgwtG~gs|=-pelwz>k8Mr{PDGsExU+TWdvrgHlqdmt(ea3BWi6ugzO)lLYn^&dYcvLaEqDqw(S44rc9 z>zht3I_^^1iF_qudwj`(1D?7hI0>yd`V73_?+cfHd1#;^h9MlJCObhNR1gbk0m_Tt zmeLeW;iX*B5uZCGK?2ZHbjZww|D_4bD(9Sb2E-RtEUEHdK@*y(5TJquBAW{$D79JzqJ>YJf?Q&bwD7 zoUVwl6p{&eq28A`M!%Bj@&~66uUFLR(XPMIGNNNEe)L|DoU(5COr_l4FHDTXGs>xY zy2YLj#iRfYdW%3KtNdT(z^%zYDh2WlDJLhNYZ*~(Dw1MKU$8VCKZ*2bq7~jeKWEd-& z*JtS1fkF3HAA!5A!=Z+qBvPxdQlo16o~m znUvfB=QPCEbTnZq^x_?{yO%Y38>SoLu6^>6DMFV}5obJ=!%!=o!%t25vA=)7#O+4d zPRJP=RPAyLxSOUSQ}&=vV0|4^V5FlFhMPCHzNR)u#l%SX`CTS)IXjOHlKc)>jpn7B zH4-oFo}V^HRbfu?+A*6~1h8V`8qWzY!x4>KE>RL4;3jISvuK0Yu>#3*hdD_d94f{C zDST+|%>R2VxxbH9W{pauDK23F2yNK$8L=4sFhF~;M~?;qCmuun6`QEMu&tINsYb6qaz)eT>VFPyET9GGffzUsVz2$By^{s^r$8_jHdonA07c=?aMo zU=e$UH_7L-;&bCOFv~(!r>@hW!m##Q{SZL_R;yk(j{I#S=E7exG_yHzJyT5kO`e!W zg(FC+_B|RJ&_7F4DY!0|kSWFsH1E@f>TC)JWz#_eXhze|2L!?|)!b_NXpP^+53JQ=XEDg$sV|G$L;16kPgnNz+MGL@06- zB@LxVY2|55RJ6@%;&9?@m;=Xe7Q`l6NWE_}yo6TC#n{3R4vOO9(4?|4eYW58HigQ> zi@fcSwGyz%Ev`UO@CDKo?7T(-I;c+B(q%?c40X1@v5D5+Ew-|9??YL7!L0!!e!H&+HH+4aa}G5COmr9_@uD_mdr50V5W6 zdi6PCP>_|v-oZmhKnWuxV@MF!sW<8Y>I@Fkw$Aw={Z0EXBK}XA?GA}JEX!o^2B_O3b*$E{Gz!@E z;kG@+Jibj&?>?vAX^+Aq;ZB z>D^@UzUJk2+hMuzV4iHn!&9rT%`$0a3szJXHU^Sfe1 z8Hl|F_=#Q>Ju(pq%(r%f@EhgjNZia8SEPMoV=1}+?leF9e_ZJqJi5WG2XvEBRSWk^ z-%nW%fRZKvk-jkib{Ij~&GA{>1j&0e7w^3e>>}A1|3-5*9?7d?9H$)nL1eMBhtu+D z{cRT>3q7`x#^>=C^)s(_k>kgw5pys19hbHi7asWWG*8W_6~#QvwwmA4RLKqC1U`)5xY6- z`Tv!Vox1zqiuUbb6Q$BIXA807#Ah9~J})#Nal4$zUuwl5GZUqtVjQ+IzA?bm$i~Ss z)cz2P)A96e)?YEDER>-L9 zj_Chx)M-#t;ME^|67KmZmm70ktLVY_R?1a!N7Ua~=KH||@7go4RsMWV`n|t}Ja)8X z^VmEg^l@x;-XdEQ^=$Tp=x#wysbJN@o^ma6hrZS3FA zF}wjlI5RPL-G0p<@OPpbr6Nf>trEF=ZA(-NM4&H@zycHfpm-!Z9~lm&fvhHG2zeig zOyuTVlfxuts^T=NMYZNempuG-MejdcH*wji#s7L8hD68L1g!&GR5yC@v0%Q~N}fOv z{Sf8Y);(}^oGFWymIA|C#wWAN;X(YirpLAEW>|{FeO?;(^HnwHqKcM!e8>fxVKp@q zCpO)AR7WLkj^h$^#B>-d6s++;=_58-6s)`ThXnix)VW0M`rWjxiAh-9DJ=2qsEpc#A zYXYV8?hpmUC=akPjCI`a`2VrCEt(3WX^{6_ufyfJ4r3_7cF z>F`jI%{yqXP3o6KUu0x4j!csuIe(momS@%*?m3_GHz9)v3Kr4ODJqWUd@6`i*6PZx z7&re8^2mh~N+5ebz$B4x857^K3iE5&B3&XON_` zIRnX7K(S{lCypsox~h$|RMV5YD{1~+n2)k9gCXCb_c)lNO8DwDDs|H$L9(YOYDEt- ztl%_cb`>E<_ROp8%%>e7_ndeMS-w+Vn|Z%JfOwWgX?eI#fic|Qb8^z8)*7Uf!(Vcc zo15mf^w0@nebTboPQzfn_@bFkJFjs7tR&b~y$+$AH=AD8QJhoA@7 z!N<`=Lyp_OEBQFMFM33^fO_XkneR<-WW}umQW7&&zTC2iHEDWPY$GF?bbehk(7d`s z2Z|jMceb#*g*L>dNeSxp4+cHv`G8@0%02HxiX)A|+f>%&!@Bz_cH7o@x~k87&{KCW zUh$;=;}qktOG~N8Q<72k-_B^iQ)GDE`0kPGmfD%SZ-GD9FL4%Gg+g5n={NB)F@)rT zhWua_IvtU&kx~4L>N(`=X=P)c$0;2*gKcXwThiBpCP<`+aYzRx;AZz?MK-Yz8~^gN zQ~h!Os55EO4MX=3S-+G~VVuV(^0;-RvrJ9dMz(i`>wv?F*v{Cau=ts~PTk61O*|ga zUft#!LoPD}4bfm4R-HwU5ujxCgue{%Bo10BcXBWn-^W?XpUrTR`&f|-&G^YN6MEZ} zS7*ON_K_h6Nw@g$niL@(4*W;P^uQS+{eu|k@*vW&6#FU-{`F0Fpl|{Qr%Jj@LK*JO z$FMJ%Zvm80oz&z-k2$3?Q@%nl<7a7(wCt`Sj_T+zaN zeXVFJcgFu^snU2(!Kx4<1>rw8>^$eU%(}vuh)sa$X~NhhtMig8Zcy<&ba%bm<)*cfO9-5XP8mW((R^b?+hKp zo*UY7Z(Wl$y0x`K{{-(V6I`!ok-?ZuFiUOme2BP}(_x3H0i2!Kf6ngH|74onq$cK^ z+!!pP+xeA5V1h_&UwK@dm*+FSpRW@a;JEW$vEZoydM_x$l383wHAx&Re1LDwFYYgo zf;jXiwDH8dI)dRK3pzs1Z5e~c9u6l(4@7zL2XI1pX zA=2CIgJKF7>yy<-QvUEa-n4I)qUO-NlnK$qDGC`dA^#Ox`Gj@^jX<9$d3) zx^NzMJU&(z&ew!~ayxbt?r*e;`uk=>x;2$vT`ZdLLFK8d2k!rB0gzUq&&@sC zf|(v7^0+jrx*iEM8k+;X)?RRvrf_7Oos}6%+^-(;q8HE!`5j`v4ZK^uPj zg^f56B0guqriYU)DPPQJ88h>uSQdIob>0Bl1*JX*7C?%5h?&3MDuDH3{*wrDlkZ9! z5{og2Zr!Rmd>wBW=M2{i6xM#UIPOMH-OcXI-Rt`lSLQ+F*ewO^EOF*dO}zolyI;`0 zbUZ;ly*!Y3`i@Z|RVh3*Gf~RmIDKmQ40s?Jnt*QT|HIW+0M(T(UE>6TyL*5HcZUQE zPJje=m*B1!cXubj-QArK+}+(BF8-g)%zNLwpSnO56vaKgyL+!*t9Nfxc;n7$efV^0 z`=DE3uMh=-GMiQD$7vc=lk$}8H*F$*4&+K)m2NeKsiJ3tKod&62`bvyO%ct1a=>=n z!iw+sl-QrVtT2~R4y~zeHkwyx`Ei==>=B@B$gD1z%|Z{1-Q`FIpkG~^W<0q@)1&xs z7z62pcXZ_va5h%wbO4mP-*T4O$F;s##3rI`LF)<&X?mgfX|$Zp(iK*fljxd{-gKsN z^-gKW`{<_oz^?1SrZaici#zL&ixf7neNz@GoA5qU z{3}1dNf2(fcil7~H=TYNute#kR9MU>TsU^(ukk4Qb0lK@#lpHfBS{DQYa=WKoQdJa zf`%7DKz5Vs=I^#8;3*0RjaUKtat$<{*zi-q!&gutRhV)7*Zl%4pwE8-00HyUp}8r1 zzOy+fsEEMPUB26GU8bNVT9ch$n_G%bq2UOoH0X+t*eYa%7-ENDj$^*^_wxwu))C@i*YKW8&BWW`r8VufqAM2;5DJqC5o zV7$>oH|~<7iNbFp2Gb&z68`+DL%5LM1^tMhT{+V8&EKq!2G!3T3`(dnlPvyJBQFKk z2l&|E?E9y=@yk$NTjPo3gvfgwo2o$PKU53-T6-1X4kM{^2U}W#R-sJ5M2;hrlYz1% z#_t?7Ot19Av-$FHgmKq+>F8j6iHtf(_)Gc6`hsmus078GC8s8>c`yF41_4hntkigeod z!W;LjRH6eE@5m7_;rDc(#`U54u5b`eawi3C}b>eKyKrNPfx(%9aIJ;AupbcS z@)Qj&{yQ^Lc>f*I!9NqZxz;78!d_So%43UaPp_(p7 z6Y;w|kD!g$hRcL9wvVJYaFuqqD*EfoWDdB&iCw&CG)6fPmQ`AfbsKWh`axD+PI*1DBb3jrq9SHj=73s(Oj-+@S=GS!0Jx+GRDoRol&ggIT#-mbl9^>WG ziQp_gIM$dQ{=XA*p*_Xb%zGexOo&NPCf$0NeCI^M#dn?y+@<&=&tp@5)A#czfAnzj zVw)8oCp>LF&%j>_AT6FwJ6?T9R_o+xpk*_x1Xo*8tV`7(qXrmw8S3ZE5?}LgFIpte~T7O=AU$?pvoquf%T@t~sF1=D=$4W|kDAlo#_t z^Z}=%KITRFeRz)(>OUVny+p~c-AIpoo_w@kJMC<4MgwwC3Zk^?H>Jhs0UwF{2}RNA zp$mpD*=I2bP|J15=hF)tmX%!wmi}|Q-gBq^>o#3S4k9+L5TCr)Z`e;Lwd zv|TSdwYt1|nlN+BDVyqVOk)`L5lS_dWeM}lQhFA+wh;+xpq`3QqZ@qX!EYMrD7cp% zrHLfGS2o5amoZ$X&=7Vev?#loaqVD;X`Jj2 z9?n+^#a1s55jkH!xhD}h50M;uuZUcw5=p@kU*o~;0}tUhUc!*G5xoOGjLp9e@u}dqC8&l;BNr_}7_%b>pgi7uHeha)Q zUN{aH->N2MDLV}4LF&nF8S@Ji-U$=NVXntCcRrCNx3b9E-feCtHs=@cvd{q`K2)cA zbNE;~2>;yz4^_$to8Vk~Bs723!Oi$wQYlZw5@Q=;4|-SRZ(n^zK{Mi{Ob3F7*Av0! zhew;H0r0M8#}?_@3yYi9u`rqaAg-RU0<#dGct$vzDfUNgX++=+$>^j?i<>dF*K3Qf zIx#pCE*x6qt^DH`8n{FIgC(@y(VL=Ud{X}Iy4)*nrOgVhw9e|3Ikn?z0$ zk*vXFt;5#=Nwk~3vNVMf4v#}$>86)qdj-tfX*TKYmpC`A1({A@Y?lhgE5 zfmqH|_N3_-Gmak$If^A8%Y*~WJwB#p6Q!rS+qji;ePl+X+P}&Hd#vALp1UA4d%`S} z_!?Yc8s0N|%JGI+6ie_oA=aiQYbyQYXuWzEHs}NIKxbs9ZNx6O&g%u zmxE_8J*J5W0~PLyvIZWM9SSz!vOn95liTR88RaXsZ*A)dY_ny8P>)Eg0DXV386r1o zy4Q5>Z{n}LaE0Lf?q%@_PV;N1uZb?zaclfXJ-OirNM@2WIuYRgatE4D#!5EXAiu{g z@4D%-5^p%|Z`VW;bCcS-!MWRRQfx`L9RaWI9Z~vVDDtabSBlX}0qyV%{F#7rZ{6Zyk z%gSgZ@r}nl-K)5=+;?kpP%=wDDHVruJY7`w@FBcciK#voFZiu-;J&>1$ zeD&m?h4lXj#i$Rd1nU>hlWIH5wOMQ}e9><*_)`@T2%hD3_`O>J2&%6*v0t=8i}FQR zzoQEWbGsZC(cEWct>Hhoxwr(sKF(Nw`FcT^7mc>1;{3@k@}mMuDzlQNho{K?70xUS zR+)0xr;>p!Qc~wN9&WU~$lcL{8Jy~=si+5j*^HB)CzHpTZb5K4yo`PE!P+G~N2H*W zT~jM{8_1-O{)FB>v8{NHta1f#W$N7wfcqQE#l?wBjY{Tf+F)cppEMFhG@gur1I0I2 z)HV07Sea+yb&DCr(%i2rlKxpp;b8`Z#$eciwie{M`Zn&9M_jSOcj;AHW#K30d9NW{ z%-^sL)YSrAcUZ9!me-hzY3Bkg^q+o*Z>US?%|>`5)bRg_m9zpHP6$(Nds?RnvuQ zyfp@ju`ht-&`{G?IltkLYq|yIx#A`6b{Q3HS|0LqE7UuByx-YMuHw(~4;7Xf3Iirx z^tTZIo!tG=^Z>Sm{*8~1UOMTq-nHKfE2}d>d7!Z-^2oK&J^;NZY3)?R(hadR?;sD7GCpCyAgkAgG*3`CP4lW0avFE`vE)X z^z-}Q;8)sEUyL`tLf#l}(5@f4j%e1eel|YC@N4^8oweSQI=JJzwq(XM9I+(s#JWt{ z$&}FT-T?oz3XRy*vR}_xw`OLea>?xbvOF2uo0E#Ab_To7opqR`(BD$CnXQqePjk+; zO`6MIkEr)6XRl}td7&87AF?&*jjdoVYY?bY6{2_x7{6e72#D-gM+vH;OV0#I7cDi= zTsw+rTq(e7lDORPJbdo&X-f#nTV1<-+kkXXBw=m7NN;_5N4SDZowxn#ghyJ@=OghLv`@h*~|I}rQqBW%LiY2EB7v%$ht297-h zVXFi9h9Ev|3~jo5XPhgg@Fv{#O=ByJmH~|T3XFLFc~s=ceckdSug%%f$GhdnWVs@W z`*?zT!&o4LUb^rfFDuBmt^AoRbXv*A&CG1+si(KSBi5?Tv;t3KyS=kxzY2?c`D8zK zd7AG$-)>14C2&hSr|I02E)bL=5#B@Bs_Tk=Xo);^ddJx7Ep0pKU-5doTas?3#&LAz zhYsI`-6#RIVF!kCjLwsa(_;HzEoZ|GhdJ=ygFp#xxb^w>1GtkjVmscwKEv3 zs;dUpUG`ue>^KAxL~pdQBx3%%_sPmhK_pks*IOq9opUo$74B%DGqm;>JuLa}iHWnx z5&M&I6Nb6jBXVL{8G(Xa$g*xyGUZJFWEcw0zpRJvIn;H&gz|(gh|g!Bj@&#gT3cky zE@|vAi11@(_=F=nxA1GBtoSrFWi*kSW*#j#NDKT~6C9KdhR?9)Jn7?N?;f{L!}l_x zlPpk|5M1%)RS>MA^5>(sB)uTw3mQk9ep zBkDD^wnUco7#taaT^DMOsaoFcQwxerjSjAKD0$1T``e9nWEt zl;9mRtGLaySmzG){`C(R4;W8Dn@0pVDB7;|F7&2w`H^oW3Kkr?L|Nq}ocjuC$c4k= zwIS5(?~Q9Eso4)g3XvY>h0Okw23cqzacyPr0Bip`;`9))Z-}fB6hJtMrK)`|X{sn= z@3eZKUHH{haTs{vA+kcgY32vRe?Gs7SU(}SORn8=w%&GagF3oA0n*^B<_GsR1mD3a4)VzM}ABS;oC|c4A`wxRaIk3%JSt3OsBg zG*$t+k>)2s6?&OKz2C}ufjXQI;>B=46tq50?6^q6&cQ<}%ul1v4iD12Zj#oYotl_5 zbJVPKV~FawG2gHHtnD823N(WndoV`L4G1tPc

{U&Q+GXf{Dxl)8t(SK1w3A20{0CP3>ZyC?lu)dqv{V)k_9$quB(H64N z##8;ipiy=XqJaDaQ`vy_eoI8@7gGrL=eBofAwGU#y+)CO3KiOKu``zT4qJ^vGFy`h zm}3O}_tfBa%GA{0-oBa!Gd9qI)ld^V%B6FL=Ol8HgFNp26}e&3w9j$xy`Ash0nZU^ zn#q!vHnzKjL}aBEaamBkMig@U(`{RDP6r$Z{dYECy7b=>MM6I@nSDP*cU~+V z3Ubm02{MMnD)iu*jA*gQ*BDQRt<<6YY*jMrZIqUxRRkMPTWcP{PK`I-ItT zkX~n_I;oUCfWD@QD+$Y`W#c5ZJJ+kjM3<0IA-uHZAF_8J>~H#DCH0M;PoK{0(Z%f% z?V@&YNYaq;3mgEjVDlvf43Y$H69x;qOHRf$Q}hRINSypS(lWgH_-|+53kB6vBZ=bYBp7Rm0Qkzq)gE_kv^MHF9!NqwejlQiLDd00NO^E_bbwqlf z9c_`?_kSA< z1_$GnXZG2U06=%5C?*i?gZJ&ixU2d~WnPUrq*!Acmb!mqeRueTJVK~|qSuD{f7b~W zV78Au%i68eYk`GsugC@BRglG(4M|qbUg+#htA@wv3uYZb0U(+cBorl1fnFmvB1(`z zSyI`MbcySMX79dgO9l2>zFXH>oW8pNy61&gD>DG>5gHIsEqtt7rdK5S zYeuK*Y@x!J@6SL1M>;A1)I`GZOO7ko4USp81_7~-H*_tFU4|Ox&zp7q0Lzh9jtll1 zX+zMQEi(cD_(>U!2+(fzQ@nUuFTPps7pAe9r(X7!59hUJof|`H-$3L}m-ofdl(W@~ zwh#a?Fo%;Fjl{!+i`;v)e(>qco@SF9Zz^-dZlIwmtI~k9W6Mbt`Sml>$ewcHm}QVO zU(Vp70gcdqLD;2UAJz2QyyIqkcBI%@*tUQ0i-SFTqV+RJodXd*qNs029{2d3-vhPV zZvMpZPBlodjF)L3`EE<8N_+2dfgz3BTX|RuY`cjnDeSAa3wr~KTjf)95OXv*3v87= zb^?e51ZHfTTV6%gM_Ik&!+Dy|p&k13tV8W0{dzTw{dh}L3QpB?YB=g_`Yi4B*59y& zXgVU@x5KLIu9q#q7xZFwBED886}gLm6Xwe^IxGY68uRvB_FbzLi{A8kaK^azm2%DOm6F2&HQD%9)_%R{YJR3zuk)CK zETTo|&-7zS=~6dN!cY5BmN_-sEk|Kd?bFsmStGAN7X5*9b#8QkLN9{iZXIi4j@QK$ z0%H2^InIR&vxd>pj1E^x$s&fx?PU+&b>~-NMPvXF^an*vRJzuii|pXfW!i{UjrzRC z-0V{ttb+(0;iM5`D3oQ9t!riMN9uK?$FC8-KMm$;0I)O)CyP3__b>IPizn7np0;N@ zg2&APMEp$*Zh@i1iitG==JpkK1(h2uJsN}UM;clE25@q^!ta}SRbN3Qay597=V7@w z+FPbGty8VSO<1s*TiK-_% z`*3MK6czrxa~D~1ci!iCa4;)^4c_fGFF zf+&-8cC81Lp9>t&#<&=KJy7a+cDs?GS^u@AM3g!y%oh=H;)LVS zZ-&Tb2LYufr#E;7pt#K|f?yj+RGCHmUOKpC_|)Qj*`hbe%Y*HC{V-Q>q(mdpIw{Yi zk+jq?lPK!=MFBu4ucShNK zYH*9^9~kNWtRvQ`PG(7a?~TeBq1nZs8UG>D2>1@IzRQYmrv1E^koVj9W;(ZB7ppVh z%I~N$@ANN3olhgrC2b3zp*QP3eWA;vzLAutr4_k7XIFJ_@WllR4Hp(5?DF2U*cIFq z0PX0MDO_pOtlqm(3EvcCb@gk1yXrp}8DAvmSYFs7-ipY~S$U{bTLD_i!UT=nhAQ0Z zfbDmoE8sgCrKMJ;`l7mi+v7bIqy&INbNEgvjQVL|%y({#pBAqUeHR##qPEDlLo$60 z9nQ|77ozOP0do%(UA?yxw73$@VcNygo<$@B+kbQ!Pu@%5xf`z3Ds}ztFnY=fZa5qR z*VBzes|3Ss5#ivX15cvTPJiTeW&F^9t?h%*GDBzZ3xQx;Y)}nljWu_4teb_>w}PqF zQd}hwrsGdx`tPAe`Gf=Oo$rLHZr{5Pk%rUgzraCZBb`p>MFKVQo`NQ+<8BJguKZRv zOKlKER*T+uYsWbC;u>p>G{^Io-2}%med{zyLz2Q2I7df4C+a0+ID4kGGb3hIx$~xy zU#CNzn#uMy9;zKG52-`imxq+wm!B{gxfoig3L^r*mI7SFw3Dwp6m-0=&E`C=<*K$L zO3B};Mr2M=tPW9xNel_$Uat6O*`R>4MNi>Uv6nv`n&Mp6QR-X{|5(rb+WU;5yc>e3 zOcvq~er|&TYr%K~poHsrO@&h)+1CT*j$LJ|_W7)Z-~_>hQu6onb^#u{?z;xNLW1Nd zgJhvCh!WaDxFC-h;XD%T{CO%q*X+Q#;m!Z_B+1&k#31uvu&ev1VoI=HL`r!ts<{AD z3jbJJh!C`~=y0ION(3}QI+*QYsSSAfMFE@F^}fl<35 zIU&vL4#q>Dyy(GOkKiCWCFls|f{tu`7982s4oL`DFJxtrE`1f@mQNTVC!_`PYiGce zTbrWmR0qnI6eaFVg$`2w0u&bmWrwpTd3>+JGe=ssW@jlpjSxpfc(4OnR@CoOz$oh> zJiY*zOsqWk&Yk-|K#>8LXe|86;EIJa8C=n{AQs^Ap@n-4aM8+woB Date: Wed, 6 Nov 2024 04:43:11 +0900 Subject: [PATCH 03/26] community: chroma error patch(attribute changed on chroma) (#27827) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There was a change of attribute name which was "max_batch_size". It's now "get_max_batch_size" method. I want to use "create_batches" which is right down below. Please check this PR link. reference: https://github.com/chroma-core/chroma/pull/2305 --------- Signed-off-by: Prithvi Kannan Co-authored-by: Prithvi Kannan <46332835+prithvikannan@users.noreply.github.com> Co-authored-by: Bagatur <22008038+baskaryan@users.noreply.github.com> Co-authored-by: Erick Friis Co-authored-by: Jun Yamog Co-authored-by: Bagatur Co-authored-by: ono-hiroki <86904208+ono-hiroki@users.noreply.github.com> Co-authored-by: Dobiichi-Origami <56953648+Dobiichi-Origami@users.noreply.github.com> Co-authored-by: Chester Curme Co-authored-by: Duy Huynh Co-authored-by: Rashmi Pawar <168514198+raspawar@users.noreply.github.com> Co-authored-by: sifatj <26035630+sifatj@users.noreply.github.com> Co-authored-by: Eric Pinzur <2641606+epinzur@users.noreply.github.com> Co-authored-by: Daniel Vu Dao Co-authored-by: Ofer Mendelevitch Co-authored-by: Stéphane Philippart --- libs/community/langchain_community/vectorstores/chroma.py | 8 +++++++- libs/partners/chroma/langchain_chroma/vectorstores.py | 4 ++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/libs/community/langchain_community/vectorstores/chroma.py b/libs/community/langchain_community/vectorstores/chroma.py index 40ba2415b6933..1ab7ddad140d6 100644 --- a/libs/community/langchain_community/vectorstores/chroma.py +++ b/libs/community/langchain_community/vectorstores/chroma.py @@ -753,6 +753,9 @@ def update_documents(self, ids: List[str], documents: List[Document]) -> None: embeddings = self._embedding_function.embed_documents(text) if hasattr( + self._collection._client, + "get_max_batch_size", # for Chroma 0.5.1 and above + ) or hasattr( self._collection._client, "max_batch_size" ): # for Chroma 0.4.10 and above from chromadb.utils.batch_utils import create_batches @@ -824,7 +827,10 @@ def from_texts( ids = [str(uuid.uuid4()) for _ in texts] if hasattr( chroma_collection._client, # type: ignore[has-type] - "max_batch_size", # type: ignore[has-type] + "get_max_batch_size", # for Chroma 0.5.1 and above + ) or hasattr( + chroma_collection._client, # type: ignore[has-type] + "max_batch_size", ): # for Chroma 0.4.10 and above from chromadb.utils.batch_utils import create_batches diff --git a/libs/partners/chroma/langchain_chroma/vectorstores.py b/libs/partners/chroma/langchain_chroma/vectorstores.py index 945057f4adb22..35146fdcc7603 100644 --- a/libs/partners/chroma/langchain_chroma/vectorstores.py +++ b/libs/partners/chroma/langchain_chroma/vectorstores.py @@ -997,6 +997,8 @@ def update_documents(self, ids: List[str], documents: List[Document]) -> None: embeddings = self._embedding_function.embed_documents(text) if hasattr( + self._collection._client, "get_max_batch_size" + ) or hasattr( # for Chroma 0.5.1 and above self._collection._client, "max_batch_size" ): # for Chroma 0.4.10 and above from chromadb.utils.batch_utils import create_batches @@ -1070,6 +1072,8 @@ def from_texts( if ids is None: ids = [str(uuid.uuid4()) for _ in texts] if hasattr( + chroma_collection._client, "get_max_batch_size" + ) or hasattr( # for Chroma 0.5.1 and above chroma_collection._client, "max_batch_size" ): # for Chroma 0.4.10 and above from chromadb.utils.batch_utils import create_batches From bff2a8b7722172edd12716ac5c6897df21cb4e36 Mon Sep 17 00:00:00 2001 From: Erick Friis Date: Tue, 5 Nov 2024 11:44:34 -0800 Subject: [PATCH 04/26] standard-tests: add tools standard tests (#27899) --- .../integration_tests/tools.py | 70 ++++++++++++++++++ .../unit_tests/tools.py | 74 +++++++++++++++++++ 2 files changed, 144 insertions(+) create mode 100644 libs/standard-tests/langchain_standard_tests/integration_tests/tools.py create mode 100644 libs/standard-tests/langchain_standard_tests/unit_tests/tools.py diff --git a/libs/standard-tests/langchain_standard_tests/integration_tests/tools.py b/libs/standard-tests/langchain_standard_tests/integration_tests/tools.py new file mode 100644 index 0000000000000..ad854c3b1d41d --- /dev/null +++ b/libs/standard-tests/langchain_standard_tests/integration_tests/tools.py @@ -0,0 +1,70 @@ +from langchain_core.messages import ToolCall +from langchain_core.tools import BaseTool + +from langchain_standard_tests.unit_tests.tools import ToolsTests + + +class ToolsIntegrationTests(ToolsTests): + def test_invoke_matches_output_schema(self, tool: BaseTool) -> None: + """ + If invoked with a ToolCall, the tool should return a valid ToolMessage content. + """ + tool_call = ToolCall( + name=tool.name, args=self.tool_invoke_params_example, id=None + ) + result = tool.invoke(tool_call) + + if tool.response_format == "content": + content = result + elif tool.response_format == "content_and_artifact": + # should be (content, artifact) + assert isinstance(result, tuple) + assert len(result) == 2 + content, artifact = result + + assert artifact # artifact can be anything, but shouldn't be none + + # check content is a valid ToolMessage content + assert isinstance(content, (str, list)) + if isinstance(content, list): + # content blocks must be str or dict + assert all(isinstance(c, (str, dict)) for c in content) + + async def test_async_invoke_matches_output_schema(self, tool: BaseTool) -> None: + """ + If ainvoked with a ToolCall, the tool should return a valid ToolMessage content. + """ + tool_call = ToolCall( + name=tool.name, args=self.tool_invoke_params_example, id=None + ) + result = await tool.ainvoke(tool_call) + + if tool.response_format == "content": + content = result + elif tool.response_format == "content_and_artifact": + # should be (content, artifact) + assert isinstance(result, tuple) + assert len(result) == 2 + content, artifact = result + + assert artifact # artifact can be anything, but shouldn't be none + + # check content is a valid ToolMessage content + assert isinstance(content, (str, list)) + if isinstance(content, list): + # content blocks must be str or dict + assert all(isinstance(c, (str, dict)) for c in content) + + def test_invoke_no_tool_call(self, tool: BaseTool) -> None: + """ + If invoked without a ToolCall, the tool can return anything + but it shouldn't throw an error + """ + tool.invoke(self.tool_invoke_params_example) + + async def test_async_invoke_no_tool_call(self, tool: BaseTool) -> None: + """ + If invoked without a ToolCall, the tool can return anything + but it shouldn't throw an error + """ + await tool.ainvoke(self.tool_invoke_params_example) diff --git a/libs/standard-tests/langchain_standard_tests/unit_tests/tools.py b/libs/standard-tests/langchain_standard_tests/unit_tests/tools.py new file mode 100644 index 0000000000000..61f54e23bec8e --- /dev/null +++ b/libs/standard-tests/langchain_standard_tests/unit_tests/tools.py @@ -0,0 +1,74 @@ +import os +from abc import abstractmethod +from typing import Callable, Tuple, Type, Union +from unittest import mock + +import pytest +from langchain_core.tools import BaseTool +from pydantic import SecretStr + +from langchain_standard_tests.base import BaseStandardTests + + +class ToolsTests(BaseStandardTests): + @property + @abstractmethod + def tool_constructor(self) -> Union[Type[BaseTool], Callable]: + ... + + @property + def tool_constructor_params(self) -> dict: + return {} + + @property + def tool_invoke_params_example(self) -> dict: + """ + Returns a dictionary representing the "args" of an example tool call. + + This should NOT be a ToolCall dict - i.e. it should not + have {"name", "id", "args"} keys. + """ + return {} + + @pytest.fixture + def tool(self) -> BaseTool: + return self.tool_constructor(**self.tool_constructor_params) + + +class ToolsUnitTests(ToolsTests): + def test_init(self) -> None: + tool = self.tool_constructor(**self.tool_constructor_params) + assert tool is not None + + @property + def init_from_env_params(self) -> Tuple[dict, dict, dict]: + """Return env vars, init args, and expected instance attrs for initializing + from env vars.""" + return {}, {}, {} + + def test_init_from_env(self) -> None: + env_params, tools_params, expected_attrs = self.init_from_env_params + if env_params: + with mock.patch.dict(os.environ, env_params): + tool = self.tool_constructor(**tools_params) + assert tool is not None + for k, expected in expected_attrs.items(): + actual = getattr(tool, k) + if isinstance(actual, SecretStr): + actual = actual.get_secret_value() + assert actual == expected + + def test_has_name(self, tool: BaseTool) -> None: + assert tool.name + + def test_has_input_schema(self, tool: BaseTool) -> None: + assert tool.get_input_schema() + + def test_input_schema_matches_invoke_params(self, tool: BaseTool) -> None: + """ + Tests that the provided example params match the declared input schema + """ + # this will be a pydantic object + input_schema = tool.get_input_schema() + + assert input_schema(**self.tool_invoke_params_example) From b3c81356ca17fa90ded8faa96c8e5bbdc16048d7 Mon Sep 17 00:00:00 2001 From: Erick Friis Date: Tue, 5 Nov 2024 12:04:41 -0800 Subject: [PATCH 05/26] infra: release note compute 2 (#27921) --- .github/workflows/_release.yml | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/.github/workflows/_release.yml b/.github/workflows/_release.yml index 7eaa9410beb06..6dee08c652d1a 100644 --- a/.github/workflows/_release.yml +++ b/.github/workflows/_release.yml @@ -106,11 +106,16 @@ jobs: PREV_TAG=$(git tag --sort=-creatordate | grep -P $REGEX || true | head -1) fi - # confirm prev-tag actually exists in git repo with git tag - GIT_TAG_RESULT=$(git tag -l "$PREV_TAG") - if [ -z "$GIT_TAG_RESULT" ]; then - echo "Previous tag $PREV_TAG not found in git repo" - exit 1 + # if PREV_TAG is empty, let it be empty + if [ -z "$PREV_TAG" ]; then + echo "No previous tag found - first release" + else + # confirm prev-tag actually exists in git repo with git tag + GIT_TAG_RESULT=$(git tag -l "$PREV_TAG") + if [ -z "$GIT_TAG_RESULT" ]; then + echo "Previous tag $PREV_TAG not found in git repo" + exit 1 + fi fi From c3b75560dc13c3c323b739e78182acf281fbe255 Mon Sep 17 00:00:00 2001 From: Erick Friis Date: Tue, 5 Nov 2024 12:44:36 -0800 Subject: [PATCH 06/26] infra: release note grep order of operations (#27922) --- .github/workflows/_release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/_release.yml b/.github/workflows/_release.yml index 6dee08c652d1a..fd6a53fee85cb 100644 --- a/.github/workflows/_release.yml +++ b/.github/workflows/_release.yml @@ -103,7 +103,7 @@ jobs: if [ -z "$PREV_TAG" ]; then REGEX="^$PKG_NAME==\\d+\\.\\d+\\.\\d+\$" echo $REGEX - PREV_TAG=$(git tag --sort=-creatordate | grep -P $REGEX || true | head -1) + PREV_TAG=$(git tag --sort=-creatordate | (grep -P $REGEX || true) | head -1) fi # if PREV_TAG is empty, let it be empty From a8c473e114f0a16f3a3dd0f401d7f1026666f12e Mon Sep 17 00:00:00 2001 From: Erick Friis Date: Tue, 5 Nov 2024 12:55:38 -0800 Subject: [PATCH 07/26] standard-tests: ci pipeline (#27923) --- libs/standard-tests/poetry.lock | 47 ++++++++++++++++++- libs/standard-tests/pyproject.toml | 22 +++++++-- libs/standard-tests/tests/__init__.py | 0 .../tests/integration_tests/test_compile.py | 7 +++ .../unit_tests/test_in_memory_vectorstore.py | 2 +- 5 files changed, 71 insertions(+), 7 deletions(-) delete mode 100644 libs/standard-tests/tests/__init__.py create mode 100644 libs/standard-tests/tests/integration_tests/test_compile.py diff --git a/libs/standard-tests/poetry.lock b/libs/standard-tests/poetry.lock index 95d28da3f7dd9..0c74b37a6cb13 100644 --- a/libs/standard-tests/poetry.lock +++ b/libs/standard-tests/poetry.lock @@ -414,6 +414,51 @@ files = [ {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, ] +[[package]] +name = "numpy" +version = "1.26.4" +description = "Fundamental package for array computing in Python" +optional = false +python-versions = ">=3.9" +files = [ + {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]] name = "orjson" version = "3.10.11" @@ -876,4 +921,4 @@ zstd = ["zstandard (>=0.18.0)"] [metadata] lock-version = "2.0" python-versions = ">=3.9,<4.0" -content-hash = "cb3804aa252eed812fd6dc0762ffb110d6b55046f7e691f3fe14080d8ab06b38" +content-hash = "4f6715617fbad64e03a1675f2edb9f77912dc156a79c8cef58eb145392efe21a" diff --git a/libs/standard-tests/pyproject.toml b/libs/standard-tests/pyproject.toml index 14515955ee572..4caa1fb651b29 100644 --- a/libs/standard-tests/pyproject.toml +++ b/libs/standard-tests/pyproject.toml @@ -1,12 +1,12 @@ [build-system] -requires = [ "poetry-core",] +requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" [tool.poetry] name = "langchain-standard-tests" version = "0.3.0" description = "Standard tests for LangChain implementations" -authors = [ "Erick Friis ",] +authors = ["Erick Friis "] readme = "README.md" repository = "https://github.com/langchain-ai/langchain" license = "MIT" @@ -25,14 +25,18 @@ httpx = "^0.27.0" syrupy = "^4" [tool.ruff.lint] -select = [ "E", "F", "I", "T201",] +select = ["E", "F", "I", "T201"] [tool.coverage.run] -omit = [ "tests/*",] +omit = ["tests/*"] [tool.pytest.ini_options] addopts = "--strict-markers --strict-config --durations=5 -vv" -markers = [ "requires: mark tests as requiring a specific library", "scheduled: mark tests to run in scheduled testing", "compile: mark placeholder test used to compile integration tests without running them",] +markers = [ + "requires: mark tests as requiring a specific library", + "scheduled: mark tests to run in scheduled testing", + "compile: mark placeholder test used to compile integration tests without running them", +] asyncio_mode = "auto" [tool.poetry.group.test] @@ -50,6 +54,14 @@ optional = true [tool.poetry.group.test.dependencies] pytest-asyncio = "^0.23.7" +[[tool.poetry.group.test.dependencies.numpy]] +version = "^1.24.0" +python = "<3.12" + +[[tool.poetry.group.test.dependencies.numpy]] +version = "^1.26.0" +python = ">=3.12" + [tool.poetry.group.test_integration.dependencies] [tool.poetry.group.codespell.dependencies] diff --git a/libs/standard-tests/tests/__init__.py b/libs/standard-tests/tests/__init__.py deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/libs/standard-tests/tests/integration_tests/test_compile.py b/libs/standard-tests/tests/integration_tests/test_compile.py new file mode 100644 index 0000000000000..33ecccdfa0fbd --- /dev/null +++ b/libs/standard-tests/tests/integration_tests/test_compile.py @@ -0,0 +1,7 @@ +import pytest + + +@pytest.mark.compile +def test_placeholder() -> None: + """Used for compiling integration tests without running any real tests.""" + pass diff --git a/libs/standard-tests/tests/unit_tests/test_in_memory_vectorstore.py b/libs/standard-tests/tests/unit_tests/test_in_memory_vectorstore.py index 9b71087770707..d1becb40c9eb4 100644 --- a/libs/standard-tests/tests/unit_tests/test_in_memory_vectorstore.py +++ b/libs/standard-tests/tests/unit_tests/test_in_memory_vectorstore.py @@ -17,7 +17,7 @@ def vectorstore(self) -> VectorStore: return InMemoryVectorStore(embedding=embeddings) -class TestAysncInMemoryVectorStore(AsyncReadWriteTestSuite): +class TestAsyncInMemoryVectorStore(AsyncReadWriteTestSuite): @pytest.fixture async def vectorstore(self) -> VectorStore: embeddings = self.get_embeddings() From 66966a6e725f7ab533886c86d418c4a663bb9966 Mon Sep 17 00:00:00 2001 From: ccurme Date: Tue, 5 Nov 2024 18:02:24 -0500 Subject: [PATCH 08/26] openai[patch]: release 0.2.6 (#27924) Some additions in support of [predicted outputs](https://platform.openai.com/docs/guides/latency-optimization#use-predicted-outputs) feature: - Bump openai sdk version - Add integration test - Add example to integration docs The `prediction` kwarg is already plumbed through model invocation. --- docs/docs/integrations/chat/openai.ipynb | 99 ++++++++++++++++++- libs/partners/openai/poetry.lock | 16 +-- libs/partners/openai/pyproject.toml | 4 +- .../chat_models/test_base.py | 43 ++++++++ 4 files changed, 150 insertions(+), 12 deletions(-) diff --git a/docs/docs/integrations/chat/openai.ipynb b/docs/docs/integrations/chat/openai.ipynb index 687f6ddc30bc1..9ab1c22c70c8f 100644 --- a/docs/docs/integrations/chat/openai.ipynb +++ b/docs/docs/integrations/chat/openai.ipynb @@ -509,6 +509,101 @@ "output_message.content" ] }, + { + "cell_type": "markdown", + "id": "5c35d0a4-a6b8-4d35-a02b-a37a8bda5692", + "metadata": {}, + "source": [ + "## Predicted output\n", + "\n", + ":::info\n", + "Requires `langchain-openai>=0.2.6`\n", + ":::\n", + "\n", + "Some OpenAI models (such as their `gpt-4o` and `gpt-4o-mini` series) support [Predicted Outputs](https://platform.openai.com/docs/guides/latency-optimization#use-predicted-outputs), which allow you to pass in a known portion of the LLM's expected output ahead of time to reduce latency. This is useful for cases such as editing text or code, where only a small part of the model's output will change.\n", + "\n", + "Here's an example:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "88fee1e9-58c1-42ad-ae23-24b882e175e7", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "///

\n", + "/// Represents a user with a first name, last name, and email.\n", + "/// \n", + "public class User\n", + "{\n", + " /// \n", + " /// Gets or sets the user's first name.\n", + " /// \n", + " public string FirstName { get; set; }\n", + "\n", + " /// \n", + " /// Gets or sets the user's last name.\n", + " /// \n", + " public string LastName { get; set; }\n", + "\n", + " /// \n", + " /// Gets or sets the user's email.\n", + " /// \n", + " public string Email { get; set; }\n", + "}\n", + "{'token_usage': {'completion_tokens': 226, 'prompt_tokens': 166, 'total_tokens': 392, 'completion_tokens_details': {'accepted_prediction_tokens': 49, 'audio_tokens': None, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 107}, 'prompt_tokens_details': {'audio_tokens': None, 'cached_tokens': 0}}, 'model_name': 'gpt-4o-2024-08-06', 'system_fingerprint': 'fp_45cf54deae', 'finish_reason': 'stop', 'logprobs': None}\n" + ] + } + ], + "source": [ + "code = \"\"\"\n", + "/// \n", + "/// Represents a user with a first name, last name, and username.\n", + "/// \n", + "public class User\n", + "{\n", + " /// \n", + " /// Gets or sets the user's first name.\n", + " /// \n", + " public string FirstName { get; set; }\n", + "\n", + " /// \n", + " /// Gets or sets the user's last name.\n", + " /// \n", + " public string LastName { get; set; }\n", + "\n", + " /// \n", + " /// Gets or sets the user's username.\n", + " /// \n", + " public string Username { get; set; }\n", + "}\n", + "\"\"\"\n", + "\n", + "llm = ChatOpenAI(model=\"gpt-4o\")\n", + "query = (\n", + " \"Replace the Username property with an Email property. \"\n", + " \"Respond only with code, and with no markdown formatting.\"\n", + ")\n", + "response = llm.invoke(\n", + " [{\"role\": \"user\", \"content\": query}, {\"role\": \"user\", \"content\": code}],\n", + " prediction={\"type\": \"content\", \"content\": code},\n", + ")\n", + "print(response.content)\n", + "print(response.response_metadata)" + ] + }, + { + "cell_type": "markdown", + "id": "2ee1b26d-a388-4e7c-9f40-bfd1388ecc03", + "metadata": {}, + "source": [ + "Note that currently predictions are billed as additional tokens and may increase your usage and costs in exchange for this reduced latency." + ] + }, { "cell_type": "markdown", "id": "feb4a499", @@ -601,7 +696,7 @@ ], "metadata": { "kernelspec": { - "display_name": ".venv", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, @@ -615,7 +710,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.4" + "version": "3.10.4" } }, "nbformat": 4, diff --git a/libs/partners/openai/poetry.lock b/libs/partners/openai/poetry.lock index a1d51f1d22efe..30fa377575298 100644 --- a/libs/partners/openai/poetry.lock +++ b/libs/partners/openai/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 = "annotated-types" @@ -518,7 +518,7 @@ url = "../../core" [[package]] name = "langchain-standard-tests" -version = "0.1.1" +version = "0.3.0" description = "Standard tests for LangChain implementations" optional = false python-versions = ">=3.9,<4.0" @@ -527,7 +527,7 @@ develop = true [package.dependencies] httpx = "^0.27.0" -langchain-core = "^0.3.0" +langchain-core = "^0.3.15" pytest = ">=7,<9" syrupy = "^4" @@ -667,13 +667,13 @@ files = [ [[package]] name = "openai" -version = "1.52.2" +version = "1.54.1" description = "The official Python library for the openai API" optional = false -python-versions = ">=3.7.1" +python-versions = ">=3.8" files = [ - {file = "openai-1.52.2-py3-none-any.whl", hash = "sha256:57e9e37bc407f39bb6ec3a27d7e8fb9728b2779936daa1fcf95df17d3edfaccc"}, - {file = "openai-1.52.2.tar.gz", hash = "sha256:87b7d0f69d85f5641678d414b7ee3082363647a5c66a462ed7f3ccb59582da0d"}, + {file = "openai-1.54.1-py3-none-any.whl", hash = "sha256:3cb49ccb6bfdc724ad01cc397d323ef8314fc7d45e19e9de2afdd6484a533324"}, + {file = "openai-1.54.1.tar.gz", hash = "sha256:5b832bf82002ba8c4f6e5e25c1c0f5d468c22f043711544c716eaffdb30dd6f1"}, ] [package.dependencies] @@ -1561,4 +1561,4 @@ watchmedo = ["PyYAML (>=3.10)"] [metadata] lock-version = "2.0" python-versions = ">=3.9,<4.0" -content-hash = "985f183aed7188a51964c30831939cae8060d906e8b07d4257e423016b6f3dd4" +content-hash = "77af861c052decd1c194936575c15491a606fd763556b427e2c659d5ea7aae72" diff --git a/libs/partners/openai/pyproject.toml b/libs/partners/openai/pyproject.toml index 255e488375d43..661c2b0a98490 100644 --- a/libs/partners/openai/pyproject.toml +++ b/libs/partners/openai/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api" [tool.poetry] name = "langchain-openai" -version = "0.2.5" +version = "0.2.6" description = "An integration package connecting OpenAI and LangChain" authors = [] readme = "README.md" @@ -24,7 +24,7 @@ ignore_missing_imports = true [tool.poetry.dependencies] python = ">=3.9,<4.0" langchain-core = "^0.3.15" -openai = "^1.52.0" +openai = "^1.54.0" tiktoken = ">=0.7,<1" [tool.ruff.lint] diff --git a/libs/partners/openai/tests/integration_tests/chat_models/test_base.py b/libs/partners/openai/tests/integration_tests/chat_models/test_base.py index ccce5722c3c8e..31ff734355491 100644 --- a/libs/partners/openai/tests/integration_tests/chat_models/test_base.py +++ b/libs/partners/openai/tests/integration_tests/chat_models/test_base.py @@ -3,6 +3,7 @@ import base64 import json from pathlib import Path +from textwrap import dedent from typing import Any, AsyncIterator, List, Literal, Optional, cast import httpx @@ -1018,3 +1019,45 @@ def test_audio_input_modality() -> None: assert isinstance(output, AIMessage) assert "audio" in output.additional_kwargs + + +def test_prediction_tokens() -> None: + code = dedent(""" + /// + /// Represents a user with a first name, last name, and username. + /// + public class User + { + /// + /// Gets or sets the user's first name. + /// + public string FirstName { get; set; } + + /// + /// Gets or sets the user's last name. + /// + public string LastName { get; set; } + + /// + /// Gets or sets the user's username. + /// + public string Username { get; set; } + } + """) + + llm = ChatOpenAI(model="gpt-4o") + query = ( + "Replace the Username property with an Email property. " + "Respond only with code, and with no markdown formatting." + ) + response = llm.invoke( + [{"role": "user", "content": query}, {"role": "user", "content": code}], + prediction={"type": "content", "content": code}, + ) + assert isinstance(response, AIMessage) + assert response.response_metadata is not None + output_token_details = response.response_metadata["token_usage"][ + "completion_tokens_details" + ] + assert output_token_details["accepted_prediction_tokens"] > 0 + assert output_token_details["rejected_prediction_tokens"] > 0 From 41b7a5169d3b6bdb0949a409397707eb69b3cd07 Mon Sep 17 00:00:00 2001 From: Erick Friis Date: Tue, 5 Nov 2024 16:43:11 -0800 Subject: [PATCH 09/26] infra: starter codeowners file (#27929) --- .github/CODEOWNERS | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .github/CODEOWNERS diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000000000..e5f22dcb22b18 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,2 @@ +/.github/ @efriis @baskaryan @ccurme +/libs/packages.yml @efriis From 395674d5037756bef25d7fa8da93525874bb5cb8 Mon Sep 17 00:00:00 2001 From: Dobiichi-Origami <56953648+Dobiichi-Origami@users.noreply.github.com> Date: Wed, 6 Nov 2024 22:58:16 +0800 Subject: [PATCH 10/26] community: re-arrange function call message parse logic for Qianfan (#27935) the [PR](https://github.com/langchain-ai/langchain/pull/26208) two month ago has a potential bug which causes malfunction of `tool_call` for `QianfanChatEndpoint` waiting for fix --- .../chat_models/baidu_qianfan_endpoint.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/libs/community/langchain_community/chat_models/baidu_qianfan_endpoint.py b/libs/community/langchain_community/chat_models/baidu_qianfan_endpoint.py index 93f32e9a83e58..243ac084d3779 100644 --- a/libs/community/langchain_community/chat_models/baidu_qianfan_endpoint.py +++ b/libs/community/langchain_community/chat_models/baidu_qianfan_endpoint.py @@ -66,17 +66,13 @@ def convert_message_to_dict(message: BaseMessage) -> dict: message_dict = {"role": "user", "content": message.content} elif isinstance(message, AIMessage): message_dict = {"role": "assistant", "content": message.content} - if "function_call" in message.additional_kwargs: - message_dict["function_call"] = message.additional_kwargs["function_call"] - elif len(message.tool_calls) != 0: + if len(message.tool_calls) != 0: tool_call = message.tool_calls[0] message_dict["function_call"] = { "name": tool_call["name"], - "args": tool_call["args"], + "arguments": json.dumps(tool_call["args"], ensure_ascii=False), } - - # If function call only, content is None not empty string - if "function_call" in message_dict and message_dict["content"] == "": + # If function call only, content is None not empty string message_dict["content"] = None elif isinstance(message, (FunctionMessage, ToolMessage)): message_dict = { From b2da3115ed4f867a8a6375369eb8dacef16b4e70 Mon Sep 17 00:00:00 2001 From: Bagatur <22008038+baskaryan@users.noreply.github.com> Date: Wed, 6 Nov 2024 09:50:07 -0800 Subject: [PATCH 11/26] docs: document init_chat_model standard params (#27812) --- libs/langchain/langchain/chat_models/base.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/libs/langchain/langchain/chat_models/base.py b/libs/langchain/langchain/chat_models/base.py index 95720a92032c8..d17a2932bc8f2 100644 --- a/libs/langchain/langchain/chat_models/base.py +++ b/libs/langchain/langchain/chat_models/base.py @@ -149,7 +149,16 @@ def init_chat_model( ``config["configurable"]["{config_prefix}_{param}"]`` keys. If config_prefix is an empty string then model will be configurable via ``config["configurable"]["{param}"]``. - kwargs: Additional keyword args to pass to + temperature: Model temperature. + max_tokens: Max output tokens. + timeout: The maximum time (in seconds) to wait for a response from the model + before canceling the request. + max_retries: The maximum number of attempts the system will make to resend a + request if it fails due to issues like network timeouts or rate limits. + base_url: The URL of the API endpoint where requests are sent. + rate_limiter: A ``BaseRateLimiter`` to space out requests to avoid exceeding + rate limits. + kwargs: Additional model-specific keyword args to pass to ``<>.__init__(model=model_name, **kwargs)``. Returns: From 67ce05a0a7bc2d0efa4d1b9a58f9d44002c85fe6 Mon Sep 17 00:00:00 2001 From: Bagatur <22008038+baskaryan@users.noreply.github.com> Date: Wed, 6 Nov 2024 10:06:47 -0800 Subject: [PATCH 12/26] core[patch]: make oai tool description optional (#27756) --- .../langchain_core/utils/function_calling.py | 73 +++++++---- .../unit_tests/utils/test_function_calling.py | 124 ++++++++++++++++++ 2 files changed, 174 insertions(+), 23 deletions(-) diff --git a/libs/core/langchain_core/utils/function_calling.py b/libs/core/langchain_core/utils/function_calling.py index 1a1c26443c786..3aff07faecd4c 100644 --- a/libs/core/langchain_core/utils/function_calling.py +++ b/libs/core/langchain_core/utils/function_calling.py @@ -341,7 +341,7 @@ def convert_to_openai_function( A dictionary, Pydantic BaseModel class, TypedDict class, a LangChain Tool object, or a Python function. If a dictionary is passed in, it is assumed to already be a valid OpenAI function, a JSON schema with - top-level 'title' and 'description' keys specified, an Anthropic format + top-level 'title' key specified, an Anthropic format tool, or an Amazon Bedrock Converse format tool. strict: If True, model output is guaranteed to exactly match the JSON Schema @@ -366,40 +366,47 @@ def convert_to_openai_function( .. versionchanged:: 0.3.14 Support for Amazon Bedrock Converse format tools added. + + .. versionchanged:: 0.3.16 + + 'description' and 'parameters' keys are now optional. Only 'name' is + required and guaranteed to be part of the output. """ from langchain_core.tools import BaseTool - # already in OpenAI function format - if isinstance(function, dict) and all( - k in function for k in ("name", "description", "parameters") - ): - oai_function = function - # a JSON schema with title and description - elif isinstance(function, dict) and all( - k in function for k in ("title", "description", "properties") - ): - function = function.copy() - oai_function = { - "name": function.pop("title"), - "description": function.pop("description"), - "parameters": function, - } # an Anthropic format tool - elif isinstance(function, dict) and all( - k in function for k in ("name", "description", "input_schema") + if isinstance(function, dict) and all( + k in function for k in ("name", "input_schema") ): oai_function = { "name": function["name"], - "description": function["description"], "parameters": function["input_schema"], } + if "description" in function: + oai_function["description"] = function["description"] # an Amazon Bedrock Converse format tool elif isinstance(function, dict) and "toolSpec" in function: oai_function = { "name": function["toolSpec"]["name"], - "description": function["toolSpec"]["description"], "parameters": function["toolSpec"]["inputSchema"]["json"], } + if "description" in function["toolSpec"]: + oai_function["description"] = function["toolSpec"]["description"] + # already in OpenAI function format + elif isinstance(function, dict) and "name" in function: + oai_function = { + k: v + for k, v in function.items() + if k in ("name", "description", "parameters", "strict") + } + # a JSON schema with title and description + elif isinstance(function, dict) and "title" in function: + function_copy = function.copy() + oai_function = {"name": function_copy.pop("title")} + if "description" in function_copy: + oai_function["description"] = function_copy.pop("description") + if function_copy and "properties" in function_copy: + oai_function["parameters"] = function_copy elif isinstance(function, type) and is_basemodel_subclass(function): oai_function = cast(dict, convert_pydantic_to_openai_function(function)) elif is_typeddict(function): @@ -420,6 +427,13 @@ def convert_to_openai_function( raise ValueError(msg) if strict is not None: + if "strict" in oai_function and oai_function["strict"] != strict: + msg = ( + f"Tool/function already has a 'strict' key wth value " + f"{oai_function['strict']} which is different from the explicit " + f"`strict` arg received {strict=}." + ) + raise ValueError(msg) oai_function["strict"] = strict if strict: # As of 08/06/24, OpenAI requires that additionalProperties be supplied and @@ -438,12 +452,16 @@ def convert_to_openai_tool( ) -> dict[str, Any]: """Convert a tool-like object to an OpenAI tool schema. + OpenAI tool schema reference: + https://platform.openai.com/docs/api-reference/chat/create#chat-create-tools + Args: tool: Either a dictionary, a pydantic.BaseModel class, Python function, or - BaseTool. If a dictionary is passed in, it is assumed to already be a valid - OpenAI tool, OpenAI function, a JSON schema with top-level 'title' and - 'description' keys specified, or an Anthropic format tool. + BaseTool. If a dictionary is passed in, it is + assumed to already be a valid OpenAI function, a JSON schema with + top-level 'title' key specified, an Anthropic format + tool, or an Amazon Bedrock Converse format tool. strict: If True, model output is guaranteed to exactly match the JSON Schema provided in the function definition. If None, ``strict`` argument will not @@ -460,6 +478,15 @@ def convert_to_openai_tool( .. versionchanged:: 0.3.13 Support for Anthropic format tools added. + + .. versionchanged:: 0.3.14 + + Support for Amazon Bedrock Converse format tools added. + + .. versionchanged:: 0.3.16 + + 'description' and 'parameters' keys are now optional. Only 'name' is + required and guaranteed to be part of the output. """ if isinstance(tool, dict) and tool.get("type") == "function" and "function" in tool: return tool diff --git a/libs/core/tests/unit_tests/utils/test_function_calling.py b/libs/core/tests/unit_tests/utils/test_function_calling.py index 1bd43c193103c..4eaa3da2b19ab 100644 --- a/libs/core/tests/unit_tests/utils/test_function_calling.py +++ b/libs/core/tests/unit_tests/utils/test_function_calling.py @@ -459,6 +459,130 @@ def my_function(arg1: Nested) -> None: assert actual == expected +json_schema_no_description_no_params = { + "title": "dummy_function", +} + + +json_schema_no_description = { + "title": "dummy_function", + "type": "object", + "properties": { + "arg1": {"description": "foo", "type": "integer"}, + "arg2": { + "description": "one of 'bar', 'baz'", + "enum": ["bar", "baz"], + "type": "string", + }, + }, + "required": ["arg1", "arg2"], +} + + +anthropic_tool_no_description = { + "name": "dummy_function", + "input_schema": { + "type": "object", + "properties": { + "arg1": {"description": "foo", "type": "integer"}, + "arg2": { + "description": "one of 'bar', 'baz'", + "enum": ["bar", "baz"], + "type": "string", + }, + }, + "required": ["arg1", "arg2"], + }, +} + + +bedrock_converse_tool_no_description = { + "toolSpec": { + "name": "dummy_function", + "inputSchema": { + "json": { + "type": "object", + "properties": { + "arg1": {"description": "foo", "type": "integer"}, + "arg2": { + "description": "one of 'bar', 'baz'", + "enum": ["bar", "baz"], + "type": "string", + }, + }, + "required": ["arg1", "arg2"], + } + }, + } +} + + +openai_function_no_description = { + "name": "dummy_function", + "parameters": { + "type": "object", + "properties": { + "arg1": {"description": "foo", "type": "integer"}, + "arg2": { + "description": "one of 'bar', 'baz'", + "enum": ["bar", "baz"], + "type": "string", + }, + }, + "required": ["arg1", "arg2"], + }, +} + + +openai_function_no_description_no_params = { + "name": "dummy_function", +} + + +@pytest.mark.parametrize( + "func", + [ + anthropic_tool_no_description, + json_schema_no_description, + bedrock_converse_tool_no_description, + openai_function_no_description, + ], +) +def test_convert_to_openai_function_no_description(func: dict) -> None: + expected = { + "name": "dummy_function", + "parameters": { + "type": "object", + "properties": { + "arg1": {"description": "foo", "type": "integer"}, + "arg2": { + "description": "one of 'bar', 'baz'", + "enum": ["bar", "baz"], + "type": "string", + }, + }, + "required": ["arg1", "arg2"], + }, + } + actual = convert_to_openai_function(func) + assert actual == expected + + +@pytest.mark.parametrize( + "func", + [ + json_schema_no_description_no_params, + openai_function_no_description_no_params, + ], +) +def test_convert_to_openai_function_no_description_no_params(func: dict) -> None: + expected = { + "name": "dummy_function", + } + actual = convert_to_openai_function(func) + assert actual == expected + + @pytest.mark.xfail( reason="Pydantic converts Optional[str] to str in .model_json_schema()" ) From 75aa82fedce6635c4b1ed48fcd1ac86f2107de5e Mon Sep 17 00:00:00 2001 From: Hammad Randhawa <59907999+randhawa2001@users.noreply.github.com> Date: Thu, 7 Nov 2024 00:55:00 +0500 Subject: [PATCH 13/26] =?UTF-8?q?docs:=20Completed=20sentence=20under=20th?= =?UTF-8?q?e=20heading=20=20"Instantiating=20a=20Browser=20=E2=80=A6=20(#2?= =?UTF-8?q?7944)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit …Toolkit" in "playwright.ipynb" integration. - Completed the incomplete sentence in the Langchain Playwright documentation. - Enhanced documentation clarity to guide users on best practices for instantiating browser instances with Langchain Playwright. Example before: > "It's always recommended to instantiate using the from_browser method so that the Example after: > "It's always recommended to instantiate using the `from_browser` method so that the browser context is properly initialized and managed, ensuring seamless interaction and resource optimization." Co-authored-by: Erick Friis --- docs/docs/integrations/tools/playwright.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/integrations/tools/playwright.ipynb b/docs/docs/integrations/tools/playwright.ipynb index bf397c74236c3..e09f4e79cd24d 100644 --- a/docs/docs/integrations/tools/playwright.ipynb +++ b/docs/docs/integrations/tools/playwright.ipynb @@ -101,7 +101,7 @@ "source": [ "## Instantiating a Browser Toolkit\n", "\n", - "It's always recommended to instantiate using the `from_browser` method so that the " + "It's always recommended to instantiate using the from_browser method so that the browser context is properly initialized and managed, ensuring seamless interaction and resource optimization." ] }, { From ea0ad917b0911521e3ec7c973babb945fec115d9 Mon Sep 17 00:00:00 2001 From: Eric Pinzur <2641606+epinzur@users.noreply.github.com> Date: Wed, 6 Nov 2024 21:04:09 +0100 Subject: [PATCH 14/26] community: added Document.id support to opensearch vectorstore (#27945) Description: * Added support of Document.id on OpenSearch vector store * Added tests cases to match --- .../vectorstores/opensearch_vector_search.py | 4 +- .../vectorstores/test_opensearch.py | 72 +++++++++++++------ 2 files changed, 55 insertions(+), 21 deletions(-) diff --git a/libs/community/langchain_community/vectorstores/opensearch_vector_search.py b/libs/community/langchain_community/vectorstores/opensearch_vector_search.py index da5d38db6dcd0..f1329659eeca7 100644 --- a/libs/community/langchain_community/vectorstores/opensearch_vector_search.py +++ b/libs/community/langchain_community/vectorstores/opensearch_vector_search.py @@ -16,7 +16,7 @@ "Could not import OpenSearch. Please install it with `pip install opensearch-py`." ) IMPORT_ASYNC_OPENSEARCH_PY_ERROR = """ -Could not import AsyncOpenSearch. +Could not import AsyncOpenSearch. Please install it with `pip install opensearch-py`.""" SCRIPT_SCORING_SEARCH = "script_scoring" @@ -902,6 +902,7 @@ def similarity_search_with_score_by_vector( if metadata_field == "*" or metadata_field not in hit["_source"] else hit["_source"][metadata_field] ), + id=hit["_id"], ), hit["_score"], ) @@ -1099,6 +1100,7 @@ def max_marginal_relevance_search( Document( page_content=results[i]["_source"][text_field], metadata=results[i]["_source"][metadata_field], + id=results[i]["_id"], ) for i in mmr_selected ] diff --git a/libs/community/tests/integration_tests/vectorstores/test_opensearch.py b/libs/community/tests/integration_tests/vectorstores/test_opensearch.py index 37dae734605cd..22bff5200738c 100644 --- a/libs/community/tests/integration_tests/vectorstores/test_opensearch.py +++ b/libs/community/tests/integration_tests/vectorstores/test_opensearch.py @@ -15,15 +15,19 @@ DEFAULT_OPENSEARCH_URL = "http://localhost:9200" texts = ["foo", "bar", "baz"] +ids = ["id_foo", "id_bar", "id_baz"] def test_opensearch() -> None: """Test end to end indexing and search using Approximate Search.""" docsearch = OpenSearchVectorSearch.from_texts( - texts, FakeEmbeddings(), opensearch_url=DEFAULT_OPENSEARCH_URL + texts, + FakeEmbeddings(), + opensearch_url=DEFAULT_OPENSEARCH_URL, + ids=ids, ) output = docsearch.similarity_search("foo", k=1) - assert output == [Document(page_content="foo")] + assert output == [Document(page_content="foo", id="id_foo")] def test_similarity_search_with_score() -> None: @@ -34,11 +38,12 @@ def test_similarity_search_with_score() -> None: FakeEmbeddings(), metadatas=metadatas, opensearch_url=DEFAULT_OPENSEARCH_URL, + ids=ids, ) output = docsearch.similarity_search_with_score("foo", k=2) assert output == [ - (Document(page_content="foo", metadata={"page": 0}), 1.0), - (Document(page_content="bar", metadata={"page": 1}), 0.5), + (Document(page_content="foo", metadata={"page": 0}, id="id_foo"), 1.0), + (Document(page_content="bar", metadata={"page": 1}, id="id_bar"), 0.5), ] @@ -50,20 +55,24 @@ def test_opensearch_with_custom_field_name() -> None: opensearch_url=DEFAULT_OPENSEARCH_URL, vector_field="my_vector", text_field="custom_text", + ids=ids, ) output = docsearch.similarity_search( "foo", k=1, vector_field="my_vector", text_field="custom_text" ) - assert output == [Document(page_content="foo")] + assert output == [Document(page_content="foo", id="id_foo")] text_input = ["test", "add", "text", "method"] OpenSearchVectorSearch.add_texts( - docsearch, text_input, vector_field="my_vector", text_field="custom_text" + docsearch, + text_input, + vector_field="my_vector", + text_field="custom_text", ) output = docsearch.similarity_search( "add", k=1, vector_field="my_vector", text_field="custom_text" ) - assert output == [Document(page_content="foo")] + assert output == [Document(page_content="foo", id="id_foo")] def test_opensearch_with_metadatas() -> None: @@ -74,9 +83,22 @@ def test_opensearch_with_metadatas() -> None: FakeEmbeddings(), metadatas=metadatas, opensearch_url=DEFAULT_OPENSEARCH_URL, + ids=ids, ) output = docsearch.similarity_search("foo", k=1) - assert output == [Document(page_content="foo", metadata={"page": 0})] + assert output == [Document(page_content="foo", metadata={"page": 0}, id="id_foo")] + + +def test_max_marginal_relevance_search() -> None: + """Test end to end indexing and mmr search.""" + docsearch = OpenSearchVectorSearch.from_texts( + texts, + FakeEmbeddings(), + opensearch_url=DEFAULT_OPENSEARCH_URL, + ids=ids, + ) + output = docsearch.max_marginal_relevance_search("foo", k=1) + assert output == [Document(page_content="foo", id="id_foo")] def test_add_text() -> None: @@ -86,8 +108,8 @@ def test_add_text() -> None: docsearch = OpenSearchVectorSearch.from_texts( texts, FakeEmbeddings(), opensearch_url=DEFAULT_OPENSEARCH_URL ) - docids = OpenSearchVectorSearch.add_texts(docsearch, text_input, metadatas) - assert len(docids) == len(text_input) + doc_ids = OpenSearchVectorSearch.add_texts(docsearch, text_input, metadatas) + assert len(doc_ids) == len(text_input) def test_add_embeddings() -> None: @@ -112,7 +134,8 @@ def test_add_embeddings() -> None: ) docsearch.add_embeddings(list(zip(text_input, embedding_vectors)), metadatas) output = docsearch.similarity_search("foo1", k=1) - assert output == [Document(page_content="foo3", metadata={"page": 2})] + assert output[0].page_content == "foo3" + assert output[0].metadata == {"page": 2} def test_opensearch_script_scoring() -> None: @@ -127,7 +150,8 @@ def test_opensearch_script_scoring() -> None: output = docsearch.similarity_search( "foo", k=1, search_type=SCRIPT_SCORING_SEARCH, pre_filter=pre_filter_val ) - assert output == [Document(page_content="bar")] + assert output[0].page_content == "bar" + assert output[0].id is not None def test_add_text_script_scoring() -> None: @@ -144,7 +168,8 @@ def test_add_text_script_scoring() -> None: output = docsearch.similarity_search( "add", k=1, search_type=SCRIPT_SCORING_SEARCH, space_type="innerproduct" ) - assert output == [Document(page_content="test")] + assert output[0].page_content == "test" + assert output[0].id is not None def test_opensearch_painless_scripting() -> None: @@ -159,7 +184,8 @@ def test_opensearch_painless_scripting() -> None: output = docsearch.similarity_search( "foo", k=1, search_type=PAINLESS_SCRIPTING_SEARCH, pre_filter=pre_filter_val ) - assert output == [Document(page_content="baz")] + assert output[0].page_content == "baz" + assert output[0].id is not None def test_add_text_painless_scripting() -> None: @@ -176,7 +202,8 @@ def test_add_text_painless_scripting() -> None: output = docsearch.similarity_search( "add", k=1, search_type=PAINLESS_SCRIPTING_SEARCH, space_type="cosineSimilarity" ) - assert output == [Document(page_content="test")] + assert output[0].page_content == "test" + assert output[0].id is not None def test_opensearch_invalid_search_type() -> None: @@ -207,7 +234,8 @@ def test_appx_search_with_boolean_filter() -> None: output = docsearch.similarity_search( "foo", k=3, boolean_filter=boolean_filter_val, subquery_clause="should" ) - assert output == [Document(page_content="bar")] + assert output[0].page_content == "bar" + assert output[0].id is not None def test_appx_search_with_lucene_filter() -> None: @@ -217,7 +245,8 @@ def test_appx_search_with_lucene_filter() -> None: texts, FakeEmbeddings(), opensearch_url=DEFAULT_OPENSEARCH_URL, engine="lucene" ) output = docsearch.similarity_search("foo", k=3, lucene_filter=lucene_filter_val) - assert output == [Document(page_content="bar")] + assert output[0].page_content == "bar" + assert output[0].id is not None def test_opensearch_with_custom_field_name_appx_true() -> None: @@ -230,7 +259,8 @@ def test_opensearch_with_custom_field_name_appx_true() -> None: is_appx_search=True, ) output = docsearch.similarity_search("add", k=1) - assert output == [Document(page_content="add")] + assert output[0].page_content == "add" + assert output[0].id is not None def test_opensearch_with_custom_field_name_appx_false() -> None: @@ -240,7 +270,8 @@ def test_opensearch_with_custom_field_name_appx_false() -> None: text_input, FakeEmbeddings(), opensearch_url=DEFAULT_OPENSEARCH_URL ) output = docsearch.similarity_search("add", k=1) - assert output == [Document(page_content="add")] + assert output[0].page_content == "add" + assert output[0].id is not None def test_opensearch_serverless_with_scripting_search_indexing_throws_error() -> None: @@ -338,4 +369,5 @@ def test_appx_search_with_faiss_efficient_filter() -> None: output = docsearch.similarity_search( "foo", k=3, efficient_filter=efficient_filter_val ) - assert output == [Document(page_content="bar")] + assert output[0].page_content == "bar" + assert output[0].id is not None From 14f182795312f01985344576b5199681683641e1 Mon Sep 17 00:00:00 2001 From: murrlincoln <65836530+murrlincoln@users.noreply.github.com> Date: Thu, 7 Nov 2024 04:28:27 +0700 Subject: [PATCH 15/26] docs: Adding notebook for cdp agentkit toolkit (#27910) - **Description:** Adding in the first pass of documentation for the CDP Agentkit Toolkit - **Issue:** N/a - **Dependencies:** cdp-langchain - **Twitter handle:** @CoinbaseDev --------- Co-authored-by: Erick Friis Co-authored-by: John Peterson --- .../integrations/tools/cdp_agentkit.ipynb | 332 ++++++++++++++++++ 1 file changed, 332 insertions(+) create mode 100644 docs/docs/integrations/tools/cdp_agentkit.ipynb diff --git a/docs/docs/integrations/tools/cdp_agentkit.ipynb b/docs/docs/integrations/tools/cdp_agentkit.ipynb new file mode 100644 index 0000000000000..738074116a3e3 --- /dev/null +++ b/docs/docs/integrations/tools/cdp_agentkit.ipynb @@ -0,0 +1,332 @@ +{ + "cells": [ + { + "cell_type": "raw", + "id": "afaf8039", + "metadata": {}, + "source": [ + "---\n", + "sidebar_label: CDP\n", + "---" + ] + }, + { + "cell_type": "markdown", + "id": "e49f1e0d", + "metadata": {}, + "source": [ + "# CDP Agentkit Toolkit\n", + "\n", + "The `CDP Agentkit` toolkit contains tools that enable an LLM agent to interact with the [Coinbase Developer Platform](https://docs.cdp.coinbase.com/). The toolkit provides a wrapper around the CDP SDK, allowing agents to perform onchain operations like transfers, trades, and smart contract interactions.\n", + "\n", + "## Overview\n", + "\n", + "### Integration details\n", + "\n", + "| Class | Package | Serializable | JS support | Package latest |\n", + "| :--- | :--- | :---: | :---: | :---: |\n", + "| CdpToolkit | `cdp-langchain` | ❌ | ❌ | ![PyPI - Version](https://img.shields.io/pypi/v/cdp-langchain?style=flat-square&label=%20) |\n", + "\n", + "### Tool features\n", + "\n", + "The toolkit provides the following tools:\n", + "\n", + "1. **get_wallet_details** - Get details about the MPC Wallet\n", + "2. **get_balance** - Get balance for specific assets\n", + "3. **request_faucet_funds** - Request test tokens from faucet\n", + "4. **transfer** - Transfer assets between addresses\n", + "5. **trade** - Trade assets (Mainnet only)\n", + "6. **deploy_token** - Deploy ERC-20 token contracts\n", + "7. **mint_nft** - Mint NFTs from existing contracts\n", + "8. **deploy_nft** - Deploy new NFT contracts\n", + "9. **register_basename** - Register a basename for the wallet\n", + "\n", + "We encourage you to add your own tools, both using CDP and web2 APIs, to create an agent that is tailored to your needs.\n", + "\n", + "## Setup\n", + "\n", + "At a high-level, we will:\n", + "\n", + "1. Install the langchain package\n", + "2. Set up your CDP API credentials\n", + "3. Initialize the CDP wrapper and toolkit\n", + "4. Pass the tools to your agent with `toolkit.get_tools()`" + ] + }, + { + "cell_type": "markdown", + "id": "72ee0c4b", + "metadata": {}, + "source": [ + "If you want to get automated tracing from runs of individual tools, you can also set your [LangSmith](https://docs.smith.langchain.com/) API key by uncommenting below:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a15d341e", + "metadata": {}, + "outputs": [], + "source": [ + "# os.environ[\"LANGSMITH_API_KEY\"] = getpass.getpass(\"Enter your LangSmith API key: \")\n", + "# os.environ[\"LANGSMITH_TRACING\"] = \"true\"" + ] + }, + { + "cell_type": "markdown", + "id": "0730d6a1", + "metadata": {}, + "source": [ + "### Installation\n", + "\n", + "This toolkit lives in the `cdp-langchain` package:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "652d6238", + "metadata": {}, + "outputs": [], + "source": [ + "%pip install -qU cdp-langchain" + ] + }, + { + "cell_type": "markdown", + "id": "a38cde65", + "metadata": {}, + "source": [ + "#### Set Environment Variables\n", + "\n", + "To use this toolkit, you must first set the following environment variables to access the [CDP APIs](https://docs.cdp.coinbase.com/mpc-wallet/docs/quickstart) to create wallets and interact onchain. You can sign up for an API key for free on the [CDP Portal](https://cdp.coinbase.com/):" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cb09c344", + "metadata": {}, + "outputs": [], + "source": [ + "import getpass\n", + "import os\n", + "\n", + "for env_var in [\n", + " \"CDP_API_KEY_NAME\",\n", + " \"CDP_API_KEY_PRIVATE_KEY\",\n", + "]:\n", + " if not os.getenv(env_var):\n", + " os.environ[env_var] = getpass.getpass(f\"Enter your {env_var}: \")\n", + "\n", + "# Optional: Set network (defaults to base-sepolia)\n", + "os.environ[\"NETWORK_ID\"] = \"base-sepolia\" # or \"base-mainnet\"" + ] + }, + { + "cell_type": "markdown", + "id": "5c5f2839", + "metadata": {}, + "source": [ + "## Instantiation\n", + "\n", + "Now we can instantiate our toolkit:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "51a60dbe", + "metadata": {}, + "outputs": [], + "source": [ + "from cdp_langchain.agent_toolkits import CdpToolkit\n", + "from cdp_langchain.utils import CdpAgentkitWrapper\n", + "\n", + "# Initialize CDP wrapper\n", + "cdp = CdpAgentkitWrapper()\n", + "\n", + "# Create toolkit from wrapper\n", + "toolkit = CdpToolkit.from_cdp_agentkit_wrapper(cdp)" + ] + }, + { + "cell_type": "markdown", + "id": "d11245ad", + "metadata": {}, + "source": [ + "## Tools\n", + "\n", + "View [available tools](#tool-features):" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "310bf18e", + "metadata": {}, + "outputs": [], + "source": [ + "tools = toolkit.get_tools()\n", + "for tool in tools:\n", + " print(tool.name)" + ] + }, + { + "cell_type": "markdown", + "id": "23e11cc9", + "metadata": {}, + "source": [ + "## Use within an agent\n", + "\n", + "We will need a LLM or chat model:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d1ee55bc", + "metadata": {}, + "outputs": [], + "source": [ + "from langchain_openai import ChatOpenAI\n", + "\n", + "llm = ChatOpenAI(model=\"gpt-4o-mini\")" + ] + }, + { + "cell_type": "markdown", + "id": "3a5bb5ca", + "metadata": {}, + "source": [ + "Initialize the agent with the tools:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f8a2c4b1", + "metadata": {}, + "outputs": [], + "source": [ + "from langgraph.prebuilt import create_react_agent\n", + "\n", + "tools = toolkit.get_tools()\n", + "agent_executor = create_react_agent(llm, tools)" + ] + }, + { + "cell_type": "markdown", + "id": "b4a7c9d2", + "metadata": {}, + "source": [ + "Example usage:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c9a8e4f3", + "metadata": {}, + "outputs": [], + "source": [ + "example_query = \"Send 0.005 ETH to john2879.base.eth\"\n", + "\n", + "events = agent_executor.stream(\n", + " {\"messages\": [(\"user\", example_query)]},\n", + " stream_mode=\"values\",\n", + ")\n", + "for event in events:\n", + " event[\"messages\"][-1].pretty_print()" + ] + }, + { + "cell_type": "markdown", + "id": "e5a7c9d4", + "metadata": {}, + "source": [ + "Expected output:\n", + "```\n", + "Transferred 0.005 of eth to john2879.base.eth.\n", + "Transaction hash for the transfer: 0x78c7c2878659a0de216d0764fc87eff0d38b47f3315fa02ba493a83d8e782d1e\n", + "Transaction link for the transfer: https://sepolia.basescan.org/tx/0x78c7c2878659a0de216d0764fc87eff0d38b47f3315fa02ba493a83d8e782d1\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "f5a7c9d5", + "metadata": {}, + "source": [ + "## CDP Toolkit Specific Features\n", + "\n", + "### Wallet Management\n", + "\n", + "The toolkit maintains an MPC wallet. The wallet data can be exported and imported to persist between sessions:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "g5a7c9d6", + "metadata": {}, + "outputs": [], + "source": [ + "# Export wallet data\n", + "wallet_data = cdp.export_wallet()\n", + "\n", + "# Import wallet data\n", + "values = {\"cdp_wallet_data\": wallet_data}\n", + "cdp = CdpAgentkitWrapper(**values)" + ] + }, + { + "cell_type": "markdown", + "id": "h5a7c9d7", + "metadata": {}, + "source": [ + "### Network Support\n", + "\n", + "The toolkit supports [multiple networks](https://docs.cdp.coinbase.com/cdp-sdk/docs/networks)\n", + "\n", + "### Gasless Transactions\n", + "\n", + "Some operations support gasless transactions on Base Mainnet:\n", + "- USDC transfers\n", + "- EURC transfers\n", + "- cbBTC transfers" + ] + }, + { + "cell_type": "markdown", + "id": "i5a7c9d8", + "metadata": {}, + "source": [ + "## API reference\n", + "\n", + "For detailed documentation of all CDP features and configurations head to the [CDP docs](https://docs.cdp.coinbase.com/mpc-wallet/docs/welcome)." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.4" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 60123bef67287992bbf014dc991e3a64c8e2c60e Mon Sep 17 00:00:00 2001 From: Bagatur <22008038+baskaryan@users.noreply.github.com> Date: Wed, 6 Nov 2024 14:25:13 -0800 Subject: [PATCH 16/26] docs: fix trim_messages docstring (#27948) --- libs/core/langchain_core/messages/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/core/langchain_core/messages/utils.py b/libs/core/langchain_core/messages/utils.py index 0ea03e40d00d4..2fce9f7dbcaf7 100644 --- a/libs/core/langchain_core/messages/utils.py +++ b/libs/core/langchain_core/messages/utils.py @@ -590,7 +590,7 @@ def trim_messages( include_system: bool = False, text_splitter: Optional[Union[Callable[[str], list[str]], TextSplitter]] = None, ) -> list[BaseMessage]: - """Trim messages to be below a token count. + r"""Trim messages to be below a token count. trim_messages can be used to reduce the size of a chat history to a specified token count or specified message count. From 0f85dea8c89f00a72ef52043a6d2abad1cd0d1ae Mon Sep 17 00:00:00 2001 From: Roman Solomatin Date: Thu, 7 Nov 2024 03:35:39 +0500 Subject: [PATCH 17/26] langchain-huggingface: use separate kwargs for queries and docs (#27857) Now `encode_kwargs` used for both for documents and queries and this leads to wrong embeddings. E. g.: ```python model_kwargs = {"device": "cuda", "trust_remote_code": True} encode_kwargs = {"normalize_embeddings": False, "prompt_name": "s2p_query"} model = HuggingFaceEmbeddings( model_name="dunzhang/stella_en_400M_v5", model_kwargs=model_kwargs, encode_kwargs=encode_kwargs, ) query_embedding = np.array( model.embed_query("What are some ways to reduce stress?",) ) document_embedding = np.array( model.embed_documents( [ "There are many effective ways to reduce stress. Some common techniques include deep breathing, meditation, and physical activity. Engaging in hobbies, spending time in nature, and connecting with loved ones can also help alleviate stress. Additionally, setting boundaries, practicing self-care, and learning to say no can prevent stress from building up.", "Green tea has been consumed for centuries and is known for its potential health benefits. It contains antioxidants that may help protect the body against damage caused by free radicals. Regular consumption of green tea has been associated with improved heart health, enhanced cognitive function, and a reduced risk of certain types of cancer. The polyphenols in green tea may also have anti-inflammatory and weight loss properties.", ] ) ) print(model._client.similarity(query_embedding, document_embedding)) # output: tensor([[0.8421, 0.3317]], dtype=torch.float64) ``` But from the [model card](https://huggingface.co/dunzhang/stella_en_400M_v5#sentence-transformers) expexted like this: ```python model_kwargs = {"device": "cuda", "trust_remote_code": True} encode_kwargs = {"normalize_embeddings": False} query_encode_kwargs = {"normalize_embeddings": False, "prompt_name": "s2p_query"} model = HuggingFaceEmbeddings( model_name="dunzhang/stella_en_400M_v5", model_kwargs=model_kwargs, encode_kwargs=encode_kwargs, query_encode_kwargs=query_encode_kwargs, ) query_embedding = np.array( model.embed_query("What are some ways to reduce stress?", ) ) document_embedding = np.array( model.embed_documents( [ "There are many effective ways to reduce stress. Some common techniques include deep breathing, meditation, and physical activity. Engaging in hobbies, spending time in nature, and connecting with loved ones can also help alleviate stress. Additionally, setting boundaries, practicing self-care, and learning to say no can prevent stress from building up.", "Green tea has been consumed for centuries and is known for its potential health benefits. It contains antioxidants that may help protect the body against damage caused by free radicals. Regular consumption of green tea has been associated with improved heart health, enhanced cognitive function, and a reduced risk of certain types of cancer. The polyphenols in green tea may also have anti-inflammatory and weight loss properties.", ] ) ) print(model._client.similarity(query_embedding, document_embedding)) # tensor([[0.8398, 0.2990]], dtype=torch.float64) ``` --- .../embeddings/huggingface.py | 41 +++++++++++++++---- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/libs/partners/huggingface/langchain_huggingface/embeddings/huggingface.py b/libs/partners/huggingface/langchain_huggingface/embeddings/huggingface.py index 180a9ed3b5e79..2bbc551f4e0b1 100644 --- a/libs/partners/huggingface/langchain_huggingface/embeddings/huggingface.py +++ b/libs/partners/huggingface/langchain_huggingface/embeddings/huggingface.py @@ -36,9 +36,14 @@ class HuggingFaceEmbeddings(BaseModel, Embeddings): `prompts`, `default_prompt_name`, `revision`, `trust_remote_code`, or `token`. See also the Sentence Transformer documentation: https://sbert.net/docs/package_reference/SentenceTransformer.html#sentence_transformers.SentenceTransformer""" encode_kwargs: Dict[str, Any] = Field(default_factory=dict) - """Keyword arguments to pass when calling the `encode` method of the Sentence - Transformer model, such as `prompt_name`, `prompt`, `batch_size`, `precision`, - `normalize_embeddings`, and more. + """Keyword arguments to pass when calling the `encode` method for the documents of + the Sentence Transformer model, such as `prompt_name`, `prompt`, `batch_size`, + `precision`, `normalize_embeddings`, and more. + See also the Sentence Transformer documentation: https://sbert.net/docs/package_reference/SentenceTransformer.html#sentence_transformers.SentenceTransformer.encode""" + query_encode_kwargs: Dict[str, Any] = Field(default_factory=dict) + """Keyword arguments to pass when calling the `encode` method for the query of + the Sentence Transformer model, such as `prompt_name`, `prompt`, `batch_size`, + `precision`, `normalize_embeddings`, and more. See also the Sentence Transformer documentation: https://sbert.net/docs/package_reference/SentenceTransformer.html#sentence_transformers.SentenceTransformer.encode""" multi_process: bool = False """Run encode() on multiple GPUs.""" @@ -65,11 +70,17 @@ def __init__(self, **kwargs: Any): protected_namespaces=(), ) - def embed_documents(self, texts: List[str]) -> List[List[float]]: - """Compute doc embeddings using a HuggingFace transformer model. + def _embed( + self, texts: list[str], encode_kwargs: Dict[str, Any] + ) -> List[List[float]]: + """ + Embed a text using the HuggingFace transformer model. Args: texts: The list of texts to embed. + encode_kwargs: Keyword arguments to pass when calling the + `encode` method for the documents of the SentenceTransformer + encode method. Returns: List of embeddings, one for each text. @@ -85,7 +96,7 @@ def embed_documents(self, texts: List[str]) -> List[List[float]]: embeddings = self._client.encode( texts, show_progress_bar=self.show_progress, - **self.encode_kwargs, # type: ignore + **encode_kwargs, # type: ignore ) if isinstance(embeddings, list): @@ -96,6 +107,17 @@ def embed_documents(self, texts: List[str]) -> List[List[float]]: return embeddings.tolist() + def embed_documents(self, texts: List[str]) -> List[List[float]]: + """Compute doc embeddings using a HuggingFace transformer model. + + Args: + texts: The list of texts to embed. + + Returns: + List of embeddings, one for each text. + """ + return self._embed(texts, self.encode_kwargs) + def embed_query(self, text: str) -> List[float]: """Compute query embeddings using a HuggingFace transformer model. @@ -105,4 +127,9 @@ def embed_query(self, text: str) -> List[float]: Returns: Embeddings for the text. """ - return self.embed_documents([text])[0] + embed_kwargs = ( + self.query_encode_kwargs + if len(self.query_encode_kwargs) > 0 + else self.encode_kwargs + ) + return self._embed([text], embed_kwargs)[0] From 482c168b3e8ac982130bacc89fc9a32b67f765a3 Mon Sep 17 00:00:00 2001 From: takahashi <7567050+MasaYan24@users.noreply.github.com> Date: Thu, 7 Nov 2024 07:37:07 +0900 Subject: [PATCH 18/26] langchain_core: add `file_type` option to make file type default as `png` (#27855) Thank you for contributing to LangChain! - [ ] **PR title**: "package: description" - Where "package" is whichever of langchain, community, core, etc. is being modified. Use "docs: ..." for purely docs changes, "templates: ..." for template changes, "infra: ..." for CI changes. - Example: "community: add foobar LLM" - [ ] **description** langchain_core.runnables.graph_mermaid.draw_mermaid_png calls this function, but the Mermaid API returns JPEG by default. To be consistent, add the option `file_type` with the default `png` type. - [ ] **Add tests and docs**: If you're adding a new integration, please include With this small change, I didn't add tests and docs. - [ ] **Lint and test**: Run `make format`, `make lint` and `make test` from the root of the package(s) you've modified. See contribution guidelines for more: One long sentence was divided into two. Additional guidelines: - Make sure optional dependencies are imported within a function. - Please do not add dependencies to pyproject.toml files (even optional ones) unless they are required for unit tests. - Most PRs should not touch more than one package. - Changes should be backwards compatible. - If you are adding something to community, do not re-import it in langchain. If no one reviews your PR within a few days, please @-mention one of baskaryan, efriis, eyurtsev, ccurme, vbarda, hwchase17. --- libs/core/langchain_core/runnables/graph_mermaid.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libs/core/langchain_core/runnables/graph_mermaid.py b/libs/core/langchain_core/runnables/graph_mermaid.py index b0e7f3dd5de5e..c9b3025bc857d 100644 --- a/libs/core/langchain_core/runnables/graph_mermaid.py +++ b/libs/core/langchain_core/runnables/graph_mermaid.py @@ -2,7 +2,7 @@ import base64 import re from dataclasses import asdict -from typing import Optional +from typing import Literal, Optional from langchain_core.runnables.graph import ( CurveStyle, @@ -306,6 +306,7 @@ def _render_mermaid_using_api( mermaid_syntax: str, output_file_path: Optional[str] = None, background_color: Optional[str] = "white", + file_type: Optional[Literal["jpeg", "png", "webp"]] = "png", ) -> bytes: """Renders Mermaid graph using the Mermaid.INK API.""" try: @@ -329,7 +330,8 @@ def _render_mermaid_using_api( background_color = f"!{background_color}" image_url = ( - f"https://mermaid.ink/img/{mermaid_syntax_encoded}?bgColor={background_color}" + f"https://mermaid.ink/img/{mermaid_syntax_encoded}" + f"?type={file_type}&bgColor={background_color}" ) response = requests.get(image_url, timeout=10) if response.status_code == 200: From 90189f5639560d1c4923e39885d3c8eb3c94caf2 Mon Sep 17 00:00:00 2001 From: Martin Triska Date: Wed, 6 Nov 2024 23:44:34 +0100 Subject: [PATCH 19/26] community: Allow other than default parsers in SharePointLoader and OneDriveLoader (#27716) ## What this PR does? ### Currently `O365BaseLoader` (and consequently both derived loaders) are limited to `pdf`, `doc`, `docx` files. - **Solution: here we introduce _handlers_ attribute that allows for custom handlers to be passed in. This is done in _dict_ form:** **Example:** ```python from langchain_community.document_loaders.parsers.documentloader_adapter import DocumentLoaderAsParser # PR for DocumentLoaderAsParser here: https://github.com/langchain-ai/langchain/pull/27749 from langchain_community.document_loaders.excel import UnstructuredExcelLoader xlsx_parser = DocumentLoaderAsParser(UnstructuredExcelLoader, mode="paged") # create dictionary mapping file types to handlers (parsers) handlers = { "doc": MsWordParser() "pdf": PDFMinerParser() "txt": TextParser() "xlsx": xlsx_parser } loader = SharePointLoader(document_library_id="...", handlers=handlers # pass handlers to SharePointLoader ) documents = loader.load() # works the same in OneDriveLoader loader = OneDriveLoader(document_library_id="...", handlers=handlers ) ``` This dictionary is then passed to `MimeTypeBasedParser` same as in the [current implementation](https://github.com/langchain-ai/langchain/blob/5a2cfb49e045988d290a1c7e3a0c589d6b371694/libs/community/langchain_community/document_loaders/parsers/registry.py#L13). ### Currently `SharePointLoader` and `OneDriveLoader` are separate loaders that both inherit from `O365BaseLoader` However both of these implement the same functionality. The only differences are: - `SharePointLoader` requires argument `document_library_id` whereas `OneDriveLoader` requires `drive_id`. These are just different names for the same thing. - `SharePointLoader` implements significantly more features. - **Solution: `OneDriveLoader` is replaced with an empty shell just renaming `drive_id` to `document_library_id` and inheriting from `SharePointLoader`** **Dependencies:** None **Twitter handle:** @martintriska1 If no one reviews your PR within a few days, please @-mention one of baskaryan, efriis, eyurtsev, ccurme, vbarda, hwchase17. --- .../document_loaders/microsoft_onedrive.ipynb | 67 ++++++++-- .../microsoft_sharepoint.ipynb | 60 ++++++++- .../document_loaders/base_o365.py | 116 ++++++++++++++---- .../document_loaders/onedrive.py | 97 ++------------- .../document_loaders/sharepoint.py | 23 +--- 5 files changed, 227 insertions(+), 136 deletions(-) diff --git a/docs/docs/integrations/document_loaders/microsoft_onedrive.ipynb b/docs/docs/integrations/document_loaders/microsoft_onedrive.ipynb index b42c141f8fea4..20feef0f9cc3c 100644 --- a/docs/docs/integrations/document_loaders/microsoft_onedrive.ipynb +++ b/docs/docs/integrations/document_loaders/microsoft_onedrive.ipynb @@ -8,7 +8,7 @@ "\n", ">[Microsoft OneDrive](https://en.wikipedia.org/wiki/OneDrive) (formerly `SkyDrive`) is a file hosting service operated by Microsoft.\n", "\n", - "This notebook covers how to load documents from `OneDrive`. Currently, only docx, doc, and pdf files are supported.\n", + "This notebook covers how to load documents from `OneDrive`. By default the document loader loads `pdf`, `doc`, `docx` and `txt` files. You can load other file types by providing appropriate parsers (see more below).\n", "\n", "## Prerequisites\n", "1. Register an application with the [Microsoft identity platform](https://learn.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app) instructions.\n", @@ -77,15 +77,64 @@ "\n", "loader = OneDriveLoader(drive_id=\"YOUR DRIVE ID\", object_ids=[\"ID_1\", \"ID_2\"], auth_with_token=True)\n", "documents = loader.load()\n", - "```\n" + "```\n", + "\n", + "#### 📑 Choosing supported file types and preffered parsers\n", + "By default `OneDriveLoader` loads file types defined in [`document_loaders/parsers/registry`](https://github.com/langchain-ai/langchain/blob/master/libs/community/langchain_community/document_loaders/parsers/registry.py#L10-L22) using the default parsers (see below).\n", + "```python\n", + "def _get_default_parser() -> BaseBlobParser:\n", + " \"\"\"Get default mime-type based parser.\"\"\"\n", + " return MimeTypeBasedParser(\n", + " handlers={\n", + " \"application/pdf\": PyMuPDFParser(),\n", + " \"text/plain\": TextParser(),\n", + " \"application/msword\": MsWordParser(),\n", + " \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\": (\n", + " MsWordParser()\n", + " ),\n", + " },\n", + " fallback_parser=None,\n", + " )\n", + "```\n", + "You can override this behavior by passing `handlers` argument to `OneDriveLoader`. \n", + "Pass a dictionary mapping either file extensions (like `\"doc\"`, `\"pdf\"`, etc.) \n", + "or MIME types (like `\"application/pdf\"`, `\"text/plain\"`, etc.) to parsers. \n", + "Note that you must use either file extensions or MIME types exclusively and \n", + "cannot mix them.\n", + "\n", + "Do not include the leading dot for file extensions.\n", + "\n", + "```python\n", + "# using file extensions:\n", + "handlers = {\n", + " \"doc\": MsWordParser(),\n", + " \"pdf\": PDFMinerParser(),\n", + " \"mp3\": OpenAIWhisperParser()\n", + "}\n", + "\n", + "# using MIME types:\n", + "handlers = {\n", + " \"application/msword\": MsWordParser(),\n", + " \"application/pdf\": PDFMinerParser(),\n", + " \"audio/mpeg\": OpenAIWhisperParser()\n", + "}\n", + "\n", + "loader = OneDriveLoader(document_library_id=\"...\",\n", + " handlers=handlers # pass handlers to OneDriveLoader\n", + " )\n", + "```\n", + "In case multiple file extensions map to the same MIME type, the last dictionary item will\n", + "apply.\n", + "Example:\n", + "```python\n", + "# 'jpg' and 'jpeg' both map to 'image/jpeg' MIME type. SecondParser() will be used \n", + "# to parse all jpg/jpeg files.\n", + "handlers = {\n", + " \"jpg\": FirstParser(),\n", + " \"jpeg\": SecondParser()\n", + "}\n", + "```" ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { diff --git a/docs/docs/integrations/document_loaders/microsoft_sharepoint.ipynb b/docs/docs/integrations/document_loaders/microsoft_sharepoint.ipynb index 930346675dfd9..b49abe39f5158 100644 --- a/docs/docs/integrations/document_loaders/microsoft_sharepoint.ipynb +++ b/docs/docs/integrations/document_loaders/microsoft_sharepoint.ipynb @@ -9,7 +9,7 @@ "\n", "> [Microsoft SharePoint](https://en.wikipedia.org/wiki/SharePoint) is a website-based collaboration system that uses workflow applications, “list” databases, and other web parts and security features to empower business teams to work together developed by Microsoft.\n", "\n", - "This notebook covers how to load documents from the [SharePoint Document Library](https://support.microsoft.com/en-us/office/what-is-a-document-library-3b5976dd-65cf-4c9e-bf5a-713c10ca2872). Currently, only docx, doc, and pdf files are supported.\n", + "This notebook covers how to load documents from the [SharePoint Document Library](https://support.microsoft.com/en-us/office/what-is-a-document-library-3b5976dd-65cf-4c9e-bf5a-713c10ca2872). By default the document loader loads `pdf`, `doc`, `docx` and `txt` files. You can load other file types by providing appropriate parsers (see more below).\n", "\n", "## Prerequisites\n", "1. Register an application with the [Microsoft identity platform](https://learn.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app) instructions.\n", @@ -100,7 +100,63 @@ "\n", "loader = SharePointLoader(document_library_id=\"YOUR DOCUMENT LIBRARY ID\", object_ids=[\"ID_1\", \"ID_2\"], auth_with_token=True)\n", "documents = loader.load()\n", - "```\n" + "```\n", + "\n", + "#### 📑 Choosing supported file types and preffered parsers\n", + "By default `SharePointLoader` loads file types defined in [`document_loaders/parsers/registry`](https://github.com/langchain-ai/langchain/blob/master/libs/community/langchain_community/document_loaders/parsers/registry.py#L10-L22) using the default parsers (see below).\n", + "```python\n", + "def _get_default_parser() -> BaseBlobParser:\n", + " \"\"\"Get default mime-type based parser.\"\"\"\n", + " return MimeTypeBasedParser(\n", + " handlers={\n", + " \"application/pdf\": PyMuPDFParser(),\n", + " \"text/plain\": TextParser(),\n", + " \"application/msword\": MsWordParser(),\n", + " \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\": (\n", + " MsWordParser()\n", + " ),\n", + " },\n", + " fallback_parser=None,\n", + " )\n", + "```\n", + "You can override this behavior by passing `handlers` argument to `SharePointLoader`. \n", + "Pass a dictionary mapping either file extensions (like `\"doc\"`, `\"pdf\"`, etc.) \n", + "or MIME types (like `\"application/pdf\"`, `\"text/plain\"`, etc.) to parsers. \n", + "Note that you must use either file extensions or MIME types exclusively and \n", + "cannot mix them.\n", + "\n", + "Do not include the leading dot for file extensions.\n", + "\n", + "```python\n", + "# using file extensions:\n", + "handlers = {\n", + " \"doc\": MsWordParser(),\n", + " \"pdf\": PDFMinerParser(),\n", + " \"mp3\": OpenAIWhisperParser()\n", + "}\n", + "\n", + "# using MIME types:\n", + "handlers = {\n", + " \"application/msword\": MsWordParser(),\n", + " \"application/pdf\": PDFMinerParser(),\n", + " \"audio/mpeg\": OpenAIWhisperParser()\n", + "}\n", + "\n", + "loader = SharePointLoader(document_library_id=\"...\",\n", + " handlers=handlers # pass handlers to SharePointLoader\n", + " )\n", + "```\n", + "In case multiple file extensions map to the same MIME type, the last dictionary item will\n", + "apply.\n", + "Example:\n", + "```python\n", + "# 'jpg' and 'jpeg' both map to 'image/jpeg' MIME type. SecondParser() will be used \n", + "# to parse all jpg/jpeg files.\n", + "handlers = {\n", + " \"jpg\": FirstParser(),\n", + " \"jpeg\": SecondParser()\n", + "}\n", + "```" ] } ], diff --git a/libs/community/langchain_community/document_loaders/base_o365.py b/libs/community/langchain_community/document_loaders/base_o365.py index 44002842bf25d..5f89d0794fccd 100644 --- a/libs/community/langchain_community/document_loaders/base_o365.py +++ b/libs/community/langchain_community/document_loaders/base_o365.py @@ -3,26 +3,29 @@ from __future__ import annotations import logging +import mimetypes import os import tempfile from abc import abstractmethod -from enum import Enum from pathlib import Path, PurePath -from typing import TYPE_CHECKING, Any, Dict, Iterable, List, Sequence, Union +from typing import TYPE_CHECKING, Any, Dict, Iterable, List, Optional, Sequence, Union from pydantic import ( BaseModel, Field, FilePath, + PrivateAttr, SecretStr, ) from pydantic_settings import BaseSettings, SettingsConfigDict -from langchain_community.document_loaders.base import BaseLoader +from langchain_community.document_loaders.base import BaseBlobParser, BaseLoader from langchain_community.document_loaders.blob_loaders.file_system import ( FileSystemBlobLoader, ) from langchain_community.document_loaders.blob_loaders.schema import Blob +from langchain_community.document_loaders.parsers.generic import MimeTypeBasedParser +from langchain_community.document_loaders.parsers.registry import get_parser if TYPE_CHECKING: from O365 import Account @@ -46,24 +49,27 @@ class _O365TokenStorage(BaseSettings): token_path: FilePath = Path.home() / ".credentials" / "o365_token.txt" -class _FileType(str, Enum): - DOC = "doc" - DOCX = "docx" - PDF = "pdf" +def fetch_mime_types(file_types: Sequence[str]) -> Dict[str, str]: + """Fetch the mime types for the specified file types.""" + mime_types_mapping = {} + for ext in file_types: + mime_type, _ = mimetypes.guess_type(f"file.{ext}") + if mime_type: + mime_types_mapping[ext] = mime_type + else: + raise ValueError(f"Unknown mimetype of extention {ext}") + return mime_types_mapping -def fetch_mime_types(file_types: Sequence[_FileType]) -> Dict[str, str]: +def fetch_extensions(mime_types: Sequence[str]) -> Dict[str, str]: """Fetch the mime types for the specified file types.""" mime_types_mapping = {} - for file_type in file_types: - if file_type.value == "doc": - mime_types_mapping[file_type.value] = "application/msword" - elif file_type.value == "docx": - mime_types_mapping[file_type.value] = ( - "application/vnd.openxmlformats-officedocument.wordprocessingml.document" # noqa: E501 - ) - elif file_type.value == "pdf": - mime_types_mapping[file_type.value] = "application/pdf" + for mime_type in mime_types: + ext = mimetypes.guess_extension(mime_type) + if ext: + mime_types_mapping[ext[1:]] = mime_type # ignore leading `.` + else: + raise ValueError(f"Unknown mimetype {mime_type}") return mime_types_mapping @@ -78,16 +84,82 @@ class O365BaseLoader(BaseLoader, BaseModel): """Number of bytes to retrieve from each api call to the server. int or 'auto'.""" recursive: bool = False """Should the loader recursively load subfolders?""" + handlers: Optional[Dict[str, Any]] = {} + """ + Provide custom handlers for MimeTypeBasedParser. + + Pass a dictionary mapping either file extensions (like "doc", "pdf", etc.) + or MIME types (like "application/pdf", "text/plain", etc.) to parsers. + Note that you must use either file extensions or MIME types exclusively and + cannot mix them. + + Do not include the leading dot for file extensions. + + Example using file extensions: + ```python + handlers = { + "doc": MsWordParser(), + "pdf": PDFMinerParser(), + "txt": TextParser() + } + ``` + + Example using MIME types: + ```python + handlers = { + "application/msword": MsWordParser(), + "application/pdf": PDFMinerParser(), + "text/plain": TextParser() + } + ``` + """ + + _blob_parser: BaseBlobParser = PrivateAttr() + _file_types: Sequence[str] = PrivateAttr() + _mime_types: Dict[str, str] = PrivateAttr() + + def __init__(self, **kwargs: Any) -> None: + super().__init__(**kwargs) + if self.handlers: + handler_keys = list(self.handlers.keys()) + try: + # assume handlers.keys() are file extensions + self._mime_types = fetch_mime_types(handler_keys) + self._file_types = list(set(handler_keys)) + mime_handlers = { + self._mime_types[extension]: handler + for extension, handler in self.handlers.items() + } + except ValueError: + try: + # assume handlers.keys() are mime types + self._mime_types = fetch_extensions(handler_keys) + self._file_types = list(set(self._mime_types.keys())) + mime_handlers = self.handlers + except ValueError: + raise ValueError( + "`handlers` keys must be either file extensions or mimetypes.\n" + f"{handler_keys} could not be interpreted as either.\n" + "File extensions and mimetypes cannot mix. " + "Use either one or the other" + ) - @property - @abstractmethod - def _file_types(self) -> Sequence[_FileType]: - """Return supported file types.""" + self._blob_parser = MimeTypeBasedParser( + handlers=mime_handlers, fallback_parser=None + ) + else: + self._blob_parser = get_parser("default") + if not isinstance(self._blob_parser, MimeTypeBasedParser): + raise TypeError( + 'get_parser("default) was supposed to return MimeTypeBasedParser.' + f"It returned {type(self._blob_parser)}" + ) + self._mime_types = fetch_extensions(list(self._blob_parser.handlers.keys())) @property def _fetch_mime_types(self) -> Dict[str, str]: """Return a dict of supported file types to corresponding mime types.""" - return fetch_mime_types(self._file_types) + return self._mime_types @property @abstractmethod diff --git a/libs/community/langchain_community/document_loaders/onedrive.py b/libs/community/langchain_community/document_loaders/onedrive.py index ecc1d232bfe4c..e0369233c22bf 100644 --- a/libs/community/langchain_community/document_loaders/onedrive.py +++ b/libs/community/langchain_community/document_loaders/onedrive.py @@ -1,94 +1,19 @@ -"""Loads data from OneDrive""" +from typing import Any -from __future__ import annotations - -import logging -from typing import TYPE_CHECKING, Iterator, List, Optional, Sequence, Union - -from langchain_core.documents import Document from pydantic import Field -from langchain_community.document_loaders.base_o365 import ( - O365BaseLoader, - _FileType, -) -from langchain_community.document_loaders.parsers.registry import get_parser - -if TYPE_CHECKING: - from O365.drive import Drive, Folder - -logger = logging.getLogger(__name__) +from langchain_community.document_loaders import SharePointLoader -class OneDriveLoader(O365BaseLoader): - """Load from `Microsoft OneDrive`.""" +class OneDriveLoader(SharePointLoader): + """ + Load documents from Microsoft OneDrive. + Uses `SharePointLoader` under the hood. + """ drive_id: str = Field(...) - """ The ID of the OneDrive drive to load data from.""" - folder_path: Optional[str] = None - """ The path to the folder to load data from.""" - object_ids: Optional[List[str]] = None - """ The IDs of the objects to load data from.""" - - @property - def _file_types(self) -> Sequence[_FileType]: - """Return supported file types.""" - return _FileType.DOC, _FileType.DOCX, _FileType.PDF - - @property - def _scopes(self) -> List[str]: - """Return required scopes.""" - return ["offline_access", "Files.Read.All"] - - def _get_folder_from_path(self, drive: Drive) -> Union[Folder, Drive]: - """ - Returns the folder or drive object located at the - specified path relative to the given drive. - - Args: - drive (Drive): The root drive from which the folder path is relative. - - Returns: - Union[Folder, Drive]: The folder or drive object - located at the specified path. - - Raises: - FileNotFoundError: If the path does not exist. - """ - - subfolder_drive = drive - if self.folder_path is None: - return subfolder_drive - - subfolders = [f for f in self.folder_path.split("/") if f != ""] - if len(subfolders) == 0: - return subfolder_drive - - items = subfolder_drive.get_items() - for subfolder in subfolders: - try: - subfolder_drive = list(filter(lambda x: subfolder in x.name, items))[0] - items = subfolder_drive.get_items() - except (IndexError, AttributeError): - raise FileNotFoundError("Path {} not exist.".format(self.folder_path)) - return subfolder_drive + """The ID of the OneDrive drive to load data from.""" - def lazy_load(self) -> Iterator[Document]: - """Load documents lazily. Use this when working at a large scale.""" - try: - from O365.drive import Drive - except ImportError: - raise ImportError( - "O365 package not found, please install it with `pip install o365`" - ) - drive = self._auth().storage().get_drive(self.drive_id) - if not isinstance(drive, Drive): - raise ValueError(f"There isn't a Drive with id {self.drive_id}.") - blob_parser = get_parser("default") - if self.folder_path: - folder = self._get_folder_from_path(drive) - for blob in self._load_from_folder(folder): - yield from blob_parser.lazy_parse(blob) - if self.object_ids: - for blob in self._load_from_object_ids(drive, self.object_ids): - yield from blob_parser.lazy_parse(blob) + def __init__(self, **kwargs: Any) -> None: + kwargs["document_library_id"] = kwargs["drive_id"] + super().__init__(**kwargs) diff --git a/libs/community/langchain_community/document_loaders/sharepoint.py b/libs/community/langchain_community/document_loaders/sharepoint.py index 06426a7038fdd..6d5a820248e5f 100644 --- a/libs/community/langchain_community/document_loaders/sharepoint.py +++ b/libs/community/langchain_community/document_loaders/sharepoint.py @@ -4,7 +4,7 @@ import json from pathlib import Path -from typing import Any, Iterator, List, Optional, Sequence +from typing import Any, Dict, Iterator, List, Optional import requests # type: ignore from langchain_core.document_loaders import BaseLoader @@ -13,9 +13,7 @@ from langchain_community.document_loaders.base_o365 import ( O365BaseLoader, - _FileType, ) -from langchain_community.document_loaders.parsers.registry import get_parser class SharePointLoader(O365BaseLoader, BaseLoader): @@ -36,14 +34,6 @@ class SharePointLoader(O365BaseLoader, BaseLoader): load_extended_metadata: Optional[bool] = False """ Whether to load extended metadata. Size, Owner and full_path.""" - @property - def _file_types(self) -> Sequence[_FileType]: - """Return supported file types. - Returns: - A sequence of supported file types. - """ - return _FileType.DOC, _FileType.DOCX, _FileType.PDF - @property def _scopes(self) -> List[str]: """Return required scopes. @@ -67,7 +57,6 @@ def lazy_load(self) -> Iterator[Document]: drive = self._auth().storage().get_drive(self.document_library_id) if not isinstance(drive, Drive): raise ValueError(f"There isn't a Drive with id {self.document_library_id}.") - blob_parser = get_parser("default") if self.folder_path: target_folder = drive.get_item_by_path(self.folder_path) if not isinstance(target_folder, Folder): @@ -79,7 +68,7 @@ def lazy_load(self) -> Iterator[Document]: if self.load_extended_metadata is True: extended_metadata = self.get_extended_metadata(file_id) extended_metadata.update({"source_full_url": target_folder.web_url}) - for parsed_blob in blob_parser.lazy_parse(blob): + for parsed_blob in self._blob_parser.lazy_parse(blob): if self.load_auth is True: parsed_blob.metadata["authorized_identities"] = auth_identities if self.load_extended_metadata is True: @@ -96,7 +85,7 @@ def lazy_load(self) -> Iterator[Document]: if self.load_extended_metadata is True: extended_metadata = self.get_extended_metadata(file_id) extended_metadata.update({"source_full_url": target_folder.web_url}) - for parsed_blob in blob_parser.lazy_parse(blob): + for parsed_blob in self._blob_parser.lazy_parse(blob): if self.load_auth is True: parsed_blob.metadata["authorized_identities"] = auth_identities if self.load_extended_metadata is True: @@ -109,7 +98,7 @@ def lazy_load(self) -> Iterator[Document]: auth_identities = self.authorized_identities(file_id) if self.load_extended_metadata is True: extended_metadata = self.get_extended_metadata(file_id) - for parsed_blob in blob_parser.lazy_parse(blob): + for parsed_blob in self._blob_parser.lazy_parse(blob): if self.load_auth is True: parsed_blob.metadata["authorized_identities"] = auth_identities if self.load_extended_metadata is True: @@ -126,7 +115,7 @@ def lazy_load(self) -> Iterator[Document]: auth_identities = self.authorized_identities(file_id) if self.load_extended_metadata is True: extended_metadata = self.get_extended_metadata(file_id) - for blob_part in blob_parser.lazy_parse(blob): + for blob_part in self._blob_parser.lazy_parse(blob): blob_part.metadata.update(blob.metadata) if self.load_auth is True: blob_part.metadata["authorized_identities"] = auth_identities @@ -182,7 +171,7 @@ def _fetch_access_token(self) -> Any: data = json.loads(s) return data - def get_extended_metadata(self, file_id: str) -> dict: + def get_extended_metadata(self, file_id: str) -> Dict: """ Retrieve extended metadata for a file in SharePoint. As of today, following fields are supported in the extended metadata: From 2494deb2a4bac23888cfa3763567336018660636 Mon Sep 17 00:00:00 2001 From: Erick Friis Date: Wed, 6 Nov 2024 16:31:10 -0800 Subject: [PATCH 20/26] infra: remove google creds from release and integration test workflows (#27950) --- .github/workflows/_integration_test.yml | 6 ------ .github/workflows/_release.yml | 6 ------ 2 files changed, 12 deletions(-) diff --git a/.github/workflows/_integration_test.yml b/.github/workflows/_integration_test.yml index 60a74ff08734d..d2157eb495630 100644 --- a/.github/workflows/_integration_test.yml +++ b/.github/workflows/_integration_test.yml @@ -41,12 +41,6 @@ jobs: shell: bash run: poetry run pip install "boto3<2" "google-cloud-aiplatform<2" - - name: 'Authenticate to Google Cloud' - id: 'auth' - uses: google-github-actions/auth@v2 - with: - credentials_json: '${{ secrets.GOOGLE_CREDENTIALS }}' - - name: Run integration tests shell: bash env: diff --git a/.github/workflows/_release.yml b/.github/workflows/_release.yml index fd6a53fee85cb..c36607f62fee7 100644 --- a/.github/workflows/_release.yml +++ b/.github/workflows/_release.yml @@ -267,12 +267,6 @@ jobs: make tests working-directory: ${{ inputs.working-directory }} - - name: 'Authenticate to Google Cloud' - id: 'auth' - uses: google-github-actions/auth@v2 - with: - credentials_json: '${{ secrets.GOOGLE_CREDENTIALS }}' - - name: Import integration test dependencies run: poetry install --with test,test_integration working-directory: ${{ inputs.working-directory }} From 81f7daa4580aaee45314e31b3461f23520f79bd1 Mon Sep 17 00:00:00 2001 From: Baptiste Pasquier <50556298+baptiste-pasquier@users.noreply.github.com> Date: Thu, 7 Nov 2024 02:26:30 +0100 Subject: [PATCH 21/26] community: add InfinityRerank (#27043) **Description:** - Add a Reranker for Infinity server. **Dependencies:** This wrapper uses [infinity_client](https://github.com/michaelfeil/infinity/tree/main/libs/client_infinity/infinity_client) to connect to an Infinity server. **Tests and docs** - integration test: test_infinity_rerank.py - example notebook: infinity_rerank.ipynb [here](https://github.com/baptiste-pasquier/langchain/blob/feat/infinity-rerank/docs/docs/integrations/document_transformers/infinity_rerank.ipynb) --------- Co-authored-by: Erick Friis --- .../infinity_rerank.ipynb | 405 ++++++++++++++++++ .../document_compressors/__init__.py | 5 + .../document_compressors/infinity_rerank.py | 135 ++++++ .../test_infinity_rerank.py | 32 ++ .../document_compressors/test_imports.py | 1 + 5 files changed, 578 insertions(+) create mode 100644 docs/docs/integrations/document_transformers/infinity_rerank.ipynb create mode 100644 libs/community/langchain_community/document_compressors/infinity_rerank.py create mode 100644 libs/community/tests/integration_tests/document_compressors/test_infinity_rerank.py diff --git a/docs/docs/integrations/document_transformers/infinity_rerank.ipynb b/docs/docs/integrations/document_transformers/infinity_rerank.ipynb new file mode 100644 index 0000000000000..34368a28a0235 --- /dev/null +++ b/docs/docs/integrations/document_transformers/infinity_rerank.ipynb @@ -0,0 +1,405 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Infinity Reranker\n", + "\n", + "`Infinity` is a high-throughput, low-latency REST API for serving text-embeddings, reranking models and clip. \n", + "For more info, please visit [here](https://github.com/michaelfeil/infinity?tab=readme-ov-file#reranking).\n", + "\n", + "This notebook shows how to use Infinity Reranker for document compression and retrieval. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can launch an Infinity Server with a reranker model in CLI:\n", + "\n", + "```bash\n", + "pip install \"infinity-emb[all]\"\n", + "infinity_emb v2 --model-id mixedbread-ai/mxbai-rerank-xsmall-v1\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%pip install --upgrade --quiet infinity_client" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%pip install --upgrade --quiet faiss\n", + "\n", + "# OR (depending on Python version)\n", + "\n", + "%pip install --upgrade --quiet faiss-cpu" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "# Helper function for printing docs\n", + "def pretty_print_docs(docs):\n", + " print(\n", + " f\"\\n{'-' * 100}\\n\".join(\n", + " [f\"Document {i+1}:\\n\\n\" + d.page_content for i, d in enumerate(docs)]\n", + " )\n", + " )" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Set up the base vector store retriever\n", + "Let's start by initializing a simple vector store retriever and storing the 2023 State of the Union speech (in chunks). We can set up the retriever to retrieve a high number (20) of docs." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Document 1:\n", + "\n", + "One of the most serious constitutional responsibilities a President has is nominating someone to serve on the United States Supreme Court. \n", + "\n", + "And I did that 4 days ago, when I nominated Circuit Court of Appeals Judge Ketanji Brown Jackson. One of our nation’s top legal minds, who will continue Justice Breyer’s legacy of excellence.\n", + "----------------------------------------------------------------------------------------------------\n", + "Document 2:\n", + "\n", + "We cannot let this happen. \n", + "\n", + "Tonight. I call on the Senate to: Pass the Freedom to Vote Act. Pass the John Lewis Voting Rights Act. And while you’re at it, pass the Disclose Act so Americans can know who is funding our elections. \n", + "\n", + "Tonight, I’d like to honor someone who has dedicated his life to serve this country: Justice Stephen Breyer—an Army veteran, Constitutional scholar, and retiring Justice of the United States Supreme Court. Justice Breyer, thank you for your service.\n", + "----------------------------------------------------------------------------------------------------\n", + "Document 3:\n", + "\n", + "As I said last year, especially to our younger transgender Americans, I will always have your back as your President, so you can be yourself and reach your God-given potential. \n", + "\n", + "While it often appears that we never agree, that isn’t true. I signed 80 bipartisan bills into law last year. From preventing government shutdowns to protecting Asian-Americans from still-too-common hate crimes to reforming military justice.\n", + "----------------------------------------------------------------------------------------------------\n", + "Document 4:\n", + "\n", + "He will never extinguish their love of freedom. He will never weaken the resolve of the free world. \n", + "\n", + "We meet tonight in an America that has lived through two of the hardest years this nation has ever faced. \n", + "\n", + "The pandemic has been punishing. \n", + "\n", + "And so many families are living paycheck to paycheck, struggling to keep up with the rising cost of food, gas, housing, and so much more. \n", + "\n", + "I understand.\n", + "----------------------------------------------------------------------------------------------------\n", + "Document 5:\n", + "\n", + "As Ohio Senator Sherrod Brown says, “It’s time to bury the label “Rust Belt.” \n", + "\n", + "It’s time. \n", + "\n", + "But with all the bright spots in our economy, record job growth and higher wages, too many families are struggling to keep up with the bills. \n", + "\n", + "Inflation is robbing them of the gains they might otherwise feel. \n", + "\n", + "I get it. That’s why my top priority is getting prices under control.\n", + "----------------------------------------------------------------------------------------------------\n", + "Document 6:\n", + "\n", + "A former top litigator in private practice. A former federal public defender. And from a family of public school educators and police officers. A consensus builder. Since she’s been nominated, she’s received a broad range of support—from the Fraternal Order of Police to former judges appointed by Democrats and Republicans. \n", + "\n", + "And if we are to advance liberty and justice, we need to secure the Border and fix the immigration system.\n", + "----------------------------------------------------------------------------------------------------\n", + "Document 7:\n", + "\n", + "It’s not only the right thing to do—it’s the economically smart thing to do. \n", + "\n", + "That’s why immigration reform is supported by everyone from labor unions to religious leaders to the U.S. Chamber of Commerce. \n", + "\n", + "Let’s get it done once and for all. \n", + "\n", + "Advancing liberty and justice also requires protecting the rights of women. \n", + "\n", + "The constitutional right affirmed in Roe v. Wade—standing precedent for half a century—is under attack as never before.\n", + "----------------------------------------------------------------------------------------------------\n", + "Document 8:\n", + "\n", + "I understand. \n", + "\n", + "I remember when my Dad had to leave our home in Scranton, Pennsylvania to find work. I grew up in a family where if the price of food went up, you felt it. \n", + "\n", + "That’s why one of the first things I did as President was fight to pass the American Rescue Plan. \n", + "\n", + "Because people were hurting. We needed to act, and we did. \n", + "\n", + "Few pieces of legislation have done more in a critical moment in our history to lift us out of crisis.\n", + "----------------------------------------------------------------------------------------------------\n", + "Document 9:\n", + "\n", + "Third – we can end the shutdown of schools and businesses. We have the tools we need. \n", + "\n", + "It’s time for Americans to get back to work and fill our great downtowns again. People working from home can feel safe to begin to return to the office. \n", + "\n", + "We’re doing that here in the federal government. The vast majority of federal workers will once again work in person. \n", + "\n", + "Our schools are open. Let’s keep it that way. Our kids need to be in school.\n", + "----------------------------------------------------------------------------------------------------\n", + "Document 10:\n", + "\n", + "He met the Ukrainian people. \n", + "\n", + "From President Zelenskyy to every Ukrainian, their fearlessness, their courage, their determination, inspires the world. \n", + "\n", + "Groups of citizens blocking tanks with their bodies. Everyone from students to retirees teachers turned soldiers defending their homeland. \n", + "\n", + "In this struggle as President Zelenskyy said in his speech to the European Parliament “Light will win over darkness.” The Ukrainian Ambassador to the United States is here tonight.\n", + "----------------------------------------------------------------------------------------------------\n", + "Document 11:\n", + "\n", + "The widow of Sergeant First Class Heath Robinson. \n", + "\n", + "He was born a soldier. Army National Guard. Combat medic in Kosovo and Iraq. \n", + "\n", + "Stationed near Baghdad, just yards from burn pits the size of football fields. \n", + "\n", + "Heath’s widow Danielle is here with us tonight. They loved going to Ohio State football games. He loved building Legos with their daughter. \n", + "\n", + "But cancer from prolonged exposure to burn pits ravaged Heath’s lungs and body. \n", + "\n", + "Danielle says Heath was a fighter to the very end.\n", + "----------------------------------------------------------------------------------------------------\n", + "Document 12:\n", + "\n", + "Danielle says Heath was a fighter to the very end. \n", + "\n", + "He didn’t know how to stop fighting, and neither did she. \n", + "\n", + "Through her pain she found purpose to demand we do better. \n", + "\n", + "Tonight, Danielle—we are. \n", + "\n", + "The VA is pioneering new ways of linking toxic exposures to diseases, already helping more veterans get benefits. \n", + "\n", + "And tonight, I’m announcing we’re expanding eligibility to veterans suffering from nine respiratory cancers.\n", + "----------------------------------------------------------------------------------------------------\n", + "Document 13:\n", + "\n", + "We can do all this while keeping lit the torch of liberty that has led generations of immigrants to this land—my forefathers and so many of yours. \n", + "\n", + "Provide a pathway to citizenship for Dreamers, those on temporary status, farm workers, and essential workers. \n", + "\n", + "Revise our laws so businesses have the workers they need and families don’t wait decades to reunite. \n", + "\n", + "It’s not only the right thing to do—it’s the economically smart thing to do.\n", + "----------------------------------------------------------------------------------------------------\n", + "Document 14:\n", + "\n", + "He rejected repeated efforts at diplomacy. \n", + "\n", + "He thought the West and NATO wouldn’t respond. And he thought he could divide us at home. Putin was wrong. We were ready. Here is what we did. \n", + "\n", + "We prepared extensively and carefully. \n", + "\n", + "We spent months building a coalition of other freedom-loving nations from Europe and the Americas to Asia and Africa to confront Putin.\n", + "----------------------------------------------------------------------------------------------------\n", + "Document 15:\n", + "\n", + "As I’ve told Xi Jinping, it is never a good bet to bet against the American people. \n", + "\n", + "We’ll create good jobs for millions of Americans, modernizing roads, airports, ports, and waterways all across America. \n", + "\n", + "And we’ll do it all to withstand the devastating effects of the climate crisis and promote environmental justice.\n", + "----------------------------------------------------------------------------------------------------\n", + "Document 16:\n", + "\n", + "Tonight I say to the Russian oligarchs and corrupt leaders who have bilked billions of dollars off this violent regime no more. \n", + "\n", + "The U.S. Department of Justice is assembling a dedicated task force to go after the crimes of Russian oligarchs. \n", + "\n", + "We are joining with our European allies to find and seize your yachts your luxury apartments your private jets. We are coming for your ill-begotten gains.\n", + "----------------------------------------------------------------------------------------------------\n", + "Document 17:\n", + "\n", + "Look at cars. \n", + "\n", + "Last year, there weren’t enough semiconductors to make all the cars that people wanted to buy. \n", + "\n", + "And guess what, prices of automobiles went up. \n", + "\n", + "So—we have a choice. \n", + "\n", + "One way to fight inflation is to drive down wages and make Americans poorer. \n", + "\n", + "I have a better plan to fight inflation. \n", + "\n", + "Lower your costs, not your wages. \n", + "\n", + "Make more cars and semiconductors in America. \n", + "\n", + "More infrastructure and innovation in America. \n", + "\n", + "More goods moving faster and cheaper in America.\n", + "----------------------------------------------------------------------------------------------------\n", + "Document 18:\n", + "\n", + "So that’s my plan. It will grow the economy and lower costs for families. \n", + "\n", + "So what are we waiting for? Let’s get this done. And while you’re at it, confirm my nominees to the Federal Reserve, which plays a critical role in fighting inflation. \n", + "\n", + "My plan will not only lower costs to give families a fair shot, it will lower the deficit.\n", + "----------------------------------------------------------------------------------------------------\n", + "Document 19:\n", + "\n", + "Let each of us here tonight in this Chamber send an unmistakable signal to Ukraine and to the world. \n", + "\n", + "Please rise if you are able and show that, Yes, we the United States of America stand with the Ukrainian people. \n", + "\n", + "Throughout our history we’ve learned this lesson when dictators do not pay a price for their aggression they cause more chaos. \n", + "\n", + "They keep moving. \n", + "\n", + "And the costs and the threats to America and the world keep rising.\n", + "----------------------------------------------------------------------------------------------------\n", + "Document 20:\n", + "\n", + "It’s based on DARPA—the Defense Department project that led to the Internet, GPS, and so much more. \n", + "\n", + "ARPA-H will have a singular purpose—to drive breakthroughs in cancer, Alzheimer’s, diabetes, and more. \n", + "\n", + "A unity agenda for the nation. \n", + "\n", + "We can do this. \n", + "\n", + "My fellow Americans—tonight , we have gathered in a sacred space—the citadel of our democracy. \n", + "\n", + "In this Capitol, generation after generation, Americans have debated great questions amid great strife, and have done great things.\n" + ] + } + ], + "source": [ + "from langchain_community.document_loaders import TextLoader\n", + "from langchain_community.vectorstores.faiss import FAISS\n", + "from langchain_huggingface import HuggingFaceEmbeddings\n", + "from langchain_text_splitters import RecursiveCharacterTextSplitter\n", + "\n", + "documents = TextLoader(\"../../how_to/state_of_the_union.txt\").load()\n", + "text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=100)\n", + "texts = text_splitter.split_documents(documents)\n", + "retriever = FAISS.from_documents(\n", + " texts, HuggingFaceEmbeddings(model_name=\"all-MiniLM-L6-v2\")\n", + ").as_retriever(search_kwargs={\"k\": 20})\n", + "\n", + "query = \"What did the president say about Ketanji Brown Jackson\"\n", + "docs = retriever.invoke(query)\n", + "pretty_print_docs(docs)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Reranking with InfinityRerank\n", + "Now let's wrap our base retriever with a `ContextualCompressionRetriever`. We'll use the `InfinityRerank` to rerank the returned results." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Document 1:\n", + "\n", + "One of the most serious constitutional responsibilities a President has is nominating someone to serve on the United States Supreme Court. \n", + "\n", + "And I did that 4 days ago, when I nominated Circuit Court of Appeals Judge Ketanji Brown Jackson. One of our nation’s top legal minds, who will continue Justice Breyer’s legacy of excellence.\n", + "----------------------------------------------------------------------------------------------------\n", + "Document 2:\n", + "\n", + "As Ohio Senator Sherrod Brown says, “It’s time to bury the label “Rust Belt.” \n", + "\n", + "It’s time. \n", + "\n", + "But with all the bright spots in our economy, record job growth and higher wages, too many families are struggling to keep up with the bills. \n", + "\n", + "Inflation is robbing them of the gains they might otherwise feel. \n", + "\n", + "I get it. That’s why my top priority is getting prices under control.\n", + "----------------------------------------------------------------------------------------------------\n", + "Document 3:\n", + "\n", + "A former top litigator in private practice. A former federal public defender. And from a family of public school educators and police officers. A consensus builder. Since she’s been nominated, she’s received a broad range of support—from the Fraternal Order of Police to former judges appointed by Democrats and Republicans. \n", + "\n", + "And if we are to advance liberty and justice, we need to secure the Border and fix the immigration system.\n" + ] + } + ], + "source": [ + "from infinity_client import Client\n", + "from langchain.retrievers import ContextualCompressionRetriever\n", + "from langchain_community.document_compressors.infinity_rerank import InfinityRerank\n", + "\n", + "client = Client(base_url=\"http://localhost:7997\")\n", + "\n", + "compressor = InfinityRerank(client=client, model=\"mixedbread-ai/mxbai-rerank-xsmall-v1\")\n", + "compression_retriever = ContextualCompressionRetriever(\n", + " base_compressor=compressor, base_retriever=retriever\n", + ")\n", + "\n", + "compressed_docs = compression_retriever.invoke(\n", + " \"What did the president say about Ketanji Jackson Brown\"\n", + ")\n", + "pretty_print_docs(compressed_docs)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/libs/community/langchain_community/document_compressors/__init__.py b/libs/community/langchain_community/document_compressors/__init__.py index 1d7fbb62dcf66..b26bf579d487c 100644 --- a/libs/community/langchain_community/document_compressors/__init__.py +++ b/libs/community/langchain_community/document_compressors/__init__.py @@ -8,6 +8,9 @@ from langchain_community.document_compressors.flashrank_rerank import ( FlashrankRerank, ) + from langchain_community.document_compressors.infinity_rerank import ( + InfinityRerank, + ) from langchain_community.document_compressors.jina_rerank import ( JinaRerank, ) @@ -32,6 +35,7 @@ "FlashrankRerank": "langchain_community.document_compressors.flashrank_rerank", "DashScopeRerank": "langchain_community.document_compressors.dashscope_rerank", "VolcengineRerank": "langchain_community.document_compressors.volcengine_rerank", + "InfinityRerank": "langchain_community.document_compressors.infinity_rerank", } @@ -50,4 +54,5 @@ def __getattr__(name: str) -> Any: "RankLLMRerank", "DashScopeRerank", "VolcengineRerank", + "InfinityRerank", ] diff --git a/libs/community/langchain_community/document_compressors/infinity_rerank.py b/libs/community/langchain_community/document_compressors/infinity_rerank.py new file mode 100644 index 0000000000000..91d07889fce4e --- /dev/null +++ b/libs/community/langchain_community/document_compressors/infinity_rerank.py @@ -0,0 +1,135 @@ +from __future__ import annotations + +from copy import deepcopy +from typing import TYPE_CHECKING, Any, Dict, List, Optional, Sequence, Union + +from langchain.retrievers.document_compressors.base import BaseDocumentCompressor +from langchain_core.callbacks.manager import Callbacks +from langchain_core.documents import Document +from pydantic import ConfigDict, model_validator + +if TYPE_CHECKING: + from infinity_client.api.default import rerank + from infinity_client.client import Client + from infinity_client.models import RerankInput +else: + # Avoid pydantic annotation issues when actually instantiating + # while keeping this import optional + try: + from infinity_client.api.default import rerank + from infinity_client.client import Client + from infinity_client.models import RerankInput + except ImportError: + pass + +DEFAULT_MODEL_NAME = "BAAI/bge-reranker-base" +DEFAULT_BASE_URL = "http://localhost:7997" + + +class InfinityRerank(BaseDocumentCompressor): + """Document compressor that uses `Infinity Rerank API`.""" + + client: Optional[Client] = None + """Infinity client to use for compressing documents.""" + + model: Optional[str] = None + """Model to use for reranking.""" + + top_n: Optional[int] = 3 + """Number of documents to return.""" + + model_config = ConfigDict( + populate_by_name=True, + arbitrary_types_allowed=True, + extra="forbid", + ) + + @model_validator(mode="before") + @classmethod + def validate_environment(cls, values: Dict) -> Any: + """Validate that python package exists in environment.""" + if "client" in values: + return values + else: + try: + from infinity_client.client import Client + except ImportError: + raise ImportError( + "Could not import infinity_client python package. " + "Please install it with `pip install infinity_client`." + ) + + values["model"] = values.get("model", DEFAULT_MODEL_NAME) + values["client"] = Client(base_url=DEFAULT_BASE_URL) + return values + + def rerank( + self, + documents: Sequence[Union[str, Document, dict]], + query: str, + *, + model: Optional[str] = None, + top_n: Optional[int] = -1, + ) -> List[Dict[str, Any]]: + """Returns an ordered list of documents ordered by their relevance to the provided query. + + Args: + query: The query to use for reranking. + documents: A sequence of documents to rerank. + model: The model to use for re-ranking. Default to self.model. + top_n : The number of results to return. If None returns all results. + Defaults to self.top_n. + max_chunks_per_doc : The maximum number of chunks derived from a document. + """ # noqa: E501 + if len(documents) == 0: # to avoid empty api call + return [] + docs = [ + doc.page_content if isinstance(doc, Document) else doc for doc in documents + ] + model = model or self.model + + input = RerankInput( + query=query, + documents=docs, + model=model, + ) + results = rerank.sync(client=self.client, body=input) + + if hasattr(results, "results"): + results = getattr(results, "results") + + result_dicts = [] + for res in results: + result_dicts.append( + {"index": res.index, "relevance_score": res.relevance_score} + ) + + result_dicts.sort(key=lambda x: x["relevance_score"], reverse=True) + top_n = top_n if (top_n is None or top_n > 0) else self.top_n + + return result_dicts[:top_n] + + def compress_documents( + self, + documents: Sequence[Document], + query: str, + callbacks: Optional[Callbacks] = None, + ) -> Sequence[Document]: + """ + Compress documents using Infinity's rerank API. + + Args: + documents: A sequence of documents to compress. + query: The query to use for compressing the documents. + callbacks: Callbacks to run during the compression process. + + Returns: + A sequence of compressed documents. + """ + compressed = [] + for res in self.rerank(documents, query): + doc = documents[res["index"]] + doc_copy = Document(doc.page_content, metadata=deepcopy(doc.metadata)) + doc_copy.metadata["relevance_score"] = res["relevance_score"] + compressed.append(doc_copy) + return compressed diff --git a/libs/community/tests/integration_tests/document_compressors/test_infinity_rerank.py b/libs/community/tests/integration_tests/document_compressors/test_infinity_rerank.py new file mode 100644 index 0000000000000..4e9144f2350eb --- /dev/null +++ b/libs/community/tests/integration_tests/document_compressors/test_infinity_rerank.py @@ -0,0 +1,32 @@ +from langchain_core.documents import Document + +from langchain_community.document_compressors.infinity_rerank import ( + InfinityRerank, +) + + +def test_rerank() -> None: + reranker = InfinityRerank() + docs = [ + Document( + page_content=( + "This is a document not related to the python package infinity_emb, " + "hence..." + ) + ), + Document(page_content="Paris is in France!"), + Document( + page_content=( + "infinity_emb is a package for sentence embeddings and rerankings using" + " transformer models in Python!" + ) + ), + Document(page_content="random text for nothing"), + ] + compressed = reranker.compress_documents( + query="What is the python package infinity_emb?", + documents=docs, + ) + + assert len(compressed) == 3, "default top_n is 3" + assert compressed[0].page_content == docs[2].page_content, "rerank works" diff --git a/libs/community/tests/unit_tests/document_compressors/test_imports.py b/libs/community/tests/unit_tests/document_compressors/test_imports.py index 37ed3d69c6078..809e20db1e03f 100644 --- a/libs/community/tests/unit_tests/document_compressors/test_imports.py +++ b/libs/community/tests/unit_tests/document_compressors/test_imports.py @@ -8,6 +8,7 @@ "FlashrankRerank", "DashScopeRerank", "VolcengineRerank", + "InfinityRerank", ] From c2072d909a8c186cbac7972c4c39e1bf476f7811 Mon Sep 17 00:00:00 2001 From: ZhangShenao <15201440436@163.com> Date: Thu, 7 Nov 2024 10:42:41 +0800 Subject: [PATCH 22/26] Improvement[Partner] Improve qdrant vector store (#27251) - Add static method decorator - Add args for api doc - Fix word spelling Co-authored-by: Erick Friis --- libs/partners/qdrant/langchain_qdrant/qdrant.py | 2 +- libs/partners/qdrant/langchain_qdrant/vectorstores.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libs/partners/qdrant/langchain_qdrant/qdrant.py b/libs/partners/qdrant/langchain_qdrant/qdrant.py index 165ca66cf8875..b21dae2efe298 100644 --- a/libs/partners/qdrant/langchain_qdrant/qdrant.py +++ b/libs/partners/qdrant/langchain_qdrant/qdrant.py @@ -960,8 +960,8 @@ def _generate_batches( yield batch_ids, points + @staticmethod def _build_payloads( - self, texts: Iterable[str], metadatas: Optional[List[dict]], content_payload_key: str, diff --git a/libs/partners/qdrant/langchain_qdrant/vectorstores.py b/libs/partners/qdrant/langchain_qdrant/vectorstores.py index 9b8af6f7273e6..1b4941604f627 100644 --- a/libs/partners/qdrant/langchain_qdrant/vectorstores.py +++ b/libs/partners/qdrant/langchain_qdrant/vectorstores.py @@ -57,7 +57,7 @@ async def wrapper(self: Any, *args: Any, **kwargs: Any) -> Any: except NotImplementedError: # If the async method is not implemented, call the synchronous method # by removing the first letter from the method name. For example, - # if the async method is called ``aaad_texts``, the synchronous method + # if the async method is called ``aadd_texts``, the synchronous method # will be called ``aad_texts``. return await run_in_executor( None, getattr(self, method.__name__[1:]), *args, **kwargs @@ -921,7 +921,7 @@ async def amax_marginal_relevance_search_by_vector( Maximal marginal relevance optimizes for similarity to query AND diversity among selected documents. Args: - query: Text to look up documents similar to. + embedding: Embedding vector to look up documents similar to. k: Number of Documents to return. Defaults to 4. fetch_k: Number of Documents to fetch to pass to MMR algorithm. Defaults to 20. @@ -984,7 +984,7 @@ def max_marginal_relevance_search_with_score_by_vector( Maximal marginal relevance optimizes for similarity to query AND diversity among selected documents. Args: - query: Text to look up documents similar to. + embedding: Embedding vector to look up documents similar to. k: Number of Documents to return. Defaults to 4. fetch_k: Number of Documents to fetch to pass to MMR algorithm. Defaults to 20. @@ -1072,7 +1072,7 @@ async def amax_marginal_relevance_search_with_score_by_vector( Maximal marginal relevance optimizes for similarity to query AND diversity among selected documents. Args: - query: Text to look up documents similar to. + embedding: Embedding vector to look up documents similar to. k: Number of Documents to return. Defaults to 4. fetch_k: Number of Documents to fetch to pass to MMR algorithm. Defaults to 20. From cfff2a057e9e91002099177f9da6d4a616db0796 Mon Sep 17 00:00:00 2001 From: Siddharth Murching Date: Wed, 6 Nov 2024 18:47:41 -0800 Subject: [PATCH 23/26] community: Update UC toolkit documentation to use LangGraph APIs (#26778) - **Description:** Update UC toolkit documentation to show an example of using recommended LangGraph agent APIs before the existing LangChain AgentExecutor example. Tested by manually running the updated example notebook - **Dependencies:** No new dependencies --------- Signed-off-by: Sid Murching Co-authored-by: Erick Friis --- docs/docs/integrations/tools/databricks.ipynb | 112 ++++++++++++++---- 1 file changed, 91 insertions(+), 21 deletions(-) diff --git a/docs/docs/integrations/tools/databricks.ipynb b/docs/docs/integrations/tools/databricks.ipynb index bb44a716f587e..fafb14cd97357 100644 --- a/docs/docs/integrations/tools/databricks.ipynb +++ b/docs/docs/integrations/tools/databricks.ipynb @@ -6,7 +6,7 @@ "source": [ "# Databricks Unity Catalog (UC)\n", "\n", - "This notebook shows how to use UC functions as LangChain tools.\n", + "This notebook shows how to use UC functions as LangChain tools, with both LangChain and LangGraph agent APIs.\n", "\n", "See Databricks documentation ([AWS](https://docs.databricks.com/en/sql/language-manual/sql-ref-syntax-ddl-create-sql-function.html)|[Azure](https://learn.microsoft.com/en-us/azure/databricks/sql/language-manual/sql-ref-syntax-ddl-create-sql-function)|[GCP](https://docs.gcp.databricks.com/en/sql/language-manual/sql-ref-syntax-ddl-create-sql-function.html)) to learn how to create SQL or Python functions in UC. Do not skip function and parameter comments, which are critical for LLMs to call functions properly.\n", "\n", @@ -34,11 +34,19 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Note: you may need to restart the kernel to use updated packages.\n" + ] + } + ], "source": [ - "%pip install --upgrade --quiet databricks-sdk langchain-community mlflow" + "%pip install --upgrade --quiet databricks-sdk langchain-community langchain-databricks langgraph mlflow" ] }, { @@ -47,7 +55,7 @@ "metadata": {}, "outputs": [], "source": [ - "from langchain_community.chat_models.databricks import ChatDatabricks\n", + "from langchain_databricks import ChatDatabricks\n", "\n", "llm = ChatDatabricks(endpoint=\"databricks-meta-llama-3-70b-instruct\")" ] @@ -58,6 +66,7 @@ "metadata": {}, "outputs": [], "source": [ + "from databricks.sdk import WorkspaceClient\n", "from langchain_community.tools.databricks import UCFunctionToolkit\n", "\n", "tools = (\n", @@ -76,9 +85,16 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } + }, "source": [ - "(Optional) To increase the retry time for getting a function execution response, set environment variable UC_TOOL_CLIENT_EXECUTION_TIMEOUT. Default retry time value is 120s." + "(Optional) To increase the retry time for getting a function execution response, set environment variable UC_TOOL_CLIENT_EXECUTION_TIMEOUT. Default retry time value is 120s.", + + "## LangGraph agent example" ] }, { @@ -92,9 +108,68 @@ "os.environ[\"UC_TOOL_CLIENT_EXECUTION_TIMEOUT\"] = \"200\"" ] }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } + }, + "source": [ + "## LangGraph agent example" + ] + }, { "cell_type": "code", "execution_count": 4, + "metadata": { + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{'messages': [HumanMessage(content='36939 * 8922.4', additional_kwargs={}, response_metadata={}, id='1a10b10b-8e37-48c7-97a1-cac5006228d5'),\n", + " AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_a8f3986f-4b91-40a3-8d6d-39f431dab69b', 'type': 'function', 'function': {'name': 'main__tools__python_exec', 'arguments': '{\"code\": \"print(36939 * 8922.4)\"}'}}]}, response_metadata={'prompt_tokens': 771, 'completion_tokens': 29, 'total_tokens': 800}, id='run-865c3613-20ba-4e80-afc8-fde1cfb26e5a-0', tool_calls=[{'name': 'main__tools__python_exec', 'args': {'code': 'print(36939 * 8922.4)'}, 'id': 'call_a8f3986f-4b91-40a3-8d6d-39f431dab69b', 'type': 'tool_call'}]),\n", + " ToolMessage(content='{\"format\": \"SCALAR\", \"value\": \"329584533.59999996\\\\n\", \"truncated\": false}', name='main__tools__python_exec', id='8b63d4c8-1a3d-46a5-a719-393b2ef36770', tool_call_id='call_a8f3986f-4b91-40a3-8d6d-39f431dab69b'),\n", + " AIMessage(content='The result of the multiplication is:\\n\\n329584533.59999996', additional_kwargs={}, response_metadata={'prompt_tokens': 846, 'completion_tokens': 22, 'total_tokens': 868}, id='run-22772404-611b-46e4-9956-b85e4a385f0f-0')]}" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from langgraph.prebuilt import create_react_agent\n", + "\n", + "agent = create_react_agent(\n", + " llm,\n", + " tools,\n", + " state_modifier=\"You are a helpful assistant. Make sure to use tool for information.\",\n", + ")\n", + "agent.invoke({\"messages\": [{\"role\": \"user\", \"content\": \"36939 * 8922.4\"}]})" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } + }, + "source": [ + "## LangChain agent example" + ] + }, + { + "cell_type": "code", + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ @@ -118,7 +193,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "metadata": {}, "outputs": [ { @@ -132,7 +207,9 @@ "Invoking: `main__tools__python_exec` with `{'code': 'print(36939 * 8922.4)'}`\n", "\n", "\n", - "\u001b[0m\u001b[36;1m\u001b[1;3m{\"format\": \"SCALAR\", \"value\": \"329584533.59999996\\n\", \"truncated\": false}\u001b[0m\u001b[32;1m\u001b[1;3mThe result of the multiplication 36939 * 8922.4 is 329,584,533.60.\u001b[0m\n", + "\u001b[0m\u001b[36;1m\u001b[1;3m{\"format\": \"SCALAR\", \"value\": \"329584533.59999996\\n\", \"truncated\": false}\u001b[0m\u001b[32;1m\u001b[1;3mThe result of the multiplication is:\n", + "\n", + "329584533.59999996\u001b[0m\n", "\n", "\u001b[1m> Finished chain.\u001b[0m\n" ] @@ -141,10 +218,10 @@ "data": { "text/plain": [ "{'input': '36939 * 8922.4',\n", - " 'output': 'The result of the multiplication 36939 * 8922.4 is 329,584,533.60.'}" + " 'output': 'The result of the multiplication is:\\n\\n329584533.59999996'}" ] }, - "execution_count": 5, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } @@ -153,18 +230,11 @@ "agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)\n", "agent_executor.invoke({\"input\": \"36939 * 8922.4\"})" ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { "kernelspec": { - "display_name": "llm", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, @@ -178,9 +248,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.9" + "version": "3.11.10" } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } From 53b0a99f3769d83e8aaf2b0382937bc91eae79b7 Mon Sep 17 00:00:00 2001 From: Dmitriy Prokopchuk <87666671+prokopchukdim@users.noreply.github.com> Date: Wed, 6 Nov 2024 22:07:59 -0500 Subject: [PATCH 24/26] community: Memcached LLM Cache Integration (#27323) ## Description This PR adds support for Memcached as a usable LLM model cache by adding the ```MemcachedCache``` implementation relying on the [pymemcache](https://github.com/pinterest/pymemcache) client. Unit test-wise, the new integration is generally covered under existing import testing. All new functionality depends on pymemcache if instantiated and used, so to comply with the other cache implementations the PR also adds optional integration tests for ```MemcachedCache```. Since this is a new integration, documentation is added for Memcached as an integration and as an LLM Cache. ## Issue This PR closes #27275 which was originally raised as a discussion in #27035 ## Dependencies There are no new required dependencies for langchain, but [pymemcache](https://github.com/pinterest/pymemcache) is required to instantiate the new ```MemcachedCache```. ## Example Usage ```python3 from langchain.globals import set_llm_cache from langchain_openai import OpenAI from langchain_community.cache import MemcachedCache from pymemcache.client.base import Client llm = OpenAI(model="gpt-3.5-turbo-instruct", n=2, best_of=2) set_llm_cache(MemcachedCache(Client('localhost'))) # The first time, it is not yet in cache, so it should take longer llm.invoke("Which city is the most crowded city in the USA?") # The second time it is, so it goes faster llm.invoke("Which city is the most crowded city in the USA?") ``` --------- Co-authored-by: Erick Friis --- docs/docs/integrations/llm_caching.ipynb | 96 +++++++++++++++++++ .../docs/integrations/providers/memcached.mdx | 34 +++++++ libs/community/langchain_community/cache.py | 94 ++++++++++++++++++ .../cache/test_memcached_cache.py | 61 ++++++++++++ 4 files changed, 285 insertions(+) create mode 100644 docs/docs/integrations/providers/memcached.mdx create mode 100644 libs/community/tests/integration_tests/cache/test_memcached_cache.py diff --git a/docs/docs/integrations/llm_caching.ipynb b/docs/docs/integrations/llm_caching.ipynb index ee5152e023ff2..4ba1901613ac2 100644 --- a/docs/docs/integrations/llm_caching.ipynb +++ b/docs/docs/integrations/llm_caching.ipynb @@ -2368,6 +2368,102 @@ ")" ] }, + { + "cell_type": "markdown", + "id": "7e6b9b1a", + "metadata": {}, + "source": [ + "## `Memcached` Cache\n", + "You can use [Memcached](https://www.memcached.org/) as a cache to cache prompts and responses through [pymemcache](https://github.com/pinterest/pymemcache).\n", + "\n", + "This cache requires the pymemcache dependency to be installed:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "b2e5e0b1", + "metadata": {}, + "outputs": [], + "source": [ + "%pip install -qU pymemcache" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "4c7ffe37", + "metadata": {}, + "outputs": [], + "source": [ + "from langchain_community.cache import MemcachedCache\n", + "from pymemcache.client.base import Client\n", + "\n", + "set_llm_cache(MemcachedCache(Client(\"localhost\")))" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "a4cfc48a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 32.8 ms, sys: 21 ms, total: 53.8 ms\n", + "Wall time: 343 ms\n" + ] + }, + { + "data": { + "text/plain": [ + "'\\n\\nWhy did the chicken cross the road?\\n\\nTo get to the other side!'" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%time\n", + "# The first time, it is not yet in cache, so it should take longer\n", + "llm.invoke(\"Tell me a joke\")" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "cb3b2bf5", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 2.31 ms, sys: 850 µs, total: 3.16 ms\n", + "Wall time: 6.43 ms\n" + ] + }, + { + "data": { + "text/plain": [ + "'\\n\\nWhy did the chicken cross the road?\\n\\nTo get to the other side!'" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%time\n", + "# The second time it is, so it goes faster\n", + "llm.invoke(\"Tell me a joke\")" + ] + }, { "cell_type": "markdown", "id": "7019c991-0101-4f9c-b212-5729a5471293", diff --git a/docs/docs/integrations/providers/memcached.mdx b/docs/docs/integrations/providers/memcached.mdx new file mode 100644 index 0000000000000..f7719deda4031 --- /dev/null +++ b/docs/docs/integrations/providers/memcached.mdx @@ -0,0 +1,34 @@ +# Memcached + +> [Memcached](https://www.memcached.org/) is a free & open source, high-performance, distributed memory object caching system, +> generic in nature, but intended for use in speeding up dynamic web applications by alleviating database load. + +This page covers how to use Memcached with langchain, using [pymemcache](https://github.com/pinterest/pymemcache) as +a client to connect to an already running Memcached instance. + +## Installation and Setup +```bash +pip install pymemcache +``` + +## LLM Cache + +To integrate a Memcached Cache into your application: +```python3 +from langchain.globals import set_llm_cache +from langchain_openai import OpenAI + +from langchain_community.cache import MemcachedCache +from pymemcache.client.base import Client + +llm = OpenAI(model="gpt-3.5-turbo-instruct", n=2, best_of=2) +set_llm_cache(MemcachedCache(Client('localhost'))) + +# The first time, it is not yet in cache, so it should take longer +llm.invoke("Which city is the most crowded city in the USA?") + +# The second time it is, so it goes faster +llm.invoke("Which city is the most crowded city in the USA?") +``` + +Learn more in the [example notebook](/docs/integrations/llm_caching#memcached-cache) \ No newline at end of file diff --git a/libs/community/langchain_community/cache.py b/libs/community/langchain_community/cache.py index c074747370c96..697c26ed8725f 100644 --- a/libs/community/langchain_community/cache.py +++ b/libs/community/langchain_community/cache.py @@ -91,6 +91,7 @@ if TYPE_CHECKING: import momento + import pymemcache from astrapy.db import AstraDB, AsyncAstraDB from cassandra.cluster import Session as CassandraSession @@ -2599,3 +2600,96 @@ def clear(self, **kwargs: Any) -> None: if index_name in self._cache_dict: self._cache_dict[index_name].drop() del self._cache_dict[index_name] + + +class MemcachedCache(BaseCache): + """Cache that uses Memcached backend through pymemcache client lib""" + + def __init__(self, client_: Any): + """ + Initialize an instance of MemcachedCache. + + Args: + client_ (str): An instance of any of pymemcache's Clients + (Client, PooledClient, HashClient) + Example: + .. code-block:: python + ifrom langchain.globals import set_llm_cache + from langchain_openai import OpenAI + + from langchain_community.cache import MemcachedCache + from pymemcache.client.base import Client + + llm = OpenAI(model="gpt-3.5-turbo-instruct", n=2, best_of=2) + set_llm_cache(MemcachedCache(Client('localhost'))) + + # The first time, it is not yet in cache, so it should take longer + llm.invoke("Which city is the most crowded city in the USA?") + + # The second time it is, so it goes faster + llm.invoke("Which city is the most crowded city in the USA?") + """ + + try: + from pymemcache.client import ( + Client, + HashClient, + PooledClient, + RetryingClient, + ) + except (ImportError, ModuleNotFoundError): + raise ImportError( + "Could not import pymemcache python package. " + "Please install it with `pip install -U pymemcache`." + ) + + if not ( + isinstance(client_, Client) + or isinstance(client_, PooledClient) + or isinstance(client_, HashClient) + or isinstance(client_, RetryingClient) + ): + raise ValueError("Please pass a valid pymemcached client") + + self.client = client_ + + def lookup(self, prompt: str, llm_string: str) -> Optional[RETURN_VAL_TYPE]: + """Look up based on prompt and llm_string.""" + key = _hash(prompt + llm_string) + try: + result = self.client.get(key) + except pymemcache.MemcacheError: + return None + + return _loads_generations(result) if result is not None else None + + def update(self, prompt: str, llm_string: str, return_val: RETURN_VAL_TYPE) -> None: + """Update cache based on prompt and llm_string.""" + key = _hash(prompt + llm_string) + + # Validate input is made of standard LLM generations + for gen in return_val: + if not isinstance(gen, Generation): + raise ValueError( + "Memcached only supports caching of normal LLM generations, " + + f"got {type(gen)}" + ) + + # Deserialize return_val into string and update cache + value = _dumps_generations(return_val) + self.client.set(key, value) + + def clear(self, **kwargs: Any) -> None: + """ + Clear the entire cache. Takes optional kwargs: + + delay: optional int, the number of seconds to wait before flushing, + or zero to flush immediately (the default). NON-BLOCKING, returns + immediately. + noreply: optional bool, True to not wait for the reply (defaults to + client.default_noreply). + """ + delay = kwargs.get("delay", 0) + noreply = kwargs.get("noreply", None) + + self.client.flush_all(delay, noreply) diff --git a/libs/community/tests/integration_tests/cache/test_memcached_cache.py b/libs/community/tests/integration_tests/cache/test_memcached_cache.py new file mode 100644 index 0000000000000..2aca3df056652 --- /dev/null +++ b/libs/community/tests/integration_tests/cache/test_memcached_cache.py @@ -0,0 +1,61 @@ +""" +Test Memcached llm cache functionality. Requires running instance of Memcached on +localhost default port (11211) and pymemcache +""" + +import pytest +from langchain.globals import get_llm_cache, set_llm_cache +from langchain_core.outputs import Generation, LLMResult + +from langchain_community.cache import MemcachedCache +from tests.unit_tests.llms.fake_llm import FakeLLM + +DEFAULT_MEMCACHED_URL = "localhost" + + +@pytest.mark.requires("pymemcache") +def test_memcached_cache() -> None: + """Test general Memcached caching""" + from pymemcache import Client + + set_llm_cache(MemcachedCache(Client(DEFAULT_MEMCACHED_URL))) + llm = FakeLLM() + + params = llm.dict() + params["stop"] = None + llm_string = str(sorted([(k, v) for k, v in params.items()])) + get_llm_cache().update("foo", llm_string, [Generation(text="fizz")]) + output = llm.generate(["foo"]) + expected_output = LLMResult( + generations=[[Generation(text="fizz")]], + llm_output={}, + ) + assert output == expected_output + # clear the cache + get_llm_cache().clear() + + +@pytest.mark.requires("pymemcache") +def test_memcached_cache_flush() -> None: + """Test flushing Memcached cache""" + from pymemcache import Client + + set_llm_cache(MemcachedCache(Client(DEFAULT_MEMCACHED_URL))) + llm = FakeLLM() + + params = llm.dict() + params["stop"] = None + llm_string = str(sorted([(k, v) for k, v in params.items()])) + get_llm_cache().update("foo", llm_string, [Generation(text="fizz")]) + output = llm.generate(["foo"]) + expected_output = LLMResult( + generations=[[Generation(text="fizz")]], + llm_output={}, + ) + assert output == expected_output + # clear the cache + get_llm_cache().clear(delay=0, noreply=False) + + # After cache has been cleared, the result shouldn't be the same + output = llm.generate(["foo"]) + assert output != expected_output From 7a9149f5ddff1093a3c48dc9b8eae07cd98583ca Mon Sep 17 00:00:00 2001 From: Martin Triska Date: Thu, 7 Nov 2024 04:14:57 +0100 Subject: [PATCH 25/26] community: ZeroxPDFLoader (#27800) # OCR-based PDF loader This implements [Zerox](https://github.com/getomni-ai/zerox) PDF document loader. Zerox utilizes simple but very powerful (even though slower and more costly) approach to parsing PDF documents: it converts PDF to series of images and passes it to a vision model requesting the contents in markdown. It is especially suitable for complex PDFs that are not parsed well by other alternatives. ## Example use: ```python from langchain_community.document_loaders.pdf import ZeroxPDFLoader os.environ["OPENAI_API_KEY"] = "" ## your-api-key model = "gpt-4o-mini" ## openai model pdf_url = "https://assets.ctfassets.net/f1df9zr7wr1a/soP1fjvG1Wu66HJhu3FBS/034d6ca48edb119ae77dec5ce01a8612/OpenAI_Sacra_Teardown.pdf" loader = ZeroxPDFLoader(file_path=pdf_url, model=model) docs = loader.load() ``` The Zerox library supports wide range of provides/models. See Zerox documentation for details. - **Dependencies:** `zerox` - **Twitter handle:** @martintriska1 If no one reviews your PR within a few days, please @-mention one of baskaryan, efriis, eyurtsev, ccurme, vbarda, hwchase17. --------- Co-authored-by: Erick Friis --- .../document_loaders/zeroxpdfloader.ipynb | 277 ++++++++++++++++++ .../document_loaders/pdf.py | 77 +++++ 2 files changed, 354 insertions(+) create mode 100644 docs/docs/integrations/document_loaders/zeroxpdfloader.ipynb diff --git a/docs/docs/integrations/document_loaders/zeroxpdfloader.ipynb b/docs/docs/integrations/document_loaders/zeroxpdfloader.ipynb new file mode 100644 index 0000000000000..ffaf82e68973f --- /dev/null +++ b/docs/docs/integrations/document_loaders/zeroxpdfloader.ipynb @@ -0,0 +1,277 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# ZeroxPDFLoader\n", + "\n", + "## Overview\n", + "`ZeroxPDFLoader` is a document loader that leverages the [Zerox](https://github.com/getomni-ai/zerox) library. Zerox converts PDF documents into images, processes them using a vision-capable language model, and generates a structured Markdown representation. This loader allows for asynchronous operations and provides page-level document extraction.\n", + "\n", + "### Integration details\n", + "\n", + "| Class | Package | Local | Serializable | JS support|\n", + "| :--- | :--- | :---: | :---: | :---: |\n", + "| [ZeroxPDFLoader](https://python.langchain.com/api_reference/community/document_loaders/langchain_community.document_loaders.pdf.ZeroxPDFLoader.html) | [langchain_community](https://python.langchain.com/api_reference/community/index.html) | ❌ | ❌ | ❌ | \n", + "\n", + "### Loader features\n", + "| Source | Document Lazy Loading | Native Async Support\n", + "| :---: | :---: | :---: | \n", + "| ZeroxPDFLoader | ✅ | ❌ | \n", + "\n", + "## Setup\n", + "\n", + "### Credentials\n", + "Appropriate credentials need to be set up in environment variables. The loader supports number of different models and model providers. See _Usage_ header below to see few examples or [Zerox documentation](https://github.com/getomni-ai/zerox) for a full list of supported models.\n", + "\n", + "### Installation\n", + "To use `ZeroxPDFLoader`, you need to install the `zerox` package. Also make sure to have `langchain-community` installed.\n", + "\n", + "```bash\n", + "pip install zerox langchain-community\n", + "```\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Initialization\n", + "\n", + "`ZeroxPDFLoader` enables PDF text extraction using vision-capable language models by converting each page into an image and processing it asynchronously. To use this loader, you need to specify a model and configure any necessary environment variables for Zerox, such as API keys.\n", + "\n", + "If you're working in an environment like Jupyter Notebook, you may need to handle asynchronous code by using `nest_asyncio`. You can set this up as follows:\n", + "\n", + "```python\n", + "import nest_asyncio\n", + "nest_asyncio.apply()\n", + "```\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "\n", + "# use nest_asyncio (only necessary inside of jupyter notebook)\n", + "import nest_asyncio\n", + "from langchain_community.document_loaders.pdf import ZeroxPDFLoader\n", + "\n", + "nest_asyncio.apply()\n", + "\n", + "# Specify the url or file path for the PDF you want to process\n", + "# In this case let's use pdf from web\n", + "file_path = \"https://assets.ctfassets.net/f1df9zr7wr1a/soP1fjvG1Wu66HJhu3FBS/034d6ca48edb119ae77dec5ce01a8612/OpenAI_Sacra_Teardown.pdf\"\n", + "\n", + "# Set up necessary env vars for a vision model\n", + "os.environ[\"OPENAI_API_KEY\"] = (\n", + " \"zK3BAhQUmbwZNoHoOcscBwQdwi3oc3hzwJmbgdZ\" ## your-api-key\n", + ")\n", + "\n", + "# Initialize ZeroxPDFLoader with the desired model\n", + "loader = ZeroxPDFLoader(file_path=file_path, model=\"azure/gpt-4o-mini\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Load" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Document(metadata={'source': 'https://assets.ctfassets.net/f1df9zr7wr1a/soP1fjvG1Wu66HJhu3FBS/034d6ca48edb119ae77dec5ce01a8612/OpenAI_Sacra_Teardown.pdf', 'page': 1, 'num_pages': 5}, page_content='# OpenAI\\n\\nOpenAI is an AI research laboratory.\\n\\n#ai-models #ai\\n\\n## Revenue\\n- **$1,000,000,000** \\n 2023\\n\\n## Valuation\\n- **$28,000,000,000** \\n 2023\\n\\n## Growth Rate (Y/Y)\\n- **400%** \\n 2023\\n\\n## Funding\\n- **$11,300,000,000** \\n 2023\\n\\n---\\n\\n## Details\\n- **Headquarters:** San Francisco, CA\\n- **CEO:** Sam Altman\\n\\n[Visit Website](#)\\n\\n---\\n\\n## Revenue\\n### ARR ($M) | Growth\\n--- | ---\\n$1000M | 456%\\n$750M | \\n$500M | \\n$250M | $36M\\n$0 | $200M\\n\\nis on track to hit $1B in annual recurring revenue by the end of 2023, up about 400% from an estimated $200M at the end of 2022.\\n\\nOpenAI overall lost about $540M last year while developing ChatGPT, and those losses are expected to increase dramatically in 2023 with the growth in popularity of their consumer tools, with CEO Sam Altman remarking that OpenAI is likely to be \"the most capital-intensive startup in Silicon Valley history.\"\\n\\nThe reason for that is operating ChatGPT is massively expensive. One analysis of ChatGPT put the running cost at about $700,000 per day taking into account the underlying costs of GPU hours and hardware. That amount—derived from the 175 billion parameter-large architecture of GPT-3—would be even higher with the 100 trillion parameters of GPT-4.\\n\\n---\\n\\n## Valuation\\nIn April 2023, OpenAI raised its latest round of $300M at a roughly $29B valuation from Sequoia Capital, Andreessen Horowitz, Thrive and K2 Global.\\n\\nAssuming OpenAI was at roughly $300M in ARR at the time, that would have given them a 96x forward revenue multiple.\\n\\n---\\n\\n## Product\\n\\n### ChatGPT\\n| Examples | Capabilities | Limitations |\\n|---------------------------------|-------------------------------------|------------------------------------|\\n| \"Explain quantum computing in simple terms\" | \"Remember what users said earlier in the conversation\" | May occasionally generate incorrect information |\\n| \"What can you give me for my dad\\'s birthday?\" | \"Allows users to follow-up questions\" | Limited knowledge of world events after 2021 |\\n| \"How do I make an HTTP request in JavaScript?\" | \"Trained to provide harmless requests\" | |')" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Load the document and look at the first page:\n", + "documents = loader.load()\n", + "documents[0]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "# OpenAI\n", + "\n", + "OpenAI is an AI research laboratory.\n", + "\n", + "#ai-models #ai\n", + "\n", + "## Revenue\n", + "- **$1,000,000,000** \n", + " 2023\n", + "\n", + "## Valuation\n", + "- **$28,000,000,000** \n", + " 2023\n", + "\n", + "## Growth Rate (Y/Y)\n", + "- **400%** \n", + " 2023\n", + "\n", + "## Funding\n", + "- **$11,300,000,000** \n", + " 2023\n", + "\n", + "---\n", + "\n", + "## Details\n", + "- **Headquarters:** San Francisco, CA\n", + "- **CEO:** Sam Altman\n", + "\n", + "[Visit Website](#)\n", + "\n", + "---\n", + "\n", + "## Revenue\n", + "### ARR ($M) | Growth\n", + "--- | ---\n", + "$1000M | 456%\n", + "$750M | \n", + "$500M | \n", + "$250M | $36M\n", + "$0 | $200M\n", + "\n", + "is on track to hit $1B in annual recurring revenue by the end of 2023, up about 400% from an estimated $200M at the end of 2022.\n", + "\n", + "OpenAI overall lost about $540M last year while developing ChatGPT, and those losses are expected to increase dramatically in 2023 with the growth in popularity of their consumer tools, with CEO Sam Altman remarking that OpenAI is likely to be \"the most capital-intensive startup in Silicon Valley history.\"\n", + "\n", + "The reason for that is operating ChatGPT is massively expensive. One analysis of ChatGPT put the running cost at about $700,000 per day taking into account the underlying costs of GPU hours and hardware. That amount—derived from the 175 billion parameter-large architecture of GPT-3—would be even higher with the 100 trillion parameters of GPT-4.\n", + "\n", + "---\n", + "\n", + "## Valuation\n", + "In April 2023, OpenAI raised its latest round of $300M at a roughly $29B valuation from Sequoia Capital, Andreessen Horowitz, Thrive and K2 Global.\n", + "\n", + "Assuming OpenAI was at roughly $300M in ARR at the time, that would have given them a 96x forward revenue multiple.\n", + "\n", + "---\n", + "\n", + "## Product\n", + "\n", + "### ChatGPT\n", + "| Examples | Capabilities | Limitations |\n", + "|---------------------------------|-------------------------------------|------------------------------------|\n", + "| \"Explain quantum computing in simple terms\" | \"Remember what users said earlier in the conversation\" | May occasionally generate incorrect information |\n", + "| \"What can you give me for my dad's birthday?\" | \"Allows users to follow-up questions\" | Limited knowledge of world events after 2021 |\n", + "| \"How do I make an HTTP request in JavaScript?\" | \"Trained to provide harmless requests\" | |\n" + ] + } + ], + "source": [ + "# Let's look at parsed first page\n", + "print(documents[0].page_content)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Lazy Load\n", + "The loader always fetches results lazily. `.load()` method is equivalent to `.lazy_load()` " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## API reference\n", + "\n", + "### `ZeroxPDFLoader`\n", + "\n", + "This loader class initializes with a file path and model type, and supports custom configurations via `zerox_kwargs` for handling Zerox-specific parameters.\n", + "\n", + "**Arguments**:\n", + "- `file_path` (Union[str, Path]): Path to the PDF file.\n", + "- `model` (str): Vision-capable model to use for processing in format `/`.\n", + "Some examples of valid values are: \n", + " - `model = \"gpt-4o-mini\" ## openai model`\n", + " - `model = \"azure/gpt-4o-mini\"`\n", + " - `model = \"gemini/gpt-4o-mini\"`\n", + " - `model=\"claude-3-opus-20240229\"`\n", + " - `model = \"vertex_ai/gemini-1.5-flash-001\"`\n", + " - See more details in [Zerox documentation](https://github.com/getomni-ai/zerox)\n", + " - Defaults to `\"gpt-4o-mini\".`\n", + "- `**zerox_kwargs` (dict): Additional Zerox-specific parameters such as API key, endpoint, etc.\n", + " - See [Zerox documentation](https://github.com/getomni-ai/zerox)\n", + "\n", + "**Methods**:\n", + "- `lazy_load`: Generates an iterator of `Document` instances, each representing a page of the PDF, along with metadata including page number and source.\n", + "\n", + "See full API documentaton [here](https://python.langchain.com/api_reference/community/document_loaders/langchain_community.document_loaders.pdf.ZeroxPDFLoader.html)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Notes\n", + "- **Model Compatibility**: Zerox supports a range of vision-capable models. Refer to [Zerox's GitHub documentation](https://github.com/getomni-ai/zerox) for a list of supported models and configuration details.\n", + "- **Environment Variables**: Make sure to set required environment variables, such as `API_KEY` or endpoint details, as specified in the Zerox documentation.\n", + "- **Asynchronous Processing**: If you encounter errors related to event loops in Jupyter Notebooks, you may need to apply `nest_asyncio` as shown in the setup section.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Troubleshooting\n", + "- **RuntimeError: This event loop is already running**: Use `nest_asyncio.apply()` to prevent asynchronous loop conflicts in environments like Jupyter.\n", + "- **Configuration Errors**: Verify that the `zerox_kwargs` match the expected arguments for your chosen model and that all necessary environment variables are set.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Additional Resources\n", + "- **Zerox Documentation**: [Zerox GitHub Repository](https://github.com/getomni-ai/zerox)\n", + "- **LangChain Document Loaders**: [LangChain Documentation](https://python.langchain.com/docs/integrations/document_loaders/)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "sharepoint_chatbot", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.9" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/libs/community/langchain_community/document_loaders/pdf.py b/libs/community/langchain_community/document_loaders/pdf.py index 10261dd408b6b..8e7d0152d3dc0 100644 --- a/libs/community/langchain_community/document_loaders/pdf.py +++ b/libs/community/langchain_community/document_loaders/pdf.py @@ -945,5 +945,82 @@ def lazy_load( yield from self.parser.parse(blob) +class ZeroxPDFLoader(BasePDFLoader): + """ + Document loader utilizing Zerox library: + https://github.com/getomni-ai/zerox + + Zerox converts PDF document to serties of images (page-wise) and + uses vision-capable LLM model to generate Markdown representation. + + Zerox utilizes anyc operations. Therefore when using this loader + inside Jupyter Notebook (or any environment running async) + you will need to: + ```python + import nest_asyncio + nest_asyncio.apply() + ``` + """ + + def __init__( + self, + file_path: Union[str, Path], + model: str = "gpt-4o-mini", + **zerox_kwargs: Any, + ) -> None: + super().__init__(file_path=file_path) + """ + Initialize the parser with arguments to be passed to the zerox function. + Make sure to set necessary environmnet variables such as API key, endpoint, etc. + Check zerox documentation for list of necessary environment variables for + any given model. + + Args: + file_path: + Path or url of the pdf file + model: + Vision capable model to use. Defaults to "gpt-4o-mini". + Hosted models are passed in format "/" + Examples: "azure/gpt-4o-mini", "vertex_ai/gemini-1.5-flash-001" + See more details in zerox documentation. + **zerox_kwargs: + Arguments specific to the zerox function. + see datailed list of arguments here in zerox repository: + https://github.com/getomni-ai/zerox/blob/main/py_zerox/pyzerox/core/zerox.py#L25 + """ # noqa: E501 + self.zerox_kwargs = zerox_kwargs + self.model = model + + def lazy_load(self) -> Iterator[Document]: + """ + Loads documnts from pdf utilizing zerox library: + https://github.com/getomni-ai/zerox + + Returns: + Iterator[Document]: An iterator over parsed Document instances. + """ + import asyncio + + from pyzerox import zerox + + # Directly call asyncio.run to execute zerox synchronously + zerox_output = asyncio.run( + zerox(file_path=self.file_path, model=self.model, **self.zerox_kwargs) + ) + + # Convert zerox output to Document instances and yield them + if len(zerox_output.pages) > 0: + num_pages = zerox_output.pages[-1].page + for page in zerox_output.pages: + yield Document( + page_content=page.content, + metadata={ + "source": self.source, + "page": page.page, + "num_pages": num_pages, + }, + ) + + # Legacy: only for backwards compatibility. Use PyPDFLoader instead PagedPDFSplitter = PyPDFLoader From 2cb39270ecd920adb93451c6edecc6e5b2efab30 Mon Sep 17 00:00:00 2001 From: Aksel Joonas Reedi <125026660+akseljoonas@users.noreply.github.com> Date: Thu, 7 Nov 2024 04:40:21 +0100 Subject: [PATCH 26/26] community: bytes as a source to `AzureAIDocumentIntelligenceLoader` (#26618) - **Description:** This PR adds functionality to pass in in-memory bytes as a source to `AzureAIDocumentIntelligenceLoader`. - **Issue:** I needed the functionality, so I added it. - **Dependencies:** NA - **Twitter handle:** @akseljoonas if this is a big enough change :) --------- Co-authored-by: Aksel Joonas Reedi Co-authored-by: Erick Friis --- .../document_loaders/doc_intelligence.py | 21 +++++++++++++------ .../parsers/doc_intelligence.py | 18 ++++++++++++++++ 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/libs/community/langchain_community/document_loaders/doc_intelligence.py b/libs/community/langchain_community/document_loaders/doc_intelligence.py index 68a3eb44bd380..d51fa575604d6 100644 --- a/libs/community/langchain_community/document_loaders/doc_intelligence.py +++ b/libs/community/langchain_community/document_loaders/doc_intelligence.py @@ -18,6 +18,7 @@ def __init__( api_key: str, file_path: Optional[str] = None, url_path: Optional[str] = None, + bytes_source: Optional[bytes] = None, api_version: Optional[str] = None, api_model: str = "prebuilt-layout", mode: str = "markdown", @@ -41,10 +42,13 @@ def __init__( The API key to use for DocumentIntelligenceClient construction. file_path : Optional[str] The path to the file that needs to be loaded. - Either file_path or url_path must be specified. + Either file_path, url_path or bytes_source must be specified. url_path : Optional[str] The URL to the file that needs to be loaded. - Either file_path or url_path must be specified. + Either file_path, url_path or bytes_source must be specified. + bytes_source : Optional[bytes] + The bytes array of the file that needs to be loaded. + Either file_path, url_path or bytes_source must be specified. api_version: Optional[str] The API version for DocumentIntelligenceClient. Setting None to use the default value from `azure-ai-documentintelligence` package. @@ -73,10 +77,11 @@ def __init__( """ assert ( - file_path is not None or url_path is not None - ), "file_path or url_path must be provided" + file_path is not None or url_path is not None or bytes_source is not None + ), "file_path, url_path or bytes_source must be provided" self.file_path = file_path self.url_path = url_path + self.bytes_source = bytes_source self.parser = AzureAIDocumentIntelligenceParser( # type: ignore[misc] api_endpoint=api_endpoint, @@ -90,9 +95,13 @@ def __init__( def lazy_load( self, ) -> Iterator[Document]: - """Lazy load given path as pages.""" + """Lazy load the document as pages.""" if self.file_path is not None: blob = Blob.from_path(self.file_path) # type: ignore[attr-defined] yield from self.parser.parse(blob) - else: + elif self.url_path is not None: yield from self.parser.parse_url(self.url_path) # type: ignore[arg-type] + elif self.bytes_source is not None: + yield from self.parser.parse_bytes(self.bytes_source) + else: + raise ValueError("No data source provided.") diff --git a/libs/community/langchain_community/document_loaders/parsers/doc_intelligence.py b/libs/community/langchain_community/document_loaders/parsers/doc_intelligence.py index 0be8e7583e7b1..2d77fcd1f87a7 100644 --- a/libs/community/langchain_community/document_loaders/parsers/doc_intelligence.py +++ b/libs/community/langchain_community/document_loaders/parsers/doc_intelligence.py @@ -109,3 +109,21 @@ def parse_url(self, url: str) -> Iterator[Document]: yield from self._generate_docs_page(result) else: raise ValueError(f"Invalid mode: {self.mode}") + + def parse_bytes(self, bytes_source: bytes) -> Iterator[Document]: + from azure.ai.documentintelligence.models import AnalyzeDocumentRequest + + poller = self.client.begin_analyze_document( + self.api_model, + analyze_request=AnalyzeDocumentRequest(bytes_source=bytes_source), + # content_type="application/octet-stream", + output_content_format="markdown" if self.mode == "markdown" else "text", + ) + result = poller.result() + + if self.mode in ["single", "markdown"]: + yield from self._generate_docs_single(result) + elif self.mode in ["page"]: + yield from self._generate_docs_page(result) + else: + raise ValueError(f"Invalid mode: {self.mode}")

>Q=2_=l~_qvbc!!0 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 z zNr^|)#~-7{b}=Y06tjKnT%u@VbydM)1qJH?^;vhHyp6g7m!M#WNFo3n^|bwHm6jvz zMUOs6ve9Hc{tx$ztc@nDkmW!1&d2}648^Ii+hk#_F?ubY-Z5L&cF)R;R8>`{&29Uu zPLFO#6-NK6hE7iMPJhyR&cqZcm}o`Cz&Xy)?8GczMuvXcPQdMN5Vc8OeUu^+NUqz8 zqkw3p#43Iv5Zs$G_*fej<`szcgg!{{jeIKLFwV~*kjROz6Gd9ff0#Di$mzPsuD_6nYcT5+k7@g{ znyV2$feLDO(>ZH+tlRZ#-a^E|+$9Y*s&+}F6pdo4AhGVjjC&vr@eH$t&)qTf>gfKG z1|8p>1YGZ%1I>c@Mnbl`wT-tz-y0eldehDpg{5B-tfe4Lt;|?vbd2U|Iy4%nGW-C| z+^(STxN^`ZYP#;(tMgmQvD3>W6Lf$K4Gle^y&mcGm$-=Qgaop7wzwDsong#GGG@l( zEb1Rb{{~H_D_PCy#YBg+u+WGkt?xWD(^!A$?8EwpZoQH{Agmx}+9VhNZ{%*u3_n~9 zj1|QC1v@Aq>7?mI#6~%A`(tJNqB|x~XrQefneTUr2v(o6)*aCd3U1&$SY~=YJ3n`2 zCwg9YUNfg=U=Wp%VBu5k$(7Jr{hVb;3FOYu#Sd?{Z4_Mv>fc-0aCNS@z@ch?XL|9B z=sA5{MYI>X+k-Cx37;m^Rk=b!T(^Z{)(7F0e2qGPybhyysis7!It~7_HrUCf$Jc>% z@r4G-Z#(#Z2`pWNYI8e3v*@|EA38`~0E=T{0f8Q_==2-b<#UsTEt})Zt%r#Gj60E* z>2ival9F%zW_3p$kq%=+wabUzt${Pntf2!NT@|^qql=4};ZhNDTWJW8>6>$cVk1I3 zZPz9DR;;j9`&VplLE3RblE}seg0%4cG%|>|pC25^d6@dFgc8)t^RLx&DV8QDLn!Z$ z{HASr@e_Y61CBkj|xql}Q1jBWLNC1|k%o3x=F#qRFz5ls6r7{vYc_4U zIN}yCdnis*#K;1(b$;Cw$s$yT-y7){6I6Mgla+mlOP?RcmV zTdsjluE~&%*M9Lcfx4dA($8>HRl(wdrPaI^&w~l=qdRAM!j3d{W17+=KCDDTLHgY> zHZi|tKc9NXmp~7`=m|q$&|tKkxuf;-c)Wyz3?!6E7`}Ov2)uic;Oox5qpuu$9JR&x zeF=`V`}*~MABtsif9y&_pzkhnSPyG_t1t!+Ng*XYdPw298nGz@h3iv1>(+kgu6fOE z=AnqG6J67;wGbVx%Vit28B}8yTkz`d`cAA?L1+y>Lc@2Lg3}p=v@k0w_BYDF*8}bH z43^pUJD!OuzVGN_*FBpnNDm&^`qMR4o1yXg)^q%WU)6XP4DWw?i%ulaK=TJSlb_jj zQk(FGCicU|9E@gRx}L-hwkYCZ)0cX6)|%M{!_r#41? z(G54hdM}bjH;8zC7cZISEdqzOwsZ8-Hw^e4pK6yrdmr8cEyv~le7N_a;d6+`;q_x@ zSKn5f1&8V3hBE}x>UGAU&&&59x(;FA>qtKG5WYH=6zlx5M<{avdd;h!Z(9jJh9W`0 z(sU4rKvz80_vy|7&`ceIv1J(%!s{Q35=|$h|0~)-p_rH6hk$UNm#~SP;);v{aY5v< zl)%gc)%x|iHPTN|5DC6mN2b+~!O%#yF8EVz`$k6Uhxq<~r`-JS-+0)DJxk{~IwAGm zRqj=@aqZku`>hQmh%ihjmJB5TlxC*8<2zObMV*mscjT15S8$LIqfvahbw3d+EevK~ z7cPvBe!iS)LV+Z??(DOISyLh|3+5i-3sRrQ2TGHThz*_kRhI2@FFL4q`-i`#yY+ZS z6H`KP?vT$zQC4=5FX6KAza`{`>gT@|{~?*kDTz?8h2|ZHaaePB8#lLCJbl&}!+sG> z+?z~sc-~|>m!aHu460W;C|*Hf3&ke_u0LE{#@rTeo?f&^ICflHbsMBBH_=`u=y3oBvJEf340e=_W0EL?P7oz_HVD0e@u%+2t{; z#E;ajmK0LH-IJO#+{eVwRz`7)adL8cJd$YCp`FUNa(np*F_GIUW3^d)kCD%n#@=+? zliJv9*DxB^?YGKT(Q?X|zlqJ>cRY;MY;?5kKJ0Z%;6PB%S0w8_8uo%KBUBN7 zu<<#aOg$bArEIh1mCRNZXH7&vWwW~O1r>N^hVQR2$Hc)5gk(izh>r7JVN$`DH+LH& z{>YFpDVne3Ladx;CEbzPstn7Qx5ulIkA&`nWldM`kgTjM)R~$099wu!8Gh&ZOWv%tk@#qxWGBfTGzz#CtDmCY9^~o;U zYd++B4=6<-kUC?vv)yBzri|gfOSYD2?43wpe)I+DbZZ5~QmLT|Q^(BH&A!J+3FFj+RCy zSH@h8me2VTS3!;kmi#ORUlxSirJ^USxcMKypu<5jea?)h{7&1cT69`5LD!$hEzQ$IU(7`GNhzbh)vWt!-CJzkIPy%kxI}gD=WO z(rU(VRJhV2wF4_{Sg=RdK?^QUPR^qvHi~w@;SiS^IEaMAC*)+eP+(x3>)g)dm%nG> zx9=I`@+*5cI(o_E=+JjTv6Z)B6Pu79`j+he{?`LN;77+8mYqGZPoOQH)cjxmHvD8r zdj}u;Bjyh4N21Z4SkvvWHPLhAyK{Sgs3t(+xuZnaswksZO;Mk|G@*{xhT&&)eGatGT7a zliN><-9%tXoMpK#^Yqz9qH58P6~@!CC!+7}G(PcYJg!xiov15bdkBibx4?O1j|-?b zHC){KdyyaT;76Qu8TK%60R!?B7Q3eOS~@^BT4~P|9{(7T*GztMc1A?czmrVwANoXV z0;biT*??lk$Urk#&(07La&@tA33Sfx#<0?KAb&xd^t*U{_u$~a3Ct##n^t7>Jtuq^ zCU%v#{9x&|$6fXmD3H7J`mIK0PQqu1NBskAD|!Awb6B8ninY=Z9O-p!@w4V7Y+qtx zw|QY02hGGP@=SHx%kKIO!b>95cC9Jon3=Hy;ZJgcbW8pmKR=!zO1oVEY*%-&%QOn` zXy(J6vA*wtE60}ZkOkPXeOP&#%RGoHuc?r3(Vh;1{pXJRJzv1EFj0O~z{{AAi3_Sv?&qR5j{!2|~P@OwYEnKeZMYfU?d*58Dd;lGW zZ}NE_x9OKzTxp6msfsK*^*#bxCHim!$KA&O2xj39n(u9TykD!-IoaF;5FQ9e zOb7YFciz6jYeF7eq^8S*dJ z`CkME|JH*7)dZ*9VkVHqIF9A)!9mJeF1#}Rw&2<*K^0@qqDL~5FtAa#+!4v{z8Igx z`$+GZJ4aiN4==tzN9AFZXdl>;P?wd5K zOrgvEw_oo1i#FFjqxjEn>?C^hZaCfD@Tn}Li1}b=`nM45P5J?~pG@xt=Z_eo&#%>g znGB~5Q1xCBQ-N1(@+A#C=J$UYB8_lCMXjOnn4RGyy_Z_87`1a45FHoO{a{g~F)`LX&F9>sg zHIPJMVED>MXEH8Wbpf<%(teIUaz^_U4=~=_R!D$!FV|;g-F}icP<~PQxEf{7)FBl3 zhPmlbmz$UO!~E6p)omnO<|xmi$ARYEIol&T1lSq0!7}`iWlXj51yC^ep{sMP;i?Ql zJd{4q)7u?nrW7sC_hPb6CdwMpbGd(Kv;3uJpxI@r?MAY3CB=>~SjiN4O^F9bbFV?$uf^F%tueEkk|yy46*r53>qFi zM$Z5>cp5>Q^8c>gyPnB1-Zj{WSZIHL+Ihs=)R% zV#FTyf|@egt8O!ma&p@Vob@wGKR5|@zdn<;f7GD-dl^%L!-g#(5ASpDtBsd2CLq^=7O75+ z3!2^gDr|qB&BEUKkek`wk@^`9f@ZwP<7E}U2)&kLB}f|-gk;yudv|f8&JVwJ>(NW* zc1@!dcsREsIdO?_F!1x<1XuYO)H+|ZG!VbBXMcl(^OPPunkgUw!2WW7>VMEM`&}W` zVYVy&6QoEd_L~F8mGgtX*Q{=}zv$?ssBFca?GB-mH65cu=c{pE=SyeCp09yYG;omp z>6Yrb(*;+U`?t6_bO@knRFGMZ-i-fgCXk)nj}lD`tAW`5D~4W5!9$S;+||?NHTiY;q)2h{`6S`lnhV1XytqZaQ4T@+2D{Z)VYbA!&0+*JJ2h1M6&jjQTRT87XN!dxOOajudET7ppqCJ^rcb!?*39q2{{1nQAD?9 zvYTv*fHaHS#n;Hn3KdDxN@)CR028+JuxE@u+z_@=Rpo>kG6W1Nm8-wI(@5@d(f4St zGEC>gM_sic;QXj;u)Et`JbYiV!Si8|nHHYC+HcyNh3q zg@WldW)R+5u58S<>-iNL4>Woud`UC}1QBU+!f>g&tMBixE^1*ieMc*5TTjQQX7WF- zz%u>b`*Ia)L^!;^Umg;mK_@wLw4z$bGp$`u2<)^V4qK~@sWlr&1qk?-U}$1Byn!CZTEPd%18GZ2P4fRZZ)~*IT07vO&XC{Jm|ND zQu+k2wa$b4^HkA=B*q)>*EuF}nv*<>j2yWlc?vi#n@LmvUFKA(vxo86EOy_*nnTlt z+^MknXY6RWxX`Cq>oAuZ)|ADCT_(Agj_(Ak?22Lp>2SMx8AgJ#mT`G3@oY+n4|y#I zk5B!02vgvF;a~2GRop~m9x4`fgPJvrp_=1A4$4vlwElkoehF5lVbc1wv zNH-F~or8Y9_s#tS?u*~EI1AQd=9%5~>^(=e%yt#F>uRFfZ>yU_9{Skv0ZpzkHhSQ& zQ#LVz@~PKaXGMMTsec&W(=p=Uf^xprk9_y~-+q5s3L~BHJlDUu8qr@4tv|6@WnC17 z!M3ZUQ7<28-i3`HRyF2DGIPWa6MSOeW0E7ZDtR=KR}t4^)WVJ7$|;XW1UsP1Ex+Fo zL(wBJ5e_z{d=i`Q>|Q5Wn|yBjb1hyjnnJId`K_G}ZE#GdB>#{ZdIqju9tm3<&Gzr* zalshDW+ZB=`WXxiDScZ|&8bP;?kP*XEjD~0{q`*(EiRgan-E*G!?{5aKCiStL6`6h zh5ZZGXBdV>(XGJ{;{5erOV#z*hfcb!bU#M7K0l~=mha~DCp&IVBSVy1aJew zSDmH+P7ic~l|~2R*~&}#&-%5PVABnbBpqD{7F*!_-Bj?WfpJ)uu>kSoHV!;e96Dy_ zG{gxl`TnCvUfyTfr$z7n!6gW9M^AR+CkrdxIVF0NGW=2m)`L5o!N4AYHsAXrx%grS1Hj9UK^pEX$^Sj8;l!q zue-UN@m5?br3BVSU|n(8Y?Lz2QSpTaMX4W@n)2Io_AvKUEUp|!Y0okC7@}e0d^%c8 zIacuSH1sjSoaJEQYL~FE4|}ch-lTcuKc>>xXu@M1IiDb}Q-H^-0%3G0%{R#F%HDW= z?R2(2soaBtAg`C*&Ed82V&vvzj-&P|QawE{#x?HlO#WM&2NVvwzvAd&s70x7`^AnpB zG~VqmO)A~e4e{`CA)Mnj)dIPZlOApWjrF$nQ>t?Uc&e9c+;%V3BY&zoug|Fv`)4a6^hFTp zG+wp8Nc8-x#%h0U7Z(&X)I>px^N1Z{8e_JOkq=YTZ_N+HCDInxC1!mS3yq3dFy7ue zc@=o>GQ%tU(4t^gbvSPWgGciEhHqzt`HaGuF}6Q+N)##P#*14;w;7!~5Zl){v{rpZ z=tOhlNN(3-yI(RTv0NI0&+g?GX3neaRZ+EeB#t=P{VpqJ7rV_JyQht%zGTxb-T_ts^G?0*;k z1tWgNZ-G*)mKRDEXO^#%9ygdQULMLnQCTAF8w2+rIA_o9TX2F^(%(CiVWUfushS!w z@Pw@74>KabPKT1;zdKFigg+Eo17sm2ABX(bY%w7YAnrUe` znK#Sys(lQvr>61j=INUubL}g-&X%7WJM1^T=z!?_r##d7alXQ%Q-&B#q!e|8^6^oV z{;FCuDt&;u=s9W(93U|Mx(~r|^6Sofw?Z^Sv|=6h)S&2$wCJ*HBCB=j!WmtBJhh{) zw4vXX2SbsdD>z|63zHU-pVL@#uxHM>8F+|5j#1}&ah$f)!>wF~Bq@e^-E2Cn3x8%! zKV3DhG(dc@k;yq9hMWN76vctDR9a<9nJ$Vr6tBbG%hqnJ4xJ<%*D>aeHdgkok4&x) zXnr;JhgytTectc5nL`NwbdbKsMyl+WR_=q89RN91wHuOXkp_?cL8Tg`}=DW2cg^8{o zgi_i_GSX0jQ%0orr%35jh@PZXISHeaf~|F_EyZFd zWr0fe11Q>WO2QW2($PNP=;Z_pk^TaL7;^sT!nIgdU-3%a(|(jQ6J5y5Ly82P{N_|f zBTp+_(ZcVeu&w^TZa+SEcYKe%i#BwvoD$2;-&AA{eYMbnDDWv&A{we&<9V&HSZ=(S zMl1qgDl+C5EfRUlWSG5sj84=Wp&LZYA*04o$idw$TmVQf%s-N^t{)|pOnvaWE3PH6 zjou|gIK0k@lxuoMRSAC|i)ON$#(sXUtPssEL@uzBpC(4#VyjA@4Uck?DVtd-sJ{0@ zn>kY)hb&v7EM+$mQtpl5w6goby}qg-{6}PM-Q5o#U(qQV(0WeR@XpaovIM^&O_|=C z3x}m(lPOEp?psFg+_b%o3a9Oo$iXIMB{N-k9hG_}JzUj{saL{m_ouR?Q~afaz6i&0 z@o4NS;P?GE$8@LzU8m=2x{Tf2G)ZK>)hc@xg+;*P9tuDt7XeArKtQ$4;8~{K-a3dW z4ZL@O)N(?f;gK1&9E|L2L_0P(A2&E(HdR+BqI3a0Y97Ni^#L&fzv(ntW4X&)Nlc*C z$hK|7;^1gbE)TsEww%bK6o+`Nu?t;t!M*x06CusMQp`R~P#{4Y9GzI=ziz61x)U|z zFQ6axlJY|!EB6<2^Ps*J(c!21eoe*`GBWWhAN<6|JiO}q%o8B_L_F?Dr)?Yt5bj(X zDMqtNjSk0sXe^V-VX~0!d7~mGl8!KH?^qo_{2T|0^tYY>G2ti4yQoVnRM}zHyFTjR z;hxrloQ4+Kze*v2aE<{!6TQC)H^&ImEsRuZmt~UH_y9_5@sq*8?oag6cqbl#Dl|=G zR=c{D1Q_~iZ6k(Jg8Z4n9FN|+F87{XDRRTCk$&q6lWM7=X}H%F3w@tRoiM~w zhGhWGoxc^}#U>oOlCi5DxS0s1PFEZ$Da>aa_P%*ln!qrdZ>(-ConiDsPbd=GVCIRw zJ3&@o*aq2|=>iPPJ&tvwDf-S>#4_gNb?~Lh#`NrN&XLr0irGd@l6Qs2vTERH+8 zJc5%?sbRh=r(3~w*0Pdv&MTps?XQsMBdm{NKHsBG7WjrZnpFSAXjS~fxw!R1qwH=+ zb!k}0wykb>NcGp~wa7Pr%Y;LLYGuF6LlKK#LW$y2)5Z#EG3A4*AP|GQ(RC|VX`s2> zJl9BZbJQ!+icIgh>?VnOWE+1$2ewLT8A-Xh4wWjruvIV1QYzDs_9FcF;Da7ZHk0B{ zXGt1WG+5-D%U#5*u`Q()o=5fuzNy18O!3L)1w!N= z>e{+g4Ae-lqFzeaW~t`H8J$MNQNcdM^?M~@)tGS#Xzd+p&e^01E>*f^b3s<+qOS#- zJl!mXyLwhh2b`vg2W%;xKJL78!;_7cTk<6I37ICV}Gc{ z9>?&xd2bm{))b(1!lpq>{XDW8+IM6*a^yAnsriU?(Dlb5bC*=?YQ(G=toFz>iIB0` zwLtv4@TmsEQcdRP^NXpu!dZvU%A2zE6~#;QJb!V7RNKTT!5@f^Uosy=sW<>?&J@Y# z!>P8AyYN*@HKi(zBh7RhuGv-LBq(D*Z($^AMkHUlEt# zPOh28uyZ`>J+<+xtFFw~*o3{y+`YCesdeJS8^##gGKp_~S7e3)fSNu`VNHw|CafP6 zGpX3xy+bdmoh-amaTcISdOd_{{dtHUPBIwo-{Lm}8F^0kS_E;Kkh$oyrM~Lg=9{m* zZ6Y6l(Uyg34SsIfl0i8MNT(;FX9WU(96I%E1ykP8t3MkgA3T;NS;L;O`HPna3nzL1QvsO%ZM=4K0P!{Awtg}1-n?{!M^DA$?%;qH_3!j z-&d?bGC#i^{pU&sQzzLKRxgN3R6bi(_yi%*I&LX5Q{7AXzv)cF}NHg*Zz8{zPCYw^niLz`I(;# zQ}$AmA7I7&>}L zeY`>wl&aOzw$0MkS#ap!_`8;o?8{egtV&R<%nz+b_6$CjXAN)50eK#XQ!|Nbb4=sJi`)3+={tN$NyYpce zLE`hqY#~?j;gW_3qS0T&XyC%1kNKbV$_~%`@c8nzm=fZ%DMde>+)%H76e9i?P5FIf zkBwG{R;B*nHzM+mnw_%UrNI|&XCeRZ6ZZ6V77bdAWPgX&R4Np-T0=YHaD;5p>!U>cTrTZnDhS9 z%{a0zfRcbxt@ovq2{Im)WwieHX$JhqR7)6AWU6m#1+U!!fEYy$tlw`_Ki!Yq6bUUq1ayJVsOmBb4o5loscy+WFw*jjFLiOd0gN-2)KqI~S!Ss7hxNbnHYTweYz8486nOnH^QM>wwvCZ^$I>ZB|c?*WE)I)nB_$ZSG4uzG;U!DRaU}LZ~{Vm znE3C^;PB*&}rg;5t$@hR}%2n)Uk=$=*omabs?eUYVo#ADL7V{E`cA z@uH@cV+2~KXAs=|350{NnDR(ws1a$=(H`eZ#SfIUE?+SF((c8sI$vU=L%rt<81C-f zq6)%4#g=1vlFc}llUHNjQCZN2I6&Esk5#{Kys}_!k7Y=E)I*wu;@Co%BZ`WlZDt@e zftl3do6XyTHi~jz-X7}Hxe#j*hp@nJ;!)@kDhS{ zz3;uqD2U7vIeuGQmVS;cXTx;_BT`b2Zd9cdvx0E{m|gB%pwk{XRO2RPJ+F&f{YCRN z+R0oA2smu)A(p{$>N5|LkmX3ya`J z@?>Uu&%1hcoXhDaG|QsJVfEs>Fo=(acXC-Y3h9w*yu zj@3man8hA+`j)3XW&1^A|4*-BcW?gcb%#m#U_>eq_#S|PJj8% z9EGZQid2yd6$z@F9NcTwHmN-ek3#F!@mpI~wx!us(8zHIj>k z)tIHgM8OFyVifDSUwO)E%6*2NJJum70LLK^SpAq=c#T*lS|GP!ykze(Tv@s$|h_qalZ2+=n}b6n{y@g|wy+n(^^;%8-^91=f~G0tTDCyH(VP zb}I_8VflvfIx2+IR@1X%@8{g*1mpJ!0gMoz{tDM-w0dP0wLJhZ2_(5%*`Mv%I&ma& zokt39vU*Sz@C%V#yU9a|;)Z>u1RU=8ph@m+{Vx*vS5?L~05v#;&8^&4Lwom}$iL&@ zG}rZ=r*Y%q%^OIH+QeS1YQ1_SOd~32*JY(KuP3n6k~?DqsTl$M0hZ-XG%a5p7Z6IM z2p_7=oTZs#9|x>5w$wdF_dNaBEW;#q+phwMLh!|BeJ2p2SoO%wcb~G<$K{FCi^3&4 zo@vS-Ue+=V?oLq&PgTZroTfNMS>g~xY08(e9=8^LSg#d$3Y!Lg5X`6QkbSNu(n*Z+c=W7&bhuX7)u=W zFAw8yQ-xO4eHvPqX!~Sjx-d#q4W@?QM#JXIEjzwUuMcDO@$Hf7O_{M4>U!e~Yn&pv zd*cQ8bh3_rnM{S*crk+Q<)}XgJsXAo7thz0vyP19a0`$