diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index cf22ea9b75332a14d994c57a58f946dc7b53b807..017c23c02503e45e36b8580c0b5c6664d59f016f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,7 +15,10 @@ jobs: strategy: matrix: python-version: + - "3.9" + - "3.10" - "3.11" + # - "3.12" steps: - uses: actions/checkout@v4 - name: Cache Poetry diff --git a/.gitignore b/.gitignore index cb4c0022d27d777ec80531b834da365db0729125..cc461499d2d720e715c86c33e513b9c259cb5737 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ venv/ **/__pycache__ **/*.py[cod] + # local env files .env*.local .env @@ -18,5 +19,11 @@ mac.env .coverage .coverage.* .pytest_cache +coverage.xml test.py output +node_modules +package-lock.json +package.json + +``` diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6a80529022ae36491cbbb22511c1a93a0050351f..b24594f35ab4a09c525946915f027ed267ac78c5 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,5 +1,5 @@ default_language_version: - python: python3.11.3 + python: python3.9 repos: - repo: meta hooks: @@ -17,14 +17,12 @@ repos: - id: blacken-docs additional_dependencies: [black==22.10.0] - - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.0.290 + - repo: https://github.com/alessandrojcm/commitlint-pre-commit-hook + rev: v9.11.0 hooks: - - id: ruff - types_or: [ python, pyi, jupyter ] - args: [ --fix ] - - id: ruff-format - types_or: [ python, pyi, jupyter ] + - id: commitlint + stages: [commit-msg] + additional_dependencies: ['@commitlint/config-conventional'] - repo: https://github.com/codespell-project/codespell rev: v2.2.4 @@ -36,13 +34,11 @@ repos: args: [ "--write-changes", "--ignore-words-list", "asend" ] exclude: "poetry.lock" - - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.4.0 hooks: - id: check-vcs-permalinks - id: end-of-file-fixer - # exclude: "tests/((commands|data)/|test_).+" - id: trailing-whitespace args: [ --markdown-linebreak-ext=md ] - id: debug-statements @@ -62,8 +58,20 @@ repos: - post-commit - push - - repo: https://github.com/alessandrojcm/commitlint-pre-commit-hook - rev: v9.11.0 + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.0.290 + hooks: + - id: ruff + types_or: [python, pyi, jupyter] + + # - repo: https://github.com/pre-commit/mirrors-mypy + # rev: v1.8.0 + # hooks: + # - id: mypy + # args: [--ignore-missing-imports] + + - repo: https://github.com/PyCQA/bandit + rev: 1.7.6 hooks: - - id: commitlint - stages: [commit-msg] + - id: bandit + args: ['-lll'] diff --git a/Makefile b/Makefile index aeb3d3b19ff9262b933b9022f6fc80c240279040..adf4eb0c4079749a2f86a0a862292f3ed0931265 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ format: - poetry run black . + poetry run black --target-version py39 . poetry run ruff --select I --fix . PYTHON_FILES=. @@ -7,7 +7,7 @@ lint: PYTHON_FILES=. lint_diff: PYTHON_FILES=$(shell git diff --name-only --diff-filter=d main | grep -E '\.py$$') lint lint_diff: - poetry run black $(PYTHON_FILES) --check + poetry run black --target-version py39 $(PYTHON_FILES) --check poetry run ruff . poetry run mypy $(PYTHON_FILES) diff --git a/README.md b/README.md index 5809e85a14c9e8b13e30c16dd86c1dbec7250ea3..fd4c12a2e5f441e8cb792d6705c976c7e67b55d4 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ To get started with _semantic-router_ we install it like so: pip install -qU semantic-router ``` -â—ï¸ _If wanting to use local embeddings you can use `FastEmbedEncoder` (`pip install -qU semantic-router[fastembed]`). To use the `HybridRouteLayer` you must `pip install -qU semantic-router[hybrid]`._ +â—ï¸ _If wanting to use local embeddings you can use `FastEmbedEncoder` (`pip install -qU "semantic-router[fastembed]`"). To use the `HybridRouteLayer` you must `pip install -qU "semantic-router[hybrid]"`._ We begin by defining a set of `Route` objects. These are the decision paths that the semantic router can decide to use, let's try two simple routes for now — one for talk on _politics_ and another for _chitchat_: diff --git a/coverage.xml b/coverage.xml index 6726da20c0072e4a9458817d708f40d897fb84a3..5850def2dfb8bf3ee91ce0e20a28f5312ec8c0b2 100644 --- a/coverage.xml +++ b/coverage.xml @@ -1,12 +1,12 @@ <?xml version="1.0" ?> -<coverage version="7.4.0" timestamp="1704449872184" lines-valid="676" lines-covered="592" line-rate="0.8757" branches-covered="0" branches-valid="0" branch-rate="0" complexity="0"> +<coverage version="7.4.0" timestamp="1704881517474" lines-valid="893" lines-covered="778" line-rate="0.8712" branches-covered="0" branches-valid="0" branch-rate="0" complexity="0"> <!-- Generated by coverage.py: https://coverage.readthedocs.io/en/7.4.0 --> <!-- Based on https://raw.githubusercontent.com/cobertura/web/master/htdocs/xml/coverage-04.dtd --> <sources> <source>/Users/jakit/customers/aurelio/semantic-router/semantic_router</source> </sources> <packages> - <package name="." line-rate="0.9317" branch-rate="0" complexity="0"> + <package name="." line-rate="0.9263" branch-rate="0" complexity="0"> <classes> <class name="__init__.py" filename="__init__.py" complexity="0" line-rate="1" branch-rate="0"> <methods/> @@ -17,301 +17,308 @@ <line number="5" hits="1"/> </lines> </class> - <class name="hybrid_layer.py" filename="hybrid_layer.py" complexity="0" line-rate="1" branch-rate="0"> + <class name="hybrid_layer.py" filename="hybrid_layer.py" complexity="0" line-rate="0.9796" branch-rate="0"> <methods/> <lines> <line number="1" hits="1"/> <line number="2" hits="1"/> <line number="4" hits="1"/> + <line number="8" hits="1"/> + <line number="9" hits="1"/> <line number="10" hits="1"/> - <line number="11" hits="1"/> + <line number="13" hits="1"/> <line number="14" hits="1"/> <line number="15" hits="1"/> <line number="16" hits="1"/> <line number="17" hits="1"/> - <line number="18" hits="1"/> - <line number="20" hits="1"/> - <line number="23" hits="1"/> - <line number="24" hits="1"/> - <line number="25" hits="1"/> + <line number="19" hits="1"/> + <line number="26" hits="1"/> <line number="27" hits="1"/> - <line number="28" hits="1"/> <line number="29" hits="1"/> - <line number="30" hits="1"/> - <line number="32" hits="1"/> - <line number="34" hits="1"/> - <line number="38" hits="1"/> - <line number="40" hits="1"/> + <line number="30" hits="0"/> + <line number="31" hits="0"/> + <line number="33" hits="1"/> + <line number="35" hits="1"/> + <line number="37" hits="1"/> <line number="41" hits="1"/> - <line number="42" hits="1"/> <line number="43" hits="1"/> <line number="44" hits="1"/> <line number="45" hits="1"/> + <line number="46" hits="1"/> <line number="47" hits="1"/> - <line number="49" hits="1"/> + <line number="48" hits="1"/> <line number="50" hits="1"/> <line number="52" hits="1"/> - <line number="54" hits="1"/> + <line number="53" hits="1"/> <line number="55" hits="1"/> - <line number="60" hits="1"/> - <line number="61" hits="1"/> - <line number="62" hits="1"/> + <line number="57" hits="1"/> + <line number="58" hits="1"/> + <line number="63" hits="1"/> <line number="64" hits="1"/> <line number="65" hits="1"/> - <line number="66" hits="1"/> - <line number="70" hits="1"/> - <line number="71" hits="1"/> + <line number="67" hits="1"/> + <line number="68" hits="1"/> + <line number="69" hits="1"/> <line number="73" hits="1"/> - <line number="75" hits="1"/> + <line number="74" hits="1"/> <line number="76" hits="1"/> <line number="78" hits="1"/> - <line number="80" hits="1"/> - <line number="82" hits="1"/> + <line number="79" hits="1"/> + <line number="81" hits="1"/> <line number="83" hits="1"/> + <line number="85" hits="1"/> <line number="86" hits="1"/> - <line number="87" hits="1"/> + <line number="89" hits="1"/> <line number="90" hits="1"/> - <line number="91" hits="1"/> - <line number="92" hits="1"/> - <line number="99" hits="1"/> - <line number="106" hits="1"/> - <line number="112" hits="1"/> - <line number="117" hits="1"/> - <line number="118" hits="1"/> + <line number="93" hits="1"/> + <line number="94" hits="1"/> + <line number="95" hits="1"/> + <line number="102" hits="1"/> + <line number="109" hits="1"/> + <line number="115" hits="1"/> <line number="120" hits="1"/> <line number="121" hits="1"/> <line number="123" hits="1"/> - <line number="125" hits="1"/> - <line number="127" hits="1"/> + <line number="124" hits="1"/> + <line number="126" hits="1"/> <line number="128" hits="1"/> - <line number="129" hits="1"/> + <line number="130" hits="1"/> <line number="131" hits="1"/> <line number="132" hits="1"/> - <line number="133" hits="1"/> <line number="134" hits="1"/> + <line number="135" hits="1"/> <line number="136" hits="1"/> <line number="137" hits="1"/> - <line number="138" hits="1"/> + <line number="139" hits="1"/> <line number="140" hits="1"/> <line number="141" hits="1"/> <line number="143" hits="1"/> <line number="144" hits="1"/> <line number="146" hits="1"/> - <line number="148" hits="1"/> + <line number="147" hits="1"/> <line number="149" hits="1"/> - <line number="150" hits="1"/> + <line number="151" hits="1"/> <line number="152" hits="1"/> <line number="153" hits="1"/> - <line number="154" hits="1"/> <line number="155" hits="1"/> <line number="156" hits="1"/> <line number="157" hits="1"/> <line number="158" hits="1"/> + <line number="159" hits="1"/> <line number="160" hits="1"/> + <line number="161" hits="1"/> <line number="163" hits="1"/> - <line number="164" hits="1"/> + <line number="166" hits="1"/> <line number="167" hits="1"/> - <line number="168" hits="1"/> <line number="170" hits="1"/> <line number="171" hits="1"/> <line number="173" hits="1"/> <line number="174" hits="1"/> - <line number="175" hits="1"/> + <line number="176" hits="1"/> <line number="177" hits="1"/> + <line number="178" hits="1"/> + <line number="180" hits="1"/> </lines> </class> - <class name="layer.py" filename="layer.py" complexity="0" line-rate="0.8836" branch-rate="0"> + <class name="layer.py" filename="layer.py" complexity="0" line-rate="0.8827" branch-rate="0"> <methods/> <lines> <line number="1" hits="1"/> <line number="2" hits="1"/> - <line number="4" hits="1"/> + <line number="3" hits="1"/> <line number="5" hits="1"/> - <line number="7" hits="1"/> + <line number="6" hits="1"/> + <line number="8" hits="1"/> + <line number="9" hits="1"/> + <line number="10" hits="1"/> + <line number="11" hits="1"/> <line number="12" hits="1"/> <line number="13" hits="1"/> - <line number="14" hits="1"/> - <line number="15" hits="1"/> + <line number="16" hits="1"/> + <line number="17" hits="1"/> <line number="18" hits="1"/> <line number="19" hits="1"/> - <line number="20" hits="1"/> <line number="21" hits="1"/> - <line number="23" hits="1"/> + <line number="22" hits="0"/> + <line number="23" hits="0"/> <line number="24" hits="0"/> <line number="25" hits="0"/> - <line number="26" hits="0"/> - <line number="27" hits="0"/> - <line number="30" hits="0"/> - <line number="31" hits="0"/> - <line number="33" hits="1"/> - <line number="34" hits="1"/> - <line number="35" hits="0"/> - <line number="38" hits="0"/> - <line number="40" hits="1"/> + <line number="28" hits="0"/> + <line number="29" hits="0"/> + <line number="31" hits="1"/> + <line number="32" hits="1"/> + <line number="33" hits="0"/> + <line number="36" hits="0"/> + <line number="38" hits="1"/> + <line number="39" hits="0"/> + <line number="40" hits="0"/> <line number="41" hits="0"/> - <line number="42" hits="0"/> - <line number="43" hits="0"/> - <line number="46" hits="1"/> + <line number="44" hits="1"/> + <line number="50" hits="1"/> <line number="52" hits="1"/> - <line number="54" hits="1"/> - <line number="60" hits="1"/> - <line number="61" hits="1"/> - <line number="63" hits="0"/> + <line number="58" hits="1"/> + <line number="59" hits="1"/> + <line number="63" hits="1"/> <line number="64" hits="0"/> - <line number="65" hits="0"/> + <line number="65" hits="1"/> <line number="66" hits="0"/> - <line number="67" hits="0"/> + <line number="67" hits="1"/> <line number="68" hits="0"/> - <line number="69" hits="0"/> - <line number="70" hits="1"/> + <line number="69" hits="1"/> + <line number="70" hits="0"/> <line number="71" hits="1"/> + <line number="72" hits="1"/> <line number="73" hits="1"/> - <line number="74" hits="1"/> + <line number="75" hits="1"/> <line number="76" hits="1"/> - <line number="77" hits="1"/> <line number="78" hits="1"/> <line number="79" hits="1"/> <line number="80" hits="1"/> <line number="81" hits="1"/> <line number="82" hits="1"/> + <line number="83" hits="1"/> <line number="84" hits="1"/> - <line number="88" hits="1"/> - <line number="89" hits="1"/> + <line number="86" hits="1"/> <line number="90" hits="1"/> <line number="91" hits="1"/> <line number="92" hits="1"/> <line number="93" hits="1"/> - <line number="97" hits="0"/> + <line number="94" hits="1"/> + <line number="95" hits="1"/> <line number="99" hits="1"/> - <line number="100" hits="1"/> - <line number="106" hits="1"/> + <line number="101" hits="1"/> + <line number="102" hits="1"/> <line number="108" hits="1"/> - <line number="109" hits="1"/> - <line number="112" hits="1"/> - <line number="113" hits="1"/> - <line number="117" hits="1"/> - <line number="120" hits="1"/> - <line number="121" hits="0"/> - <line number="123" hits="1"/> - <line number="124" hits="1"/> + <line number="110" hits="1"/> + <line number="111" hits="1"/> + <line number="114" hits="1"/> + <line number="115" hits="1"/> + <line number="119" hits="1"/> + <line number="122" hits="1"/> + <line number="123" hits="0"/> <line number="125" hits="1"/> <line number="126" hits="1"/> <line number="127" hits="1"/> + <line number="128" hits="1"/> <line number="129" hits="1"/> - <line number="130" hits="1"/> <line number="131" hits="1"/> + <line number="132" hits="1"/> <line number="133" hits="1"/> - <line number="134" hits="1"/> <line number="135" hits="1"/> <line number="136" hits="1"/> <line number="137" hits="1"/> <line number="138" hits="1"/> + <line number="139" hits="1"/> <line number="140" hits="1"/> - <line number="141" hits="1"/> - <line number="142" hits="0"/> - <line number="144" hits="1"/> - <line number="145" hits="1"/> - <line number="148" hits="1"/> - <line number="149" hits="1"/> + <line number="142" hits="1"/> + <line number="143" hits="1"/> + <line number="144" hits="0"/> + <line number="146" hits="1"/> + <line number="147" hits="1"/> <line number="150" hits="1"/> <line number="151" hits="1"/> + <line number="152" hits="1"/> <line number="153" hits="1"/> + <line number="154" hits="1"/> <line number="156" hits="1"/> - <line number="157" hits="1"/> - <line number="158" hits="1"/> - <line number="159" hits="1"/> - <line number="160" hits="1"/> <line number="162" hits="1"/> <line number="163" hits="1"/> <line number="164" hits="1"/> <line number="165" hits="1"/> - <line number="167" hits="1"/> - <line number="169" hits="1"/> - <line number="171" hits="1"/> + <line number="166" hits="1"/> + <line number="170" hits="1"/> + <line number="172" hits="1"/> <line number="173" hits="1"/> <line number="174" hits="1"/> <line number="175" hits="1"/> - <line number="176" hits="1"/> <line number="177" hits="1"/> <line number="179" hits="1"/> - <line number="180" hits="1"/> + <line number="181" hits="1"/> + <line number="182" hits="1"/> <line number="183" hits="1"/> + <line number="184" hits="1"/> <line number="185" hits="1"/> - <line number="186" hits="0"/> - <line number="192" hits="1"/> - <line number="193" hits="1"/> - <line number="194" hits="1"/> - <line number="195" hits="1"/> - <line number="196" hits="1"/> - <line number="198" hits="1"/> + <line number="187" hits="1"/> + <line number="188" hits="1"/> + <line number="189" hits="0"/> + <line number="190" hits="0"/> + <line number="195" hits="0"/> + <line number="196" hits="0"/> + <line number="198" hits="0"/> <line number="199" hits="1"/> - <line number="200" hits="1"/> - <line number="201" hits="1"/> <line number="202" hits="1"/> <line number="204" hits="1"/> - <line number="205" hits="1"/> - <line number="206" hits="1"/> - <line number="207" hits="1"/> - <line number="209" hits="1"/> - <line number="210" hits="1"/> + <line number="205" hits="0"/> + <line number="211" hits="1"/> <line number="212" hits="1"/> + <line number="213" hits="1"/> + <line number="214" hits="1"/> <line number="215" hits="1"/> - <line number="216" hits="1"/> <line number="217" hits="1"/> + <line number="218" hits="1"/> <line number="219" hits="1"/> <line number="220" hits="1"/> <line number="221" hits="1"/> <line number="223" hits="1"/> <line number="224" hits="1"/> <line number="225" hits="1"/> - <line number="227" hits="1"/> + <line number="226" hits="1"/> <line number="228" hits="1"/> <line number="229" hits="1"/> <line number="231" hits="1"/> - <line number="233" hits="1"/> + <line number="234" hits="1"/> <line number="235" hits="1"/> + <line number="237" hits="1"/> <line number="238" hits="1"/> + <line number="240" hits="1"/> <line number="241" hits="1"/> - <line number="242" hits="1"/> <line number="243" hits="1"/> + <line number="244" hits="1"/> + <line number="246" hits="1"/> + <line number="248" hits="1"/> <line number="250" hits="1"/> - <line number="251" hits="1"/> + <line number="253" hits="1"/> + <line number="256" hits="1"/> <line number="257" hits="1"/> - <line number="262" hits="1"/> - <line number="263" hits="1"/> + <line number="258" hits="1"/> <line number="265" hits="1"/> - <line number="267" hits="1"/> - <line number="268" hits="1"/> - <line number="270" hits="1"/> - <line number="271" hits="1"/> - <line number="273" hits="1"/> - <line number="274" hits="1"/> - <line number="276" hits="1"/> + <line number="266" hits="1"/> + <line number="272" hits="1"/> <line number="277" hits="1"/> <line number="278" hits="1"/> - <line number="279" hits="1"/> <line number="280" hits="1"/> - <line number="281" hits="1"/> <line number="282" hits="1"/> - <line number="284" hits="1"/> - <line number="287" hits="1"/> + <line number="283" hits="1"/> + <line number="285" hits="1"/> + <line number="286" hits="1"/> <line number="288" hits="1"/> + <line number="289" hits="1"/> <line number="291" hits="1"/> <line number="292" hits="1"/> + <line number="293" hits="1"/> <line number="294" hits="1"/> <line number="295" hits="1"/> + <line number="296" hits="1"/> <line number="297" hits="1"/> - <line number="298" hits="1"/> <line number="299" hits="1"/> - <line number="301" hits="1"/> + <line number="302" hits="1"/> <line number="303" hits="1"/> - <line number="304" hits="1"/> + <line number="306" hits="1"/> + <line number="307" hits="1"/> + <line number="309" hits="1"/> <line number="310" hits="1"/> - <line number="311" hits="1"/> <line number="312" hits="1"/> + <line number="313" hits="1"/> <line number="314" hits="1"/> - <line number="315" hits="1"/> <line number="316" hits="1"/> + <line number="318" hits="1"/> + <line number="319" hits="1"/> + <line number="325" hits="1"/> + <line number="326" hits="1"/> + <line number="327" hits="1"/> + <line number="329" hits="1"/> + <line number="330" hits="1"/> + <line number="331" hits="1"/> </lines> </class> <class name="linear.py" filename="linear.py" complexity="0" line-rate="1" branch-rate="0"> @@ -332,7 +339,7 @@ <line number="30" hits="1"/> </lines> </class> - <class name="route.py" filename="route.py" complexity="0" line-rate="0.9275" branch-rate="0"> + <class name="route.py" filename="route.py" complexity="0" line-rate="0.9342" branch-rate="0"> <methods/> <lines> <line number="1" hits="1"/> @@ -343,114 +350,131 @@ <line number="8" hits="1"/> <line number="9" hits="1"/> <line number="10" hits="1"/> - <line number="13" hits="1"/> + <line number="11" hits="1"/> <line number="14" hits="1"/> <line number="15" hits="1"/> <line number="16" hits="1"/> - <line number="18" hits="1"/> + <line number="17" hits="1"/> <line number="19" hits="1"/> <line number="20" hits="1"/> <line number="21" hits="1"/> <line number="22" hits="1"/> - <line number="25" hits="1"/> + <line number="23" hits="1"/> <line number="26" hits="1"/> - <line number="28" hits="1"/> + <line number="27" hits="1"/> <line number="29" hits="1"/> <line number="30" hits="1"/> - <line number="33" hits="1"/> - <line number="35" hits="1"/> + <line number="31" hits="1"/> + <line number="34" hits="1"/> <line number="36" hits="1"/> <line number="37" hits="1"/> <line number="38" hits="1"/> - <line number="41" hits="1"/> + <line number="39" hits="1"/> <line number="42" hits="1"/> <line number="43" hits="1"/> <line number="44" hits="1"/> <line number="45" hits="1"/> + <line number="46" hits="1"/> <line number="47" hits="1"/> - <line number="48" hits="1"/> - <line number="50" hits="0"/> - <line number="53" hits="0"/> - <line number="56" hits="1"/> - <line number="57" hits="1"/> - <line number="59" hits="1"/> - <line number="60" hits="1"/> - <line number="62" hits="1"/> + <line number="49" hits="1"/> + <line number="50" hits="1"/> + <line number="51" hits="1"/> + <line number="52" hits="1"/> + <line number="57" hits="0"/> + <line number="60" hits="0"/> <line number="63" hits="1"/> <line number="64" hits="1"/> <line number="66" hits="1"/> <line number="67" hits="1"/> + <line number="69" hits="1"/> + <line number="70" hits="1"/> <line number="71" hits="1"/> - <line number="72" hits="1"/> <line number="73" hits="1"/> <line number="74" hits="1"/> - <line number="76" hits="1"/> - <line number="77" hits="1"/> + <line number="78" hits="1"/> <line number="79" hits="1"/> <line number="80" hits="1"/> - <line number="82" hits="1"/> + <line number="81" hits="1"/> <line number="83" hits="1"/> <line number="84" hits="1"/> - <line number="86" hits="0"/> - <line number="88" hits="1"/> + <line number="86" hits="1"/> + <line number="87" hits="1"/> <line number="89" hits="1"/> <line number="90" hits="1"/> - <line number="92" hits="1"/> - <line number="117" hits="1"/> - <line number="118" hits="1"/> - <line number="119" hits="0"/> - <line number="121" hits="1"/> - <line number="123" hits="1"/> + <line number="91" hits="1"/> + <line number="93" hits="0"/> + <line number="95" hits="1"/> + <line number="96" hits="1"/> + <line number="97" hits="1"/> + <line number="99" hits="1"/> + <line number="124" hits="1"/> <line number="125" hits="1"/> <line number="126" hits="1"/> <line number="127" hits="0"/> + <line number="129" hits="1"/> + <line number="131" hits="1"/> + <line number="133" hits="1"/> + <line number="134" hits="1"/> + <line number="135" hits="1"/> + <line number="136" hits="1"/> + <line number="137" hits="0"/> </lines> </class> - <class name="schema.py" filename="schema.py" complexity="0" line-rate="0.973" branch-rate="0"> + <class name="schema.py" filename="schema.py" complexity="0" line-rate="0.9574" branch-rate="0"> <methods/> <lines> <line number="1" hits="1"/> <line number="3" hits="1"/> <line number="4" hits="1"/> <line number="6" hits="1"/> - <line number="11" hits="1"/> - <line number="14" hits="1"/> - <line number="15" hits="1"/> + <line number="12" hits="1"/> + <line number="13" hits="1"/> <line number="16" hits="1"/> <line number="17" hits="1"/> + <line number="18" hits="1"/> + <line number="19" hits="1"/> <line number="20" hits="1"/> - <line number="21" hits="1"/> - <line number="22" hits="1"/> + <line number="23" hits="1"/> + <line number="24" hits="1"/> <line number="25" hits="1"/> - <line number="26" hits="1"/> - <line number="27" hits="1"/> <line number="28" hits="1"/> <line number="29" hits="1"/> + <line number="30" hits="1"/> <line number="31" hits="1"/> <line number="32" hits="1"/> - <line number="33" hits="1"/> <line number="34" hits="1"/> <line number="35" hits="1"/> <line number="36" hits="1"/> <line number="37" hits="1"/> <line number="38" hits="1"/> <line number="39" hits="1"/> - <line number="41" hits="0"/> + <line number="40" hits="0"/> + <line number="41" hits="1"/> + <line number="42" hits="1"/> <line number="43" hits="1"/> <line number="44" hits="1"/> - <line number="47" hits="1"/> + <line number="46" hits="0"/> <line number="48" hits="1"/> <line number="49" hits="1"/> <line number="52" hits="1"/> <line number="53" hits="1"/> - <line number="55" hits="1"/> + <line number="54" hits="1"/> + <line number="56" hits="1"/> + <line number="57" hits="1"/> + <line number="58" hits="1"/> + <line number="59" hits="1"/> <line number="61" hits="1"/> <line number="62" hits="1"/> + <line number="65" hits="1"/> + <line number="66" hits="1"/> + <line number="68" hits="1"/> + <line number="74" hits="1"/> + <line number="75" hits="1"/> </lines> </class> </classes> </package> - <package name="encoders" line-rate="0.966" branch-rate="0" complexity="0"> + <package name="encoders" line-rate="0.9369" branch-rate="0" complexity="0"> <classes> <class name="__init__.py" filename="encoders/__init__.py" complexity="0" line-rate="1" branch-rate="0"> <methods/> @@ -460,7 +484,8 @@ <line number="3" hits="1"/> <line number="4" hits="1"/> <line number="5" hits="1"/> - <line number="7" hits="1"/> + <line number="6" hits="1"/> + <line number="8" hits="1"/> </lines> </class> <class name="base.py" filename="encoders/base.py" complexity="0" line-rate="1" branch-rate="0"> @@ -470,66 +495,76 @@ <line number="4" hits="1"/> <line number="5" hits="1"/> <line number="6" hits="1"/> - <line number="8" hits="1"/> + <line number="7" hits="1"/> <line number="9" hits="1"/> - <line number="11" hits="1"/> + <line number="10" hits="1"/> <line number="12" hits="1"/> + <line number="13" hits="1"/> </lines> </class> - <class name="bm25.py" filename="encoders/bm25.py" complexity="0" line-rate="1" branch-rate="0"> + <class name="bm25.py" filename="encoders/bm25.py" complexity="0" line-rate="0.9574" branch-rate="0"> <methods/> <lines> <line number="1" hits="1"/> <line number="3" hits="1"/> - <line number="5" hits="1"/> + <line number="4" hits="1"/> + <line number="7" hits="1"/> <line number="8" hits="1"/> <line number="9" hits="1"/> <line number="10" hits="1"/> - <line number="11" hits="1"/> - <line number="13" hits="1"/> - <line number="14" hits="1"/> - <line number="15" hits="1"/> - <line number="17" hits="1"/> + <line number="12" hits="1"/> <line number="18" hits="1"/> <line number="19" hits="1"/> <line number="20" hits="1"/> - <line number="21" hits="1"/> - <line number="23" hits="1"/> - <line number="25" hits="1"/> - <line number="26" hits="1"/> + <line number="21" hits="0"/> + <line number="22" hits="0"/> <line number="27" hits="1"/> - <line number="28" hits="1"/> <line number="29" hits="1"/> <line number="30" hits="1"/> <line number="31" hits="1"/> - <line number="33" hits="1"/> + <line number="32" hits="1"/> + <line number="34" hits="1"/> <line number="35" hits="1"/> <line number="36" hits="1"/> <line number="37" hits="1"/> <line number="38" hits="1"/> <line number="39" hits="1"/> - <line number="40" hits="1"/> <line number="41" hits="1"/> - <line number="42" hits="1"/> <line number="43" hits="1"/> + <line number="44" hits="1"/> <line number="45" hits="1"/> <line number="46" hits="1"/> <line number="47" hits="1"/> <line number="48" hits="1"/> + <line number="49" hits="1"/> + <line number="51" hits="1"/> + <line number="53" hits="1"/> + <line number="54" hits="1"/> + <line number="55" hits="1"/> + <line number="56" hits="1"/> + <line number="57" hits="1"/> + <line number="58" hits="1"/> + <line number="59" hits="1"/> + <line number="60" hits="1"/> + <line number="61" hits="1"/> + <line number="63" hits="1"/> + <line number="64" hits="1"/> + <line number="65" hits="1"/> + <line number="66" hits="1"/> + <line number="67" hits="1"/> </lines> </class> <class name="cohere.py" filename="encoders/cohere.py" complexity="0" line-rate="1" branch-rate="0"> <methods/> <lines> <line number="1" hits="1"/> - <line number="3" hits="1"/> - <line number="5" hits="1"/> - <line number="8" hits="1"/> + <line number="2" hits="1"/> + <line number="4" hits="1"/> + <line number="6" hits="1"/> <line number="9" hits="1"/> <line number="10" hits="1"/> - <line number="12" hits="1"/> - <line number="17" hits="1"/> - <line number="18" hits="1"/> + <line number="11" hits="1"/> + <line number="13" hits="1"/> <line number="19" hits="1"/> <line number="20" hits="1"/> <line number="21" hits="1"/> @@ -538,22 +573,60 @@ <line number="24" hits="1"/> <line number="25" hits="1"/> <line number="26" hits="1"/> + <line number="27" hits="1"/> <line number="28" hits="1"/> - <line number="29" hits="1"/> <line number="30" hits="1"/> <line number="31" hits="1"/> <line number="32" hits="1"/> <line number="33" hits="1"/> <line number="34" hits="1"/> <line number="35" hits="1"/> + <line number="36" hits="1"/> + <line number="37" hits="1"/> </lines> </class> - <class name="fastembed.py" filename="encoders/fastembed.py" complexity="0" line-rate="0.8621" branch-rate="0"> + <class name="fastembed.py" filename="encoders/fastembed.py" complexity="0" line-rate="0.7" branch-rate="0"> <methods/> <lines> <line number="1" hits="1"/> <line number="3" hits="1"/> <line number="4" hits="1"/> + <line number="6" hits="1"/> + <line number="9" hits="1"/> + <line number="10" hits="1"/> + <line number="11" hits="1"/> + <line number="12" hits="1"/> + <line number="13" hits="1"/> + <line number="14" hits="1"/> + <line number="15" hits="1"/> + <line number="17" hits="1"/> + <line number="20" hits="1"/> + <line number="21" hits="1"/> + <line number="23" hits="1"/> + <line number="24" hits="1"/> + <line number="25" hits="1"/> + <line number="26" hits="0"/> + <line number="27" hits="0"/> + <line number="33" hits="1"/> + <line number="40" hits="1"/> + <line number="42" hits="1"/> + <line number="43" hits="0"/> + <line number="45" hits="1"/> + <line number="46" hits="0"/> + <line number="47" hits="0"/> + <line number="48" hits="0"/> + <line number="49" hits="0"/> + <line number="50" hits="0"/> + <line number="51" hits="0"/> + </lines> + </class> + <class name="huggingface.py" filename="encoders/huggingface.py" complexity="0" line-rate="0.9667" branch-rate="0"> + <methods/> + <lines> + <line number="1" hits="1"/> + <line number="2" hits="1"/> + <line number="3" hits="1"/> + <line number="6" hits="1"/> <line number="7" hits="1"/> <line number="8" hits="1"/> <line number="9" hits="1"/> @@ -561,83 +634,258 @@ <line number="11" hits="1"/> <line number="12" hits="1"/> <line number="13" hits="1"/> + <line number="14" hits="1"/> <line number="15" hits="1"/> - <line number="16" hits="1"/> <line number="17" hits="1"/> + <line number="18" hits="1"/> <line number="19" hits="1"/> - <line number="20" hits="1"/> <line number="21" hits="1"/> - <line number="22" hits="0"/> - <line number="23" hits="0"/> - <line number="28" hits="1"/> + <line number="22" hits="1"/> + <line number="23" hits="1"/> + <line number="24" hits="1"/> + <line number="25" hits="1"/> + <line number="31" hits="1"/> + <line number="32" hits="1"/> + <line number="33" hits="1"/> + <line number="34" hits="1"/> + <line number="40" hits="1"/> + <line number="42" hits="1"/> + <line number="47" hits="1"/> + <line number="49" hits="1"/> + <line number="50" hits="0"/> + <line number="53" hits="1"/> + <line number="54" hits="1"/> + <line number="55" hits="1"/> + <line number="57" hits="1"/> + <line number="59" hits="1"/> + <line number="66" hits="1"/> + <line number="67" hits="1"/> + <line number="68" hits="1"/> + <line number="70" hits="1"/> + <line number="74" hits="1"/> + <line number="75" hits="1"/> + <line number="77" hits="1"/> + <line number="78" hits="1"/> + <line number="81" hits="1"/> + <line number="82" hits="1"/> + <line number="86" hits="0"/> + <line number="90" hits="1"/> + <line number="91" hits="1"/> + <line number="93" hits="1"/> + <line number="94" hits="1"/> + <line number="95" hits="1"/> + <line number="97" hits="1"/> + <line number="98" hits="1"/> + <line number="99" hits="1"/> + <line number="102" hits="1"/> + <line number="106" hits="1"/> + <line number="107" hits="1"/> + <line number="108" hits="1"/> + <line number="111" hits="1"/> + <line number="112" hits="1"/> + </lines> + </class> + <class name="openai.py" filename="encoders/openai.py" complexity="0" line-rate="0.9767" branch-rate="0"> + <methods/> + <lines> + <line number="1" hits="1"/> + <line number="2" hits="1"/> + <line number="4" hits="1"/> + <line number="5" hits="1"/> + <line number="6" hits="1"/> + <line number="8" hits="1"/> + <line number="9" hits="1"/> + <line number="10" hits="1"/> + <line number="13" hits="1"/> + <line number="14" hits="1"/> + <line number="15" hits="1"/> + <line number="17" hits="1"/> + <line number="23" hits="1"/> + <line number="24" hits="1"/> + <line number="25" hits="1"/> + <line number="26" hits="1"/> + <line number="27" hits="1"/> + <line number="28" hits="0"/> + <line number="29" hits="1"/> + <line number="30" hits="1"/> + <line number="31" hits="1"/> + <line number="32" hits="1"/> + <line number="34" hits="1"/> <line number="35" hits="1"/> + <line number="36" hits="1"/> <line number="37" hits="1"/> <line number="38" hits="1"/> - <line number="40" hits="1"/> <line number="41" hits="1"/> <line number="42" hits="1"/> <line number="43" hits="1"/> <line number="44" hits="1"/> - <line number="45" hits="0"/> - <line number="46" hits="0"/> + <line number="45" hits="1"/> + <line number="46" hits="1"/> + <line number="47" hits="1"/> + <line number="48" hits="1"/> + <line number="49" hits="1"/> + <line number="50" hits="1"/> + <line number="51" hits="1"/> + <line number="52" hits="1"/> + <line number="54" hits="1"/> + <line number="59" hits="1"/> + <line number="61" hits="1"/> + <line number="62" hits="1"/> + </lines> + </class> + </classes> + </package> + <package name="llms" line-rate="0.9043" branch-rate="0" complexity="0"> + <classes> + <class name="__init__.py" filename="llms/__init__.py" complexity="0" line-rate="1" branch-rate="0"> + <methods/> + <lines> + <line number="1" hits="1"/> + <line number="2" hits="1"/> + <line number="3" hits="1"/> + <line number="4" hits="1"/> + <line number="6" hits="1"/> + </lines> + </class> + <class name="base.py" filename="llms/base.py" complexity="0" line-rate="1" branch-rate="0"> + <methods/> + <lines> + <line number="1" hits="1"/> + <line number="3" hits="1"/> + <line number="5" hits="1"/> + <line number="8" hits="1"/> + <line number="9" hits="1"/> + <line number="11" hits="1"/> + <line number="12" hits="1"/> + <line number="14" hits="1"/> + <line number="15" hits="1"/> </lines> </class> - <class name="openai.py" filename="encoders/openai.py" complexity="0" line-rate="0.9762" branch-rate="0"> + <class name="cohere.py" filename="llms/cohere.py" complexity="0" line-rate="0.9655" branch-rate="0"> <methods/> <lines> <line number="1" hits="1"/> <line number="2" hits="1"/> <line number="4" hits="1"/> + <line number="6" hits="1"/> + <line number="7" hits="1"/> + <line number="10" hits="1"/> + <line number="11" hits="1"/> + <line number="13" hits="1"/> + <line number="18" hits="1"/> + <line number="19" hits="1"/> + <line number="20" hits="1"/> + <line number="21" hits="1"/> + <line number="22" hits="1"/> + <line number="23" hits="1"/> + <line number="24" hits="1"/> + <line number="25" hits="1"/> + <line number="26" hits="1"/> + <line number="27" hits="1"/> + <line number="29" hits="1"/> + <line number="30" hits="1"/> + <line number="31" hits="1"/> + <line number="32" hits="1"/> + <line number="33" hits="1"/> + <line number="39" hits="1"/> + <line number="41" hits="1"/> + <line number="42" hits="0"/> + <line number="43" hits="1"/> + <line number="45" hits="1"/> + <line number="46" hits="1"/> + </lines> + </class> + <class name="openai.py" filename="llms/openai.py" complexity="0" line-rate="0.8571" branch-rate="0"> + <methods/> + <lines> + <line number="1" hits="1"/> + <line number="3" hits="1"/> <line number="5" hits="1"/> <line number="6" hits="1"/> + <line number="7" hits="1"/> <line number="8" hits="1"/> - <line number="9" hits="1"/> + <line number="11" hits="1"/> <line number="12" hits="1"/> <line number="13" hits="1"/> <line number="14" hits="1"/> <line number="16" hits="1"/> - <line number="21" hits="1"/> - <line number="22" hits="1"/> <line number="23" hits="1"/> <line number="24" hits="1"/> <line number="25" hits="1"/> - <line number="26" hits="0"/> + <line number="26" hits="1"/> <line number="27" hits="1"/> - <line number="28" hits="1"/> + <line number="28" hits="0"/> <line number="29" hits="1"/> <line number="30" hits="1"/> + <line number="31" hits="1"/> <line number="32" hits="1"/> <line number="33" hits="1"/> <line number="34" hits="1"/> - <line number="35" hits="1"/> <line number="36" hits="1"/> + <line number="37" hits="1"/> + <line number="38" hits="1"/> <line number="39" hits="1"/> <line number="40" hits="1"/> + <line number="47" hits="1"/> + <line number="49" hits="1"/> + <line number="50" hits="0"/> + <line number="51" hits="1"/> + <line number="52" hits="0"/> + <line number="53" hits="0"/> + <line number="54" hits="0"/> + </lines> + </class> + <class name="openrouter.py" filename="llms/openrouter.py" complexity="0" line-rate="0.8649" branch-rate="0"> + <methods/> + <lines> + <line number="1" hits="1"/> + <line number="3" hits="1"/> + <line number="5" hits="1"/> + <line number="6" hits="1"/> + <line number="7" hits="1"/> + <line number="8" hits="1"/> + <line number="11" hits="1"/> + <line number="12" hits="1"/> + <line number="13" hits="1"/> + <line number="14" hits="1"/> + <line number="15" hits="1"/> + <line number="17" hits="1"/> + <line number="25" hits="1"/> + <line number="26" hits="1"/> + <line number="29" hits="1"/> + <line number="30" hits="1"/> + <line number="31" hits="1"/> + <line number="32" hits="1"/> + <line number="33" hits="0"/> + <line number="34" hits="1"/> + <line number="35" hits="1"/> + <line number="36" hits="1"/> + <line number="37" hits="1"/> + <line number="38" hits="1"/> + <line number="39" hits="1"/> <line number="41" hits="1"/> <line number="42" hits="1"/> <line number="43" hits="1"/> <line number="44" hits="1"/> <line number="45" hits="1"/> - <line number="46" hits="1"/> - <line number="47" hits="1"/> - <line number="48" hits="1"/> - <line number="49" hits="1"/> - <line number="50" hits="1"/> <line number="52" hits="1"/> - <line number="57" hits="1"/> - <line number="59" hits="1"/> - <line number="60" hits="1"/> + <line number="54" hits="1"/> + <line number="55" hits="0"/> + <line number="56" hits="1"/> + <line number="57" hits="0"/> + <line number="58" hits="0"/> + <line number="59" hits="0"/> </lines> </class> </classes> </package> - <package name="utils" line-rate="0.5714" branch-rate="0" complexity="0"> + <package name="utils" line-rate="0.5246" branch-rate="0" complexity="0"> <classes> <class name="__init__.py" filename="utils/__init__.py" complexity="0" line-rate="1" branch-rate="0"> <methods/> <lines/> </class> - <class name="function_call.py" filename="utils/function_call.py" complexity="0" line-rate="0.2545" branch-rate="0"> + <class name="function_call.py" filename="utils/function_call.py" complexity="0" line-rate="0.2456" branch-rate="0"> <methods/> <lines> <line number="1" hits="1"/> @@ -663,57 +911,60 @@ <line number="35" hits="1"/> <line number="41" hits="1"/> <line number="44" hits="1"/> - <line number="45" hits="0"/> <line number="47" hits="0"/> - <line number="76" hits="0"/> + <line number="49" hits="0"/> <line number="77" hits="0"/> <line number="78" hits="0"/> + <line number="79" hits="0"/> <line number="80" hits="0"/> <line number="82" hits="0"/> - <line number="83" hits="0"/> <line number="84" hits="0"/> <line number="85" hits="0"/> - <line number="88" hits="1"/> - <line number="90" hits="0"/> + <line number="86" hits="0"/> + <line number="87" hits="0"/> + <line number="90" hits="1"/> <line number="92" hits="0"/> - <line number="93" hits="0"/> <line number="94" hits="0"/> <line number="95" hits="0"/> - <line number="99" hits="0"/> - <line number="100" hits="0"/> + <line number="96" hits="0"/> + <line number="97" hits="0"/> <line number="101" hits="0"/> <line number="102" hits="0"/> <line number="103" hits="0"/> <line number="104" hits="0"/> <line number="105" hits="0"/> <line number="106" hits="0"/> - <line number="110" hits="1"/> - <line number="111" hits="0"/> - <line number="113" hits="0"/> - <line number="114" hits="0"/> + <line number="107" hits="0"/> + <line number="108" hits="0"/> + <line number="112" hits="1"/> <line number="115" hits="0"/> - <line number="116" hits="0"/> + <line number="117" hits="0"/> <line number="118" hits="0"/> <line number="119" hits="0"/> + <line number="120" hits="0"/> + <line number="122" hits="0"/> + <line number="123" hits="0"/> + <line number="124" hits="0"/> </lines> </class> - <class name="llm.py" filename="utils/llm.py" complexity="0" line-rate="0.2857" branch-rate="0"> + <class name="llm.py" filename="utils/llm.py" complexity="0" line-rate="0" branch-rate="0"> <methods/> <lines> - <line number="1" hits="1"/> - <line number="3" hits="1"/> - <line number="5" hits="1"/> - <line number="8" hits="1"/> + <line number="1" hits="0"/> + <line number="3" hits="0"/> + <line number="5" hits="0"/> + <line number="6" hits="0"/> <line number="9" hits="0"/> <line number="10" hits="0"/> - <line number="15" hits="0"/> - <line number="27" hits="0"/> - <line number="29" hits="0"/> + <line number="11" hits="0"/> + <line number="16" hits="0"/> + <line number="28" hits="0"/> <line number="30" hits="0"/> <line number="31" hits="0"/> <line number="32" hits="0"/> <line number="33" hits="0"/> <line number="34" hits="0"/> + <line number="35" hits="0"/> </lines> </class> <class name="logger.py" filename="utils/logger.py" complexity="0" line-rate="1" branch-rate="0"> @@ -746,34 +997,34 @@ <line number="1" hits="1"/> <line number="3" hits="1"/> <line number="6" hits="1"/> - <line number="29" hits="1"/> - <line number="30" hits="1"/> <line number="31" hits="1"/> <line number="32" hits="1"/> + <line number="33" hits="1"/> <line number="34" hits="1"/> - <line number="35" hits="1"/> <line number="36" hits="1"/> <line number="37" hits="1"/> + <line number="38" hits="1"/> <line number="39" hits="1"/> - <line number="40" hits="1"/> <line number="41" hits="1"/> <line number="42" hits="1"/> <line number="43" hits="1"/> + <line number="44" hits="1"/> <line number="45" hits="1"/> - <line number="46" hits="1"/> <line number="47" hits="1"/> <line number="48" hits="1"/> <line number="49" hits="1"/> + <line number="50" hits="1"/> <line number="51" hits="1"/> - <line number="52" hits="1"/> + <line number="53" hits="1"/> <line number="54" hits="1"/> - <line number="59" hits="1"/> - <line number="60" hits="1"/> - <line number="63" hits="1"/> - <line number="64" hits="1"/> - <line number="67" hits="1"/> - <line number="71" hits="1"/> - <line number="72" hits="1"/> + <line number="56" hits="1"/> + <line number="61" hits="1"/> + <line number="62" hits="1"/> + <line number="65" hits="1"/> + <line number="66" hits="1"/> + <line number="69" hits="1"/> + <line number="74" hits="1"/> + <line number="75" hits="1"/> </lines> </class> </classes> diff --git a/docs/00-introduction.ipynb b/docs/00-introduction.ipynb index 4d672f379a44b236ad60a04eaf439c7a0c29ec94..0665070391a00545a4230aead9f22bd9b22717b3 100644 --- a/docs/00-introduction.ipynb +++ b/docs/00-introduction.ipynb @@ -44,13 +44,6 @@ "!pip install -qU semantic-router==0.0.15" ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "_**âš ï¸ If using Google Colab, install the prerequisites and then restart the notebook before continuing**_" - ] - }, { "cell_type": "markdown", "metadata": {}, diff --git a/docs/01-save-load-from-file.ipynb b/docs/01-save-load-from-file.ipynb index 43937d2b7d74f1161073d866128df7b43ce87dca..6c5945cb9020a5d2296b86a1c282553abfb15736 100644 --- a/docs/01-save-load-from-file.ipynb +++ b/docs/01-save-load-from-file.ipynb @@ -39,13 +39,6 @@ "!pip install -qU semantic-router==0.0.15" ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "_**âš ï¸ If using Google Colab, install the prerequisites and then restart the notebook before continuing**_" - ] - }, { "cell_type": "markdown", "metadata": {}, diff --git a/docs/02-dynamic-routes.ipynb b/docs/02-dynamic-routes.ipynb index 70c5eced9ece37a822ac0af0174f03f9ec07768a..88b7794aadac761ec74dc872d2203203208791e7 100644 --- a/docs/02-dynamic-routes.ipynb +++ b/docs/02-dynamic-routes.ipynb @@ -1,376 +1,453 @@ { - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "[](https://colab.research.google.com/github/aurelio-labs/semantic-router/blob/main/docs/02-dynamic-routes.ipynb) [](https://nbviewer.org/github/aurelio-labs/semantic-router/blob/main/docs/02-dynamic-routes.ipynb)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Dynamic Routes" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In semantic-router there are two types of routes that can be chosen. Both routes belong to the `Route` object, the only difference between them is that _static_ routes return a `Route.name` when chosen, whereas _dynamic_ routes use an LLM call to produce parameter input values.\n", - "\n", - "For example, a _static_ route will tell us if a query is talking about mathematics by returning the route name (which could be `\"math\"` for example). A _dynamic_ route can generate additional values, so it may decide a query is talking about maths, but it can also generate Python code that we can later execute to answer the user's query, this output may look like `\"math\", \"import math; output = math.sqrt(64)`." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Installing the Library" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "!pip install -qU semantic-router==0.0.15" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "_**âš ï¸ If using Google Colab, install the prerequisites and then restart the notebook before continuing**_" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Initializing Routes and RouteLayer" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Dynamic routes are treated in the same way as static routes, let's begin by initializing a `RouteLayer` consisting of static routes." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "from semantic_router import Route\n", - "\n", - "politics = Route(\n", - " name=\"politics\",\n", - " utterances=[\n", - " \"isn't politics the best thing ever\",\n", - " \"why don't you tell me about your political opinions\",\n", - " \"don't you just love the president\" \"don't you just hate the president\",\n", - " \"they're going to destroy this country!\",\n", - " \"they will save the country!\",\n", - " ],\n", - ")\n", - "chitchat = Route(\n", - " name=\"chitchat\",\n", - " utterances=[\n", - " \"how's the weather today?\",\n", - " \"how are things going?\",\n", - " \"lovely weather today\",\n", - " \"the weather is horrendous\",\n", - " \"let's go to the chippy\",\n", - " ],\n", - ")\n", - "\n", - "routes = [politics, chitchat]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We initialize our `RouteLayer` with our `encoder` and `routes`. We can use popular encoder APIs like `CohereEncoder` and `OpenAIEncoder`, or local alternatives like `FastEmbedEncoder`." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ + "cells": [ { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001b[32m2024-01-07 18:11:05 INFO semantic_router.utils.logger Initializing RouteLayer\u001b[0m\n" - ] - } - ], - "source": [ - "import os\n", - "from getpass import getpass\n", - "from semantic_router import RouteLayer\n", - "from semantic_router.encoders import CohereEncoder, OpenAIEncoder\n", - "\n", - "# dashboard.cohere.ai\n", - "# os.environ[\"COHERE_API_KEY\"] = os.getenv(\"COHERE_API_KEY\") or getpass(\n", - "# \"Enter Cohere API Key: \"\n", - "# )\n", - "# platform.openai.com\n", - "os.environ[\"OPENAI_API_KEY\"] = os.getenv(\"OPENAI_API_KEY\") or getpass(\n", - " \"Enter OpenAI API Key: \"\n", - ")\n", - "\n", - "# encoder = CohereEncoder()\n", - "encoder = OpenAIEncoder()\n", - "\n", - "rl = RouteLayer(encoder=encoder, routes=routes)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We run the solely static routes layer:" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ + "cell_type": "markdown", + "metadata": { + "id": "UxqB7_Ieur0s" + }, + "source": [ + "[](https://colab.research.google.com/github/aurelio-labs/semantic-router/blob/main/docs/02-dynamic-routes.ipynb) [](https://nbviewer.org/github/aurelio-labs/semantic-router/blob/main/docs/02-dynamic-routes.ipynb)" + ] + }, { - "data": { - "text/plain": [ - "RouteChoice(name='chitchat', function_call=None)" + "cell_type": "markdown", + "metadata": { + "id": "EduhQaNAur0u" + }, + "source": [ + "# Dynamic Routes" ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "rl(\"how's the weather today?\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Creating a Dynamic Route" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "As with static routes, we must create a dynamic route before adding it to our route layer. To make a route dynamic, we need to provide a `function_schema`. The function schema provides instructions on what a function is, so that an LLM can decide how to use it correctly." - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [], - "source": [ - "from datetime import datetime\n", - "from zoneinfo import ZoneInfo\n", - "\n", - "\n", - "def get_time(timezone: str) -> str:\n", - " \"\"\"Finds the current time in a specific timezone.\n", - "\n", - " :param timezone: The timezone to find the current time in, should\n", - " be a valid timezone from the IANA Time Zone Database like\n", - " \"America/New_York\" or \"Europe/London\".\n", - " :type timezone: str\n", - " :return: The current time in the specified timezone.\"\"\"\n", - " now = datetime.now(ZoneInfo(timezone))\n", - " return now.strftime(\"%H:%M\")" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ + }, { - "data": { - "text/plain": [ - "'12:11'" + "cell_type": "markdown", + "metadata": { + "id": "_4JgNeX4ur0v" + }, + "source": [ + "In semantic-router there are two types of routes that can be chosen. Both routes belong to the `Route` object, the only difference between them is that _static_ routes return a `Route.name` when chosen, whereas _dynamic_ routes use an LLM call to produce parameter input values.\n", + "\n", + "For example, a _static_ route will tell us if a query is talking about mathematics by returning the route name (which could be `\"math\"` for example). A _dynamic_ route can generate additional values, so it may decide a query is talking about maths, but it can also generate Python code that we can later execute to answer the user's query, this output may look like `\"math\", \"import math; output = math.sqrt(64)`." ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "get_time(\"America/New_York\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "To get the function schema we can use the `get_schema` function from the `function_call` module." - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ + }, { - "data": { - "text/plain": [ - "{'name': 'get_time',\n", - " 'description': 'Finds the current time in a specific timezone.\\n\\n:param timezone: The timezone to find the current time in, should\\n be a valid timezone from the IANA Time Zone Database like\\n \"America/New_York\" or \"Europe/London\".\\n:type timezone: str\\n:return: The current time in the specified timezone.',\n", - " 'signature': '(timezone: str) -> str',\n", - " 'output': \"<class 'str'>\"}" + "cell_type": "markdown", + "metadata": { + "id": "bbmw8CO4ur0v" + }, + "source": [ + "## Installing the Library" ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from semantic_router.utils.function_call import get_schema\n", - "\n", - "schema = get_schema(get_time)\n", - "schema" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We use this to define our dynamic route:" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [], - "source": [ - "time_route = Route(\n", - " name=\"get_time\",\n", - " utterances=[\n", - " \"what is the time in new york city?\",\n", - " \"what is the time in london?\",\n", - " \"I live in Rome, what time is it?\",\n", - " ],\n", - " function_schema=schema,\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Add the new route to our `layer`:" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ + }, { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001b[32m2024-01-07 18:11:20 INFO semantic_router.utils.logger Adding `get_time` route\u001b[0m\n" - ] - } - ], - "source": [ - "rl.add(time_route)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now we can ask our layer a time related question to trigger our new dynamic route." - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "dLElfRhgur0v" + }, + "outputs": [], + "source": [ + "!pip install -qU semantic-router==0.0.15" + ] + }, { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001b[33m2024-01-07 18:11:23 WARNING semantic_router.utils.logger No LLM provided for dynamic route, will use OpenAI LLM default. Ensure API key is set in OPENAI_API_KEY environment variable.\u001b[0m\n", - "\u001b[32m2024-01-07 18:11:23 INFO semantic_router.utils.logger Extracting function input...\u001b[0m\n" - ] + "cell_type": "markdown", + "metadata": { + "id": "BixZd6Eour0w" + }, + "source": [ + "## Initializing Routes and RouteLayer" + ] }, { - "data": { - "text/plain": [ - "RouteChoice(name='get_time', function_call={'timezone': 'new york city'})" + "cell_type": "markdown", + "metadata": { + "id": "PxnW9qBvur0x" + }, + "source": [ + "Dynamic routes are treated in the same way as static routes, let's begin by initializing a `RouteLayer` consisting of static routes." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "id": "kc9Ty6Lgur0x" + }, + "outputs": [], + "source": [ + "from semantic_router import Route\n", + "\n", + "politics = Route(\n", + " name=\"politics\",\n", + " utterances=[\n", + " \"isn't politics the best thing ever\",\n", + " \"why don't you tell me about your political opinions\",\n", + " \"don't you just love the president\" \"don't you just hate the president\",\n", + " \"they're going to destroy this country!\",\n", + " \"they will save the country!\",\n", + " ],\n", + ")\n", + "chitchat = Route(\n", + " name=\"chitchat\",\n", + " utterances=[\n", + " \"how's the weather today?\",\n", + " \"how are things going?\",\n", + " \"lovely weather today\",\n", + " \"the weather is horrendous\",\n", + " \"let's go to the chippy\",\n", + " ],\n", + ")\n", + "\n", + "routes = [politics, chitchat]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "voWyqmffur0x" + }, + "source": [ + "We initialize our `RouteLayer` with our `encoder` and `routes`. We can use popular encoder APIs like `CohereEncoder` and `OpenAIEncoder`, or local alternatives like `FastEmbedEncoder`." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "id": "BI9AiDspur0y", + "outputId": "27329a54-3f16-44a5-ac20-13a6b26afb97", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "\u001b[32m2024-01-08 11:12:24 INFO semantic_router.utils.logger Initializing RouteLayer\u001b[0m\n" + ] + } + ], + "source": [ + "import os\n", + "from getpass import getpass\n", + "from semantic_router import RouteLayer\n", + "from semantic_router.encoders import CohereEncoder, OpenAIEncoder\n", + "\n", + "# dashboard.cohere.ai\n", + "# os.environ[\"COHERE_API_KEY\"] = os.getenv(\"COHERE_API_KEY\") or getpass(\n", + "# \"Enter Cohere API Key: \"\n", + "# )\n", + "# platform.openai.com\n", + "os.environ[\"OPENAI_API_KEY\"] = os.getenv(\"OPENAI_API_KEY\") or getpass(\n", + " \"Enter OpenAI API Key: \"\n", + ")\n", + "\n", + "# encoder = CohereEncoder()\n", + "encoder = OpenAIEncoder()\n", + "\n", + "rl = RouteLayer(encoder=encoder, routes=routes)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "GuLCeIS5ur0y" + }, + "source": [ + "We run the solely static routes layer:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "id": "_rNREh7gur0y", + "outputId": "f3a1dc0b-d760-4efb-b634-d3547011dcb7", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "RouteChoice(name='chitchat', function_call=None)" + ] + }, + "metadata": {}, + "execution_count": 4 + } + ], + "source": [ + "rl(\"how's the weather today?\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "McbLKO26ur0y" + }, + "source": [ + "## Creating a Dynamic Route" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ANAoEjxYur0y" + }, + "source": [ + "As with static routes, we must create a dynamic route before adding it to our route layer. To make a route dynamic, we need to provide a `function_schema`. The function schema provides instructions on what a function is, so that an LLM can decide how to use it correctly." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "id": "5jaF1Xa5ur0y" + }, + "outputs": [], + "source": [ + "from datetime import datetime\n", + "from zoneinfo import ZoneInfo\n", + "\n", + "\n", + "def get_time(timezone: str) -> str:\n", + " \"\"\"Finds the current time in a specific timezone.\n", + "\n", + " :param timezone: The timezone to find the current time in, should\n", + " be a valid timezone from the IANA Time Zone Database like\n", + " \"America/New_York\" or \"Europe/London\". Do NOT put the place\n", + " name itself like \"rome\", or \"new york\", you must provide\n", + " the IANA format.\n", + " :type timezone: str\n", + " :return: The current time in the specified timezone.\"\"\"\n", + " now = datetime.now(ZoneInfo(timezone))\n", + " return now.strftime(\"%H:%M\")" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "id": "YyFKV8jMur0z", + "outputId": "29cf80f4-552c-47bb-fbf9-019f5dfdf00a", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + } + }, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "'06:13'" + ], + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + } + }, + "metadata": {}, + "execution_count": 6 + } + ], + "source": [ + "get_time(\"America/New_York\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4qyaRuNXur0z" + }, + "source": [ + "To get the function schema we can use the `get_schema` function from the `function_call` module." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "id": "tOjuhp5Xur0z", + "outputId": "ca88a3ea-d70a-4950-be9a-63fab699de3b", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'name': 'get_time',\n", + " 'description': 'Finds the current time in a specific timezone.\\n\\n:param timezone: The timezone to find the current time in, should\\n be a valid timezone from the IANA Time Zone Database like\\n \"America/New_York\" or \"Europe/London\". Do NOT put the place\\n name itself like \"rome\", or \"new york\", you must provide\\n the IANA format.\\n:type timezone: str\\n:return: The current time in the specified timezone.',\n", + " 'signature': '(timezone: str) -> str',\n", + " 'output': \"<class 'str'>\"}" + ] + }, + "metadata": {}, + "execution_count": 7 + } + ], + "source": [ + "from semantic_router.utils.function_call import get_schema\n", + "\n", + "schema = get_schema(get_time)\n", + "schema" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HcF7jGjAur0z" + }, + "source": [ + "We use this to define our dynamic route:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "id": "iesBG9P3ur0z" + }, + "outputs": [], + "source": [ + "time_route = Route(\n", + " name=\"get_time\",\n", + " utterances=[\n", + " \"what is the time in new york city?\",\n", + " \"what is the time in london?\",\n", + " \"I live in Rome, what time is it?\",\n", + " ],\n", + " function_schema=schema,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZiUs3ovpur0z" + }, + "source": [ + "Add the new route to our `layer`:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "id": "-0vY8PRXur0z", + "outputId": "db01e14c-eab3-4f93-f4c2-e30f508c8b5d", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "\u001b[32m2024-01-08 11:15:26 INFO semantic_router.utils.logger Adding `get_time` route\u001b[0m\n" + ] + } + ], + "source": [ + "rl.add(time_route)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7yoE0IrNur0z" + }, + "source": [ + "Now we can ask our layer a time related question to trigger our new dynamic route." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "id": "Wfb68M0-ur0z", + "outputId": "79923883-2a4d-4744-f8ce-e818cb5f14c3", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 53 + } + }, + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "\u001b[32m2024-01-08 11:16:24 INFO semantic_router.utils.logger Extracting function input...\u001b[0m\n" + ] + }, + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "'06:16'" + ], + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + } + }, + "metadata": {}, + "execution_count": 11 + } + ], + "source": [ + "out = rl(\"what is the time in new york city?\")\n", + "get_time(**out.function_call)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Qt0vkq2Xur00" + }, + "source": [ + "Our dynamic route provides both the route itself _and_ the input parameters required to use the route." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "J0oD1dxIur00" + }, + "source": [ + "---" ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" } - ], - "source": [ - "# https://platform.openai.com/\n", - "os.environ[\"OPENAI_API_KEY\"] = os.getenv(\"OPENAI_API_KEY\") or getpass(\n", - " \"Enter OpenAI API Key: \"\n", - ")\n", - "\n", - "rl(\"what is the time in new york city?\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Our dynamic route provides both the route itself _and_ the input parameters required to use the route." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "decision-layer", - "language": "python", - "name": "python3" + ], + "metadata": { + "kernelspec": { + "display_name": "decision-layer", + "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.5" + }, + "colab": { + "provenance": [] + } }, - "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.5" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/docs/03-basic-langchain-agent.ipynb b/docs/03-basic-langchain-agent.ipynb index c8c48b3dbedf5c6a09243ff2c93a1071f40c916d..dc728495136a804a79340026d14f56807929e443 100644 --- a/docs/03-basic-langchain-agent.ipynb +++ b/docs/03-basic-langchain-agent.ipynb @@ -83,15 +83,6 @@ " openai==1.6.1" ] }, - { - "cell_type": "markdown", - "metadata": { - "id": "cHtVnoJPA04x" - }, - "source": [ - "_**âš ï¸ If using Google Colab, install the prerequisites and then restart the notebook before continuing**_" - ] - }, { "cell_type": "markdown", "metadata": { diff --git a/docs/04-chat-history.ipynb b/docs/04-chat-history.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..4ac533b1ef4126ac63cb6b8cacf2441d73a538ea --- /dev/null +++ b/docs/04-chat-history.ipynb @@ -0,0 +1,139 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "[](https://colab.research.google.com/github/aurelio-labs/semantic-router/blob/main/docs/00-introduction.ipynb) [](https://nbviewer.org/github/aurelio-labs/semantic-router/blob/main/docs/00-introduction.ipynb)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Considering Chat History" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Applying semantic-router to the most recent interaction in a conversation can work for many cases but it misses scenarios where information provided in the latest interaction." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/jamesbriggs/opt/anaconda3/envs/decision-layer/lib/python3.11/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", + " from .autonotebook import tqdm as notebook_tqdm\n", + "100%|██████████| 83.2M/83.2M [00:09<00:00, 8.45MiB/s]\n" + ] + }, + { + "data": { + "text/plain": [ + "{'split 1': ['User: Hello! Can you tell me the latest news headlines?',\n", + " 'Bot: Hi! Sure, here are the top news headlines for today...'],\n", + " 'split 2': [\"User: That's quite interesting. I'm also looking for some new music to listen to.\",\n", + " 'Bot: What genre do you prefer?',\n", + " 'User: I like pop music.',\n", + " 'Bot: You might enjoy the latest album by Dua Lipa.',\n", + " \"User: I'll give it a listen. Also, I'm planning a trip and need some travel tips.\",\n", + " 'Bot: Sure, where are you planning to go?'],\n", + " 'split 3': [\"User: I'm thinking of visiting Italy.\",\n", + " 'Bot: Italy is a beautiful country. Make sure to visit the Colosseum in Rome and the canals in Venice.'],\n", + " 'split 4': ['User: Those sound like great suggestions. I also need some help with my diet.',\n", + " 'Bot: What kind of diet are you following?',\n", + " \"User: I'm trying to eat more protein.\",\n", + " 'Bot: Include lean meats, eggs, and legumes in your diet for a protein boost.',\n", + " \"User: Thanks for the tips! I'll talk to you later.\",\n", + " \"Bot: You're welcome! Don't hesitate to reach out if you need more help.\",\n", + " 'User: I appreciate it. Goodbye!',\n", + " 'Bot: Goodbye! Take care!']}" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from semantic_router.schema import Conversation, Message\n", + "from semantic_router.encoders import FastEmbedEncoder\n", + "\n", + "\n", + "messages = [\n", + " \"User: Hello! Can you tell me the latest news headlines?\",\n", + " \"Bot: Hi! Sure, here are the top news headlines for today...\",\n", + " \"User: That's quite interesting. I'm also looking for some new music to listen to.\",\n", + " \"Bot: What genre do you prefer?\",\n", + " \"User: I like pop music.\",\n", + " \"Bot: You might enjoy the latest album by Dua Lipa.\",\n", + " \"User: I'll give it a listen. Also, I'm planning a trip and need some travel tips.\",\n", + " \"Bot: Sure, where are you planning to go?\",\n", + " \"User: I'm thinking of visiting Italy.\",\n", + " \"Bot: Italy is a beautiful country. Make sure to visit the Colosseum in Rome and the canals in Venice.\",\n", + " \"User: Those sound like great suggestions. I also need some help with my diet.\",\n", + " \"Bot: What kind of diet are you following?\",\n", + " \"User: I'm trying to eat more protein.\",\n", + " \"Bot: Include lean meats, eggs, and legumes in your diet for a protein boost.\",\n", + " \"User: Thanks for the tips! I'll talk to you later.\",\n", + " \"Bot: You're welcome! Don't hesitate to reach out if you need more help.\",\n", + " \"User: I appreciate it. Goodbye!\",\n", + " \"Bot: Goodbye! Take care!\",\n", + "]\n", + "\n", + "encoder = FastEmbedEncoder(model_name=\"sentence-transformers/all-MiniLM-L6-v2\")\n", + "\n", + "convo = Conversation(\n", + " messages=[\n", + " Message(role=m.split(\": \")[0], content=m.split(\": \")[1]) for m in messages\n", + " ]\n", + ")\n", + "\n", + "convo.split_by_topic(\n", + " encoder=encoder, threshold=0.72, split_method=\"cumulative_similarity_drop\"\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "ml", + "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.5" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/docs/encoders/fastembed.ipynb b/docs/encoders/fastembed.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..68b1f69cd7228a25ec2ae97e6ffa4f13ca39a116 --- /dev/null +++ b/docs/encoders/fastembed.ipynb @@ -0,0 +1,262 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "[](https://colab.research.google.com/github/aurelio-labs/semantic-router/blob/main/docs/encoders/fastembed.ipynb) [](https://nbviewer.org/github/aurelio-labs/semantic-router/blob/main/docs/encoders/fastembed.ipynb)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Using FastEmbedEncoder" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "FastEmbed is a _lightweight and fast_ embedding library built for generating embeddings. It can be run locally and supports many open source encoders.\n", + "\n", + "Beyond being a local, open source library, there are two key reasons we might want to run this library over other open source alternatives:\n", + "\n", + "* **Lightweight and Fast**: The library uses an ONNX runtime so there is no heavy PyTorch dependency, supports quantized model weights (smaller memory footprint), is developed for running on CPU, and uses data-parallelism for encoding large datasets.\n", + "\n", + "* **Open-weight models**: FastEmbed supports many open source and open-weight models, included some that outperform popular encoders like OpenAI's Ada-002." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Getting Started" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We start by installing semantic-router with the `[fastembed]` flag to include all necessary dependencies for `FastEmbedEncoder`:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!pip install -qU \"semantic-router[fastembed]==0.0.15\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We start by defining a dictionary mapping routes to example phrases that should trigger those routes." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "from semantic_router import Route\n", + "\n", + "politics = Route(\n", + " name=\"politics\",\n", + " utterances=[\n", + " \"isn't politics the best thing ever\",\n", + " \"why don't you tell me about your political opinions\",\n", + " \"don't you just love the president\",\n", + " \"don't you just hate the president\",\n", + " \"they're going to destroy this country!\",\n", + " \"they will save the country!\",\n", + " ],\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's define another for good measure:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "chitchat = Route(\n", + " name=\"chitchat\",\n", + " utterances=[\n", + " \"how's the weather today?\",\n", + " \"how are things going?\",\n", + " \"lovely weather today\",\n", + " \"the weather is horrendous\",\n", + " \"let's go to the chippy\",\n", + " ],\n", + ")\n", + "\n", + "routes = [politics, chitchat]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we initialize our embedding model, you can find a list of [all available embedding models here](https://qdrant.github.io/fastembed/examples/Supported_Models/):" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "from semantic_router.encoders import FastEmbedEncoder\n", + "\n", + "encoder = FastEmbedEncoder(name=\"BAAI/bge-small-en-v1.5\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "_**âš ï¸ If you see an ImportError, you must install the FastEmbed library. You can do so by installing Semantic Router using `pip install -qU \"semantic-router[fastembed]\"`.**_" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we define the `RouteLayer`. When called, the route layer will consume text (a query) and output the category (`Route`) it belongs to — to initialize a `RouteLayer` we need our `encoder` model and a list of `routes`." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m2024-01-06 16:53:16 INFO semantic_router.utils.logger Initializing RouteLayer\u001b[0m\n" + ] + } + ], + "source": [ + "from semantic_router.layer import RouteLayer\n", + "\n", + "rl = RouteLayer(encoder=encoder, routes=routes)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we can test it:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "RouteChoice(name='politics', function_call=None)" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "rl(\"don't you love politics?\")" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "RouteChoice(name='chitchat', function_call=None)" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "rl(\"how's the weather today?\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Both are classified accurately, what if we send a query that is unrelated to our existing `Route` objects?" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "RouteChoice(name=None, function_call=None)" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "rl(\"I'm interested in learning about llama 2\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In this case, we return `None` because no matches were identified." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "decision-layer", + "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.9.18" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/docs/encoders/huggingface.ipynb b/docs/encoders/huggingface.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..4e9c28cdd9d1cc4c65b84a30de2d896b77ef2049 --- /dev/null +++ b/docs/encoders/huggingface.ipynb @@ -0,0 +1,271 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "[](https://colab.research.google.com/github/aurelio-labs/semantic-router/blob/main/docs/encoders/huggingface.ipynb) [](https://nbviewer.org/github/aurelio-labs/semantic-router/blob/main/docs/encoders/huggingface.ipynb)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Using HuggingFaceEncoder" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "HuggingFace is a huge ecosystem of open source models. It can be run locally and supports the largest library of encoders." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Getting Started" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We start by installing semantic-router with the `[local]` flag to include all necessary dependencies for `HuggingFaceEncoder`:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!pip install -qU \"semantic-router[local]==0.0.16\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We start by defining a dictionary mapping routes to example phrases that should trigger those routes." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "from semantic_router import Route\n", + "\n", + "politics = Route(\n", + " name=\"politics\",\n", + " utterances=[\n", + " \"isn't politics the best thing ever\",\n", + " \"why don't you tell me about your political opinions\",\n", + " \"don't you just love the president\",\n", + " \"don't you just hate the president\",\n", + " \"they're going to destroy this country!\",\n", + " \"they will save the country!\",\n", + " ],\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "_**âš ï¸ If you see an ImportError, you must install local dependencies. You can do so by installing Semantic Router using `pip install -qU \"semantic-router[local]\"`.**_" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's define another for good measure:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "chitchat = Route(\n", + " name=\"chitchat\",\n", + " utterances=[\n", + " \"how's the weather today?\",\n", + " \"how are things going?\",\n", + " \"lovely weather today\",\n", + " \"the weather is horrendous\",\n", + " \"let's go to the chippy\",\n", + " ],\n", + ")\n", + "\n", + "routes = [politics, chitchat]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we initialize our embedding model." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/jamesbriggs/opt/anaconda3/envs/decision-layer/lib/python3.11/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", + " from .autonotebook import tqdm as notebook_tqdm\n", + "tokenizer_config.json: 100%|██████████| 350/350 [00:00<00:00, 1.06MB/s]\n", + "vocab.txt: 100%|██████████| 232k/232k [00:00<00:00, 1.05MB/s]\n", + "tokenizer.json: 100%|██████████| 466k/466k [00:00<00:00, 1.43MB/s]\n", + "special_tokens_map.json: 100%|██████████| 112/112 [00:00<00:00, 386kB/s]\n", + "config.json: 100%|██████████| 612/612 [00:00<00:00, 2.90MB/s]\n", + "pytorch_model.bin: 100%|██████████| 90.9M/90.9M [00:01<00:00, 63.2MB/s]\n" + ] + } + ], + "source": [ + "from semantic_router.encoders import HuggingFaceEncoder\n", + "\n", + "encoder = HuggingFaceEncoder()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we define the `RouteLayer`. When called, the route layer will consume text (a query) and output the category (`Route`) it belongs to — to initialize a `RouteLayer` we need our `encoder` model and a list of `routes`." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m2024-01-09 00:22:35 INFO semantic_router.utils.logger Initializing RouteLayer\u001b[0m\n" + ] + } + ], + "source": [ + "from semantic_router.layer import RouteLayer\n", + "\n", + "rl = RouteLayer(encoder=encoder, routes=routes)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we can test it:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "RouteChoice(name='politics', function_call=None)" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "rl(\"don't you love politics?\")" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "RouteChoice(name='chitchat', function_call=None)" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "rl(\"how's the weather today?\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Both are classified accurately, what if we send a query that is unrelated to our existing `Route` objects?" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "RouteChoice(name=None, function_call=None)" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "rl(\"I'm interested in learning about llama 2\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In this case, we return `None` because no matches were identified." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "decision-layer", + "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.5" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/docs/examples/function_calling.ipynb b/docs/examples/function_calling.ipynb index 401ab04a71296066ad1aa7762d0c4e3f1b7f9d52..5392e54e537cadeb74ec3554c37d8f76c9e4a96c 100644 --- a/docs/examples/function_calling.ipynb +++ b/docs/examples/function_calling.ipynb @@ -512,7 +512,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.3" + "version": "3.9.18" } }, "nbformat": 4, diff --git a/poetry.lock b/poetry.lock index 2ca6055c061bb6141341cea33a9b7039045d86dd..1328ceea35bda84609bb6f2985c06959522912a5 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. [[package]] name = "aiohttp" @@ -250,6 +250,17 @@ d = ["aiohttp (>=3.7.4)", "aiohttp (>=3.7.4,!=3.9.0)"] jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] uvloop = ["uvloop (>=0.15.2)"] +[[package]] +name = "cachetools" +version = "5.3.2" +description = "Extensible memoizing collections and decorators" +optional = false +python-versions = ">=3.7" +files = [ + {file = "cachetools-5.3.2-py3-none-any.whl", hash = "sha256:861f35a13a451f94e301ce2bec7cac63e881232ccce7ed67fab9b5df4d3beaa1"}, + {file = "cachetools-5.3.2.tar.gz", hash = "sha256:086ee420196f7b2ab9ca2db2520aca326318b68fe5ba8bc4d49cca91add450f2"}, +] + [[package]] name = "certifi" version = "2023.11.17" @@ -325,6 +336,17 @@ files = [ [package.dependencies] pycparser = "*" +[[package]] +name = "chardet" +version = "5.2.0" +description = "Universal encoding detector for Python 3" +optional = false +python-versions = ">=3.7" +files = [ + {file = "chardet-5.2.0-py3-none-any.whl", hash = "sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970"}, + {file = "chardet-5.2.0.tar.gz", hash = "sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7"}, +] + [[package]] name = "charset-normalizer" version = "3.3.2" @@ -440,13 +462,13 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""} [[package]] name = "cohere" -version = "4.40" +version = "4.41" description = "Python SDK for the Cohere API" optional = false python-versions = ">=3.8,<4.0" files = [ - {file = "cohere-4.40-py3-none-any.whl", hash = "sha256:75dac8369d97fadc05901352d9db64a0ca6cd40c08423f3c4691f57eb7b131e7"}, - {file = "cohere-4.40.tar.gz", hash = "sha256:d9e5c1fa7f80a193c03330a634954b927bf188ead7dcfdb51865480f73aebda8"}, + {file = "cohere-4.41-py3-none-any.whl", hash = "sha256:39470cc412fa96a1c612f522d48d7d86b34b3163a04030cff83ec48ebbaff32f"}, + {file = "cohere-4.41.tar.gz", hash = "sha256:8509ca196dc038eca81e474d3cd5896da2ea168a4d3c578b4cb6969994be34ef"}, ] [package.dependencies] @@ -624,6 +646,17 @@ files = [ {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"}, ] +[[package]] +name = "distlib" +version = "0.3.8" +description = "Distribution utilities" +optional = false +python-versions = "*" +files = [ + {file = "distlib-0.3.8-py2.py3-none-any.whl", hash = "sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784"}, + {file = "distlib-0.3.8.tar.gz", hash = "sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64"}, +] + [[package]] name = "distro" version = "1.9.0" @@ -679,42 +712,42 @@ tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipyth [[package]] name = "fastavro" -version = "1.9.2" +version = "1.9.3" description = "Fast read/write of AVRO files" optional = false python-versions = ">=3.8" files = [ - {file = "fastavro-1.9.2-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:223cecf135fd29b83ca6a30035b15b8db169aeaf8dc4f9a5d34afadc4b31638a"}, - {file = "fastavro-1.9.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e08c9be8c6f7eed2cf30f8b64d50094cba38a81b751c7db9f9c4be2656715259"}, - {file = "fastavro-1.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:394f06cc865c6fbae3bbca323633a28a5d914c55dc2c1cdefb75432456ef8f6f"}, - {file = "fastavro-1.9.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7a7caadd47bdd04bda534ff70b4b98d2823800c488fd911918115aec4c4dc09b"}, - {file = "fastavro-1.9.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:68478a1b8a583d83ad6550e9dceac6cbb148a99a52c3559a0413bf4c0b9c8786"}, - {file = "fastavro-1.9.2-cp310-cp310-win_amd64.whl", hash = "sha256:b59a1123f1d534743af33fdbda80dd7b9146685bdd7931eae12bee6203065222"}, - {file = "fastavro-1.9.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:887c20dc527a549764c91f9e48ece071f2f26d217af66ebcaeb87bf29578fee5"}, - {file = "fastavro-1.9.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46458f78b481c12db62d3d8a81bae09cb0b5b521c0d066c6856fc2746908d00d"}, - {file = "fastavro-1.9.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f4a2a4bed0e829f79fa1e4f172d484b2179426e827bcc80c0069cc81328a5af"}, - {file = "fastavro-1.9.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6167f9bbe1c5a28fbc2db767f97dbbb4981065e6eeafd4e613f6fe76c576ffd4"}, - {file = "fastavro-1.9.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d574bc385f820da0404528157238de4e5fdd775d2cb3d05b3b0f1b475d493837"}, - {file = "fastavro-1.9.2-cp311-cp311-win_amd64.whl", hash = "sha256:ec600eb15b3ec931904c5bf8da62b3b725cb0f369add83ba47d7b5e9322f92a0"}, - {file = "fastavro-1.9.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:c82b0761503420cd45f7f50bc31975ac1c75b5118e15434c1d724b751abcc249"}, - {file = "fastavro-1.9.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:db62d9b8c944b8d9c481e5f980d5becfd034bdd58c72e27c9333bd504b06bda0"}, - {file = "fastavro-1.9.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65e61f040bc9494646f42a466e9cd428783b82d7161173f3296710723ba5a453"}, - {file = "fastavro-1.9.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:6278b93cdd5bef1778c0232ce1f265137f90bc6be97a5c1dd7e0d99a406c0488"}, - {file = "fastavro-1.9.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cd003ddea5d89720194b6e57011c37221d9fc4ddc750e6f4723516eb659be686"}, - {file = "fastavro-1.9.2-cp312-cp312-win_amd64.whl", hash = "sha256:43f09d100a26e8b59f30dde664d93e423b648e008abfc43132608a18fe8ddcc2"}, - {file = "fastavro-1.9.2-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:3ddffeff5394f285c69f9cd481f47b6cf62379840cdbe6e0dc74683bd589b56e"}, - {file = "fastavro-1.9.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e75a2b2ec697d2058a7d96522e921f03f174cf9049ace007c24be7ab58c5370"}, - {file = "fastavro-1.9.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fd2e8fd0567483eb0fdada1b979ad4d493305dfdd3f351c82a87df301f0ae1f"}, - {file = "fastavro-1.9.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:c652dbe3f087c943a5b89f9a50a574e64f23790bfbec335ce2b91a2ae354a443"}, - {file = "fastavro-1.9.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bba73e9a1822162f1b3a43de0362f29880014c5c4d49d63ad7fcce339ef73ea2"}, - {file = "fastavro-1.9.2-cp38-cp38-win_amd64.whl", hash = "sha256:beeef2964bbfd09c539424808539b956d7425afbb7055b89e2aa311374748b56"}, - {file = "fastavro-1.9.2-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:d5fa48266d75e057b27d8586b823d6d7d7c94593fd989d75033eb4c8078009fb"}, - {file = "fastavro-1.9.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b69aeb0d063f5955a0e412f9779444fc452568a49db75a90a8d372f9cb4a01c8"}, - {file = "fastavro-1.9.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ce336c59fb40fdb8751bda8cc6076cfcdf9767c3c107f6049e049166b26c61f"}, - {file = "fastavro-1.9.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:581036e18661f045415a51ad528865e1d7ba5a9690a3dede9e6ea50f94ed6c4c"}, - {file = "fastavro-1.9.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:39b6b5c3cda569c0a130fd2d08d4c53a326ede7e05174a24eda08f7698f70eda"}, - {file = "fastavro-1.9.2-cp39-cp39-win_amd64.whl", hash = "sha256:d33e40f246bf07f106f9d2da68d0234efcc62276b6e35bde00ff920ea7f871fd"}, - {file = "fastavro-1.9.2.tar.gz", hash = "sha256:5c1ffad986200496bd69b5c4748ae90b5d934d3b1456f33147bee3a0bb17f89b"}, + {file = "fastavro-1.9.3-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:5e9b2e1427fb84c0754bc34923d10cabcf2ed23230201208a1371ab7b6027674"}, + {file = "fastavro-1.9.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4ef82f86ae276309abc0072598474b6be68105a0b28f8d7cc0398d1d353d7de"}, + {file = "fastavro-1.9.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:280ef7ab7232ecb2097038d6842416ec717d0e1c314b80ff245f85201f3396a4"}, + {file = "fastavro-1.9.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4a36cfc0421ed7576ecb1c22de7bd1dedcce62aebbffcc597379d59171e5d76e"}, + {file = "fastavro-1.9.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d80f2e20199140eb8c036b4393e9bc9eff325543311b958c72318999499d4279"}, + {file = "fastavro-1.9.3-cp310-cp310-win_amd64.whl", hash = "sha256:a435f7edd7c5b52cee3f23ca950cd9373ab35cf2aa3d269b3d6aca7e2fc1372c"}, + {file = "fastavro-1.9.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2a7053ed10194ec53754f5337b57b3273a74b48505edcd6edb79fe3c4cd259c0"}, + {file = "fastavro-1.9.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:853e01f13534d1baa0a3d493a8573e665e93ffa35b4bf1d125e21764d343af8e"}, + {file = "fastavro-1.9.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a5a279cda25d876e6f120950cadf184a307fd8998f9a22a90bb62e6749f88d1e"}, + {file = "fastavro-1.9.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:63d6f928840f3fb1f2e1fe20bc8b7d0e1a51ba4bb0e554ecb837a669fba31288"}, + {file = "fastavro-1.9.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8807046edc78f50b3ea5f55f6a534c87b2a13538e7c56fec3532ef802bcae333"}, + {file = "fastavro-1.9.3-cp311-cp311-win_amd64.whl", hash = "sha256:e502579da4a51c5630eadbd811a1b3d262d6e783bf19998cfb33d2ea0cf6f516"}, + {file = "fastavro-1.9.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:6b665efe442061df8d9608c2fb692847df85d52ad825b776c441802f0dfa6571"}, + {file = "fastavro-1.9.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b8c96d81f0115633489d7f1133a03832922629a61ca81c1d47b482ddcda3b94"}, + {file = "fastavro-1.9.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:338c7ec94dd2474c4679e44d2560a1922cb6fa99acbb7b18957264baf8eadfc7"}, + {file = "fastavro-1.9.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:a509b34c9af71a109c633631ac2f6d2209830e13200d0048f7e9c057fd563f8f"}, + {file = "fastavro-1.9.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:967edefab470987c024cd5a1fcd04744a50a91e740c7bdf325181043a47f1083"}, + {file = "fastavro-1.9.3-cp312-cp312-win_amd64.whl", hash = "sha256:033c15e8ed02f80f01d58be1cd880b09fd444faf277263d563a727711d47a98a"}, + {file = "fastavro-1.9.3-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:6b38723327603d77080aec56628e13a739415f8596ca0cc41a905615977c6d6b"}, + {file = "fastavro-1.9.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:046d75c4400941fd08f0a6855a34ae63bf02ea01f366b5b749942abe10640056"}, + {file = "fastavro-1.9.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87ab312b8baf0e61ee717878d390022ee1b713d70b244d69efbf3325680f9749"}, + {file = "fastavro-1.9.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:c562fcf8f5091a2446aafd0c2a0da590c24e0b53527a0100d33908e32f20eea8"}, + {file = "fastavro-1.9.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2aa0111e7ebd076d2a094862bbdf8ea175cebba148fcce6c89ff46b625e334b4"}, + {file = "fastavro-1.9.3-cp38-cp38-win_amd64.whl", hash = "sha256:652072e0f455ca19a1ee502b527e603389783657c130d81f89df66775979d6f5"}, + {file = "fastavro-1.9.3-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:0a57cdd4edaee36d4216faf801ebc7f53f45e4e1518bdd9832d6f6f1d6e2d88f"}, + {file = "fastavro-1.9.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b46a18ebed61573b0823c28eda2716485d283258a83659c7fe6ad3aaeacfed4"}, + {file = "fastavro-1.9.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f756f0723f3bd97db20437d0a8e45712839e6ccd7c82f4d82469533be48b4c7"}, + {file = "fastavro-1.9.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d98d5a08063f5b6d7ac5016a0dfe0698b50d9987cb74686f7dfa8288b7b09e0b"}, + {file = "fastavro-1.9.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:00698e60db58a2d52cb709df882d451fb7664ebb2f8cb37d9171697e060dc767"}, + {file = "fastavro-1.9.3-cp39-cp39-win_amd64.whl", hash = "sha256:d021bbc135023194688e88a7431fb0b5e3ce20e27153bf258f2ce08ee1a0106b"}, + {file = "fastavro-1.9.3.tar.gz", hash = "sha256:a30d3d2353f6d3b4f6dcd6a97ae937b3775faddd63f5856fe11ba3b0dbb1756a"}, ] [package.extras] @@ -746,7 +779,7 @@ tqdm = ">=4.65,<5.0" name = "filelock" version = "3.13.1" description = "A platform independent file lock." -optional = true +optional = false python-versions = ">=3.8" files = [ {file = "filelock-3.13.1-py3-none-any.whl", hash = "sha256:57dbda9b35157b05fb3e58ee91448612eb674172fab98ee235ccb0b5bee19a1c"}, @@ -1069,13 +1102,13 @@ test = ["flaky", "ipyparallel", "pre-commit", "pytest (>=7.0)", "pytest-asyncio" [[package]] name = "ipython" -version = "8.19.0" +version = "8.18.1" description = "IPython: Productive Interactive Computing" optional = false -python-versions = ">=3.10" +python-versions = ">=3.9" files = [ - {file = "ipython-8.19.0-py3-none-any.whl", hash = "sha256:2f55d59370f59d0d2b2212109fe0e6035cfea436b1c0e6150ad2244746272ec5"}, - {file = "ipython-8.19.0.tar.gz", hash = "sha256:ac4da4ecf0042fb4e0ce57c60430c2db3c719fa8bdf92f8631d6bd8a5785d1f0"}, + {file = "ipython-8.18.1-py3-none-any.whl", hash = "sha256:e8267419d72d81955ec1177f8a29aaa90ac80ad647499201119e2f05e99aa397"}, + {file = "ipython-8.18.1.tar.gz", hash = "sha256:ca6f079bb33457c66e233e4580ebfc4128855b4cf6370dddd73842a9563e8a27"}, ] [package.dependencies] @@ -1089,19 +1122,20 @@ prompt-toolkit = ">=3.0.41,<3.1.0" pygments = ">=2.4.0" stack-data = "*" traitlets = ">=5" +typing-extensions = {version = "*", markers = "python_version < \"3.10\""} [package.extras] -all = ["black", "curio", "docrepr", "exceptiongroup", "ipykernel", "ipyparallel", "ipywidgets", "matplotlib", "matplotlib (!=3.2.0)", "nbconvert", "nbformat", "notebook", "numpy (>=1.23)", "pandas", "pickleshare", "pytest", "pytest-asyncio (<0.22)", "qtconsole", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "trio", "typing-extensions"] +all = ["black", "curio", "docrepr", "exceptiongroup", "ipykernel", "ipyparallel", "ipywidgets", "matplotlib", "matplotlib (!=3.2.0)", "nbconvert", "nbformat", "notebook", "numpy (>=1.22)", "pandas", "pickleshare", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio (<0.22)", "qtconsole", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "trio", "typing-extensions"] black = ["black"] -doc = ["docrepr", "exceptiongroup", "ipykernel", "matplotlib", "pickleshare", "pytest", "pytest-asyncio (<0.22)", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "typing-extensions"] +doc = ["docrepr", "exceptiongroup", "ipykernel", "matplotlib", "pickleshare", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio (<0.22)", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "typing-extensions"] kernel = ["ipykernel"] nbconvert = ["nbconvert"] nbformat = ["nbformat"] notebook = ["ipywidgets", "notebook"] parallel = ["ipyparallel"] qtconsole = ["qtconsole"] -test = ["pickleshare", "pytest", "pytest-asyncio (<0.22)", "testpath"] -test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.23)", "pandas", "pickleshare", "pytest", "pytest-asyncio (<0.22)", "testpath", "trio"] +test = ["pickleshare", "pytest (<7.1)", "pytest-asyncio (<0.22)", "testpath"] +test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.22)", "pandas", "pickleshare", "pytest (<7.1)", "pytest-asyncio (<0.22)", "testpath", "trio"] [[package]] name = "jedi" @@ -1122,6 +1156,23 @@ docs = ["Jinja2 (==2.11.3)", "MarkupSafe (==1.1.1)", "Pygments (==2.8.1)", "alab qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] testing = ["Django", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] +[[package]] +name = "jinja2" +version = "3.1.2" +description = "A very fast and expressive template engine." +optional = true +python-versions = ">=3.7" +files = [ + {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, + {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, +] + +[package.dependencies] +MarkupSafe = ">=2.0" + +[package.extras] +i18n = ["Babel (>=2.7)"] + [[package]] name = "joblib" version = "1.3.2" @@ -1145,6 +1196,7 @@ files = [ ] [package.dependencies] +importlib-metadata = {version = ">=4.8.3", markers = "python_version < \"3.10\""} jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" python-dateutil = ">=2.8.2" pyzmq = ">=23.0" @@ -1157,13 +1209,13 @@ test = ["coverage", "ipykernel (>=6.14)", "mypy", "paramiko", "pre-commit", "pyt [[package]] name = "jupyter-core" -version = "5.7.0" +version = "5.7.1" description = "Jupyter core package. A base package on which Jupyter projects rely." optional = false python-versions = ">=3.8" files = [ - {file = "jupyter_core-5.7.0-py3-none-any.whl", hash = "sha256:16eea462f7dad23ba9f86542bdf17f830804e2028eb48d609b6134d91681e983"}, - {file = "jupyter_core-5.7.0.tar.gz", hash = "sha256:cb8d3ed92144d2463a3c5664fdd686a3f0c1442ea45df8babb1c1a9e6333fe03"}, + {file = "jupyter_core-5.7.1-py3-none-any.whl", hash = "sha256:c65c82126453a723a2804aa52409930434598fd9d35091d63dfb919d2b765bb7"}, + {file = "jupyter_core-5.7.1.tar.gz", hash = "sha256:de61a9d7fc71240f688b2fb5ab659fbb56979458dc66a71decd098e03c79e218"}, ] [package.dependencies] @@ -1175,6 +1227,65 @@ traitlets = ">=5.3" docs = ["myst-parser", "pydata-sphinx-theme", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling", "traitlets"] test = ["ipykernel", "pre-commit", "pytest", "pytest-cov", "pytest-timeout"] +[[package]] +name = "markupsafe" +version = "2.1.3" +description = "Safely add untrusted strings to HTML/XML markup." +optional = true +python-versions = ">=3.7" +files = [ + {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-win32.whl", hash = "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-win32.whl", hash = "sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-win_amd64.whl", hash = "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-win32.whl", hash = "sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-win_amd64.whl", hash = "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-win32.whl", hash = "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-win_amd64.whl", hash = "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba"}, + {file = "MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad"}, +] + [[package]] name = "matplotlib-inline" version = "0.1.6" @@ -1402,6 +1513,24 @@ files = [ {file = "nest_asyncio-1.5.8.tar.gz", hash = "sha256:25aa2ca0d2a5b5531956b9e273b45cf664cae2b145101d73b86b199978d48fdb"}, ] +[[package]] +name = "networkx" +version = "3.2.1" +description = "Python package for creating and manipulating graphs and networks" +optional = true +python-versions = ">=3.9" +files = [ + {file = "networkx-3.2.1-py3-none-any.whl", hash = "sha256:f18c69adc97877c42332c170849c96cefa91881c99a7cb3e95b7c659ebdc1ec2"}, + {file = "networkx-3.2.1.tar.gz", hash = "sha256:9f1bb5cf3409bf324e0a722c20bdb4c20ee39bf1c30ce8ae499c8502b0b5e0c6"}, +] + +[package.extras] +default = ["matplotlib (>=3.5)", "numpy (>=1.22)", "pandas (>=1.4)", "scipy (>=1.9,!=1.11.0,!=1.11.1)"] +developer = ["changelist (==0.4)", "mypy (>=1.1)", "pre-commit (>=3.2)", "rtoml"] +doc = ["nb2plots (>=0.7)", "nbconvert (<7.9)", "numpydoc (>=1.6)", "pillow (>=9.4)", "pydata-sphinx-theme (>=0.14)", "sphinx (>=7)", "sphinx-gallery (>=0.14)", "texext (>=0.6.7)"] +extra = ["lxml (>=4.6)", "pydot (>=1.4.2)", "pygraphviz (>=1.11)", "sympy (>=1.10)"] +test = ["pytest (>=7.2)", "pytest-cov (>=4.0)"] + [[package]] name = "nltk" version = "3.8.1" @@ -1461,6 +1590,147 @@ files = [ {file = "numpy-1.25.2.tar.gz", hash = "sha256:fd608e19c8d7c55021dffd43bfe5492fab8cc105cc8986f813f8c3c048b38760"}, ] +[[package]] +name = "nvidia-cublas-cu12" +version = "12.1.3.1" +description = "CUBLAS native runtime libraries" +optional = true +python-versions = ">=3" +files = [ + {file = "nvidia_cublas_cu12-12.1.3.1-py3-none-manylinux1_x86_64.whl", hash = "sha256:ee53ccca76a6fc08fb9701aa95b6ceb242cdaab118c3bb152af4e579af792728"}, + {file = "nvidia_cublas_cu12-12.1.3.1-py3-none-win_amd64.whl", hash = "sha256:2b964d60e8cf11b5e1073d179d85fa340c120e99b3067558f3cf98dd69d02906"}, +] + +[[package]] +name = "nvidia-cuda-cupti-cu12" +version = "12.1.105" +description = "CUDA profiling tools runtime libs." +optional = true +python-versions = ">=3" +files = [ + {file = "nvidia_cuda_cupti_cu12-12.1.105-py3-none-manylinux1_x86_64.whl", hash = "sha256:e54fde3983165c624cb79254ae9818a456eb6e87a7fd4d56a2352c24ee542d7e"}, + {file = "nvidia_cuda_cupti_cu12-12.1.105-py3-none-win_amd64.whl", hash = "sha256:bea8236d13a0ac7190bd2919c3e8e6ce1e402104276e6f9694479e48bb0eb2a4"}, +] + +[[package]] +name = "nvidia-cuda-nvrtc-cu12" +version = "12.1.105" +description = "NVRTC native runtime libraries" +optional = true +python-versions = ">=3" +files = [ + {file = "nvidia_cuda_nvrtc_cu12-12.1.105-py3-none-manylinux1_x86_64.whl", hash = "sha256:339b385f50c309763ca65456ec75e17bbefcbbf2893f462cb8b90584cd27a1c2"}, + {file = "nvidia_cuda_nvrtc_cu12-12.1.105-py3-none-win_amd64.whl", hash = "sha256:0a98a522d9ff138b96c010a65e145dc1b4850e9ecb75a0172371793752fd46ed"}, +] + +[[package]] +name = "nvidia-cuda-runtime-cu12" +version = "12.1.105" +description = "CUDA Runtime native Libraries" +optional = true +python-versions = ">=3" +files = [ + {file = "nvidia_cuda_runtime_cu12-12.1.105-py3-none-manylinux1_x86_64.whl", hash = "sha256:6e258468ddf5796e25f1dc591a31029fa317d97a0a94ed93468fc86301d61e40"}, + {file = "nvidia_cuda_runtime_cu12-12.1.105-py3-none-win_amd64.whl", hash = "sha256:dfb46ef84d73fababab44cf03e3b83f80700d27ca300e537f85f636fac474344"}, +] + +[[package]] +name = "nvidia-cudnn-cu12" +version = "8.9.2.26" +description = "cuDNN runtime libraries" +optional = true +python-versions = ">=3" +files = [ + {file = "nvidia_cudnn_cu12-8.9.2.26-py3-none-manylinux1_x86_64.whl", hash = "sha256:5ccb288774fdfb07a7e7025ffec286971c06d8d7b4fb162525334616d7629ff9"}, +] + +[package.dependencies] +nvidia-cublas-cu12 = "*" + +[[package]] +name = "nvidia-cufft-cu12" +version = "11.0.2.54" +description = "CUFFT native runtime libraries" +optional = true +python-versions = ">=3" +files = [ + {file = "nvidia_cufft_cu12-11.0.2.54-py3-none-manylinux1_x86_64.whl", hash = "sha256:794e3948a1aa71fd817c3775866943936774d1c14e7628c74f6f7417224cdf56"}, + {file = "nvidia_cufft_cu12-11.0.2.54-py3-none-win_amd64.whl", hash = "sha256:d9ac353f78ff89951da4af698f80870b1534ed69993f10a4cf1d96f21357e253"}, +] + +[[package]] +name = "nvidia-curand-cu12" +version = "10.3.2.106" +description = "CURAND native runtime libraries" +optional = true +python-versions = ">=3" +files = [ + {file = "nvidia_curand_cu12-10.3.2.106-py3-none-manylinux1_x86_64.whl", hash = "sha256:9d264c5036dde4e64f1de8c50ae753237c12e0b1348738169cd0f8a536c0e1e0"}, + {file = "nvidia_curand_cu12-10.3.2.106-py3-none-win_amd64.whl", hash = "sha256:75b6b0c574c0037839121317e17fd01f8a69fd2ef8e25853d826fec30bdba74a"}, +] + +[[package]] +name = "nvidia-cusolver-cu12" +version = "11.4.5.107" +description = "CUDA solver native runtime libraries" +optional = true +python-versions = ">=3" +files = [ + {file = "nvidia_cusolver_cu12-11.4.5.107-py3-none-manylinux1_x86_64.whl", hash = "sha256:8a7ec542f0412294b15072fa7dab71d31334014a69f953004ea7a118206fe0dd"}, + {file = "nvidia_cusolver_cu12-11.4.5.107-py3-none-win_amd64.whl", hash = "sha256:74e0c3a24c78612192a74fcd90dd117f1cf21dea4822e66d89e8ea80e3cd2da5"}, +] + +[package.dependencies] +nvidia-cublas-cu12 = "*" +nvidia-cusparse-cu12 = "*" +nvidia-nvjitlink-cu12 = "*" + +[[package]] +name = "nvidia-cusparse-cu12" +version = "12.1.0.106" +description = "CUSPARSE native runtime libraries" +optional = true +python-versions = ">=3" +files = [ + {file = "nvidia_cusparse_cu12-12.1.0.106-py3-none-manylinux1_x86_64.whl", hash = "sha256:f3b50f42cf363f86ab21f720998517a659a48131e8d538dc02f8768237bd884c"}, + {file = "nvidia_cusparse_cu12-12.1.0.106-py3-none-win_amd64.whl", hash = "sha256:b798237e81b9719373e8fae8d4f091b70a0cf09d9d85c95a557e11df2d8e9a5a"}, +] + +[package.dependencies] +nvidia-nvjitlink-cu12 = "*" + +[[package]] +name = "nvidia-nccl-cu12" +version = "2.18.1" +description = "NVIDIA Collective Communication Library (NCCL) Runtime" +optional = true +python-versions = ">=3" +files = [ + {file = "nvidia_nccl_cu12-2.18.1-py3-none-manylinux1_x86_64.whl", hash = "sha256:1a6c4acefcbebfa6de320f412bf7866de856e786e0462326ba1bac40de0b5e71"}, +] + +[[package]] +name = "nvidia-nvjitlink-cu12" +version = "12.3.101" +description = "Nvidia JIT LTO Library" +optional = true +python-versions = ">=3" +files = [ + {file = "nvidia_nvjitlink_cu12-12.3.101-py3-none-manylinux1_x86_64.whl", hash = "sha256:64335a8088e2b9d196ae8665430bc6a2b7e6ef2eb877a9c735c804bd4ff6467c"}, + {file = "nvidia_nvjitlink_cu12-12.3.101-py3-none-win_amd64.whl", hash = "sha256:1b2e317e437433753530792f13eece58f0aec21a2b05903be7bffe58a606cbd1"}, +] + +[[package]] +name = "nvidia-nvtx-cu12" +version = "12.1.105" +description = "NVIDIA Tools Extension" +optional = true +python-versions = ">=3" +files = [ + {file = "nvidia_nvtx_cu12-12.1.105-py3-none-manylinux1_x86_64.whl", hash = "sha256:dc21cf308ca5691e7c04d962e213f8a4aa9bbfa23d95412f452254c2caeb09e5"}, + {file = "nvidia_nvtx_cu12-12.1.105-py3-none-win_amd64.whl", hash = "sha256:65f4d98982b31b60026e0e6de73fbdfc09d08a96f4656dd3665ca616a11e1e82"}, +] + [[package]] name = "onnx" version = "1.15.0" @@ -1545,13 +1815,13 @@ sympy = "*" [[package]] name = "openai" -version = "1.6.1" +version = "1.7.0" description = "The official Python library for the openai API" optional = false python-versions = ">=3.7.1" files = [ - {file = "openai-1.6.1-py3-none-any.whl", hash = "sha256:bc9f774838d67ac29fb24cdeb2d58faf57de8b311085dcd1348f7aa02a96c7ee"}, - {file = "openai-1.6.1.tar.gz", hash = "sha256:d553ca9dbf9486b08e75b09e8671e4f638462aaadccfced632bf490fc3d75fa2"}, + {file = "openai-1.7.0-py3-none-any.whl", hash = "sha256:2282e8e15acb05df79cccba330c025b8e84284c7ec1f3fa31f167a8479066333"}, + {file = "openai-1.7.0.tar.gz", hash = "sha256:f2a8dcb739e8620c9318a2c6304ea72aebb572ba02fa1d586344405e80d567d3"}, ] [package.dependencies] @@ -1835,6 +2105,25 @@ files = [ plugins = ["importlib-metadata"] windows-terminal = ["colorama (>=0.4.6)"] +[[package]] +name = "pyproject-api" +version = "1.6.1" +description = "API to interact with the python pyproject.toml based projects" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pyproject_api-1.6.1-py3-none-any.whl", hash = "sha256:4c0116d60476b0786c88692cf4e325a9814965e2469c5998b830bba16b183675"}, + {file = "pyproject_api-1.6.1.tar.gz", hash = "sha256:1817dc018adc0d1ff9ca1ed8c60e1623d5aaca40814b953af14a9cf9a5cae538"}, +] + +[package.dependencies] +packaging = ">=23.1" +tomli = {version = ">=2.0.1", markers = "python_version < \"3.11\""} + +[package.extras] +docs = ["furo (>=2023.8.19)", "sphinx (<7.2)", "sphinx-autodoc-typehints (>=1.24)"] +testing = ["covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)", "setuptools (>=68.1.2)", "wheel (>=0.41.2)"] + [[package]] name = "pyreadline3" version = "3.4.1" @@ -1972,7 +2261,6 @@ files = [ {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, - {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, @@ -1980,15 +2268,8 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, - {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, - {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, - {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, - {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, @@ -2005,7 +2286,6 @@ files = [ {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, - {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, @@ -2013,7 +2293,6 @@ files = [ {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, - {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, @@ -2273,6 +2552,125 @@ files = [ {file = "ruff-0.1.11.tar.gz", hash = "sha256:f9d4d88cb6eeb4dfe20f9f0519bd2eaba8119bde87c3d5065c541dbae2b5a2cb"}, ] +[[package]] +name = "safetensors" +version = "0.4.1" +description = "" +optional = true +python-versions = ">=3.7" +files = [ + {file = "safetensors-0.4.1-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:cba01c6b76e01ec453933b3b3c0157c59b52881c83eaa0f7666244e71aa75fd1"}, + {file = "safetensors-0.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:7a8f6f679d97ea0135c7935c202feefbd042c149aa70ee759855e890c01c7814"}, + {file = "safetensors-0.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bbc2ce1f5ae5143a7fb72b71fa71db6a42b4f6cf912aa3acdc6b914084778e68"}, + {file = "safetensors-0.4.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2d87d993eaefe6611a9c241a8bd364a5f1ffed5771c74840363a6c4ed8d868f6"}, + {file = "safetensors-0.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:097e9af2efa8778cd2f0cba451784253e62fa7cc9fc73c0744d27212f7294e25"}, + {file = "safetensors-0.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d10a9f7bae608ccfdc009351f01dc3d8535ff57f9488a58a4c38e45bf954fe93"}, + {file = "safetensors-0.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:270b99885ec14abfd56c1d7f28ada81740a9220b4bae960c3de1c6fe84af9e4d"}, + {file = "safetensors-0.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:285b52a481e7ba93e29ad4ec5841ef2c4479ef0a6c633c4e2629e0508453577b"}, + {file = "safetensors-0.4.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:c3c9f0ca510e0de95abd6424789dcbc879942a3a4e29b0dfa99d9427bf1da75c"}, + {file = "safetensors-0.4.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:88b4653059c903015284a9722f9a46838c654257173b279c8f6f46dbe80b612d"}, + {file = "safetensors-0.4.1-cp310-none-win32.whl", hash = "sha256:2fe6926110e3d425c4b684a4379b7796fdc26ad7d16922ea1696c8e6ea7e920f"}, + {file = "safetensors-0.4.1-cp310-none-win_amd64.whl", hash = "sha256:a79e16222106b2f5edbca1b8185661477d8971b659a3c814cc6f15181a9b34c8"}, + {file = "safetensors-0.4.1-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:d93321eea0dd7e81b283e47a1d20dee6069165cc158286316d0d06d340de8fe8"}, + {file = "safetensors-0.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8ff8e41c8037db17de0ea2a23bc684f43eaf623be7d34906fe1ac10985b8365e"}, + {file = "safetensors-0.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39d36f1d88468a87c437a1bc27c502e71b6ca44c385a9117a9f9ba03a75cc9c6"}, + {file = "safetensors-0.4.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7ef010e9afcb4057fb6be3d0a0cfa07aac04fe97ef73fe4a23138d8522ba7c17"}, + {file = "safetensors-0.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b287304f2b2220d51ccb51fd857761e78bcffbeabe7b0238f8dc36f2edfd9542"}, + {file = "safetensors-0.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e09000b2599e1836314430f81a3884c66a5cbabdff5d9f175b5d560d4de38d78"}, + {file = "safetensors-0.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9c80ce0001efa16066358d2dd77993adc25f5a6c61850e4ad096a2232930bce"}, + {file = "safetensors-0.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:413e1f6ac248f7d1b755199a06635e70c3515493d3b41ba46063dec33aa2ebb7"}, + {file = "safetensors-0.4.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d3ac139377cfe71ba04573f1cda66e663b7c3e95be850e9e6c2dd4b5984bd513"}, + {file = "safetensors-0.4.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:04157d008385bea66d12fe90844a80d4a76dc25ec5230b5bd9a630496d1b7c03"}, + {file = "safetensors-0.4.1-cp311-none-win32.whl", hash = "sha256:5f25297148ec665f0deb8bd67e9564634d8d6841041ab5393ccfe203379ea88b"}, + {file = "safetensors-0.4.1-cp311-none-win_amd64.whl", hash = "sha256:b2f8877990a72ff595507b80f4b69036a9a1986a641f8681adf3425d97d3d2a5"}, + {file = "safetensors-0.4.1-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:eb2c1da1cc39509d1a55620a5f4d14f8911c47a89c926a96e6f4876e864375a3"}, + {file = "safetensors-0.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:303d2c0415cf15a28f8d7f17379ea3c34c2b466119118a34edd9965983a1a8a6"}, + {file = "safetensors-0.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb4cb3e37a9b961ddd68e873b29fe9ab4a081e3703412e34aedd2b7a8e9cafd9"}, + {file = "safetensors-0.4.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ae5497adc68669db2fed7cb2dad81e6a6106e79c9a132da3efdb6af1db1014fa"}, + {file = "safetensors-0.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b30abd0cddfe959d1daedf92edcd1b445521ebf7ddefc20860ed01486b33c90"}, + {file = "safetensors-0.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d784a98c492c751f228a4a894c3b8a092ff08b24e73b5568938c28b8c0e8f8df"}, + {file = "safetensors-0.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e57a5ab08b0ec7a7caf30d2ac79bb30c89168431aca4f8854464bb9461686925"}, + {file = "safetensors-0.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:edcf3121890b5f0616aa5a54683b1a5d2332037b970e507d6bb7841a3a596556"}, + {file = "safetensors-0.4.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:fdb58dee173ef33634c3016c459d671ca12d11e6acf9db008261cbe58107e579"}, + {file = "safetensors-0.4.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:780dc21eb3fd32ddd0e8c904bdb0290f2454f4ac21ae71e94f9ce72db1900a5a"}, + {file = "safetensors-0.4.1-cp37-cp37m-macosx_10_7_x86_64.whl", hash = "sha256:48901bd540f8a3c1791314bc5c8a170927bf7f6acddb75bf0a263d081a3637d4"}, + {file = "safetensors-0.4.1-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:3b0b7b2d5976fbed8a05e2bbdce5816a59e6902e9e7c7e07dc723637ed539787"}, + {file = "safetensors-0.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f69903ff49cb30b9227fb5d029bea276ea20d04b06803877a420c5b1b74c689"}, + {file = "safetensors-0.4.1-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0ddd050e01f3e843aa8c1c27bf68675b8a08e385d0045487af4d70418c3cb356"}, + {file = "safetensors-0.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9a82bc2bd7a9a0e08239bdd6d7774d64121f136add93dfa344a2f1a6d7ef35fa"}, + {file = "safetensors-0.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6ace9e66a40f98a216ad661245782483cf79cf56eb2b112650bb904b0baa9db5"}, + {file = "safetensors-0.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82cbb8f4d022f2e94498cbefca900698b8ded3d4f85212f47da614001ff06652"}, + {file = "safetensors-0.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:791edc10a3c359a2f5f52d5cddab0df8a45107d91027d86c3d44e57162e5d934"}, + {file = "safetensors-0.4.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:83c2cfbe8c6304f0891e7bb378d56f66d2148972eeb5f747cd8a2246886f0d8c"}, + {file = "safetensors-0.4.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:04dd14f53f5500eb4c4149674216ba1000670efbcf4b1b5c2643eb244e7882ea"}, + {file = "safetensors-0.4.1-cp37-none-win32.whl", hash = "sha256:d5b3defa74f3723a388bfde2f5d488742bc4879682bd93267c09a3bcdf8f869b"}, + {file = "safetensors-0.4.1-cp37-none-win_amd64.whl", hash = "sha256:25a043cbb59d4f75e9dd87fdf5c009dd8830105a2c57ace49b72167dd9808111"}, + {file = "safetensors-0.4.1-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:3f6a520af7f2717c5ecba112041f2c8af1ca6480b97bf957aba81ed9642e654c"}, + {file = "safetensors-0.4.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c3807ac3b16288dffebb3474b555b56fe466baa677dfc16290dcd02dca1ab228"}, + {file = "safetensors-0.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b58ba13a9e82b4bc3fc221914f6ef237fe6c2adb13cede3ace64d1aacf49610"}, + {file = "safetensors-0.4.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dac4bb42f8679aadc59bd91a4c5a1784a758ad49d0912995945cd674089f628e"}, + {file = "safetensors-0.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:911b48dc09e321a194def3a7431662ff4f03646832f3a8915bbf0f449b8a5fcb"}, + {file = "safetensors-0.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:82571d20288c975c1b30b08deb9b1c3550f36b31191e1e81fae87669a92217d0"}, + {file = "safetensors-0.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da52ee0dc8ba03348ffceab767bd8230842fdf78f8a996e2a16445747143a778"}, + {file = "safetensors-0.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2536b11ce665834201072e9397404170f93f3be10cca9995b909f023a04501ee"}, + {file = "safetensors-0.4.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:998fbac99ca956c3a09fe07cc0b35fac26a521fa8865a690686d889f0ff4e4a6"}, + {file = "safetensors-0.4.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:845be0aafabf2a60c2d482d4e93023fecffe5e5443d801d7a7741bae9de41233"}, + {file = "safetensors-0.4.1-cp38-none-win32.whl", hash = "sha256:ce7a28bc8af685a69d7e869d09d3e180a275e3281e29cf5f1c7319e231932cc7"}, + {file = "safetensors-0.4.1-cp38-none-win_amd64.whl", hash = "sha256:e056fb9e22d118cc546107f97dc28b449d88274207dd28872bd668c86216e4f6"}, + {file = "safetensors-0.4.1-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:bdc0d039e44a727824639824090bd8869535f729878fa248addd3dc01db30eae"}, + {file = "safetensors-0.4.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3c1b1d510c7aba71504ece87bf393ea82638df56303e371e5e2cf09d18977dd7"}, + {file = "safetensors-0.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bd0afd95c1e497f520e680ea01e0397c0868a3a3030e128438cf6e9e3fcd671"}, + {file = "safetensors-0.4.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f603bdd8deac6726d39f41688ed353c532dd53935234405d79e9eb53f152fbfb"}, + {file = "safetensors-0.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d8a85e3e47e0d4eebfaf9a58b40aa94f977a56050cb5598ad5396a9ee7c087c6"}, + {file = "safetensors-0.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e0ccb5aa0f3be2727117e5631200fbb3a5b3a2b3757545a92647d6dd8be6658f"}, + {file = "safetensors-0.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d784938534e255473155e4d9f276ee69eb85455b6af1292172c731409bf9adee"}, + {file = "safetensors-0.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a257de175c254d39ccd6a21341cd62eb7373b05c1e618a78096a56a857e0c316"}, + {file = "safetensors-0.4.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:6fd80f7794554091836d4d613d33a7d006e2b8d6ba014d06f97cebdfda744f64"}, + {file = "safetensors-0.4.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:35803201d980efcf964b75a0a2aee97fe5e9ecc5f3ad676b38fafdfe98e0620d"}, + {file = "safetensors-0.4.1-cp39-none-win32.whl", hash = "sha256:7ff8a36e0396776d3ed9a106fc9a9d7c55d4439ca9a056a24bf66d343041d3e6"}, + {file = "safetensors-0.4.1-cp39-none-win_amd64.whl", hash = "sha256:bfa2e20342b81921b98edba52f8deb68843fa9c95250739a56b52ceda5ea5c61"}, + {file = "safetensors-0.4.1-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:ae2d5a31cfb8a973a318f7c4d2cffe0bd1fe753cdf7bb41a1939d45a0a06f964"}, + {file = "safetensors-0.4.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1a45dbf03e8334d3a5dc93687d98b6dc422f5d04c7d519dac09b84a3c87dd7c6"}, + {file = "safetensors-0.4.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2297b359d91126c0f9d4fd17bae3cfa2fe3a048a6971b8db07db746ad92f850c"}, + {file = "safetensors-0.4.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bda3d98e2bcece388232cfc551ebf063b55bdb98f65ab54df397da30efc7dcc5"}, + {file = "safetensors-0.4.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f8934bdfd202ebd0697040a3dff40dd77bc4c5bbf3527ede0532f5e7fb4d970f"}, + {file = "safetensors-0.4.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:42c3710cec7e5c764c7999697516370bee39067de0aa089b7e2cfb97ac8c6b20"}, + {file = "safetensors-0.4.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:53134226053e56bd56e73f7db42596e7908ed79f3c9a1016e4c1dade593ac8e5"}, + {file = "safetensors-0.4.1-pp37-pypy37_pp73-macosx_10_7_x86_64.whl", hash = "sha256:257d59e40a1b367cb544122e7451243d65b33c3f34d822a347f4eea6fdf97fdf"}, + {file = "safetensors-0.4.1-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d54c2f1826e790d1eb2d2512bfd0ee443f0206b423d6f27095057c7f18a0687"}, + {file = "safetensors-0.4.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:645b3f1138fce6e818e79d4128afa28f0657430764cc045419c1d069ff93f732"}, + {file = "safetensors-0.4.1-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e9a7ffb1e551c6df51d267f5a751f042b183df22690f6feceac8d27364fd51d7"}, + {file = "safetensors-0.4.1-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:44e230fbbe120de564b64f63ef3a8e6ff02840fa02849d9c443d56252a1646d4"}, + {file = "safetensors-0.4.1-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:9d16b3b2fcc6fca012c74bd01b5619c655194d3e3c13e4d4d0e446eefa39a463"}, + {file = "safetensors-0.4.1-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:5d95ea4d8b32233910734a904123bdd3979c137c461b905a5ed32511defc075f"}, + {file = "safetensors-0.4.1-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:dab431699b5d45e0ca043bc580651ce9583dda594e62e245b7497adb32e99809"}, + {file = "safetensors-0.4.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:16d8bbb7344e39cb9d4762e85c21df94ebeb03edac923dd94bb9ed8c10eac070"}, + {file = "safetensors-0.4.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1faf5111c66a6ba91f85dff2e36edaaf36e6966172703159daeef330de4ddc7b"}, + {file = "safetensors-0.4.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:660ca1d8bff6c7bc7c6b30b9b32df74ef3ab668f5df42cefd7588f0d40feadcb"}, + {file = "safetensors-0.4.1-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:ae2f67f04ed0bb2e56fd380a8bd3eef03f609df53f88b6f5c7e89c08e52aae00"}, + {file = "safetensors-0.4.1-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:c8ed5d2c04cdc1afc6b3c28d59580448ac07732c50d94c15e14670f9c473a2ce"}, + {file = "safetensors-0.4.1-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:2b6a2814278b6660261aa9a9aae524616de9f1ec364e3716d219b6ed8f91801f"}, + {file = "safetensors-0.4.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:3cfd1ca35eacc635f0eaa894e5c5ed83ffebd0f95cac298fd430014fa7323631"}, + {file = "safetensors-0.4.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4177b456c6b0c722d82429127b5beebdaf07149d265748e97e0a34ff0b3694c8"}, + {file = "safetensors-0.4.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:313e8472197bde54e3ec54a62df184c414582979da8f3916981b6a7954910a1b"}, + {file = "safetensors-0.4.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fdb4adb76e21bad318210310590de61c9f4adcef77ee49b4a234f9dc48867869"}, + {file = "safetensors-0.4.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:1d568628e9c43ca15eb96c217da73737c9ccb07520fafd8a1eba3f2750614105"}, + {file = "safetensors-0.4.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:573b6023a55a2f28085fc0a84e196c779b6cbef4d9e73acea14c8094fee7686f"}, + {file = "safetensors-0.4.1.tar.gz", hash = "sha256:2304658e6ada81a5223225b4efe84748e760c46079bffedf7e321763cafb36c9"}, +] + +[package.extras] +all = ["safetensors[jax]", "safetensors[numpy]", "safetensors[paddlepaddle]", "safetensors[pinned-tf]", "safetensors[quality]", "safetensors[testing]", "safetensors[torch]"] +dev = ["safetensors[all]"] +jax = ["flax (>=0.6.3)", "jax (>=0.3.25)", "jaxlib (>=0.3.25)", "safetensors[numpy]"] +numpy = ["numpy (>=1.21.6)"] +paddlepaddle = ["paddlepaddle (>=2.4.1)", "safetensors[numpy]"] +pinned-tf = ["safetensors[numpy]", "tensorflow (==2.11.0)"] +quality = ["black (==22.3)", "click (==8.0.4)", "flake8 (>=3.8.3)", "isort (>=5.5.4)"] +tensorflow = ["safetensors[numpy]", "tensorflow (>=2.11.0)"] +testing = ["h5py (>=3.7.0)", "huggingface_hub (>=0.12.1)", "hypothesis (>=6.70.2)", "pytest (>=7.2.0)", "pytest-benchmark (>=4.0.0)", "safetensors[numpy]", "setuptools_rust (>=1.5.2)"] +torch = ["safetensors[numpy]", "torch (>=1.10)"] + [[package]] name = "six" version = "1.16.0" @@ -2465,6 +2863,59 @@ files = [ {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, ] +[[package]] +name = "torch" +version = "2.1.2" +description = "Tensors and Dynamic neural networks in Python with strong GPU acceleration" +optional = true +python-versions = ">=3.8.0" +files = [ + {file = "torch-2.1.2-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:3a871edd6c02dae77ad810335c0833391c1a4ce49af21ea8cf0f6a5d2096eea8"}, + {file = "torch-2.1.2-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:bef6996c27d8f6e92ea4e13a772d89611da0e103b48790de78131e308cf73076"}, + {file = "torch-2.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:0e13034fd5fb323cbbc29e56d0637a3791e50dd589616f40c79adfa36a5a35a1"}, + {file = "torch-2.1.2-cp310-none-macosx_10_9_x86_64.whl", hash = "sha256:d9b535cad0df3d13997dbe8bd68ac33e0e3ae5377639c9881948e40794a61403"}, + {file = "torch-2.1.2-cp310-none-macosx_11_0_arm64.whl", hash = "sha256:f9a55d55af02826ebfbadf4e9b682f0f27766bc33df8236b48d28d705587868f"}, + {file = "torch-2.1.2-cp311-cp311-manylinux1_x86_64.whl", hash = "sha256:a6ebbe517097ef289cc7952783588c72de071d4b15ce0f8b285093f0916b1162"}, + {file = "torch-2.1.2-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:8f32ce591616a30304f37a7d5ea80b69ca9e1b94bba7f308184bf616fdaea155"}, + {file = "torch-2.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:e0ee6cf90c8970e05760f898d58f9ac65821c37ffe8b04269ec787aa70962b69"}, + {file = "torch-2.1.2-cp311-none-macosx_10_9_x86_64.whl", hash = "sha256:76d37967c31c99548ad2c4d3f2cf191db48476f2e69b35a0937137116da356a1"}, + {file = "torch-2.1.2-cp311-none-macosx_11_0_arm64.whl", hash = "sha256:e2d83f07b4aac983453ea5bf8f9aa9dacf2278a8d31247f5d9037f37befc60e4"}, + {file = "torch-2.1.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:f41fe0c7ecbf903a568c73486139a75cfab287a0f6c17ed0698fdea7a1e8641d"}, + {file = "torch-2.1.2-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:e3225f47d50bb66f756fe9196a768055d1c26b02154eb1f770ce47a2578d3aa7"}, + {file = "torch-2.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:33d59cd03cb60106857f6c26b36457793637512998666ee3ce17311f217afe2b"}, + {file = "torch-2.1.2-cp38-none-macosx_10_9_x86_64.whl", hash = "sha256:8e221deccd0def6c2badff6be403e0c53491805ed9915e2c029adbcdb87ab6b5"}, + {file = "torch-2.1.2-cp38-none-macosx_11_0_arm64.whl", hash = "sha256:05b18594f60a911a0c4f023f38a8bda77131fba5fd741bda626e97dcf5a3dd0a"}, + {file = "torch-2.1.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:9ca96253b761e9aaf8e06fb30a66ee301aecbf15bb5a303097de1969077620b6"}, + {file = "torch-2.1.2-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:d93ba70f67b08c2ae5598ee711cbc546a1bc8102cef938904b8c85c2089a51a0"}, + {file = "torch-2.1.2-cp39-cp39-win_amd64.whl", hash = "sha256:255b50bc0608db177e6a3cc118961d77de7e5105f07816585fa6f191f33a9ff3"}, + {file = "torch-2.1.2-cp39-none-macosx_10_9_x86_64.whl", hash = "sha256:6984cd5057c0c977b3c9757254e989d3f1124f4ce9d07caa6cb637783c71d42a"}, + {file = "torch-2.1.2-cp39-none-macosx_11_0_arm64.whl", hash = "sha256:bc195d7927feabc0eb7c110e457c955ed2ab616f3c7c28439dd4188cf589699f"}, +] + +[package.dependencies] +filelock = "*" +fsspec = "*" +jinja2 = "*" +networkx = "*" +nvidia-cublas-cu12 = {version = "12.1.3.1", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} +nvidia-cuda-cupti-cu12 = {version = "12.1.105", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} +nvidia-cuda-nvrtc-cu12 = {version = "12.1.105", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} +nvidia-cuda-runtime-cu12 = {version = "12.1.105", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} +nvidia-cudnn-cu12 = {version = "8.9.2.26", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} +nvidia-cufft-cu12 = {version = "11.0.2.54", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} +nvidia-curand-cu12 = {version = "10.3.2.106", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} +nvidia-cusolver-cu12 = {version = "11.4.5.107", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} +nvidia-cusparse-cu12 = {version = "12.1.0.106", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} +nvidia-nccl-cu12 = {version = "2.18.1", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} +nvidia-nvtx-cu12 = {version = "12.1.105", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} +sympy = "*" +triton = {version = "2.1.0", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} +typing-extensions = "*" + +[package.extras] +dynamo = ["jinja2"] +opt-einsum = ["opt-einsum (>=3.3)"] + [[package]] name = "tornado" version = "6.4" @@ -2485,6 +2936,33 @@ files = [ {file = "tornado-6.4.tar.gz", hash = "sha256:72291fa6e6bc84e626589f1c29d90a5a6d593ef5ae68052ee2ef000dfd273dee"}, ] +[[package]] +name = "tox" +version = "4.11.4" +description = "tox is a generic virtualenv management and test command line tool" +optional = false +python-versions = ">=3.8" +files = [ + {file = "tox-4.11.4-py3-none-any.whl", hash = "sha256:2adb83d68f27116812b69aa36676a8d6a52249cb0d173649de0e7d0c2e3e7229"}, + {file = "tox-4.11.4.tar.gz", hash = "sha256:73a7240778fabf305aeb05ab8ea26e575e042ab5a18d71d0ed13e343a51d6ce1"}, +] + +[package.dependencies] +cachetools = ">=5.3.1" +chardet = ">=5.2" +colorama = ">=0.4.6" +filelock = ">=3.12.3" +packaging = ">=23.1" +platformdirs = ">=3.10" +pluggy = ">=1.3" +pyproject-api = ">=1.6.1" +tomli = {version = ">=2.0.1", markers = "python_version < \"3.11\""} +virtualenv = ">=20.24.3" + +[package.extras] +docs = ["furo (>=2023.8.19)", "sphinx (>=7.2.4)", "sphinx-argparse-cli (>=1.11.1)", "sphinx-autodoc-typehints (>=1.24)", "sphinx-copybutton (>=0.5.2)", "sphinx-inline-tabs (>=2023.4.21)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] +testing = ["build[virtualenv] (>=0.10)", "covdefaults (>=2.3)", "detect-test-pollution (>=1.1.1)", "devpi-process (>=1)", "diff-cover (>=7.7)", "distlib (>=0.3.7)", "flaky (>=3.7)", "hatch-vcs (>=0.3)", "hatchling (>=1.18)", "psutil (>=5.9.5)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)", "pytest-xdist (>=3.3.1)", "re-assert (>=1.1)", "time-machine (>=2.12)", "wheel (>=0.41.2)"] + [[package]] name = "tqdm" version = "4.66.1" @@ -2520,6 +2998,99 @@ files = [ docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] test = ["argcomplete (>=3.0.3)", "mypy (>=1.7.0)", "pre-commit", "pytest (>=7.0,<7.5)", "pytest-mock", "pytest-mypy-testing"] +[[package]] +name = "transformers" +version = "4.36.2" +description = "State-of-the-art Machine Learning for JAX, PyTorch and TensorFlow" +optional = true +python-versions = ">=3.8.0" +files = [ + {file = "transformers-4.36.2-py3-none-any.whl", hash = "sha256:462066c4f74ee52516f12890dcc9ec71d1a5e97998db621668455117a54330f6"}, + {file = "transformers-4.36.2.tar.gz", hash = "sha256:d8068e897e47793281501e547d2bbdfc5b8556409c2cb6c3d9e2ca77d4c0b4ec"}, +] + +[package.dependencies] +filelock = "*" +huggingface-hub = ">=0.19.3,<1.0" +numpy = ">=1.17" +packaging = ">=20.0" +pyyaml = ">=5.1" +regex = "!=2019.12.17" +requests = "*" +safetensors = ">=0.3.1" +tokenizers = ">=0.14,<0.19" +tqdm = ">=4.27" + +[package.extras] +accelerate = ["accelerate (>=0.21.0)"] +agents = ["Pillow (>=10.0.1,<=15.0)", "accelerate (>=0.21.0)", "datasets (!=2.5.0)", "diffusers", "opencv-python", "sentencepiece (>=0.1.91,!=0.1.92)", "torch (>=1.10,!=1.12.0)"] +all = ["Pillow (>=10.0.1,<=15.0)", "accelerate (>=0.21.0)", "av (==9.2.0)", "codecarbon (==1.2.0)", "decord (==0.6.0)", "flax (>=0.4.1,<=0.7.0)", "jax (>=0.4.1,<=0.4.13)", "jaxlib (>=0.4.1,<=0.4.13)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "onnxconverter-common", "optax (>=0.0.8,<=0.1.4)", "optuna", "phonemizer", "protobuf", "pyctcdecode (>=0.4.0)", "ray[tune] (>=2.7.0)", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "tensorflow (>=2.6,<2.16)", "tensorflow-text (<2.16)", "tf2onnx", "timm", "tokenizers (>=0.14,<0.19)", "torch (>=1.10,!=1.12.0)", "torchaudio", "torchvision"] +audio = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)"] +codecarbon = ["codecarbon (==1.2.0)"] +deepspeed = ["accelerate (>=0.21.0)", "deepspeed (>=0.9.3)"] +deepspeed-testing = ["GitPython (<3.1.19)", "accelerate (>=0.21.0)", "beautifulsoup4", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "deepspeed (>=0.9.3)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "hf-doc-builder (>=0.3.0)", "nltk", "optuna", "parameterized", "protobuf", "psutil", "pydantic (<2)", "pytest (>=7.2.0)", "pytest-timeout", "pytest-xdist", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (==0.1.5)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "sentencepiece (>=0.1.91,!=0.1.92)", "tensorboard", "timeout-decorator"] +dev = ["GitPython (<3.1.19)", "Pillow (>=10.0.1,<=15.0)", "accelerate (>=0.21.0)", "av (==9.2.0)", "beautifulsoup4", "codecarbon (==1.2.0)", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "decord (==0.6.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "flax (>=0.4.1,<=0.7.0)", "fugashi (>=1.0)", "hf-doc-builder", "hf-doc-builder (>=0.3.0)", "ipadic (>=1.0.0,<2.0)", "isort (>=5.5.4)", "jax (>=0.4.1,<=0.4.13)", "jaxlib (>=0.4.1,<=0.4.13)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "nltk", "onnxconverter-common", "optax (>=0.0.8,<=0.1.4)", "optuna", "parameterized", "phonemizer", "protobuf", "psutil", "pyctcdecode (>=0.4.0)", "pydantic (<2)", "pytest (>=7.2.0)", "pytest-timeout", "pytest-xdist", "ray[tune] (>=2.7.0)", "rhoknp (>=1.1.0,<1.3.1)", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (==0.1.5)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "scikit-learn", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "sudachidict-core (>=20220729)", "sudachipy (>=0.6.6)", "tensorboard", "tensorflow (>=2.6,<2.16)", "tensorflow-text (<2.16)", "tf2onnx", "timeout-decorator", "timm", "tokenizers (>=0.14,<0.19)", "torch (>=1.10,!=1.12.0)", "torchaudio", "torchvision", "unidic (>=1.0.2)", "unidic-lite (>=1.0.7)", "urllib3 (<2.0.0)"] +dev-tensorflow = ["GitPython (<3.1.19)", "Pillow (>=10.0.1,<=15.0)", "beautifulsoup4", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "hf-doc-builder", "hf-doc-builder (>=0.3.0)", "isort (>=5.5.4)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "nltk", "onnxconverter-common", "onnxruntime (>=1.4.0)", "onnxruntime-tools (>=1.4.2)", "parameterized", "phonemizer", "protobuf", "psutil", "pyctcdecode (>=0.4.0)", "pydantic (<2)", "pytest (>=7.2.0)", "pytest-timeout", "pytest-xdist", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (==0.1.5)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "scikit-learn", "sentencepiece (>=0.1.91,!=0.1.92)", "tensorboard", "tensorflow (>=2.6,<2.16)", "tensorflow-text (<2.16)", "tf2onnx", "timeout-decorator", "tokenizers (>=0.14,<0.19)", "urllib3 (<2.0.0)"] +dev-torch = ["GitPython (<3.1.19)", "Pillow (>=10.0.1,<=15.0)", "accelerate (>=0.21.0)", "beautifulsoup4", "codecarbon (==1.2.0)", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "fugashi (>=1.0)", "hf-doc-builder", "hf-doc-builder (>=0.3.0)", "ipadic (>=1.0.0,<2.0)", "isort (>=5.5.4)", "kenlm", "librosa", "nltk", "onnxruntime (>=1.4.0)", "onnxruntime-tools (>=1.4.2)", "optuna", "parameterized", "phonemizer", "protobuf", "psutil", "pyctcdecode (>=0.4.0)", "pydantic (<2)", "pytest (>=7.2.0)", "pytest-timeout", "pytest-xdist", "ray[tune] (>=2.7.0)", "rhoknp (>=1.1.0,<1.3.1)", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (==0.1.5)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "scikit-learn", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "sudachidict-core (>=20220729)", "sudachipy (>=0.6.6)", "tensorboard", "timeout-decorator", "timm", "tokenizers (>=0.14,<0.19)", "torch (>=1.10,!=1.12.0)", "torchaudio", "torchvision", "unidic (>=1.0.2)", "unidic-lite (>=1.0.7)", "urllib3 (<2.0.0)"] +docs = ["Pillow (>=10.0.1,<=15.0)", "accelerate (>=0.21.0)", "av (==9.2.0)", "codecarbon (==1.2.0)", "decord (==0.6.0)", "flax (>=0.4.1,<=0.7.0)", "hf-doc-builder", "jax (>=0.4.1,<=0.4.13)", "jaxlib (>=0.4.1,<=0.4.13)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "onnxconverter-common", "optax (>=0.0.8,<=0.1.4)", "optuna", "phonemizer", "protobuf", "pyctcdecode (>=0.4.0)", "ray[tune] (>=2.7.0)", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "tensorflow (>=2.6,<2.16)", "tensorflow-text (<2.16)", "tf2onnx", "timm", "tokenizers (>=0.14,<0.19)", "torch (>=1.10,!=1.12.0)", "torchaudio", "torchvision"] +docs-specific = ["hf-doc-builder"] +flax = ["flax (>=0.4.1,<=0.7.0)", "jax (>=0.4.1,<=0.4.13)", "jaxlib (>=0.4.1,<=0.4.13)", "optax (>=0.0.8,<=0.1.4)"] +flax-speech = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)"] +ftfy = ["ftfy"] +integrations = ["optuna", "ray[tune] (>=2.7.0)", "sigopt"] +ja = ["fugashi (>=1.0)", "ipadic (>=1.0.0,<2.0)", "rhoknp (>=1.1.0,<1.3.1)", "sudachidict-core (>=20220729)", "sudachipy (>=0.6.6)", "unidic (>=1.0.2)", "unidic-lite (>=1.0.7)"] +modelcreation = ["cookiecutter (==1.7.3)"] +natten = ["natten (>=0.14.6)"] +onnx = ["onnxconverter-common", "onnxruntime (>=1.4.0)", "onnxruntime-tools (>=1.4.2)", "tf2onnx"] +onnxruntime = ["onnxruntime (>=1.4.0)", "onnxruntime-tools (>=1.4.2)"] +optuna = ["optuna"] +quality = ["GitPython (<3.1.19)", "datasets (!=2.5.0)", "hf-doc-builder (>=0.3.0)", "isort (>=5.5.4)", "ruff (==0.1.5)", "urllib3 (<2.0.0)"] +ray = ["ray[tune] (>=2.7.0)"] +retrieval = ["datasets (!=2.5.0)", "faiss-cpu"] +sagemaker = ["sagemaker (>=2.31.0)"] +sentencepiece = ["protobuf", "sentencepiece (>=0.1.91,!=0.1.92)"] +serving = ["fastapi", "pydantic (<2)", "starlette", "uvicorn"] +sigopt = ["sigopt"] +sklearn = ["scikit-learn"] +speech = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)", "torchaudio"] +testing = ["GitPython (<3.1.19)", "beautifulsoup4", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "hf-doc-builder (>=0.3.0)", "nltk", "parameterized", "protobuf", "psutil", "pydantic (<2)", "pytest (>=7.2.0)", "pytest-timeout", "pytest-xdist", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (==0.1.5)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "tensorboard", "timeout-decorator"] +tf = ["keras-nlp (>=0.3.1)", "onnxconverter-common", "tensorflow (>=2.6,<2.16)", "tensorflow-text (<2.16)", "tf2onnx"] +tf-cpu = ["keras-nlp (>=0.3.1)", "onnxconverter-common", "tensorflow-cpu (>=2.6,<2.16)", "tensorflow-text (<2.16)", "tf2onnx"] +tf-speech = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)"] +timm = ["timm"] +tokenizers = ["tokenizers (>=0.14,<0.19)"] +torch = ["accelerate (>=0.21.0)", "torch (>=1.10,!=1.12.0)"] +torch-speech = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)", "torchaudio"] +torch-vision = ["Pillow (>=10.0.1,<=15.0)", "torchvision"] +torchhub = ["filelock", "huggingface-hub (>=0.19.3,<1.0)", "importlib-metadata", "numpy (>=1.17)", "packaging (>=20.0)", "protobuf", "regex (!=2019.12.17)", "requests", "sentencepiece (>=0.1.91,!=0.1.92)", "tokenizers (>=0.14,<0.19)", "torch (>=1.10,!=1.12.0)", "tqdm (>=4.27)"] +video = ["av (==9.2.0)", "decord (==0.6.0)"] +vision = ["Pillow (>=10.0.1,<=15.0)"] + +[[package]] +name = "triton" +version = "2.1.0" +description = "A language and compiler for custom Deep Learning operations" +optional = true +python-versions = "*" +files = [ + {file = "triton-2.1.0-0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:66439923a30d5d48399b08a9eae10370f6c261a5ec864a64983bae63152d39d7"}, + {file = "triton-2.1.0-0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:919b06453f0033ea52c13eaf7833de0e57db3178d23d4e04f9fc71c4f2c32bf8"}, + {file = "triton-2.1.0-0-cp37-cp37m-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ae4bb8a91de790e1866405211c4d618379781188f40d5c4c399766914e84cd94"}, + {file = "triton-2.1.0-0-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:39f6fb6bdccb3e98f3152e3fbea724f1aeae7d749412bbb1fa9c441d474eba26"}, + {file = "triton-2.1.0-0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:21544e522c02005a626c8ad63d39bdff2f31d41069592919ef281e964ed26446"}, + {file = "triton-2.1.0-0-pp37-pypy37_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:143582ca31dd89cd982bd3bf53666bab1c7527d41e185f9e3d8a3051ce1b663b"}, + {file = "triton-2.1.0-0-pp38-pypy38_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:82fc5aeeedf6e36be4e4530cbdcba81a09d65c18e02f52dc298696d45721f3bd"}, + {file = "triton-2.1.0-0-pp39-pypy39_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:81a96d110a738ff63339fc892ded095b31bd0d205e3aace262af8400d40b6fa8"}, +] + +[package.dependencies] +filelock = "*" + +[package.extras] +build = ["cmake (>=3.18)", "lit"] +tests = ["autopep8", "flake8", "isort", "numpy", "pytest", "scipy (>=1.7.1)"] +tutorials = ["matplotlib", "pandas", "tabulate"] + [[package]] name = "types-pyyaml" version = "6.0.12.12" @@ -2558,6 +3129,26 @@ brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] zstd = ["zstandard (>=0.18.0)"] +[[package]] +name = "virtualenv" +version = "20.25.0" +description = "Virtual Python Environment builder" +optional = false +python-versions = ">=3.7" +files = [ + {file = "virtualenv-20.25.0-py3-none-any.whl", hash = "sha256:4238949c5ffe6876362d9c0180fc6c3a824a7b12b80604eeb8085f2ed7460de3"}, + {file = "virtualenv-20.25.0.tar.gz", hash = "sha256:bf51c0d9c7dd63ea8e44086fa1e4fb1093a31e963b86959257378aef020e1f1b"}, +] + +[package.dependencies] +distlib = ">=0.3.7,<1" +filelock = ">=3.12.2,<4" +platformdirs = ">=3.9.1,<5" + +[package.extras] +docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] +test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"] + [[package]] name = "wcwidth" version = "0.2.13" @@ -2700,8 +3291,9 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [extras] fastembed = ["fastembed"] hybrid = ["pinecone-text"] +local = ["torch", "transformers"] [metadata] lock-version = "2.0" -python-versions = ">=3.10,<3.12" -content-hash = "c3d1f027aca765b48cccd119ab67670ecb51248433dda40bc8a9cbcc38f68d7c" +python-versions = "^3.9" +content-hash = "4ceb0344e006fc7657c66548321ff51d34a297ee6f9ab069fdc53e1256024a12" diff --git a/pyproject.toml b/pyproject.toml index 5b0e1f304e1d57beec6c5454ef32e953add68338..45f105fd9ac63138f7b5d4d82b6300d1052f2ccb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,22 +14,25 @@ readme = "README.md" packages = [{include = "semantic_router"}] [tool.poetry.dependencies] -python = ">=3.10,<3.12" +python = "^3.9" pydantic = "^1.8.2" openai = "^1.3.9" cohere = "^4.32" numpy = "^1.25.2" -pinecone-text = {version = "^0.7.0", optional = true} colorlog = "^6.8.0" pyyaml = "^6.0.1" -fastembed = {version = "^0.1.3", optional = true} +pinecone-text = {version = "^0.7.1", optional = true} +fastembed = {version = "^0.1.3", optional = true, python = "<3.12"} +torch = {version = "^2.1.2", optional = true} +transformers = {version = "^4.36.2", optional = true} [tool.poetry.extras] hybrid = ["pinecone-text"] fastembed = ["fastembed"] +local = ["torch", "transformers"] [tool.poetry.group.dev.dependencies] -ipykernel = "^6.26.0" +ipykernel = "^6.25.0" ruff = "^0.1.5" black = {extras = ["jupyter"], version = "^23.12.0"} pytest = "^7.4.3" diff --git a/replace.py b/replace.py new file mode 100644 index 0000000000000000000000000000000000000000..508c3f33f32c42600dc9aa25c21f62bbaf119dd3 --- /dev/null +++ b/replace.py @@ -0,0 +1,28 @@ +import os +import re + + +def replace_type_hints(file_path): + with open(file_path, "rb") as file: + file_data = file.read() + + # Decode the file data with error handling + file_data = file_data.decode("utf-8", errors="ignore") + + # Regular expression pattern to find 'Optional[dict[int, int]]' and replace with 'Optional[dict[int, int]]' + file_data = re.sub( + r"dict\[(\w+), (\w+)\]\s*\|\s*None", r"Optional[dict[\1, \2]]", file_data + ) + + with open(file_path, "w") as file: + file.write(file_data) + + +# Directory path +dir_path = "/Users/jakit/customers/aurelio/semantic-router" + +# Traverse the directory +for root, dirs, files in os.walk(dir_path): + for file in files: + if file.endswith(".py"): + replace_type_hints(os.path.join(root, file)) diff --git a/semantic_router/encoders/__init__.py b/semantic_router/encoders/__init__.py index 2f71ff4e5984d310a0bac4efab9b24c0e61ac6ad..713f8a995e7e52db60cf38d3023bf182dde56361 100644 --- a/semantic_router/encoders/__init__.py +++ b/semantic_router/encoders/__init__.py @@ -2,6 +2,7 @@ from semantic_router.encoders.base import BaseEncoder from semantic_router.encoders.bm25 import BM25Encoder from semantic_router.encoders.cohere import CohereEncoder from semantic_router.encoders.fastembed import FastEmbedEncoder +from semantic_router.encoders.huggingface import HuggingFaceEncoder from semantic_router.encoders.openai import OpenAIEncoder from semantic_router.encoders.tfidf import TfidfEncoder @@ -12,4 +13,5 @@ __all__ = [ "BM25Encoder", "TfidfEncoder", "FastEmbedEncoder", + "HuggingFaceEncoder", ] diff --git a/semantic_router/encoders/bm25.py b/semantic_router/encoders/bm25.py index 68150cb767faec1a8c3c5417f9d5f6db3a977cda..451273cdcc78899861c7b64baea4eb4e1cc6b33b 100644 --- a/semantic_router/encoders/bm25.py +++ b/semantic_router/encoders/bm25.py @@ -1,26 +1,37 @@ -from typing import Any +from typing import Any, Optional from semantic_router.encoders import BaseEncoder from semantic_router.utils.logger import logger class BM25Encoder(BaseEncoder): - model: Any | None = None - idx_mapping: dict[int, int] | None = None + model: Optional[Any] = None + idx_mapping: Optional[dict[int, int]] = None type: str = "sparse" - def __init__(self, name: str = "bm25", score_threshold: float = 0.82): + def __init__( + self, + name: str = "bm25", + score_threshold: float = 0.82, + use_default_params: bool = True, + ): super().__init__(name=name, score_threshold=score_threshold) try: from pinecone_text.sparse import BM25Encoder as encoder except ImportError: raise ImportError( "Please install pinecone-text to use BM25Encoder. " - "You can install it with: `pip install semantic-router[hybrid]`" + "You can install it with: `pip install 'semantic-router[hybrid]'`" ) - logger.info("Downloading and initializing BM25 model parameters.") - self.model = encoder.default() + self.model = encoder() + + if use_default_params: + logger.info("Downloading and initializing default sBM25 model parameters.") + self.model = encoder.default() + self._set_idx_mapping() + + def _set_idx_mapping(self): params = self.model.get_params() doc_freq = params["doc_freq"] if isinstance(doc_freq, dict): @@ -53,3 +64,4 @@ class BM25Encoder(BaseEncoder): if self.model is None: raise ValueError("Model is not initialized.") self.model.fit(docs) + self._set_idx_mapping() diff --git a/semantic_router/encoders/cohere.py b/semantic_router/encoders/cohere.py index 2f80aaafdc5b5554f86851e6dfc3b12fb3ca08b0..ec8ee0f8fcebd39444f3689d7bdffc2b7e98c812 100644 --- a/semantic_router/encoders/cohere.py +++ b/semantic_router/encoders/cohere.py @@ -1,4 +1,5 @@ import os +from typing import Optional import cohere @@ -6,13 +7,13 @@ from semantic_router.encoders import BaseEncoder class CohereEncoder(BaseEncoder): - client: cohere.Client | None = None + client: Optional[cohere.Client] = None type: str = "cohere" def __init__( self, - name: str | None = None, - cohere_api_key: str | None = None, + name: Optional[str] = None, + cohere_api_key: Optional[str] = None, score_threshold: float = 0.3, ): if name is None: diff --git a/semantic_router/encoders/fastembed.py b/semantic_router/encoders/fastembed.py index 413e3a6ada8e956fcbb8cbdfdd640a29883647df..98cfc6cc529ff4c06e0a3e7f0d0af779df7f71dd 100644 --- a/semantic_router/encoders/fastembed.py +++ b/semantic_router/encoders/fastembed.py @@ -27,7 +27,7 @@ class FastEmbedEncoder(BaseEncoder): raise ImportError( "Please install fastembed to use FastEmbedEncoder. " "You can install it with: " - "`pip install semantic-router[fastembed]`" + "`pip install 'semantic-router[fastembed]'`" ) embedding_args = { diff --git a/semantic_router/encoders/huggingface.py b/semantic_router/encoders/huggingface.py new file mode 100644 index 0000000000000000000000000000000000000000..ace189213b76aed940dd8b4280ce1505339f656f --- /dev/null +++ b/semantic_router/encoders/huggingface.py @@ -0,0 +1,114 @@ +from typing import Any, Optional + +from pydantic import PrivateAttr + +from semantic_router.encoders import BaseEncoder + + +class HuggingFaceEncoder(BaseEncoder): + name: str = "sentence-transformers/all-MiniLM-L6-v2" + type: str = "huggingface" + score_threshold: float = 0.5 + tokenizer_kwargs: dict = {} + model_kwargs: dict = {} + device: Optional[str] = None + _tokenizer: Any = PrivateAttr() + _model: Any = PrivateAttr() + _torch: Any = PrivateAttr() + + def __init__(self, **data): + super().__init__(**data) + self._tokenizer, self._model = self._initialize_hf_model() + + def _initialize_hf_model(self): + try: + from transformers import AutoModel, AutoTokenizer + except ImportError: + raise ImportError( + "Please install transformers to use HuggingFaceEncoder. " + "You can install it with: " + "`pip install semantic-router[local]`" + ) + + try: + import torch + except ImportError: + raise ImportError( + "Please install Pytorch to use HuggingFaceEncoder. " + "You can install it with: " + "`pip install semantic-router[local]`" + ) + + self._torch = torch + + tokenizer = AutoTokenizer.from_pretrained( + self.name, + **self.tokenizer_kwargs, + ) + + model = AutoModel.from_pretrained(self.name, **self.model_kwargs) + + if self.device: + model.to(self.device) + + else: + device = "cuda" if self._torch.cuda.is_available() else "cpu" + model.to(device) + self.device = device + + return tokenizer, model + + def __call__( + self, + docs: list[str], + batch_size: int = 32, + normalize_embeddings: bool = True, + pooling_strategy: str = "mean", + ) -> list[list[float]]: + all_embeddings = [] + for i in range(0, len(docs), batch_size): + batch_docs = docs[i : i + batch_size] + + encoded_input = self._tokenizer( + batch_docs, padding=True, truncation=True, return_tensors="pt" + ).to(self.device) + + with self._torch.no_grad(): + model_output = self._model(**encoded_input) + + if pooling_strategy == "mean": + embeddings = self._mean_pooling( + model_output, encoded_input["attention_mask"] + ) + elif pooling_strategy == "max": + embeddings = self._max_pooling( + model_output, encoded_input["attention_mask"] + ) + else: + raise ValueError( + "Invalid pooling_strategy. Please use 'mean' or 'max'." + ) + + if normalize_embeddings: + embeddings = self._torch.nn.functional.normalize(embeddings, p=2, dim=1) + + embeddings = embeddings.tolist() + all_embeddings.extend(embeddings) + return all_embeddings + + def _mean_pooling(self, model_output, attention_mask): + token_embeddings = model_output[0] + input_mask_expanded = ( + attention_mask.unsqueeze(-1).expand(token_embeddings.size()).float() + ) + return self._torch.sum( + token_embeddings * input_mask_expanded, 1 + ) / self._torch.clamp(input_mask_expanded.sum(1), min=1e-9) + + def _max_pooling(self, model_output, attention_mask): + token_embeddings = model_output[0] + input_mask_expanded = ( + attention_mask.unsqueeze(-1).expand(token_embeddings.size()).float() + ) + token_embeddings[input_mask_expanded == 0] = -1e9 + return self._torch.max(token_embeddings, 1)[0] diff --git a/semantic_router/encoders/openai.py b/semantic_router/encoders/openai.py index 4ec87638cf9fc2c9d33c3b7c6a77d9d38ecf9b5b..169761afa8f726a72439a534a69bac3ebf73de29 100644 --- a/semantic_router/encoders/openai.py +++ b/semantic_router/encoders/openai.py @@ -1,5 +1,6 @@ import os from time import sleep +from typing import Optional import openai from openai import OpenAIError @@ -10,13 +11,13 @@ from semantic_router.utils.logger import logger class OpenAIEncoder(BaseEncoder): - client: openai.Client | None + client: Optional[openai.Client] type: str = "openai" def __init__( self, - name: str | None = None, - openai_api_key: str | None = None, + name: Optional[str] = None, + openai_api_key: Optional[str] = None, score_threshold: float = 0.82, ): if name is None: diff --git a/semantic_router/hybrid_layer.py b/semantic_router/hybrid_layer.py index 5791231d44fdfb4cd9ac8a8a3e7ee962529bed93..0979d420ee3e4ad88ce72cb3174604c61cf198d9 100644 --- a/semantic_router/hybrid_layer.py +++ b/semantic_router/hybrid_layer.py @@ -1,3 +1,5 @@ +from typing import Optional + import numpy as np from numpy.linalg import norm @@ -17,14 +19,20 @@ class HybridRouteLayer: def __init__( self, - dense_encoder: BaseEncoder, - sparse_encoder: BaseEncoder, + encoder: BaseEncoder, + sparse_encoder: Optional[BM25Encoder] = None, routes: list[Route] = [], alpha: float = 0.3, ): self.encoder = dense_encoder self.score_threshold = self.encoder.score_threshold - self.sparse_encoder = sparse_encoder + + if sparse_encoder is None: + logger.warning("No sparse_encoder provided. Using default BM25Encoder.") + self.sparse_encoder = BM25Encoder() + else: + self.sparse_encoder = sparse_encoder + self.alpha = alpha self.routes = routes if isinstance(self.sparse_encoder, TfidfEncoder) and hasattr( @@ -38,7 +46,7 @@ class HybridRouteLayer: # self._add_route(route=route) self._add_routes(routes) - def __call__(self, text: str) -> str | None: + def __call__(self, text: str) -> Optional[str]: results = self._query(text) top_class, top_class_scores = self._semantic_classify(results) passed = self._pass_threshold(top_class_scores, self.score_threshold) diff --git a/semantic_router/layer.py b/semantic_router/layer.py index 082617566edb395c282491c04c9d38da8ae2ed16..cf546bfc1d791c6843bd62ce5ad4f178b9f0254b 100644 --- a/semantic_router/layer.py +++ b/semantic_router/layer.py @@ -1,5 +1,6 @@ import json import os +from typing import Optional import numpy as np import yaml @@ -52,7 +53,7 @@ class LayerConfig: self, routes: list[Route] = [], encoder_type: str = "openai", - encoder_name: str | None = None, + encoder_name: Optional[str] = None, ): self.encoder_type = encoder_type if encoder_name is None: @@ -131,7 +132,7 @@ class LayerConfig: self.routes.append(route) logger.info(f"Added route `{route.name}`") - def get(self, name: str) -> Route | None: + def get(self, name: str) -> Optional[Route]: for route in self.routes: if route.name == name: return route @@ -147,16 +148,17 @@ class LayerConfig: class RouteLayer: - index: np.ndarray | None = None - categories: np.ndarray | None = None + index: Optional[np.ndarray] = None + categories: Optional[np.ndarray] = None score_threshold: float encoder: BaseEncoder def __init__( self, - encoder: BaseEncoder | None = None, - llm: BaseLLM | None = None, - routes: list[Route] | None = None, + encoder: Optional[BaseEncoder] = None, + llm: Optional[BaseLLM] = None, + routes: Optional[list[Route]] = None, + top_k_routes: int = 3, ): logger.info("Initializing RouteLayer") self.index = None diff --git a/semantic_router/llms/base.py b/semantic_router/llms/base.py index 51db1fd0e5f317ba7a436cecaac891e8628a161e..bf5f29b6005daaa76abc4674971dc8f775f4af80 100644 --- a/semantic_router/llms/base.py +++ b/semantic_router/llms/base.py @@ -1,3 +1,5 @@ +from typing import Optional + from pydantic import BaseModel from semantic_router.schema import Message @@ -9,5 +11,5 @@ class BaseLLM(BaseModel): class Config: arbitrary_types_allowed = True - def __call__(self, messages: list[Message]) -> str | None: + def __call__(self, messages: list[Message]) -> Optional[str]: raise NotImplementedError("Subclasses must implement this method") diff --git a/semantic_router/llms/cohere.py b/semantic_router/llms/cohere.py index 775817001f22a4474f8705b2335c697730035d47..0ec21f354c090f0d1d00da7c20b89c5b233c3a89 100644 --- a/semantic_router/llms/cohere.py +++ b/semantic_router/llms/cohere.py @@ -1,4 +1,5 @@ import os +from typing import Optional import cohere @@ -7,12 +8,12 @@ from semantic_router.schema import Message class CohereLLM(BaseLLM): - client: cohere.Client | None = None + client: Optional[cohere.Client] = None def __init__( self, - name: str | None = None, - cohere_api_key: str | None = None, + name: Optional[str] = None, + cohere_api_key: Optional[str] = None, ): if name is None: name = os.getenv("COHERE_CHAT_MODEL_NAME", "command") diff --git a/semantic_router/llms/openai.py b/semantic_router/llms/openai.py index 43ddd642bd42702461da56fd5de87dea01635dfb..8b3442c742c2f268773bf551fb49ce0cd24645af 100644 --- a/semantic_router/llms/openai.py +++ b/semantic_router/llms/openai.py @@ -1,4 +1,5 @@ import os +from typing import Optional import openai @@ -8,14 +9,14 @@ from semantic_router.utils.logger import logger class OpenAILLM(BaseLLM): - client: openai.OpenAI | None - temperature: float | None - max_tokens: int | None + client: Optional[openai.OpenAI] + temperature: Optional[float] + max_tokens: Optional[int] def __init__( self, - name: str | None = None, - openai_api_key: str | None = None, + name: Optional[str] = None, + openai_api_key: Optional[str] = None, temperature: float = 0.01, max_tokens: int = 200, ): diff --git a/semantic_router/llms/openrouter.py b/semantic_router/llms/openrouter.py index 587eeb121e60c4e6f63dac289e390dd5c9086a1a..4cc15d6bfedbfa67fb5957129d1ce901544dcb38 100644 --- a/semantic_router/llms/openrouter.py +++ b/semantic_router/llms/openrouter.py @@ -1,4 +1,5 @@ import os +from typing import Optional import openai @@ -8,15 +9,15 @@ from semantic_router.utils.logger import logger class OpenRouterLLM(BaseLLM): - client: openai.OpenAI | None - base_url: str | None - temperature: float | None - max_tokens: int | None + client: Optional[openai.OpenAI] + base_url: Optional[str] + temperature: Optional[float] + max_tokens: Optional[int] def __init__( self, - name: str | None = None, - openrouter_api_key: str | None = None, + name: Optional[str] = None, + openrouter_api_key: Optional[str] = None, base_url: str = "https://openrouter.ai/api/v1", temperature: float = 0.01, max_tokens: int = 200, diff --git a/semantic_router/route.py b/semantic_router/route.py index 0d8269f0a24df70cb71da172781154de64bf1425..2289825071a39652aeaa467395103d71dc623140 100644 --- a/semantic_router/route.py +++ b/semantic_router/route.py @@ -1,6 +1,6 @@ import json import re -from typing import Any, Callable, Union +from typing import Any, Callable, Optional, Union from pydantic import BaseModel @@ -41,9 +41,9 @@ def is_valid(route_config: str) -> bool: class Route(BaseModel): name: str utterances: list[str] - description: str | None = None - function_schema: dict[str, Any] | None = None - llm: BaseLLM | None = None + description: Optional[str] = None + function_schema: Optional[dict[str, Any]] = None + llm: Optional[BaseLLM] = None def __call__(self, query: str) -> RouteChoice: if self.function_schema: @@ -96,29 +96,29 @@ class Route(BaseModel): logger.info("Generating dynamic route...") prompt = f""" - You are tasked to generate a JSON configuration based on the provided - function schema. Please follow the template below, no other tokens allowed: - - <config> - {{ - "name": "<function_name>", - "utterances": [ - "<example_utterance_1>", - "<example_utterance_2>", - "<example_utterance_3>", - "<example_utterance_4>", - "<example_utterance_5>"] - }} - </config> - - Only include the "name" and "utterances" keys in your answer. - The "name" should match the function name and the "utterances" - should comprise a list of 5 example phrases that could be used to invoke - the function. Use real values instead of placeholders. - - Input schema: - {function_schema} - """ +You are tasked to generate a JSON configuration based on the provided +function schema. Please follow the template below, no other tokens allowed: + +<config> +{{ + "name": "<function_name>", + "utterances": [ + "<example_utterance_1>", + "<example_utterance_2>", + "<example_utterance_3>", + "<example_utterance_4>", + "<example_utterance_5>"] +}} +</config> + +Only include the "name" and "utterances" keys in your answer. +The "name" should match the function name and the "utterances" +should comprise a list of 5 example phrases that could be used to invoke +the function. Use real values instead of placeholders. + +Input schema: +{function_schema} +""" llm_input = [Message(role="user", content=prompt)] output = llm(llm_input) diff --git a/semantic_router/schema.py b/semantic_router/schema.py index 5e94c23b13f8c9d9359609e46c790e18dd860ab4..bb1a4c6ac26819ef7b13bec1f293fe6e51a66a7a 100644 --- a/semantic_router/schema.py +++ b/semantic_router/schema.py @@ -1,4 +1,5 @@ from enum import Enum +from typing import Optional from pydantic import BaseModel from pydantic.dataclasses import dataclass @@ -20,17 +21,19 @@ class EncoderType(Enum): class RouteChoice(BaseModel): - name: str | None = None - function_call: dict | None = None + name: Optional[str] = None + function_call: Optional[dict] = None + similarity_score: Optional[float] = None + trigger: Optional[bool] = None @dataclass class Encoder: type: EncoderType - name: str | None + name: Optional[str] model: BaseEncoder - def __init__(self, type: str, name: str | None): + def __init__(self, type: str, name: Optional[str]): self.type = EncoderType(type) self.name = name if self.type == EncoderType.HUGGINGFACE: diff --git a/semantic_router/utils/function_call.py b/semantic_router/utils/function_call.py index cedd9b6ecd86131b630cf6d4921848604dc88fa0..3c8b3277b3b4cdd8d3c2ebc1849ff3da4cbd1ca7 100644 --- a/semantic_router/utils/function_call.py +++ b/semantic_router/utils/function_call.py @@ -47,33 +47,36 @@ def extract_function_inputs( logger.info("Extracting function input...") prompt = f""" - You are a helpful assistant designed to output JSON. - Given the following function schema - << {function_schema} >> - and query - << {query} >> - extract the parameters values from the query, in a valid JSON format. - Example: - Input: - query: "How is the weather in Hawaii right now in International units?" - schema: - {{ - "name": "get_weather", - "description": "Useful to get the weather in a specific location", - "signature": "(location: str, degree: str) -> str", - "output": "<class 'str'>", - }} - - Result: {{ - "location": "London", - "degree": "Celsius", - }} - - Input: - query: {query} - schema: {function_schema} - Result: - """ +You are a helpful assistant designed to output JSON. +Given the following function schema +<< {function_schema} >> +and query +<< {query} >> +extract the parameters values from the query, in a valid JSON format. +Example: +Input: +query: "How is the weather in Hawaii right now in International units?" +schema: +{{ + "name": "get_weather", + "description": "Useful to get the weather in a specific location", + "signature": "(location: str, degree: str) -> float", + "output": "<class 'float'>", +}} + +Result: +{{ + "location": "Hawaii", + "degree": "Kelvin", +}} + +Input: +query: \"{query}\" +schema: +{json.dumps(function_schema, indent=4)} + +Result: +""" llm_input = [Message(role="user", content=prompt)] output = llm(llm_input) if not output: diff --git a/semantic_router/utils/llm.py b/semantic_router/utils/llm.py index e92c1bcf7752b5fce5a071dde41da4a24d0851a9..4f89566f79df700ec3ae8103b5b8cdfd84700627 100644 --- a/semantic_router/utils/llm.py +++ b/semantic_router/utils/llm.py @@ -1,11 +1,12 @@ import os +from typing import Optional import openai from semantic_router.utils.logger import logger -def llm(prompt: str) -> str | None: +def llm(prompt: str) -> Optional[str]: try: client = openai.OpenAI( base_url="https://openrouter.ai/api/v1", @@ -35,7 +36,7 @@ def llm(prompt: str) -> str | None: # TODO integrate async LLM function -# async def allm(prompt: str) -> str | None: +# async def allm(prompt: str) -> Optional[str]: # try: # client = openai.AsyncOpenAI( # base_url="https://openrouter.ai/api/v1", diff --git a/test_output.txt b/test_output.txt deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/tests/unit/encoders/test_bm25.py b/tests/unit/encoders/test_bm25.py index 9c28ab2d6f32bc31b7cd5d6e2252ad9c41880b96..73e52d5585a3391488d7198d64543a0b2f0dcc5c 100644 --- a/tests/unit/encoders/test_bm25.py +++ b/tests/unit/encoders/test_bm25.py @@ -5,7 +5,11 @@ from semantic_router.encoders import BM25Encoder @pytest.fixture def bm25_encoder(): - return BM25Encoder() + sparse_encoder = BM25Encoder(use_default_params=False) + sparse_encoder.fit( + ["The quick brown fox", "jumps over the lazy dog", "Hello, world!"] + ) + return sparse_encoder class TestBM25Encoder: diff --git a/tests/unit/encoders/test_huggingface.py b/tests/unit/encoders/test_huggingface.py new file mode 100644 index 0000000000000000000000000000000000000000..1e916f3eca2956b32c6147db6cf5c42695720f14 --- /dev/null +++ b/tests/unit/encoders/test_huggingface.py @@ -0,0 +1,63 @@ +from unittest.mock import patch + +import numpy as np +import pytest + +from semantic_router.encoders.huggingface import HuggingFaceEncoder + +encoder = HuggingFaceEncoder() + + +class TestHuggingFaceEncoder: + def test_huggingface_encoder_import_errors_transformers(self): + with patch.dict("sys.modules", {"transformers": None}): + with pytest.raises(ImportError) as error: + HuggingFaceEncoder() + + assert "Please install transformers to use HuggingFaceEncoder" in str( + error.value + ) + + def test_huggingface_encoder_import_errors_torch(self): + with patch.dict("sys.modules", {"torch": None}): + with pytest.raises(ImportError) as error: + HuggingFaceEncoder() + + assert "Please install Pytorch to use HuggingFaceEncoder" in str(error.value) + + def test_huggingface_encoder_mean_pooling(self): + test_docs = ["This is a test", "This is another test"] + embeddings = encoder(test_docs, pooling_strategy="mean") + assert isinstance(embeddings, list) + assert len(embeddings) == len(test_docs) + assert all(isinstance(embedding, list) for embedding in embeddings) + assert all(len(embedding) > 0 for embedding in embeddings) + + def test_huggingface_encoder_max_pooling(self): + test_docs = ["This is a test", "This is another test"] + embeddings = encoder(test_docs, pooling_strategy="max") + assert isinstance(embeddings, list) + assert len(embeddings) == len(test_docs) + assert all(isinstance(embedding, list) for embedding in embeddings) + assert all(len(embedding) > 0 for embedding in embeddings) + + def test_huggingface_encoder_normalized_embeddings(self): + docs = ["This is a test document.", "Another test document."] + unnormalized_embeddings = encoder(docs, normalize_embeddings=False) + normalized_embeddings = encoder(docs, normalize_embeddings=True) + assert len(unnormalized_embeddings) == len(normalized_embeddings) + + for unnormalized, normalized in zip( + unnormalized_embeddings, normalized_embeddings + ): + norm_unnormalized = np.linalg.norm(unnormalized, ord=2) + norm_normalized = np.linalg.norm(normalized, ord=2) + # Ensure the norm of the normalized embeddings is approximately 1 + assert np.isclose(norm_normalized, 1.0) + # Ensure the normalized embeddings are actually normalized versions of unnormalized embeddings + np.testing.assert_allclose( + normalized, + np.divide(unnormalized, norm_unnormalized), + rtol=1e-5, + atol=1e-5, # Adjust tolerance levels + ) diff --git a/tests/unit/test_hybrid_layer.py b/tests/unit/test_hybrid_layer.py index 323912c284e338502d138e1894111d68f540d12f..cf1e66c3bfa11a60d257a6dd0eb9099d45d37e59 100644 --- a/tests/unit/test_hybrid_layer.py +++ b/tests/unit/test_hybrid_layer.py @@ -2,9 +2,9 @@ import pytest from semantic_router.encoders import ( BaseEncoder, + BM25Encoder, CohereEncoder, OpenAIEncoder, - BM25Encoder, TfidfEncoder, ) from semantic_router.hybrid_layer import HybridRouteLayer @@ -62,10 +62,14 @@ def routes(): ] +sparse_encoder = BM25Encoder(use_default_params=False) +sparse_encoder.fit(["The quick brown fox", "jumps over the lazy dog", "Hello, world!"]) + + class TestHybridRouteLayer: - def test_initialization(self, openai_encoder, bm25_encoder, routes): + def test_initialization(self, openai_encoder, routes): route_layer = HybridRouteLayer( - dense_encoder=openai_encoder, sparse_encoder=bm25_encoder, routes=routes + encoder=openai_encoder, sparse_encoder=sparse_encoder, routes=routes ) assert route_layer.index is not None and route_layer.categories is not None assert openai_encoder.score_threshold == 0.82 @@ -73,22 +77,20 @@ class TestHybridRouteLayer: assert len(route_layer.index) == 5 assert len(set(route_layer.categories)) == 2 - def test_initialization_different_encoders( - self, cohere_encoder, openai_encoder, bm25_encoder - ): + def test_initialization_different_encoders(self, cohere_encoder, openai_encoder): route_layer_cohere = HybridRouteLayer( - dense_encoder=cohere_encoder, sparse_encoder=bm25_encoder + encoder=cohere_encoder, sparse_encoder=sparse_encoder ) assert route_layer_cohere.score_threshold == 0.3 route_layer_openai = HybridRouteLayer( - dense_encoder=openai_encoder, sparse_encoder=bm25_encoder + encoder=openai_encoder, sparse_encoder=sparse_encoder ) assert route_layer_openai.score_threshold == 0.82 - def test_add_route(self, openai_encoder, bm25_encoder): + def test_add_route(self, openai_encoder): route_layer = HybridRouteLayer( - dense_encoder=openai_encoder, sparse_encoder=bm25_encoder + encoder=openai_encoder, sparse_encoder=sparse_encoder ) route = Route(name="Route 3", utterances=["Yes", "No"]) route_layer._add_routes([route]) @@ -96,9 +98,9 @@ class TestHybridRouteLayer: assert len(route_layer.index) == 2 assert len(set(route_layer.categories)) == 1 - def test_add_multiple_routes(self, openai_encoder, bm25_encoder, routes): + def test_add_multiple_routes(self, openai_encoder, routes): route_layer = HybridRouteLayer( - dense_encoder=openai_encoder, sparse_encoder=bm25_encoder + encoder=openai_encoder, sparse_encoder=sparse_encoder ) for route in routes: route_layer.add(route) @@ -106,22 +108,22 @@ class TestHybridRouteLayer: assert len(route_layer.index) == 5 assert len(set(route_layer.categories)) == 2 - def test_query_and_classification(self, openai_encoder, bm25_encoder, routes): + def test_query_and_classification(self, openai_encoder, routes): route_layer = HybridRouteLayer( - dense_encoder=openai_encoder, sparse_encoder=bm25_encoder, routes=routes + encoder=openai_encoder, sparse_encoder=sparse_encoder, routes=routes ) query_result = route_layer("Hello") assert query_result in ["Route 1", "Route 2"] - def test_query_with_no_index(self, openai_encoder, bm25_encoder): + def test_query_with_no_index(self, openai_encoder): route_layer = HybridRouteLayer( - dense_encoder=openai_encoder, sparse_encoder=bm25_encoder + encoder=openai_encoder, sparse_encoder=sparse_encoder ) assert route_layer("Anything") is None - def test_semantic_classify(self, openai_encoder, bm25_encoder, routes): + def test_semantic_classify(self, openai_encoder, routes): route_layer = HybridRouteLayer( - dense_encoder=openai_encoder, sparse_encoder=bm25_encoder, routes=routes + encoder=openai_encoder, sparse_encoder=sparse_encoder, routes=routes ) classification, score = route_layer._semantic_classify( [ @@ -132,11 +134,9 @@ class TestHybridRouteLayer: assert classification == "Route 1" assert score == [0.9] - def test_semantic_classify_multiple_routes( - self, openai_encoder, bm25_encoder, routes - ): + def test_semantic_classify_multiple_routes(self, openai_encoder, routes): route_layer = HybridRouteLayer( - dense_encoder=openai_encoder, sparse_encoder=bm25_encoder, routes=routes + encoder=openai_encoder, sparse_encoder=sparse_encoder, routes=routes ) classification, score = route_layer._semantic_classify( [ @@ -148,16 +148,16 @@ class TestHybridRouteLayer: assert classification == "Route 1" assert score == [0.9, 0.8] - def test_pass_threshold(self, openai_encoder, bm25_encoder): + def test_pass_threshold(self, openai_encoder): route_layer = HybridRouteLayer( - dense_encoder=openai_encoder, sparse_encoder=bm25_encoder + encoder=openai_encoder, sparse_encoder=sparse_encoder ) assert not route_layer._pass_threshold([], 0.5) assert route_layer._pass_threshold([0.6, 0.7], 0.5) def test_failover_score_threshold(self, base_encoder): route_layer = HybridRouteLayer( - dense_encoder=base_encoder, sparse_encoder=base_encoder + encoder=base_encoder, sparse_encoder=sparse_encoder ) assert base_encoder.score_threshold == 0.50 assert route_layer.score_threshold == 0.50