diff --git a/coverage.xml b/coverage.xml index 7eb662b902de37fa6581d52548d1cf54db5e5be4..5088c54e5a3540a52642431cd0533ed6aae47578 100644 --- a/coverage.xml +++ b/coverage.xml @@ -1,12 +1,12 @@ <?xml version="1.0" ?> -<coverage version="7.4.0" timestamp="1707722055292" lines-valid="1402" lines-covered="1188" line-rate="0.8474" branches-covered="0" branches-valid="0" branch-rate="0" complexity="0"> - <!-- Generated by coverage.py: https://coverage.readthedocs.io/en/7.4.0 --> +<coverage version="7.4.1" timestamp="1708577611401" lines-valid="1704" lines-covered="1346" line-rate="0.7899" branches-covered="0" branches-valid="0" branch-rate="0" complexity="0"> + <!-- Generated by coverage.py: https://coverage.readthedocs.io/en/7.4.1 --> <!-- Based on https://raw.githubusercontent.com/cobertura/web/master/htdocs/xml/coverage-04.dtd --> <sources> <source>/home/dustinmorris/semantic-router/semantic_router</source> </sources> <packages> - <package name="." line-rate="0.9055" branch-rate="0" complexity="0"> + <package name="." line-rate="0.9" branch-rate="0" complexity="0"> <classes> <class name="__init__.py" filename="__init__.py" complexity="0" line-rate="1" branch-rate="0"> <methods/> @@ -127,284 +127,285 @@ <line number="189" hits="1"/> </lines> </class> - <class name="layer.py" filename="layer.py" complexity="0" line-rate="0.9055" branch-rate="0"> + <class name="layer.py" filename="layer.py" complexity="0" line-rate="0.8949" 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"/> + <line number="5" hits="1"/> <line number="7" hits="1"/> <line number="8" hits="1"/> - <line number="10" 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="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="21" hits="1"/> - <line number="22" hits="1"/> + <line number="23" hits="1"/> <line number="24" hits="1"/> - <line number="25" hits="0"/> - <line number="26" hits="0"/> - <line number="27" hits="0"/> + <line number="25" hits="1"/> + <line number="27" hits="1"/> <line number="28" hits="0"/> + <line number="29" hits="0"/> + <line number="30" hits="0"/> <line number="31" hits="0"/> - <line number="32" hits="0"/> - <line number="34" hits="1"/> - <line number="35" hits="1"/> - <line number="36" hits="0"/> + <line number="34" hits="0"/> + <line number="35" hits="0"/> + <line number="37" hits="1"/> + <line number="38" hits="1"/> <line number="39" hits="0"/> - <line number="41" hits="1"/> <line number="42" hits="0"/> - <line number="43" hits="0"/> - <line number="44" hits="0"/> - <line number="47" hits="1"/> - <line number="53" hits="1"/> - <line number="55" hits="1"/> - <line number="61" hits="1"/> - <line number="62" hits="1"/> - <line number="66" hits="1"/> - <line number="67" hits="0"/> - <line number="68" hits="1"/> - <line number="69" hits="0"/> + <line number="44" hits="1"/> + <line number="45" hits="0"/> + <line number="46" hits="0"/> + <line number="47" hits="0"/> + <line number="50" hits="1"/> + <line number="56" hits="1"/> + <line number="58" hits="1"/> + <line number="64" hits="1"/> + <line number="65" hits="1"/> + <line number="69" hits="1"/> <line number="70" hits="1"/> - <line number="71" hits="0"/> - <line number="72" hits="1"/> - <line number="73" hits="0"/> - <line number="74" hits="1"/> + <line number="71" hits="1"/> + <line number="72" hits="0"/> <line number="75" hits="1"/> - <line number="76" 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="85" hits="1"/> <line number="86" hits="1"/> <line number="87" hits="1"/> + <line number="88" hits="1"/> <line number="89" hits="1"/> + <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="96" hits="1"/> <line number="97" hits="1"/> <line number="98" hits="1"/> - <line number="102" hits="0"/> - <line number="104" hits="1"/> + <line number="100" hits="1"/> + <line number="101" hits="1"/> + <line number="102" hits="1"/> + <line number="103" hits="1"/> <line number="105" hits="1"/> - <line number="111" hits="1"/> + <line number="106" hits="1"/> + <line number="110" hits="1"/> + <line number="112" hits="1"/> <line number="113" hits="1"/> - <line number="114" hits="1"/> - <line number="117" hits="1"/> - <line number="118" hits="1"/> + <line number="115" hits="1"/> + <line number="116" hits="1"/> + <line number="121" hits="1"/> <line number="122" hits="1"/> - <line number="125" hits="1"/> - <line number="126" hits="0"/> + <line number="124" 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="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="1"/> - <line number="143" hits="1"/> - <line number="145" hits="1"/> <line number="146" hits="1"/> - <line number="147" hits="0"/> <line number="149" hits="1"/> - <line number="150" hits="1"/> + <line number="150" hits="0"/> + <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="162" hits="1"/> + <line number="163" hits="1"/> + <line number="164" hits="1"/> <line number="165" hits="1"/> <line number="166" hits="1"/> <line number="167" hits="1"/> - <line number="168" hits="1"/> <line number="169" hits="1"/> + <line number="170" hits="1"/> + <line number="171" hits="0"/> <line number="173" hits="1"/> - <line number="175" hits="1"/> - <line number="176" hits="1"/> + <line number="174" hits="1"/> <line number="177" hits="1"/> <line number="178" hits="1"/> + <line number="179" hits="1"/> <line number="180" hits="1"/> - <line number="181" hits="1"/> <line number="182" hits="1"/> - <line number="184" hits="1"/> - <line number="186" hits="1"/> - <line number="188" hits="1"/> <line number="189" hits="1"/> <line number="190" hits="1"/> <line number="191" hits="1"/> - <line number="194" hits="1"/> - <line number="195" hits="1"/> - <line number="197" hits="1"/> + <line number="192" hits="1"/> + <line number="196" hits="1"/> + <line number="198" hits="1"/> + <line number="199" hits="1"/> + <line number="200" hits="1"/> + <line number="201" hits="1"/> <line number="203" hits="1"/> <line number="204" hits="1"/> <line number="205" hits="1"/> - <line number="206" hits="1"/> - <line number="208" hits="1"/> - <line number="210" hits="1"/> + <line number="207" hits="1"/> + <line number="209" hits="1"/> + <line number="211" hits="1"/> <line number="212" hits="1"/> - <line number="214" hits="1"/> - <line number="215" hits="1"/> - <line number="216" hits="1"/> - <line number="217" hits="1"/> - <line number="222" hits="1"/> - <line number="223" hits="1"/> - <line number="224" hits="1"/> - <line number="225" hits="1"/> + <line number="213" hits="1"/> + <line number="214" hits="0"/> + <line number="217" hits="0"/> + <line number="218" hits="1"/> + <line number="220" hits="1"/> + <line number="226" hits="1"/> + <line number="227" hits="1"/> <line number="228" hits="1"/> - <line number="229" hits="0"/> - <line number="230" hits="0"/> - <line number="236" hits="0"/> - <line number="237" hits="0"/> + <line number="229" hits="1"/> + <line number="231" hits="1"/> + <line number="233" hits="1"/> + <line number="235" hits="1"/> + <line number="237" hits="1"/> + <line number="238" hits="1"/> <line number="239" hits="0"/> <line number="240" hits="1"/> - <line number="243" hits="1"/> <line number="245" hits="1"/> - <line number="246" hits="0"/> - <line number="252" hits="1"/> - <line number="253" hits="1"/> - <line number="254" hits="1"/> - <line number="255" hits="1"/> - <line number="256" hits="1"/> - <line number="258" hits="1"/> - <line number="259" hits="1"/> - <line number="260" hits="1"/> - <line number="261" hits="1"/> - <line number="262" hits="1"/> - <line number="264" hits="1"/> - <line number="265" hits="1"/> + <line number="246" hits="1"/> + <line number="247" hits="1"/> + <line number="248" hits="1"/> + <line number="251" hits="1"/> + <line number="252" hits="0"/> + <line number="253" hits="0"/> + <line number="259" hits="0"/> + <line number="260" hits="0"/> + <line number="262" hits="0"/> + <line number="263" hits="1"/> <line number="266" hits="1"/> - <line number="267" hits="1"/> - <line number="269" hits="1"/> - <line number="270" hits="1"/> - <line number="272" hits="1"/> - <line number="274" hits="1"/> + <line number="268" hits="1"/> + <line number="269" hits="0"/> <line number="275" hits="1"/> + <line number="276" hits="1"/> + <line number="277" hits="1"/> <line number="278" hits="1"/> <line number="279" hits="1"/> <line number="281" hits="1"/> <line number="282" hits="1"/> + <line number="283" hits="1"/> <line number="284" hits="1"/> <line number="285" hits="1"/> <line number="287" hits="1"/> <line number="288" hits="1"/> + <line number="289" hits="1"/> <line number="290" hits="1"/> <line number="292" hits="1"/> <line number="293" 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="304" hits="1"/> - <line number="305" hits="1"/> - <line number="310" hits="1"/> + <line number="306" hits="1"/> + <line number="308" hits="1"/> + <line number="309" hits="1"/> <line number="311" hits="1"/> - <line number="313" hits="1"/> - <line number="315" hits="1"/> - <line number="318" hits="1"/> + <line number="312" hits="0"/> + <line number="314" hits="1"/> + <line number="320" hits="1"/> <line number="321" hits="1"/> <line number="322" hits="1"/> <line number="323" hits="1"/> - <line number="330" hits="1"/> - <line number="331" hits="1"/> - <line number="337" hits="1"/> - <line number="340" hits="1"/> - <line number="341" hits="1"/> - <line number="342" hits="1"/> - <line number="344" hits="1"/> - <line number="346" hits="1"/> - <line number="348" hits="1"/> - <line number="349" hits="1"/> - <line number="351" hits="1"/> + <line number="325" hits="1"/> + <line number="326" hits="1"/> + <line number="328" hits="1"/> + <line number="330" hits="0"/> + <line number="345" hits="1"/> + <line number="347" hits="1"/> + <line number="350" hits="1"/> <line number="352" hits="1"/> <line number="354" hits="1"/> - <line number="355" hits="1"/> - <line number="357" hits="1"/> - <line number="358" hits="1"/> - <line number="359" hits="1"/> <line number="360" hits="1"/> - <line number="361" hits="1"/> - <line number="362" hits="1"/> <line number="363" hits="1"/> + <line number="364" hits="1"/> <line number="365" hits="1"/> - <line number="368" hits="1"/> - <line number="369" hits="1"/> - <line number="372" hits="1"/> + <line number="367" hits="1"/> + <line number="370" hits="1"/> + <line number="371" hits="1"/> <line number="373" hits="1"/> + <line number="374" hits="1"/> <line number="375" hits="1"/> <line number="376" hits="1"/> + <line number="377" hits="1"/> <line number="378" hits="1"/> <line number="379" hits="1"/> - <line number="380" hits="1"/> - <line number="382" hits="1"/> + <line number="381" hits="1"/> <line number="384" hits="1"/> + <line number="385" hits="1"/> <line number="388" hits="1"/> <line number="389" hits="1"/> - <line number="390" hits="1"/> + <line number="391" hits="0"/> + <line number="392" hits="0"/> <line number="394" hits="1"/> <line number="395" hits="1"/> - <line number="401" hits="1"/> - <line number="402" hits="1"/> - <line number="403" hits="1"/> + <line number="396" hits="1"/> + <line number="398" hits="1"/> + <line number="400" hits="1"/> + <line number="404" hits="1"/> <line number="405" hits="1"/> <line number="406" hits="1"/> - <line number="407" hits="1"/> - <line number="409" hits="1"/> + <line number="410" hits="1"/> <line number="411" hits="1"/> - <line number="415" hits="1"/> <line number="417" hits="1"/> - <line number="424" hits="1"/> - <line number="426" hits="1"/> + <line number="418" hits="1"/> + <line number="419" hits="1"/> + <line number="421" hits="1"/> + <line number="422" hits="1"/> + <line number="423" hits="1"/> + <line number="425" hits="1"/> <line number="427" hits="1"/> - <line number="429" hits="1"/> - <line number="430" hits="1"/> - <line number="432" hits="1"/> - <line number="437" hits="1"/> - <line number="439" hits="1"/> + <line number="431" hits="1"/> + <line number="433" hits="1"/> <line number="441" hits="1"/> - <line number="442" hits="0"/> - <line number="443" hits="0"/> - <line number="445" hits="1"/> + <line number="442" hits="1"/> + <line number="443" hits="1"/> + <line number="444" hits="1"/> + <line number="446" hits="1"/> <line number="447" hits="1"/> - <line number="451" hits="1"/> + <line number="449" hits="1"/> + <line number="450" hits="1"/> <line number="452" hits="1"/> - <line number="453" hits="1"/> - <line number="455" hits="1"/> + <line number="457" hits="1"/> <line number="459" hits="1"/> - <line number="460" hits="1"/> <line number="461" hits="1"/> - <line number="462" hits="1"/> - <line number="463" hits="1"/> - <line number="464" hits="1"/> + <line number="462" hits="0"/> + <line number="463" hits="0"/> <line number="465" hits="1"/> - <line number="468" hits="1"/> + <line number="467" hits="1"/> + <line number="471" hits="1"/> + <line number="472" hits="1"/> + <line number="473" hits="1"/> <line number="474" hits="1"/> - <line number="475" hits="1"/> <line number="476" hits="1"/> - <line number="478" hits="1"/> + <line number="477" hits="1"/> <line number="479" hits="1"/> - <line number="480" hits="1"/> + <line number="483" hits="1"/> + <line number="484" hits="1"/> + <line number="485" hits="1"/> + <line number="486" hits="1"/> + <line number="487" hits="1"/> <line number="488" hits="1"/> + <line number="489" hits="1"/> + <line number="491" hits="1"/> <line number="492" hits="1"/> + <line number="495" hits="1"/> + <line number="501" hits="1"/> + <line number="502" hits="1"/> + <line number="503" hits="1"/> + <line number="505" hits="1"/> + <line number="506" hits="1"/> + <line number="507" hits="1"/> + <line number="515" hits="1"/> + <line number="519" hits="1"/> </lines> </class> <class name="linear.py" filename="linear.py" complexity="0" line-rate="1" branch-rate="0"> @@ -425,87 +426,93 @@ <line number="30" hits="1"/> </lines> </class> - <class name="route.py" filename="route.py" complexity="0" line-rate="0.9103" branch-rate="0"> + <class name="route.py" filename="route.py" complexity="0" line-rate="0.9048" branch-rate="0"> <methods/> <lines> <line number="1" hits="1"/> <line number="2" 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="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="49" hits="1"/> + <line number="48" hits="1"/> <line number="50" hits="1"/> <line number="51" hits="1"/> - <line number="52" hits="1"/> - <line number="56" hits="0"/> - <line number="57" hits="0"/> - <line number="62" hits="0"/> - <line number="65" hits="0"/> - <line number="68" hits="1"/> - <line number="69" hits="1"/> - <line number="71" hits="1"/> + <line number="53" hits="1"/> + <line number="54" hits="1"/> + <line number="55" hits="1"/> + <line number="56" hits="1"/> + <line number="60" hits="0"/> + <line number="61" hits="0"/> + <line number="66" hits="0"/> + <line number="69" hits="0"/> <line number="72" hits="1"/> - <line number="74" hits="1"/> - <line number="75" hits="1"/> - <line number="76" hits="1"/> + <line number="73" hits="1"/> <line number="78" hits="1"/> <line number="79" hits="1"/> - <line number="83" hits="1"/> - <line number="84" hits="1"/> - <line number="85" hits="1"/> + <line number="80" hits="1"/> + <line number="81" hits="0"/> <line number="86" hits="1"/> <line number="88" hits="1"/> <line number="89" hits="1"/> - <line number="91" hits="1"/> + <line number="90" hits="1"/> <line number="92" hits="1"/> - <line number="94" hits="1"/> - <line number="95" hits="1"/> - <line number="96" hits="1"/> - <line number="98" hits="0"/> + <line number="93" hits="1"/> + <line number="97" hits="1"/> + <line number="98" hits="1"/> + <line number="99" hits="1"/> <line number="100" hits="1"/> - <line number="101" hits="1"/> <line number="102" hits="1"/> - <line number="104" hits="1"/> - <line number="129" hits="1"/> - <line number="130" hits="1"/> - <line number="131" hits="1"/> - <line number="132" hits="0"/> - <line number="134" hits="1"/> - <line number="136" 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="103" hits="1"/> + <line number="105" hits="1"/> + <line number="106" hits="1"/> + <line number="108" hits="1"/> + <line number="109" hits="1"/> + <line number="110" hits="1"/> + <line number="112" hits="0"/> + <line number="114" hits="1"/> + <line number="115" hits="1"/> + <line number="116" hits="1"/> + <line number="118" hits="1"/> + <line number="143" hits="1"/> + <line number="144" hits="1"/> + <line number="145" hits="1"/> + <line number="146" hits="0"/> + <line number="148" hits="1"/> + <line number="150" 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="0"/> </lines> </class> <class name="schema.py" filename="schema.py" complexity="0" line-rate="0.8929" branch-rate="0"> @@ -648,7 +655,7 @@ </class> </classes> </package> - <package name="encoders" line-rate="0.8771" branch-rate="0" complexity="0"> + <package name="encoders" line-rate="0.834" branch-rate="0" complexity="0"> <classes> <class name="__init__.py" filename="encoders/__init__.py" complexity="0" line-rate="1" branch-rate="0"> <methods/> @@ -662,7 +669,8 @@ <line number="7" hits="1"/> <line number="8" hits="1"/> <line number="9" hits="1"/> - <line number="11" hits="1"/> + <line number="10" hits="1"/> + <line number="12" hits="1"/> </lines> </class> <class name="base.py" filename="encoders/base.py" complexity="0" line-rate="1" branch-rate="0"> @@ -739,15 +747,15 @@ <line number="2" hits="1"/> <line number="4" hits="1"/> <line number="6" hits="1"/> - <line number="9" hits="1"/> + <line number="7" hits="1"/> <line number="10" hits="1"/> <line number="11" hits="1"/> <line number="12" hits="1"/> - <line number="14" hits="1"/> - <line number="21" hits="1"/> + <line number="13" hits="1"/> + <line number="15" hits="1"/> <line number="22" hits="1"/> <line number="23" hits="1"/> - <line number="28" hits="1"/> + <line number="24" hits="1"/> <line number="29" hits="1"/> <line number="30" hits="1"/> <line number="31" hits="1"/> @@ -755,14 +763,15 @@ <line number="33" hits="1"/> <line number="34" hits="1"/> <line number="35" hits="1"/> - <line number="39" hits="1"/> + <line number="36" hits="1"/> <line number="40" hits="1"/> <line number="41" hits="1"/> <line number="42" hits="1"/> <line number="43" hits="1"/> - <line number="46" hits="1"/> + <line number="44" hits="1"/> <line number="47" hits="1"/> <line number="48" hits="1"/> + <line number="49" hits="1"/> </lines> </class> <class name="fastembed.py" filename="encoders/fastembed.py" complexity="0" line-rate="0.8667" branch-rate="0"> @@ -865,7 +874,7 @@ <line number="114" hits="0"/> </lines> </class> - <class name="mistral.py" filename="encoders/mistral.py" complexity="0" line-rate="0.95" branch-rate="0"> + <class name="mistral.py" filename="encoders/mistral.py" complexity="0" line-rate="0.9512" branch-rate="0"> <methods/> <lines> <line number="2" hits="1"/> @@ -875,11 +884,11 @@ <line number="7" hits="1"/> <line number="8" hits="1"/> <line number="10" hits="1"/> - <line number="13" hits="1"/> - <line number="16" hits="1"/> + <line number="11" hits="1"/> + <line number="14" hits="1"/> <line number="17" hits="1"/> - <line number="19" hits="1"/> - <line number="25" hits="1"/> + <line number="18" hits="1"/> + <line number="20" hits="1"/> <line number="26" hits="1"/> <line number="27" hits="1"/> <line number="28" hits="1"/> @@ -887,14 +896,14 @@ <line number="30" hits="1"/> <line number="31" hits="1"/> <line number="32" hits="1"/> - <line number="33" hits="0"/> + <line number="33" hits="1"/> <line number="34" hits="0"/> - <line number="36" hits="1"/> + <line number="35" hits="0"/> <line number="37" hits="1"/> <line number="38" hits="1"/> <line number="39" hits="1"/> <line number="40" hits="1"/> - <line number="43" hits="1"/> + <line number="41" hits="1"/> <line number="44" hits="1"/> <line number="45" hits="1"/> <line number="46" hits="1"/> @@ -904,13 +913,14 @@ <line number="50" hits="1"/> <line number="51" hits="1"/> <line number="52" hits="1"/> - <line number="54" hits="1"/> + <line number="53" hits="1"/> <line number="55" hits="1"/> <line number="56" hits="1"/> <line number="57" hits="1"/> + <line number="58" hits="1"/> </lines> </class> - <class name="openai.py" filename="encoders/openai.py" complexity="0" line-rate="0.9783" branch-rate="0"> + <class name="openai.py" filename="encoders/openai.py" complexity="0" line-rate="1" branch-rate="0"> <methods/> <lines> <line number="1" hits="1"/> @@ -922,43 +932,45 @@ <line number="8" hits="1"/> <line number="10" hits="1"/> <line number="11" hits="1"/> - <line number="14" hits="1"/> + <line number="12" hits="1"/> <line number="15" hits="1"/> <line number="16" hits="1"/> <line number="17" hits="1"/> - <line number="19" hits="1"/> - <line number="26" hits="1"/> - <line number="27" hits="1"/> + <line number="18" hits="1"/> + <line number="20" hits="1"/> <line number="28" hits="1"/> <line number="29" hits="1"/> <line number="30" hits="1"/> - <line number="31" hits="0"/> + <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="39" hits="1"/> - <line number="41" hits="1"/> + <line number="36" hits="1"/> + <line number="37" hits="1"/> + <line number="38" 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="55" hits="1"/> - <line number="56" hits="1"/> - <line number="57" hits="1"/> + <line number="51" hits="1"/> + <line number="52" hits="1"/> + <line number="53" hits="1"/> <line number="58" hits="1"/> <line number="59" hits="1"/> <line number="60" hits="1"/> <line number="61" hits="1"/> <line number="62" hits="1"/> <line number="63" hits="1"/> + <line number="64" hits="1"/> <line number="65" hits="1"/> - <line number="70" hits="1"/> - <line number="72" hits="1"/> + <line number="66" hits="1"/> + <line number="68" hits="1"/> <line number="73" hits="1"/> + <line number="75" hits="1"/> + <line number="76" hits="1"/> </lines> </class> <class name="tfidf.py" filename="encoders/tfidf.py" complexity="0" line-rate="0.9844" branch-rate="0"> @@ -1030,17 +1042,17 @@ <line number="80" hits="1"/> </lines> </class> - <class name="zure.py" filename="encoders/zure.py" complexity="0" line-rate="0.9444" branch-rate="0"> + <class name="vit.py" filename="encoders/vit.py" complexity="0" line-rate="0.4737" 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="5" hits="1"/> - <line number="6" hits="1"/> <line number="7" 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"/> @@ -1050,10 +1062,72 @@ <line number="19" hits="1"/> <line number="20" hits="1"/> <line number="22" hits="1"/> - <line number="31" hits="1"/> - <line number="32" hits="1"/> - <line number="33" hits="1"/> - <line number="34" hits="1"/> + <line number="23" hits="1"/> + <line number="24" 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="36" hits="0"/> + <line number="37" hits="0"/> + <line number="38" hits="0"/> + <line number="39" hits="0"/> + <line number="40" hits="0"/> + <line number="46" hits="0"/> + <line number="47" hits="0"/> + <line number="49" hits="0"/> + <line number="53" hits="0"/> + <line number="55" hits="0"/> + <line number="56" hits="0"/> + <line number="59" hits="0"/> + <line number="60" hits="0"/> + <line number="61" hits="0"/> + <line number="63" hits="0"/> + <line number="65" hits="1"/> + <line number="66" hits="0"/> + <line number="67" hits="0"/> + <line number="68" hits="0"/> + <line number="69" hits="0"/> + <line number="71" hits="1"/> + <line number="72" hits="0"/> + <line number="73" hits="0"/> + <line number="74" hits="0"/> + <line number="76" hits="1"/> + <line number="81" hits="0"/> + <line number="82" hits="0"/> + <line number="83" hits="0"/> + <line number="84" hits="0"/> + <line number="85" hits="0"/> + <line number="86" hits="0"/> + <line number="92" hits="0"/> + <line number="93" hits="0"/> + </lines> + </class> + <class name="zure.py" filename="encoders/zure.py" complexity="0" line-rate="0.9589" branch-rate="0"> + <methods/> + <lines> + <line number="1" hits="1"/> + <line number="2" hits="1"/> + <line number="3" hits="1"/> + <line number="5" hits="1"/> + <line number="6" hits="1"/> + <line number="7" hits="1"/> + <line number="9" hits="1"/> + <line number="10" hits="1"/> + <line number="11" 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="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"/> @@ -1062,54 +1136,300 @@ <line number="40" hits="1"/> <line number="41" hits="1"/> <line number="42" hits="1"/> - <line number="43" hits="0"/> + <line number="43" hits="1"/> <line number="44" hits="1"/> <line number="45" hits="1"/> + <line number="46" 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="0"/> + <line number="51" hits="0"/> + <line number="52" hits="1"/> <line number="53" hits="1"/> <line number="54" hits="1"/> - <line number="55" hits="1"/> - <line number="56" hits="0"/> + <line number="55" hits="0"/> + <line number="56" hits="1"/> <line number="57" hits="1"/> <line number="58" hits="1"/> - <line number="59" hits="1"/> - <line number="60" hits="0"/> - <line number="61" hits="1"/> + <line number="59" hits="0"/> + <line number="60" hits="1"/> + <line number="67" hits="1"/> <line number="68" hits="1"/> - <line number="69" hits="1"/> + <line number="75" hits="1"/> <line number="76" hits="1"/> - <line number="77" 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="85" hits="1"/> + <line number="87" hits="1"/> <line number="88" hits="1"/> <line number="89" hits="1"/> - <line number="90" hits="1"/> + <line number="92" hits="1"/> <line number="93" hits="1"/> <line number="94" hits="1"/> - <line number="95" hits="1"/> - <line number="97" hits="1"/> + <line number="96" hits="1"/> + <line number="98" hits="1"/> <line number="99" hits="1"/> <line number="100" hits="1"/> <line number="101" hits="1"/> <line number="102" hits="1"/> <line number="103" hits="1"/> <line number="104" hits="1"/> - <line number="105" hits="1"/> - <line number="107" hits="1"/> - <line number="112" hits="1"/> + <line number="106" hits="1"/> + <line number="111" hits="1"/> + <line number="113" hits="1"/> <line number="114" hits="1"/> - <line number="115" hits="1"/> </lines> </class> </classes> </package> - <package name="llms" line-rate="0.7214" branch-rate="0" complexity="0"> + <package name="index" line-rate="0.4842" branch-rate="0" complexity="0"> + <classes> + <class name="__init__.py" filename="index/__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="5" hits="1"/> + </lines> + </class> + <class name="base.py" filename="index/base.py" complexity="0" line-rate="0.7619" branch-rate="0"> + <methods/> + <lines> + <line number="1" hits="1"/> + <line number="3" hits="1"/> + <line number="4" hits="1"/> + <line number="7" 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="22" hits="1"/> + <line number="29" hits="0"/> + <line number="31" hits="1"/> + <line number="36" hits="0"/> + <line number="38" hits="1"/> + <line number="43" hits="0"/> + <line number="45" hits="1"/> + <line number="50" hits="0"/> + <line number="52" hits="1"/> + <line number="57" hits="0"/> + <line number="59" hits="1"/> + <line number="60" hits="1"/> + </lines> + </class> + <class name="local.py" filename="index/local.py" complexity="0" line-rate="0.8519" 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="9" hits="1"/> + <line number="10" hits="1"/> + <line number="16" hits="1"/> + <line number="17" hits="1"/> + <line number="19" hits="1"/> + <line number="20" hits="1"/> + <line number="22" hits="1"/> + <line number="25" hits="1"/> + <line number="26" hits="1"/> + <line number="27" hits="1"/> + <line number="28" hits="1"/> + <line number="30" hits="0"/> + <line number="31" hits="1"/> + <line number="32" hits="1"/> + <line number="33" hits="1"/> + <line number="34" hits="1"/> + <line number="36" hits="1"/> + <line number="37" hits="1"/> + <line number="38" hits="1"/> + <line number="40" hits="1"/> + <line number="47" hits="0"/> + <line number="48" hits="0"/> + <line number="49" hits="0"/> + <line number="51" hits="1"/> + <line number="52" hits="1"/> + <line number="58" hits="1"/> + <line number="62" hits="1"/> + <line number="63" hits="1"/> + <line number="64" hits="1"/> + <line number="66" hits="1"/> + <line number="68" hits="1"/> + <line number="69" hits="1"/> + <line number="71" hits="1"/> + <line number="75" hits="1"/> + <line number="80" hits="1"/> + <line number="81" hits="1"/> + <line number="82" hits="1"/> + <line number="83" hits="1"/> + <line number="85" hits="0"/> + <line number="89" hits="1"/> + <line number="93" hits="0"/> + <line number="95" hits="1"/> + <line number="97" hits="1"/> + <line number="98" hits="0"/> + <line number="99" hits="1"/> + <line number="100" hits="1"/> + <line number="102" hits="1"/> + <line number="103" hits="1"/> + <line number="104" hits="1"/> + <line number="106" hits="0"/> + </lines> + </class> + <class name="pinecone.py" filename="index/pinecone.py" complexity="0" line-rate="0.2887" 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"/> + <line number="7" hits="1"/> + <line number="8" hits="1"/> + <line number="10" hits="1"/> + <line number="11" hits="1"/> + <line number="14" hits="1"/> + <line number="15" hits="0"/> + <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="24" hits="1"/> + <line number="25" hits="0"/> + <line number="27" hits="0"/> + <line number="28" hits="0"/> + <line number="29" hits="0"/> + <line number="31" hits="1"/> + <line number="32" hits="0"/> + <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="52" hits="0"/> + <line number="53" hits="0"/> + <line number="55" hits="0"/> + <line number="56" hits="0"/> + <line number="57" hits="0"/> + <line number="58" hits="0"/> + <line number="60" hits="0"/> + <line number="62" hits="1"/> + <line number="63" hits="0"/> + <line number="64" hits="0"/> + <line number="66" hits="0"/> + <line number="67" hits="0"/> + <line number="68" hits="0"/> + <line number="73" hits="0"/> + <line number="74" hits="0"/> + <line number="75" hits="0"/> + <line number="76" hits="0"/> + <line number="78" hits="1"/> + <line number="79" hits="0"/> + <line number="80" hits="0"/> + <line number="81" hits="0"/> + <line number="84" hits="0"/> + <line number="91" hits="0"/> + <line number="92" hits="0"/> + <line number="93" hits="0"/> + <line number="94" hits="0"/> + <line number="95" hits="0"/> + <line number="97" hits="0"/> + <line number="99" hits="0"/> + <line number="100" hits="0"/> + <line number="101" hits="0"/> + <line number="107" hits="0"/> + <line number="108" hits="0"/> + <line number="109" hits="0"/> + <line number="110" hits="0"/> + <line number="111" hits="0"/> + <line number="113" hits="1"/> + <line number="116" hits="0"/> + <line number="117" hits="0"/> + <line number="119" hits="0"/> + <line number="120" hits="0"/> + <line number="121" hits="0"/> + <line number="122" hits="0"/> + <line number="123" hits="0"/> + <line number="124" hits="0"/> + <line number="125" hits="0"/> + <line number="127" hits="0"/> + <line number="129" hits="1"/> + <line number="130" hits="0"/> + <line number="131" hits="0"/> + <line number="132" hits="0"/> + <line number="134" hits="1"/> + <line number="138" hits="0"/> + <line number="139" hits="0"/> + <line number="140" hits="0"/> + <line number="141" hits="0"/> + <line number="143" hits="0"/> + <line number="144" hits="0"/> + <line number="146" hits="0"/> + <line number="149" hits="0"/> + <line number="150" hits="0"/> + <line number="151" hits="0"/> + <line number="152" hits="0"/> + <line number="154" hits="0"/> + <line number="155" hits="0"/> + <line number="156" hits="0"/> + <line number="159" hits="0"/> + <line number="160" hits="0"/> + <line number="163" hits="0"/> + <line number="165" hits="0"/> + <line number="166" hits="0"/> + <line number="167" hits="0"/> + <line number="170" hits="0"/> + <line number="171" hits="0"/> + <line number="173" hits="0"/> + <line number="176" hits="0"/> + <line number="177" hits="0"/> + <line number="178" hits="0"/> + <line number="180" hits="0"/> + <line number="182" hits="1"/> + <line number="190" hits="0"/> + <line number="191" hits="0"/> + <line number="192" hits="0"/> + <line number="194" hits="1"/> + <line number="195" hits="0"/> + <line number="196" hits="0"/> + <line number="197" hits="0"/> + <line number="199" hits="0"/> + <line number="201" hits="1"/> + <line number="202" hits="0"/> + <line number="204" hits="1"/> + <line number="205" hits="0"/> + <line number="206" hits="0"/> + <line number="207" hits="0"/> + <line number="213" hits="0"/> + <line number="215" hits="1"/> + <line number="216" hits="0"/> + <line number="217" hits="0"/> + <line number="218" hits="0"/> + <line number="219" hits="0"/> + <line number="224" hits="0"/> + <line number="225" hits="0"/> + <line number="226" hits="0"/> + <line number="228" hits="1"/> + <line number="229" hits="0"/> + <line number="231" hits="1"/> + <line number="232" hits="0"/> + </lines> + </class> + </classes> + </package> + <package name="llms" line-rate="0.7321" branch-rate="0" complexity="0"> <classes> <class name="__init__.py" filename="llms/__init__.py" complexity="0" line-rate="1" branch-rate="0"> <methods/> @@ -1248,7 +1568,7 @@ <line number="74" hits="0"/> </lines> </class> - <class name="mistral.py" filename="llms/mistral.py" complexity="0" line-rate="0.8286" branch-rate="0"> + <class name="mistral.py" filename="llms/mistral.py" complexity="0" line-rate="0.8333" branch-rate="0"> <methods/> <lines> <line number="1" hits="1"/> @@ -1257,12 +1577,12 @@ <line number="6" hits="1"/> <line number="7" hits="1"/> <line number="8" hits="1"/> - <line number="11" hits="1"/> + <line number="9" hits="1"/> <line number="12" hits="1"/> <line number="13" hits="1"/> <line number="14" hits="1"/> - <line number="16" hits="1"/> - <line number="23" hits="1"/> + <line number="15" hits="1"/> + <line number="17" hits="1"/> <line number="24" hits="1"/> <line number="25" hits="1"/> <line number="26" hits="1"/> @@ -1270,25 +1590,26 @@ <line number="28" hits="1"/> <line number="29" hits="1"/> <line number="30" hits="1"/> - <line number="31" hits="0"/> + <line number="31" hits="1"/> <line number="32" hits="0"/> - <line number="35" hits="1"/> + <line number="33" hits="0"/> <line number="36" hits="1"/> - <line number="38" hits="1"/> + <line number="37" hits="1"/> <line number="39" hits="1"/> <line number="40" hits="1"/> <line number="41" hits="1"/> <line number="42" hits="1"/> - <line number="49" hits="1"/> - <line number="51" hits="1"/> - <line number="52" hits="0"/> - <line number="53" hits="1"/> - <line number="54" hits="0"/> + <line number="43" hits="1"/> + <line number="50" hits="1"/> + <line number="52" hits="1"/> + <line number="53" hits="0"/> + <line number="54" hits="1"/> <line number="55" hits="0"/> <line number="56" hits="0"/> + <line number="57" hits="0"/> </lines> </class> - <class name="openai.py" filename="llms/openai.py" complexity="0" line-rate="0.8571" branch-rate="0"> + <class name="openai.py" filename="llms/openai.py" complexity="0" line-rate="0.8889" branch-rate="0"> <methods/> <lines> <line number="1" hits="1"/> @@ -1297,35 +1618,36 @@ <line number="6" hits="1"/> <line number="7" hits="1"/> <line number="8" hits="1"/> - <line number="11" hits="1"/> + <line number="9" hits="1"/> <line number="12" hits="1"/> <line number="13" hits="1"/> <line number="14" hits="1"/> - <line number="16" hits="1"/> - <line number="23" hits="1"/> + <line number="15" hits="1"/> + <line number="17" 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="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="35" hits="1"/> + <line number="33" hits="1"/> <line number="36" hits="1"/> - <line number="38" hits="1"/> + <line number="37" hits="1"/> <line number="39" hits="1"/> <line number="40" hits="1"/> <line number="41" hits="1"/> <line number="42" hits="1"/> - <line number="49" hits="1"/> - <line number="51" hits="1"/> - <line number="52" hits="0"/> - <line number="53" hits="1"/> - <line number="54" hits="0"/> + <line number="43" hits="1"/> + <line number="50" hits="1"/> + <line number="52" hits="1"/> + <line number="53" hits="0"/> + <line number="54" hits="1"/> <line number="55" hits="0"/> <line number="56" hits="0"/> + <line number="57" hits="0"/> </lines> </class> <class name="openrouter.py" filename="llms/openrouter.py" complexity="0" line-rate="0.8649" branch-rate="0"> @@ -1370,7 +1692,7 @@ <line number="61" hits="0"/> </lines> </class> - <class name="zure.py" filename="llms/zure.py" complexity="0" line-rate="0.8684" branch-rate="0"> + <class name="zure.py" filename="llms/zure.py" complexity="0" line-rate="0.8974" branch-rate="0"> <methods/> <lines> <line number="1" hits="1"/> @@ -1379,38 +1701,39 @@ <line number="6" hits="1"/> <line number="7" hits="1"/> <line number="8" hits="1"/> - <line number="11" hits="1"/> + <line number="9" hits="1"/> <line number="12" hits="1"/> <line number="13" hits="1"/> <line number="14" hits="1"/> - <line number="16" hits="1"/> - <line number="25" hits="1"/> + <line number="15" hits="1"/> + <line number="17" 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="0"/> + <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="38" hits="1"/> + <line number="36" hits="1"/> <line number="39" hits="1"/> <line number="40" hits="1"/> <line number="41" hits="1"/> - <line number="43" hits="1"/> + <line number="42" hits="1"/> <line number="44" hits="1"/> <line number="45" hits="1"/> <line number="46" hits="1"/> <line number="47" hits="1"/> - <line number="54" hits="1"/> - <line number="56" hits="1"/> - <line number="57" hits="0"/> - <line number="58" hits="1"/> - <line number="59" hits="0"/> + <line number="48" hits="1"/> + <line number="55" hits="1"/> + <line number="57" hits="1"/> + <line number="58" hits="0"/> + <line number="59" hits="1"/> <line number="60" hits="0"/> <line number="61" hits="0"/> + <line number="62" hits="0"/> </lines> </class> </classes> @@ -1504,12 +1827,25 @@ </class> </classes> </package> - <package name="utils" line-rate="0.4688" branch-rate="0" complexity="0"> + <package name="utils" line-rate="0.5278" 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="defaults.py" filename="utils/defaults.py" complexity="0" line-rate="1" branch-rate="0"> + <methods/> + <lines> + <line number="1" hits="1"/> + <line number="2" hits="1"/> + <line number="5" hits="1"/> + <line number="6" hits="1"/> + <line number="10" hits="1"/> + <line number="14" hits="1"/> + <line number="18" hits="1"/> + <line number="22" hits="1"/> + </lines> + </class> <class name="function_call.py" filename="utils/function_call.py" complexity="0" line-rate="0.3667" branch-rate="0"> <methods/> <lines> diff --git a/docs/05-local-execution.ipynb b/docs/05-local-execution.ipynb index 2ceaf072e4596b72ebf60446a7d053c8bb640444..e3e6572b9c79869c622e92a6796da33e89686316 100644 --- a/docs/05-local-execution.ipynb +++ b/docs/05-local-execution.ipynb @@ -351,7 +351,7 @@ " n_gpu_layers=-1 if enable_gpu else 0,\n", " n_ctx=2048,\n", ")\n", - "_llm.verbose=False\n", + "_llm.verbose = False\n", "llm = LlamaCppLLM(name=\"Mistral-7B-v0.2-Instruct\", llm=_llm, max_tokens=None)\n", "\n", "rl = RouteLayer(encoder=encoder, routes=routes, llm=llm)" diff --git a/docs/encoders/vision-transformer.ipynb b/docs/encoders/vision-transformer.ipynb index eee2a31460ff4b36c9b6c9b59c5b54c66fe9e6a6..c8f9d0b4b993caf71a51d143a06f912fecc9704c 100644 --- a/docs/encoders/vision-transformer.ipynb +++ b/docs/encoders/vision-transformer.ipynb @@ -73,7 +73,9 @@ "from datasets import load_dataset\n", "\n", "images = load_dataset(\"aurelio-ai/shrek-detection\")\n", - "shrek_entries = filter(lambda entry: entry[\"is_shrek\"], images[\"train\"]) # We only want Shrek images for our route\n", + "shrek_entries = filter(\n", + " lambda entry: entry[\"is_shrek\"], images[\"train\"]\n", + ") # We only want Shrek images for our route\n", "shrek_images = list(map(lambda entry: entry[\"image\"], shrek_entries))\n", "shrek_images" ] @@ -95,10 +97,7 @@ "source": [ "from semantic_router import Route\n", "\n", - "shrek = Route(\n", - " name=\"shrek\",\n", - " utterances=shrek_images\n", - ")\n", + "shrek = Route(name=\"shrek\", utterances=shrek_images)\n", "\n", "routes = [shrek]" ] @@ -131,7 +130,9 @@ "source": [ "from semantic_router.encoders import VitEncoder\n", "\n", - "encoder = VitEncoder(device=\"mps\") # Using MBP Metal acceleration (for other platforms, please see https://pytorch.org/docs/stable/tensor_attributes.html#torch.device)" + "encoder = VitEncoder(\n", + " device=\"mps\"\n", + ") # Using MBP Metal acceleration (for other platforms, please see https://pytorch.org/docs/stable/tensor_attributes.html#torch.device)" ] }, { @@ -179,12 +180,21 @@ "\n", "from PIL import Image\n", "\n", + "\n", "def load_img(url):\n", " resp = requests.get(url)\n", " return Image.open(BytesIO(resp.content))\n", "\n", - "test_shrek = load_img(\"https://static.wikia.nocookie.net/dreamworks/images/6/67/Shrek_Profile.jpg/revision/latest/thumbnail/width/360/height/360?cb=20231223041813\")\n", - "test_not_shrek = list(map(lambda entry: entry[\"image\"], filter(lambda entry: not entry[\"is_shrek\"], images[\"train\"])))[0]" + "\n", + "test_shrek = load_img(\n", + " \"https://static.wikia.nocookie.net/dreamworks/images/6/67/Shrek_Profile.jpg/revision/latest/thumbnail/width/360/height/360?cb=20231223041813\"\n", + ")\n", + "test_not_shrek = list(\n", + " map(\n", + " lambda entry: entry[\"image\"],\n", + " filter(lambda entry: not entry[\"is_shrek\"], images[\"train\"]),\n", + " )\n", + ")[0]" ] }, { diff --git a/docs/examples/pinecone-and-scaling.ipynb b/docs/examples/pinecone-and-scaling.ipynb index d541ee9b866e1b9f73bd319f2a80ffd7f58fe7bf..142380a596dbd658305fa4cae6d2b9904123ca81 100644 --- a/docs/examples/pinecone-and-scaling.ipynb +++ b/docs/examples/pinecone-and-scaling.ipynb @@ -1,876 +1,881 @@ { - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "id": "UxqB7_Ieur0s" - }, - "source": [ - "[](https://colab.research.google.com/github/aurelio-labs/semantic-router/blob/main/docs/examples/pinecone-and-scaling.ipynb) [](https://nbviewer.org/github/aurelio-labs/semantic-router/blob/main/docs/examples/pinecone-and-scaling.ipynb)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "EduhQaNAur0u" - }, - "source": [ - "# Scaling to Many Routes and Using Pinecone" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "_4JgNeX4ur0v" - }, - "source": [ - "Semantic router can be used with many hundreds, thousands, or even more routes. At very large scales it can be useful to use a vector database to store and search though your route vector space. Although we do not demonstrate _very large_ scale in this notebook, we will demonstrate more routes than usual and we will also see how to use the `PineconeIndex` for potential scalability and route persistence beyond our local machines." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "bbmw8CO4ur0v" - }, - "source": [ - "## Installing the Library" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "dLElfRhgur0v" - }, - "outputs": [], - "source": [ - "!pip install -qU \\\n", - " \"semantic-router[local, pinecone]==0.0.22\" \\\n", - " datasets==2.17.0" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Downloading Routes" - ] - }, - { - "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", - "Using the latest cached version of the dataset since aurelio-ai/generic-routes couldn't be found on the Hugging Face Hub\n", - "Found the latest cached dataset configuration 'default' at /Users/jamesbriggs/.cache/huggingface/datasets/aurelio-ai___generic-routes/default/0.0.0/5ed6ce316bb803dc716232e6c5f0eb1c7400e24d (last modified on Sun Feb 18 15:49:32 2024).\n" - ] - }, - { - "data": { - "text/plain": [ - "Dataset({\n", - " features: ['name', 'utterances', 'description', 'function_schema', 'llm', 'score_threshold'],\n", - " num_rows: 50\n", - "})" - ] - }, - "execution_count": 1, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from datasets import load_dataset\n", - "\n", - "data = load_dataset(\"aurelio-ai/generic-routes\", split=\"train\")\n", - "data" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Each row in this dataset is a single route:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'name': 'politics',\n", - " 'utterances': [\"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 presidentdon't you just hate the president\",\n", - " \"they're going to destroy this country!\",\n", - " 'they will save the country!'],\n", - " 'description': None,\n", - " 'function_schema': None,\n", - " 'llm': None,\n", - " 'score_threshold': 0.82}" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "data[0]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We transform these into `Route` objects like so:" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Route(name='politics', utterances=[\"isn't politics the best thing ever\", \"why don't you tell me about your political opinions\", \"don't you just love the presidentdon't you just hate the president\", \"they're going to destroy this country!\", 'they will save the country!'], description=None, function_schema=None, llm=None, score_threshold=0.82)" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from semantic_router import Route\n", - "\n", - "routes = [Route(**data[i]) for i in range(len(data))]\n", - "routes[0]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Next we initialize an `encoder`. We will use a simple `HuggingFaceEncoder`, we can also use popular encoder APIs like `CohereEncoder` and `OpenAIEncoder`." - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "BI9AiDspur0y", - "outputId": "27329a54-3f16-44a5-ac20-13a6b26afb97" - }, - "outputs": [], - "source": [ - "from semantic_router.encoders import HuggingFaceEncoder\n", - "\n", - "encoder = HuggingFaceEncoder()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now we initialize our `PineconeIndex`, all it requires is a [Pinecone API key](https://app.pinecone.io) (you do need to be using Pinecone Serverless)." - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001b[33m2024-02-18 17:11:50 WARNING semantic_router.utils.logger Index could not be initialized.\u001b[0m\n" - ] - } - ], - "source": [ - "import os\n", - "from getpass import getpass\n", - "from semantic_router.index import PineconeIndex\n", - "\n", - "os.environ[\"PINECONE_API_KEY\"] = os.environ.get(\"PINECONE_API_KEY\") or getpass(\"Enter Pinecone API key: \")\n", - "\n", - "index = PineconeIndex()" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001b[32m2024-02-18 17:12:21 INFO semantic_router.utils.logger local\u001b[0m\n" - ] - } - ], - "source": [ - "from semantic_router import RouteLayer\n", - "\n", - "rl = RouteLayer(encoder=encoder, routes=routes, index=index)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "GuLCeIS5ur0y" - }, - "source": [ - "We run the solely static routes layer:" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "_rNREh7gur0y", - "outputId": "f3a1dc0b-d760-4efb-b634-d3547011dcb7" - }, - "outputs": [ - { - "data": { - "text/plain": [ - "'chitchat'" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "rl(\"how's the weather today?\").name" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "_If you see a warning about no classification being found, wait a moment and run the above cell again._" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "McbLKO26ur0y" - }, - "source": [ - "## Loading Index From Previous Initialization" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "ANAoEjxYur0y" - }, - "source": [ - "Because we're using Pinecone our route index can now persist / be access from different locations by simply connecting to the pre-existing index, by default this index uses the identifier `\"semantic-router--index\"` — this is the index we'll be loading here, but we can change the name via the `index_name` parameter if preferred.\n", - "\n", - "First, let's delete our old route layer, `index`, and `routes`." - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": { - "id": "5jaF1Xa5ur0y" - }, - "outputs": [], - "source": [ - "del rl, index, routes" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Let's load our index first. As mentioned, `\"index\"` is the default index name, so we don't need to specify this parameter — but we do so below for demonstrative purposes." - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [], - "source": [ - "index = PineconeIndex(index_name=\"index\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We load the pre-existing routes from this index like so:" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[('fitness_tips', 'suggest a workout routine'),\n", - " ('daily_inspiration', 'give me an inspirational quote'),\n", - " ('creative_writing_and_literature', 'how can I improve my writing skills?'),\n", - " ('chitchat', \"let's go to the chippy\"),\n", - " ('astronomy_and_space_exploration',\n", - " 'what are some interesting facts about the universe?'),\n", - " ('chitchat', 'the weather is horrendous'),\n", - " ('cloud_computing', 'AWS vs Azure vs Google Cloud'),\n", - " ('chitchat', 'how are things going?'),\n", - " ('educational_facts', 'tell me an interesting fact'),\n", - " ('chitchat', \"how's the weather today?\"),\n", - " ('ethical_considerations_in_tech', 'ethical hacking and its importance'),\n", - " ('compliments', 'say something nice about me'),\n", - " ('food_and_recipes', \"what's your favorite food?\"),\n", - " ('interview_preparation', 'common programming interview questions'),\n", - " ('gaming_and_esports', 'what are the popular games right now?'),\n", - " ('frameworks_and_libraries',\n", - " \"what's the difference between React and Angular?\"),\n", - " ('environmental_awareness', 'how can I be more eco-friendly?'),\n", - " ('career_advice_in_tech',\n", - " 'how to build a portfolio for software development'),\n", - " ('educational_facts', 'do you know any historical trivia?'),\n", - " ('interview_preparation', 'tips for technical interviews'),\n", - " ('data_structures_and_algorithms', 'algorithms every developer should know'),\n", - " ('cybersecurity_best_practices', 'securing your web applications'),\n", - " ('jokes', 'know any good jokes?'),\n", - " ('interview_preparation', 'how to prepare for a coding interview'),\n", - " ('coding_standards_and_conventions', 'maintaining consistency in codebase'),\n", - " ('cloud_computing', 'best practices for cloud security'),\n", - " ('historical_events', 'tell me about a significant historical event'),\n", - " ('coding_standards_and_conventions', 'JavaScript coding conventions'),\n", - " ('career_advice_in_tech', 'navigating career growth in tech'),\n", - " ('development_tools', 'best Git clients for macOS'),\n", - " ('environmental_awareness', 'what are some ways to save the planet?'),\n", - " ('historical_events', 'who was a notable figure in ancient history?'),\n", - " ('career_advice', 'suggest some career development tips'),\n", - " ('compliments', 'I need some positive vibes'),\n", - " ('frameworks_and_libraries', 'best Python libraries for data analysis'),\n", - " ('book_recommendations', \"what's your favorite book?\"),\n", - " ('gardening_and_horticulture', 'suggest some easy-care indoor plants'),\n", - " ('mental_health_support', 'what are ways to improve mental health?'),\n", - " ('data_structures_and_algorithms', 'basic data structures for beginners'),\n", - " ('hobbies_and_interests', 'suggest me a hobby'),\n", - " ('career_advice_in_tech', 'tips for landing your first tech job'),\n", - " ('art_and_culture', \"what's an interesting cultural tradition?\"),\n", - " ('language_learning', 'suggest ways to learn a new language'),\n", - " ('cybersecurity_best_practices',\n", - " 'introduction to ethical hacking for developers'),\n", - " ('debugging_tips', 'tips for debugging asynchronous code'),\n", - " ('coding_standards_and_conventions', 'why coding standards matter'),\n", - " ('daily_inspiration', 'share something uplifting'),\n", - " ('environmental_awareness', 'tell me about sustainability practices'),\n", - " ('career_advice', 'how can I improve my resume?'),\n", - " ('daily_inspiration', 'I need some inspiration for today'),\n", - " ('debugging_tips', 'best tools for JavaScript debugging'),\n", - " ('food_and_recipes', 'tell me about a dish from your country'),\n", - " ('jokes', 'make me laugh'),\n", - " ('best_practices', 'best practices for error handling in JavaScript'),\n", - " ('gaming_and_esports', 'suggest a good game for beginners'),\n", - " ('hobbies_and_interests', 'what are your interests?'),\n", - " ('machine_learning_in_development', 'using TensorFlow for beginners'),\n", - " ('language_syntax', 'how do closures work in JavaScript?'),\n", - " ('machine_learning_in_development',\n", - " 'machine learning model deployment best practices'),\n", - " ('gaming_and_esports', 'tell me about upcoming esports events'),\n", - " ('art_and_culture', 'suggest some must-visit museums'),\n", - " ('language_learning', 'how can I improve my Spanish?'),\n", - " ('mindfulness_and_wellness', 'how can I relax?'),\n", - " ('astronomy_and_space_exploration', 'tell me about the latest space mission'),\n", - " ('machine_learning_in_development',\n", - " 'how to start with machine learning in Python'),\n", - " ('frameworks_and_libraries', 'introduction to Django for web development'),\n", - " ('data_structures_and_algorithms', 'complexity analysis of algorithms'),\n", - " ('debugging_tips', 'how do I debug segmentation faults in C++?'),\n", - " ('career_advice', 'what are the emerging career fields?'),\n", - " ('creative_writing_and_literature', 'suggest some classic literature'),\n", - " ('hobbies_and_interests', \"I'm looking for a new pastime\"),\n", - " ('best_practices', 'how to write clean code in Python'),\n", - " ('fitness_tips', 'how can I stay active at home?'),\n", - " ('ethical_considerations_in_tech',\n", - " 'the role of ethics in artificial intelligence'),\n", - " ('cloud_computing', 'introduction to cloud storage options'),\n", - " ('ethical_considerations_in_tech', 'privacy concerns in app development'),\n", - " ('language_syntax', 'explain the syntax of Python functions'),\n", - " ('creative_writing_and_literature', 'what are some tips for storytelling?'),\n", - " ('cybersecurity_best_practices', 'common security vulnerabilities to avoid'),\n", - " ('book_recommendations', 'I need a book recommendation'),\n", - " ('mental_health_support', 'how can I manage stress?'),\n", - " ('chitchat', 'lovely weather today'),\n", - " ('mental_health_support', 'share some self-care practices'),\n", - " ('best_practices', 'what are the best practices for REST API design?'),\n", - " ('food_and_recipes', 'suggest a recipe for dinner'),\n", - " ('language_syntax', 'what are the new features in Java 15?'),\n", - " ('gardening_and_horticulture', 'how do I start a vegetable garden?'),\n", - " ('language_learning',\n", - " 'what are some effective language learning techniques?'),\n", - " ('historical_events', 'share an interesting piece of medieval history'),\n", - " ('mindfulness_and_wellness', 'tell me about mindfulness'),\n", - " ('development_tools', 'using Docker in development'),\n", - " ('book_recommendations', 'suggest a good book to read'),\n", - " ('gardening_and_horticulture',\n", - " 'what are some tips for sustainable gardening?'),\n", - " ('art_and_culture', 'tell me about your favorite artist'),\n", - " ('educational_facts', 'share a science fact'),\n", - " ('astronomy_and_space_exploration', 'how can I stargaze effectively?'),\n", - " ('fitness_tips', 'give me a fitness tip'),\n", - " ('development_tools', 'recommendations for Python IDEs'),\n", - " ('jokes', 'tell me a joke'),\n", - " ('compliments', 'give me a compliment'),\n", - " ('politics', \"why don't you tell me about your political opinions\"),\n", - " ('pet_care_advice', 'suggest some tips for cat care'),\n", - " ('music_discovery', 'suggest some new music'),\n", - " ('personal_questions', \"what's your favorite color?\"),\n", - " ('travel_stories', 'tell me about your favorite travel destination'),\n", - " ('tech_trends', 'tell me about the latest gadgets'),\n", - " ('science_and_innovation', 'tell me about a recent innovation'),\n", - " ('programming_challenges', 'suggest a coding challenge for beginners'),\n", - " ('project_management_in_tech', 'agile vs waterfall project management'),\n", - " ('science_and_innovation', 'what are the latest scientific discoveries?'),\n", - " ('programming_challenges', 'where can I find algorithmic puzzles?'),\n", - " ('personal_questions', 'what do you like to do for fun?'),\n", - " ('open_source_contributions', 'best practices for open-source contributors'),\n", - " ('music_discovery', 'who are the top artists right now?'),\n", - " ('mobile_app_development', 'optimizing performance in mobile apps'),\n", - " ('open_source_contributions', 'how to start contributing to open source'),\n", - " ('programming_challenges', 'programming tasks to improve problem-solving'),\n", - " ('politics', \"isn't politics the best thing ever\"),\n", - " ('politics',\n", - " \"don't you just love the presidentdon't you just hate the president\"),\n", - " ('project_management_in_tech', 'how to lead a development team'),\n", - " ('philosophical_questions', 'what is the meaning of life?'),\n", - " ('version_control_systems', 'introduction to SVN for beginners'),\n", - " ('software_architecture', 'explain microservices architecture'),\n", - " ('version_control_systems', 'best practices for branching in Git'),\n", - " ('pet_care_advice', 'what should I know about keeping a pet rabbit?'),\n", - " ('politics', 'they will save the country!'),\n", - " ('pet_care_advice', 'how can I train my dog?'),\n", - " ('philosophical_questions', 'what are your thoughts on free will?'),\n", - " ('mobile_app_development',\n", - " 'best tools for cross-platform mobile development'),\n", - " ('personal_questions', 'do you have any hobbies?'),\n", - " ('travel_stories', 'share a travel story'),\n", - " ('science_and_innovation', 'how does AI impact our daily lives?'),\n", - " ('movie_suggestions', \"what's your favorite movie?\"),\n", - " ('mobile_app_development', 'Kotlin vs Swift for mobile development'),\n", - " ('mindfulness_and_wellness', 'give me a wellness tip'),\n", - " ('motivation', 'I need some motivation'),\n", - " ('music_discovery', 'recommend songs for a workout playlist'),\n", - " ('software_architecture', 'introduction to domain-driven design'),\n", - " ('software_architecture', 'differences between MVC and MVVM'),\n", - " ('movie_suggestions', 'suggest a good movie for tonight'),\n", - " ('web_development_trends', 'emerging back-end technologies'),\n", - " ('philosophical_questions', 'do you believe in fate?'),\n", - " ('web_development_trends', 'the future of web development'),\n", - " ('web_development_trends', \"what's new in front-end development?\"),\n", - " ('motivation', 'give me a motivational quote'),\n", - " ('tech_trends', \"what's new in technology?\"),\n", - " ('version_control_systems', 'how to revert a commit in Git'),\n", - " ('project_management_in_tech', 'tools for managing tech projects'),\n", - " ('movie_suggestions', 'recommend a movie'),\n", - " ('motivation', 'inspire me'),\n", - " ('travel_stories', \"what's the most interesting place you've visited?\"),\n", - " ('tech_trends', 'what are the emerging tech trends?'),\n", - " ('politics', \"they're going to destroy this country!\"),\n", - " ('open_source_contributions', 'finding projects that accept contributions')]" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "index.get_routes()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We will transform these into a dictionary format that we can use to initialize our `Route` objects." - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [], - "source": [ - "routes_dict = {}\n", - "for route, utterance in index.get_routes():\n", - " if route not in routes_dict:\n", - " routes_dict[route] = []\n", - " routes_dict[route].append(utterance)" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'jokes': ['tell me a joke', 'make me laugh', 'know any good jokes?'],\n", - " 'career_advice': ['suggest some career development tips',\n", - " 'what are the emerging career fields?',\n", - " 'how can I improve my resume?'],\n", - " 'environmental_awareness': ['tell me about sustainability practices',\n", - " 'how can I be more eco-friendly?',\n", - " 'what are some ways to save the planet?'],\n", - " 'data_structures_and_algorithms': ['algorithms every developer should know',\n", - " 'basic data structures for beginners',\n", - " 'complexity analysis of algorithms'],\n", - " 'chitchat': ['lovely weather today',\n", - " \"how's the weather today?\",\n", - " 'how are things going?',\n", - " 'the weather is horrendous',\n", - " \"let's go to the chippy\"],\n", - " 'daily_inspiration': ['share something uplifting',\n", - " 'give me an inspirational quote',\n", - " 'I need some inspiration for today'],\n", - " 'career_advice_in_tech': ['how to build a portfolio for software development',\n", - " 'navigating career growth in tech',\n", - " 'tips for landing your first tech job'],\n", - " 'cloud_computing': ['best practices for cloud security',\n", - " 'introduction to cloud storage options',\n", - " 'AWS vs Azure vs Google Cloud'],\n", - " 'language_syntax': ['explain the syntax of Python functions',\n", - " 'how do closures work in JavaScript?',\n", - " 'what are the new features in Java 15?'],\n", - " 'art_and_culture': [\"what's an interesting cultural tradition?\",\n", - " 'suggest some must-visit museums',\n", - " 'tell me about your favorite artist'],\n", - " 'hobbies_and_interests': [\"I'm looking for a new pastime\",\n", - " 'what are your interests?',\n", - " 'suggest me a hobby'],\n", - " 'mental_health_support': ['what are ways to improve mental health?',\n", - " 'how can I manage stress?',\n", - " 'share some self-care practices'],\n", - " 'gardening_and_horticulture': ['how do I start a vegetable garden?',\n", - " 'suggest some easy-care indoor plants',\n", - " 'what are some tips for sustainable gardening?'],\n", - " 'book_recommendations': ['I need a book recommendation',\n", - " \"what's your favorite book?\",\n", - " 'suggest a good book to read'],\n", - " 'development_tools': ['best Git clients for macOS',\n", - " 'using Docker in development',\n", - " 'recommendations for Python IDEs'],\n", - " 'debugging_tips': ['best tools for JavaScript debugging',\n", - " 'how do I debug segmentation faults in C++?',\n", - " 'tips for debugging asynchronous code'],\n", - " 'cybersecurity_best_practices': ['securing your web applications',\n", - " 'common security vulnerabilities to avoid',\n", - " 'introduction to ethical hacking for developers'],\n", - " 'interview_preparation': ['how to prepare for a coding interview',\n", - " 'common programming interview questions',\n", - " 'tips for technical interviews'],\n", - " 'best_practices': ['how to write clean code in Python',\n", - " 'best practices for error handling in JavaScript',\n", - " 'what are the best practices for REST API design?'],\n", - " 'educational_facts': ['do you know any historical trivia?',\n", - " 'share a science fact',\n", - " 'tell me an interesting fact'],\n", - " 'language_learning': ['what are some effective language learning techniques?',\n", - " 'suggest ways to learn a new language',\n", - " 'how can I improve my Spanish?'],\n", - " 'mindfulness_and_wellness': ['tell me about mindfulness',\n", - " 'how can I relax?',\n", - " 'give me a wellness tip'],\n", - " 'gaming_and_esports': ['suggest a good game for beginners',\n", - " 'what are the popular games right now?',\n", - " 'tell me about upcoming esports events'],\n", - " 'historical_events': ['tell me about a significant historical event',\n", - " 'who was a notable figure in ancient history?',\n", - " 'share an interesting piece of medieval history'],\n", - " 'frameworks_and_libraries': ['best Python libraries for data analysis',\n", - " 'introduction to Django for web development',\n", - " \"what's the difference between React and Angular?\"],\n", - " 'food_and_recipes': ['suggest a recipe for dinner',\n", - " 'tell me about a dish from your country',\n", - " \"what's your favorite food?\"],\n", - " 'fitness_tips': ['suggest a workout routine',\n", - " 'give me a fitness tip',\n", - " 'how can I stay active at home?'],\n", - " 'ethical_considerations_in_tech': ['ethical hacking and its importance',\n", - " 'privacy concerns in app development',\n", - " 'the role of ethics in artificial intelligence'],\n", - " 'astronomy_and_space_exploration': ['tell me about the latest space mission',\n", - " 'what are some interesting facts about the universe?',\n", - " 'how can I stargaze effectively?'],\n", - " 'creative_writing_and_literature': ['what are some tips for storytelling?',\n", - " 'suggest some classic literature',\n", - " 'how can I improve my writing skills?'],\n", - " 'machine_learning_in_development': ['using TensorFlow for beginners',\n", - " 'machine learning model deployment best practices',\n", - " 'how to start with machine learning in Python'],\n", - " 'compliments': ['give me a compliment',\n", - " 'say something nice about me',\n", - " 'I need some positive vibes'],\n", - " 'coding_standards_and_conventions': ['maintaining consistency in codebase',\n", - " 'why coding standards matter',\n", - " 'JavaScript coding conventions'],\n", - " 'politics': [\"why don't you tell me about your political opinions\",\n", - " \"they're going to destroy this country!\",\n", - " 'they will save the country!',\n", - " \"isn't politics the best thing ever\",\n", - " \"don't you just love the presidentdon't you just hate the president\"],\n", - " 'motivation': ['give me a motivational quote',\n", - " 'inspire me',\n", - " 'I need some motivation'],\n", - " 'movie_suggestions': ['recommend a movie',\n", - " \"what's your favorite movie?\",\n", - " 'suggest a good movie for tonight'],\n", - " 'music_discovery': ['suggest some new music',\n", - " 'recommend songs for a workout playlist',\n", - " 'who are the top artists right now?'],\n", - " 'web_development_trends': [\"what's new in front-end development?\",\n", - " 'emerging back-end technologies',\n", - " 'the future of web development'],\n", - " 'science_and_innovation': ['tell me about a recent innovation',\n", - " 'how does AI impact our daily lives?',\n", - " 'what are the latest scientific discoveries?'],\n", - " 'open_source_contributions': ['best practices for open-source contributors',\n", - " 'how to start contributing to open source',\n", - " 'finding projects that accept contributions'],\n", - " 'travel_stories': [\"what's the most interesting place you've visited?\",\n", - " 'tell me about your favorite travel destination',\n", - " 'share a travel story'],\n", - " 'pet_care_advice': ['how can I train my dog?',\n", - " 'suggest some tips for cat care',\n", - " 'what should I know about keeping a pet rabbit?'],\n", - " 'mobile_app_development': ['Kotlin vs Swift for mobile development',\n", - " 'optimizing performance in mobile apps',\n", - " 'best tools for cross-platform mobile development'],\n", - " 'version_control_systems': ['introduction to SVN for beginners',\n", - " 'how to revert a commit in Git',\n", - " 'best practices for branching in Git'],\n", - " 'project_management_in_tech': ['agile vs waterfall project management',\n", - " 'tools for managing tech projects',\n", - " 'how to lead a development team'],\n", - " 'programming_challenges': ['where can I find algorithmic puzzles?',\n", - " 'programming tasks to improve problem-solving',\n", - " 'suggest a coding challenge for beginners'],\n", - " 'tech_trends': [\"what's new in technology?\",\n", - " 'tell me about the latest gadgets',\n", - " 'what are the emerging tech trends?'],\n", - " 'software_architecture': ['introduction to domain-driven design',\n", - " 'differences between MVC and MVVM',\n", - " 'explain microservices architecture'],\n", - " 'philosophical_questions': ['what is the meaning of life?',\n", - " 'do you believe in fate?',\n", - " 'what are your thoughts on free will?'],\n", - " 'personal_questions': [\"what's your favorite color?\",\n", - " 'what do you like to do for fun?',\n", - " 'do you have any hobbies?']}" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "routes_dict" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now we transform these into a list of `Route` objects." - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Route(name='jokes', utterances=['tell me a joke', 'make me laugh', 'know any good jokes?'], description=None, function_schema=None, llm=None, score_threshold=None)" - ] - }, - "execution_count": 15, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "routes = [Route(name=route, utterances=utterances) for route, utterances in routes_dict.items()]\n", - "routes[0]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now we reinitialize our `RouteLayer`:" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 35 - }, - "id": "YyFKV8jMur0z", - "outputId": "29cf80f4-552c-47bb-fbf9-019f5dfdf00a" - }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001b[32m2024-02-18 17:16:19 INFO semantic_router.utils.logger local\u001b[0m\n" - ] - } - ], - "source": [ - "from semantic_router import RouteLayer\n", - "\n", - "rl = RouteLayer(encoder=encoder, routes=routes, index=index)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "And test it again:" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'jokes'" - ] - }, - "execution_count": 18, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "rl(\"say something to make me laugh\").name" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'jokes'" - ] - }, - "execution_count": 21, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "rl(\"tell me something amusing\").name" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'chitchat'" - ] - }, - "execution_count": 27, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "rl(\"it's raining cats and dogs today\").name" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "Qt0vkq2Xur00" - }, - "source": [ - "Perfect, our routes loaded from our `PineconeIndex` are working as expected! As mentioned, we can use the `PineconeIndex` for persistance and high scale use-cases, for example where we might have hundreds of thousands of utterances, or even millions." - ] + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "UxqB7_Ieur0s" + }, + "source": [ + "[](https://colab.research.google.com/github/aurelio-labs/semantic-router/blob/main/docs/examples/pinecone-and-scaling.ipynb) [](https://nbviewer.org/github/aurelio-labs/semantic-router/blob/main/docs/examples/pinecone-and-scaling.ipynb)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EduhQaNAur0u" + }, + "source": [ + "# Scaling to Many Routes and Using Pinecone" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_4JgNeX4ur0v" + }, + "source": [ + "Semantic router can be used with many hundreds, thousands, or even more routes. At very large scales it can be useful to use a vector database to store and search though your route vector space. Although we do not demonstrate _very large_ scale in this notebook, we will demonstrate more routes than usual and we will also see how to use the `PineconeIndex` for potential scalability and route persistence beyond our local machines." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bbmw8CO4ur0v" + }, + "source": [ + "## Installing the Library" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "dLElfRhgur0v" + }, + "outputs": [], + "source": [ + "!pip install -qU \\\n", + " \"semantic-router[local, pinecone]==0.0.22\" \\\n", + " datasets==2.17.0" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Downloading Routes" + ] + }, + { + "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", + "Using the latest cached version of the dataset since aurelio-ai/generic-routes couldn't be found on the Hugging Face Hub\n", + "Found the latest cached dataset configuration 'default' at /Users/jamesbriggs/.cache/huggingface/datasets/aurelio-ai___generic-routes/default/0.0.0/5ed6ce316bb803dc716232e6c5f0eb1c7400e24d (last modified on Sun Feb 18 15:49:32 2024).\n" + ] + }, + { + "data": { + "text/plain": [ + "Dataset({\n", + " features: ['name', 'utterances', 'description', 'function_schema', 'llm', 'score_threshold'],\n", + " num_rows: 50\n", + "})" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from datasets import load_dataset\n", + "\n", + "data = load_dataset(\"aurelio-ai/generic-routes\", split=\"train\")\n", + "data" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Each row in this dataset is a single route:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'name': 'politics',\n", + " 'utterances': [\"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 presidentdon't you just hate the president\",\n", + " \"they're going to destroy this country!\",\n", + " 'they will save the country!'],\n", + " 'description': None,\n", + " 'function_schema': None,\n", + " 'llm': None,\n", + " 'score_threshold': 0.82}" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data[0]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We transform these into `Route` objects like so:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Route(name='politics', utterances=[\"isn't politics the best thing ever\", \"why don't you tell me about your political opinions\", \"don't you just love the presidentdon't you just hate the president\", \"they're going to destroy this country!\", 'they will save the country!'], description=None, function_schema=None, llm=None, score_threshold=0.82)" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from semantic_router import Route\n", + "\n", + "routes = [Route(**data[i]) for i in range(len(data))]\n", + "routes[0]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Next we initialize an `encoder`. We will use a simple `HuggingFaceEncoder`, we can also use popular encoder APIs like `CohereEncoder` and `OpenAIEncoder`." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "BI9AiDspur0y", + "outputId": "27329a54-3f16-44a5-ac20-13a6b26afb97" + }, + "outputs": [], + "source": [ + "from semantic_router.encoders import HuggingFaceEncoder\n", + "\n", + "encoder = HuggingFaceEncoder()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we initialize our `PineconeIndex`, all it requires is a [Pinecone API key](https://app.pinecone.io) (you do need to be using Pinecone Serverless)." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[33m2024-02-18 17:11:50 WARNING semantic_router.utils.logger Index could not be initialized.\u001b[0m\n" + ] + } + ], + "source": [ + "import os\n", + "from getpass import getpass\n", + "from semantic_router.index import PineconeIndex\n", + "\n", + "os.environ[\"PINECONE_API_KEY\"] = os.environ.get(\"PINECONE_API_KEY\") or getpass(\n", + " \"Enter Pinecone API key: \"\n", + ")\n", + "\n", + "index = PineconeIndex()" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m2024-02-18 17:12:21 INFO semantic_router.utils.logger local\u001b[0m\n" + ] + } + ], + "source": [ + "from semantic_router import RouteLayer\n", + "\n", + "rl = RouteLayer(encoder=encoder, routes=routes, index=index)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "GuLCeIS5ur0y" + }, + "source": [ + "We run the solely static routes layer:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" }, + "id": "_rNREh7gur0y", + "outputId": "f3a1dc0b-d760-4efb-b634-d3547011dcb7" + }, + "outputs": [ { - "cell_type": "markdown", - "metadata": { - "id": "J0oD1dxIur00" - }, - "source": [ - "---" + "data": { + "text/plain": [ + "'chitchat'" ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" } - ], - "metadata": { + ], + "source": [ + "rl(\"how's the weather today?\").name" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "_If you see a warning about no classification being found, wait a moment and run the above cell again._" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "McbLKO26ur0y" + }, + "source": [ + "## Loading Index From Previous Initialization" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ANAoEjxYur0y" + }, + "source": [ + "Because we're using Pinecone our route index can now persist / be access from different locations by simply connecting to the pre-existing index, by default this index uses the identifier `\"semantic-router--index\"` — this is the index we'll be loading here, but we can change the name via the `index_name` parameter if preferred.\n", + "\n", + "First, let's delete our old route layer, `index`, and `routes`." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "id": "5jaF1Xa5ur0y" + }, + "outputs": [], + "source": [ + "del rl, index, routes" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's load our index first. As mentioned, `\"index\"` is the default index name, so we don't need to specify this parameter — but we do so below for demonstrative purposes." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "index = PineconeIndex(index_name=\"index\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We load the pre-existing routes from this index like so:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[('fitness_tips', 'suggest a workout routine'),\n", + " ('daily_inspiration', 'give me an inspirational quote'),\n", + " ('creative_writing_and_literature', 'how can I improve my writing skills?'),\n", + " ('chitchat', \"let's go to the chippy\"),\n", + " ('astronomy_and_space_exploration',\n", + " 'what are some interesting facts about the universe?'),\n", + " ('chitchat', 'the weather is horrendous'),\n", + " ('cloud_computing', 'AWS vs Azure vs Google Cloud'),\n", + " ('chitchat', 'how are things going?'),\n", + " ('educational_facts', 'tell me an interesting fact'),\n", + " ('chitchat', \"how's the weather today?\"),\n", + " ('ethical_considerations_in_tech', 'ethical hacking and its importance'),\n", + " ('compliments', 'say something nice about me'),\n", + " ('food_and_recipes', \"what's your favorite food?\"),\n", + " ('interview_preparation', 'common programming interview questions'),\n", + " ('gaming_and_esports', 'what are the popular games right now?'),\n", + " ('frameworks_and_libraries',\n", + " \"what's the difference between React and Angular?\"),\n", + " ('environmental_awareness', 'how can I be more eco-friendly?'),\n", + " ('career_advice_in_tech',\n", + " 'how to build a portfolio for software development'),\n", + " ('educational_facts', 'do you know any historical trivia?'),\n", + " ('interview_preparation', 'tips for technical interviews'),\n", + " ('data_structures_and_algorithms', 'algorithms every developer should know'),\n", + " ('cybersecurity_best_practices', 'securing your web applications'),\n", + " ('jokes', 'know any good jokes?'),\n", + " ('interview_preparation', 'how to prepare for a coding interview'),\n", + " ('coding_standards_and_conventions', 'maintaining consistency in codebase'),\n", + " ('cloud_computing', 'best practices for cloud security'),\n", + " ('historical_events', 'tell me about a significant historical event'),\n", + " ('coding_standards_and_conventions', 'JavaScript coding conventions'),\n", + " ('career_advice_in_tech', 'navigating career growth in tech'),\n", + " ('development_tools', 'best Git clients for macOS'),\n", + " ('environmental_awareness', 'what are some ways to save the planet?'),\n", + " ('historical_events', 'who was a notable figure in ancient history?'),\n", + " ('career_advice', 'suggest some career development tips'),\n", + " ('compliments', 'I need some positive vibes'),\n", + " ('frameworks_and_libraries', 'best Python libraries for data analysis'),\n", + " ('book_recommendations', \"what's your favorite book?\"),\n", + " ('gardening_and_horticulture', 'suggest some easy-care indoor plants'),\n", + " ('mental_health_support', 'what are ways to improve mental health?'),\n", + " ('data_structures_and_algorithms', 'basic data structures for beginners'),\n", + " ('hobbies_and_interests', 'suggest me a hobby'),\n", + " ('career_advice_in_tech', 'tips for landing your first tech job'),\n", + " ('art_and_culture', \"what's an interesting cultural tradition?\"),\n", + " ('language_learning', 'suggest ways to learn a new language'),\n", + " ('cybersecurity_best_practices',\n", + " 'introduction to ethical hacking for developers'),\n", + " ('debugging_tips', 'tips for debugging asynchronous code'),\n", + " ('coding_standards_and_conventions', 'why coding standards matter'),\n", + " ('daily_inspiration', 'share something uplifting'),\n", + " ('environmental_awareness', 'tell me about sustainability practices'),\n", + " ('career_advice', 'how can I improve my resume?'),\n", + " ('daily_inspiration', 'I need some inspiration for today'),\n", + " ('debugging_tips', 'best tools for JavaScript debugging'),\n", + " ('food_and_recipes', 'tell me about a dish from your country'),\n", + " ('jokes', 'make me laugh'),\n", + " ('best_practices', 'best practices for error handling in JavaScript'),\n", + " ('gaming_and_esports', 'suggest a good game for beginners'),\n", + " ('hobbies_and_interests', 'what are your interests?'),\n", + " ('machine_learning_in_development', 'using TensorFlow for beginners'),\n", + " ('language_syntax', 'how do closures work in JavaScript?'),\n", + " ('machine_learning_in_development',\n", + " 'machine learning model deployment best practices'),\n", + " ('gaming_and_esports', 'tell me about upcoming esports events'),\n", + " ('art_and_culture', 'suggest some must-visit museums'),\n", + " ('language_learning', 'how can I improve my Spanish?'),\n", + " ('mindfulness_and_wellness', 'how can I relax?'),\n", + " ('astronomy_and_space_exploration', 'tell me about the latest space mission'),\n", + " ('machine_learning_in_development',\n", + " 'how to start with machine learning in Python'),\n", + " ('frameworks_and_libraries', 'introduction to Django for web development'),\n", + " ('data_structures_and_algorithms', 'complexity analysis of algorithms'),\n", + " ('debugging_tips', 'how do I debug segmentation faults in C++?'),\n", + " ('career_advice', 'what are the emerging career fields?'),\n", + " ('creative_writing_and_literature', 'suggest some classic literature'),\n", + " ('hobbies_and_interests', \"I'm looking for a new pastime\"),\n", + " ('best_practices', 'how to write clean code in Python'),\n", + " ('fitness_tips', 'how can I stay active at home?'),\n", + " ('ethical_considerations_in_tech',\n", + " 'the role of ethics in artificial intelligence'),\n", + " ('cloud_computing', 'introduction to cloud storage options'),\n", + " ('ethical_considerations_in_tech', 'privacy concerns in app development'),\n", + " ('language_syntax', 'explain the syntax of Python functions'),\n", + " ('creative_writing_and_literature', 'what are some tips for storytelling?'),\n", + " ('cybersecurity_best_practices', 'common security vulnerabilities to avoid'),\n", + " ('book_recommendations', 'I need a book recommendation'),\n", + " ('mental_health_support', 'how can I manage stress?'),\n", + " ('chitchat', 'lovely weather today'),\n", + " ('mental_health_support', 'share some self-care practices'),\n", + " ('best_practices', 'what are the best practices for REST API design?'),\n", + " ('food_and_recipes', 'suggest a recipe for dinner'),\n", + " ('language_syntax', 'what are the new features in Java 15?'),\n", + " ('gardening_and_horticulture', 'how do I start a vegetable garden?'),\n", + " ('language_learning',\n", + " 'what are some effective language learning techniques?'),\n", + " ('historical_events', 'share an interesting piece of medieval history'),\n", + " ('mindfulness_and_wellness', 'tell me about mindfulness'),\n", + " ('development_tools', 'using Docker in development'),\n", + " ('book_recommendations', 'suggest a good book to read'),\n", + " ('gardening_and_horticulture',\n", + " 'what are some tips for sustainable gardening?'),\n", + " ('art_and_culture', 'tell me about your favorite artist'),\n", + " ('educational_facts', 'share a science fact'),\n", + " ('astronomy_and_space_exploration', 'how can I stargaze effectively?'),\n", + " ('fitness_tips', 'give me a fitness tip'),\n", + " ('development_tools', 'recommendations for Python IDEs'),\n", + " ('jokes', 'tell me a joke'),\n", + " ('compliments', 'give me a compliment'),\n", + " ('politics', \"why don't you tell me about your political opinions\"),\n", + " ('pet_care_advice', 'suggest some tips for cat care'),\n", + " ('music_discovery', 'suggest some new music'),\n", + " ('personal_questions', \"what's your favorite color?\"),\n", + " ('travel_stories', 'tell me about your favorite travel destination'),\n", + " ('tech_trends', 'tell me about the latest gadgets'),\n", + " ('science_and_innovation', 'tell me about a recent innovation'),\n", + " ('programming_challenges', 'suggest a coding challenge for beginners'),\n", + " ('project_management_in_tech', 'agile vs waterfall project management'),\n", + " ('science_and_innovation', 'what are the latest scientific discoveries?'),\n", + " ('programming_challenges', 'where can I find algorithmic puzzles?'),\n", + " ('personal_questions', 'what do you like to do for fun?'),\n", + " ('open_source_contributions', 'best practices for open-source contributors'),\n", + " ('music_discovery', 'who are the top artists right now?'),\n", + " ('mobile_app_development', 'optimizing performance in mobile apps'),\n", + " ('open_source_contributions', 'how to start contributing to open source'),\n", + " ('programming_challenges', 'programming tasks to improve problem-solving'),\n", + " ('politics', \"isn't politics the best thing ever\"),\n", + " ('politics',\n", + " \"don't you just love the presidentdon't you just hate the president\"),\n", + " ('project_management_in_tech', 'how to lead a development team'),\n", + " ('philosophical_questions', 'what is the meaning of life?'),\n", + " ('version_control_systems', 'introduction to SVN for beginners'),\n", + " ('software_architecture', 'explain microservices architecture'),\n", + " ('version_control_systems', 'best practices for branching in Git'),\n", + " ('pet_care_advice', 'what should I know about keeping a pet rabbit?'),\n", + " ('politics', 'they will save the country!'),\n", + " ('pet_care_advice', 'how can I train my dog?'),\n", + " ('philosophical_questions', 'what are your thoughts on free will?'),\n", + " ('mobile_app_development',\n", + " 'best tools for cross-platform mobile development'),\n", + " ('personal_questions', 'do you have any hobbies?'),\n", + " ('travel_stories', 'share a travel story'),\n", + " ('science_and_innovation', 'how does AI impact our daily lives?'),\n", + " ('movie_suggestions', \"what's your favorite movie?\"),\n", + " ('mobile_app_development', 'Kotlin vs Swift for mobile development'),\n", + " ('mindfulness_and_wellness', 'give me a wellness tip'),\n", + " ('motivation', 'I need some motivation'),\n", + " ('music_discovery', 'recommend songs for a workout playlist'),\n", + " ('software_architecture', 'introduction to domain-driven design'),\n", + " ('software_architecture', 'differences between MVC and MVVM'),\n", + " ('movie_suggestions', 'suggest a good movie for tonight'),\n", + " ('web_development_trends', 'emerging back-end technologies'),\n", + " ('philosophical_questions', 'do you believe in fate?'),\n", + " ('web_development_trends', 'the future of web development'),\n", + " ('web_development_trends', \"what's new in front-end development?\"),\n", + " ('motivation', 'give me a motivational quote'),\n", + " ('tech_trends', \"what's new in technology?\"),\n", + " ('version_control_systems', 'how to revert a commit in Git'),\n", + " ('project_management_in_tech', 'tools for managing tech projects'),\n", + " ('movie_suggestions', 'recommend a movie'),\n", + " ('motivation', 'inspire me'),\n", + " ('travel_stories', \"what's the most interesting place you've visited?\"),\n", + " ('tech_trends', 'what are the emerging tech trends?'),\n", + " ('politics', \"they're going to destroy this country!\"),\n", + " ('open_source_contributions', 'finding projects that accept contributions')]" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "index.get_routes()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We will transform these into a dictionary format that we can use to initialize our `Route` objects." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "routes_dict = {}\n", + "for route, utterance in index.get_routes():\n", + " if route not in routes_dict:\n", + " routes_dict[route] = []\n", + " routes_dict[route].append(utterance)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'jokes': ['tell me a joke', 'make me laugh', 'know any good jokes?'],\n", + " 'career_advice': ['suggest some career development tips',\n", + " 'what are the emerging career fields?',\n", + " 'how can I improve my resume?'],\n", + " 'environmental_awareness': ['tell me about sustainability practices',\n", + " 'how can I be more eco-friendly?',\n", + " 'what are some ways to save the planet?'],\n", + " 'data_structures_and_algorithms': ['algorithms every developer should know',\n", + " 'basic data structures for beginners',\n", + " 'complexity analysis of algorithms'],\n", + " 'chitchat': ['lovely weather today',\n", + " \"how's the weather today?\",\n", + " 'how are things going?',\n", + " 'the weather is horrendous',\n", + " \"let's go to the chippy\"],\n", + " 'daily_inspiration': ['share something uplifting',\n", + " 'give me an inspirational quote',\n", + " 'I need some inspiration for today'],\n", + " 'career_advice_in_tech': ['how to build a portfolio for software development',\n", + " 'navigating career growth in tech',\n", + " 'tips for landing your first tech job'],\n", + " 'cloud_computing': ['best practices for cloud security',\n", + " 'introduction to cloud storage options',\n", + " 'AWS vs Azure vs Google Cloud'],\n", + " 'language_syntax': ['explain the syntax of Python functions',\n", + " 'how do closures work in JavaScript?',\n", + " 'what are the new features in Java 15?'],\n", + " 'art_and_culture': [\"what's an interesting cultural tradition?\",\n", + " 'suggest some must-visit museums',\n", + " 'tell me about your favorite artist'],\n", + " 'hobbies_and_interests': [\"I'm looking for a new pastime\",\n", + " 'what are your interests?',\n", + " 'suggest me a hobby'],\n", + " 'mental_health_support': ['what are ways to improve mental health?',\n", + " 'how can I manage stress?',\n", + " 'share some self-care practices'],\n", + " 'gardening_and_horticulture': ['how do I start a vegetable garden?',\n", + " 'suggest some easy-care indoor plants',\n", + " 'what are some tips for sustainable gardening?'],\n", + " 'book_recommendations': ['I need a book recommendation',\n", + " \"what's your favorite book?\",\n", + " 'suggest a good book to read'],\n", + " 'development_tools': ['best Git clients for macOS',\n", + " 'using Docker in development',\n", + " 'recommendations for Python IDEs'],\n", + " 'debugging_tips': ['best tools for JavaScript debugging',\n", + " 'how do I debug segmentation faults in C++?',\n", + " 'tips for debugging asynchronous code'],\n", + " 'cybersecurity_best_practices': ['securing your web applications',\n", + " 'common security vulnerabilities to avoid',\n", + " 'introduction to ethical hacking for developers'],\n", + " 'interview_preparation': ['how to prepare for a coding interview',\n", + " 'common programming interview questions',\n", + " 'tips for technical interviews'],\n", + " 'best_practices': ['how to write clean code in Python',\n", + " 'best practices for error handling in JavaScript',\n", + " 'what are the best practices for REST API design?'],\n", + " 'educational_facts': ['do you know any historical trivia?',\n", + " 'share a science fact',\n", + " 'tell me an interesting fact'],\n", + " 'language_learning': ['what are some effective language learning techniques?',\n", + " 'suggest ways to learn a new language',\n", + " 'how can I improve my Spanish?'],\n", + " 'mindfulness_and_wellness': ['tell me about mindfulness',\n", + " 'how can I relax?',\n", + " 'give me a wellness tip'],\n", + " 'gaming_and_esports': ['suggest a good game for beginners',\n", + " 'what are the popular games right now?',\n", + " 'tell me about upcoming esports events'],\n", + " 'historical_events': ['tell me about a significant historical event',\n", + " 'who was a notable figure in ancient history?',\n", + " 'share an interesting piece of medieval history'],\n", + " 'frameworks_and_libraries': ['best Python libraries for data analysis',\n", + " 'introduction to Django for web development',\n", + " \"what's the difference between React and Angular?\"],\n", + " 'food_and_recipes': ['suggest a recipe for dinner',\n", + " 'tell me about a dish from your country',\n", + " \"what's your favorite food?\"],\n", + " 'fitness_tips': ['suggest a workout routine',\n", + " 'give me a fitness tip',\n", + " 'how can I stay active at home?'],\n", + " 'ethical_considerations_in_tech': ['ethical hacking and its importance',\n", + " 'privacy concerns in app development',\n", + " 'the role of ethics in artificial intelligence'],\n", + " 'astronomy_and_space_exploration': ['tell me about the latest space mission',\n", + " 'what are some interesting facts about the universe?',\n", + " 'how can I stargaze effectively?'],\n", + " 'creative_writing_and_literature': ['what are some tips for storytelling?',\n", + " 'suggest some classic literature',\n", + " 'how can I improve my writing skills?'],\n", + " 'machine_learning_in_development': ['using TensorFlow for beginners',\n", + " 'machine learning model deployment best practices',\n", + " 'how to start with machine learning in Python'],\n", + " 'compliments': ['give me a compliment',\n", + " 'say something nice about me',\n", + " 'I need some positive vibes'],\n", + " 'coding_standards_and_conventions': ['maintaining consistency in codebase',\n", + " 'why coding standards matter',\n", + " 'JavaScript coding conventions'],\n", + " 'politics': [\"why don't you tell me about your political opinions\",\n", + " \"they're going to destroy this country!\",\n", + " 'they will save the country!',\n", + " \"isn't politics the best thing ever\",\n", + " \"don't you just love the presidentdon't you just hate the president\"],\n", + " 'motivation': ['give me a motivational quote',\n", + " 'inspire me',\n", + " 'I need some motivation'],\n", + " 'movie_suggestions': ['recommend a movie',\n", + " \"what's your favorite movie?\",\n", + " 'suggest a good movie for tonight'],\n", + " 'music_discovery': ['suggest some new music',\n", + " 'recommend songs for a workout playlist',\n", + " 'who are the top artists right now?'],\n", + " 'web_development_trends': [\"what's new in front-end development?\",\n", + " 'emerging back-end technologies',\n", + " 'the future of web development'],\n", + " 'science_and_innovation': ['tell me about a recent innovation',\n", + " 'how does AI impact our daily lives?',\n", + " 'what are the latest scientific discoveries?'],\n", + " 'open_source_contributions': ['best practices for open-source contributors',\n", + " 'how to start contributing to open source',\n", + " 'finding projects that accept contributions'],\n", + " 'travel_stories': [\"what's the most interesting place you've visited?\",\n", + " 'tell me about your favorite travel destination',\n", + " 'share a travel story'],\n", + " 'pet_care_advice': ['how can I train my dog?',\n", + " 'suggest some tips for cat care',\n", + " 'what should I know about keeping a pet rabbit?'],\n", + " 'mobile_app_development': ['Kotlin vs Swift for mobile development',\n", + " 'optimizing performance in mobile apps',\n", + " 'best tools for cross-platform mobile development'],\n", + " 'version_control_systems': ['introduction to SVN for beginners',\n", + " 'how to revert a commit in Git',\n", + " 'best practices for branching in Git'],\n", + " 'project_management_in_tech': ['agile vs waterfall project management',\n", + " 'tools for managing tech projects',\n", + " 'how to lead a development team'],\n", + " 'programming_challenges': ['where can I find algorithmic puzzles?',\n", + " 'programming tasks to improve problem-solving',\n", + " 'suggest a coding challenge for beginners'],\n", + " 'tech_trends': [\"what's new in technology?\",\n", + " 'tell me about the latest gadgets',\n", + " 'what are the emerging tech trends?'],\n", + " 'software_architecture': ['introduction to domain-driven design',\n", + " 'differences between MVC and MVVM',\n", + " 'explain microservices architecture'],\n", + " 'philosophical_questions': ['what is the meaning of life?',\n", + " 'do you believe in fate?',\n", + " 'what are your thoughts on free will?'],\n", + " 'personal_questions': [\"what's your favorite color?\",\n", + " 'what do you like to do for fun?',\n", + " 'do you have any hobbies?']}" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "routes_dict" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we transform these into a list of `Route` objects." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Route(name='jokes', utterances=['tell me a joke', 'make me laugh', 'know any good jokes?'], description=None, function_schema=None, llm=None, score_threshold=None)" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "routes = [\n", + " Route(name=route, utterances=utterances)\n", + " for route, utterances in routes_dict.items()\n", + "]\n", + "routes[0]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we reinitialize our `RouteLayer`:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { "colab": { - "provenance": [] - }, - "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" + "base_uri": "https://localhost:8080/", + "height": 35 + }, + "id": "YyFKV8jMur0z", + "outputId": "29cf80f4-552c-47bb-fbf9-019f5dfdf00a" + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m2024-02-18 17:16:19 INFO semantic_router.utils.logger local\u001b[0m\n" + ] } + ], + "source": [ + "from semantic_router import RouteLayer\n", + "\n", + "rl = RouteLayer(encoder=encoder, routes=routes, index=index)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And test it again:" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'jokes'" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "rl(\"say something to make me laugh\").name" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'jokes'" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "rl(\"tell me something amusing\").name" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'chitchat'" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "rl(\"it's raining cats and dogs today\").name" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Qt0vkq2Xur00" + }, + "source": [ + "Perfect, our routes loaded from our `PineconeIndex` are working as expected! As mentioned, we can use the `PineconeIndex` for persistance and high scale use-cases, for example where we might have hundreds of thousands of utterances, or even millions." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "J0oD1dxIur00" + }, + "source": [ + "---" + ] + } + ], + "metadata": { + "colab": { + "provenance": [] + }, + "kernelspec": { + "display_name": "decision-layer", + "language": "python", + "name": "python3" }, - "nbformat": 4, - "nbformat_minor": 0 + "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": 0 } diff --git a/docs/examples/video-splitter.ipynb b/docs/examples/video-splitter.ipynb index 0f06a5e94f7d5c32b5f7f3ac44de719f5c065678..5b44f85eacd58e4aa9e206a0354681c995315c8b 100644 --- a/docs/examples/video-splitter.ipynb +++ b/docs/examples/video-splitter.ipynb @@ -34,10 +34,11 @@ ], "source": [ "import cv2\n", - "vidcap = cv2.VideoCapture('https://www.w3schools.com/html/mov_bbb.mp4')\n", + "\n", + "vidcap = cv2.VideoCapture(\"https://www.w3schools.com/html/mov_bbb.mp4\")\n", "\n", "frames = []\n", - "success,image = vidcap.read()\n", + "success, image = vidcap.read()\n", "while success:\n", " frames.append(image)\n", " success, image = vidcap.read()\n", @@ -155,14 +156,14 @@ "source": [ "import matplotlib.pyplot as plt\n", "\n", - "f, axarr = plt.subplots(len(splits), 3, figsize=(20,5))\n", + "f, axarr = plt.subplots(len(splits), 3, figsize=(20, 5))\n", "\n", "for i, split in enumerate(splits):\n", - " axarr[i,0].imshow(split.docs[0])\n", + " axarr[i, 0].imshow(split.docs[0])\n", " num_docs = len(split.docs)\n", " mid = num_docs // 2\n", - " axarr[i,1].imshow(split.docs[mid])\n", - " axarr[i,2].imshow(split.docs[num_docs-1])" + " axarr[i, 1].imshow(split.docs[mid])\n", + " axarr[i, 2].imshow(split.docs[num_docs - 1])" ] }, { @@ -209,10 +210,12 @@ } ], "source": [ - "vidcap = cv2.VideoCapture('http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/WeAreGoingOnBullrun.mp4')\n", + "vidcap = cv2.VideoCapture(\n", + " \"http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/WeAreGoingOnBullrun.mp4\"\n", + ")\n", "\n", "frames = []\n", - "success,image = vidcap.read()\n", + "success, image = vidcap.read()\n", "while success:\n", " frames.append(image)\n", " success, image = vidcap.read()\n", @@ -268,14 +271,14 @@ "source": [ "import matplotlib.pyplot as plt\n", "\n", - "f, axarr = plt.subplots(len(splits), 3, figsize=(20,60))\n", + "f, axarr = plt.subplots(len(splits), 3, figsize=(20, 60))\n", "\n", "for i, split in enumerate(splits):\n", - " axarr[i,0].imshow(split.docs[0])\n", + " axarr[i, 0].imshow(split.docs[0])\n", " num_docs = len(split.docs)\n", " mid = num_docs // 2\n", - " axarr[i,1].imshow(split.docs[mid])\n", - " axarr[i,2].imshow(split.docs[num_docs-1])" + " axarr[i, 1].imshow(split.docs[mid])\n", + " axarr[i, 2].imshow(split.docs[num_docs - 1])" ] } ], diff --git a/docs/indexes/pinecone.ipynb b/docs/indexes/pinecone.ipynb index 849afea4535e5f263542ccf2eec7ed97ccc49fec..8236c15525d08e389416c5a87a22f453f4f689c0 100644 --- a/docs/indexes/pinecone.ipynb +++ b/docs/indexes/pinecone.ipynb @@ -66,7 +66,9 @@ "from semantic_router.encoders import OpenAIEncoder\n", "\n", "# get at platform.openai.com\n", - "os.environ[\"OPENAI_API_KEY\"] = os.environ.get(\"OPENAI_API_KEY\") or getpass(\"Enter OpenAI API key: \")\n", + "os.environ[\"OPENAI_API_KEY\"] = os.environ.get(\"OPENAI_API_KEY\") or getpass(\n", + " \"Enter OpenAI API key: \"\n", + ")\n", "encoder = OpenAIEncoder()" ] }, @@ -79,7 +81,9 @@ "from semantic_router.index.pinecone import PineconeIndex\n", "\n", "# get at app.pinecone.io\n", - "os.environ[\"PINECONE_API_KEY\"] = os.environ.get(\"PINECONE_API_KEY\") or getpass(\"Enter Pinecone API key: \")\n", + "os.environ[\"PINECONE_API_KEY\"] = os.environ.get(\"PINECONE_API_KEY\") or getpass(\n", + " \"Enter Pinecone API key: \"\n", + ")\n", "pc_index = PineconeIndex()" ] }, diff --git a/poetry.lock b/poetry.lock index e62acb3cf0c8cb590e87d60e49282cf29026acd7..1f68d5a7e70ac6c73db6fe986666a264df5417fe 100644 --- a/poetry.lock +++ b/poetry.lock @@ -3599,9 +3599,9 @@ fastembed = ["fastembed"] hybrid = ["pinecone-text"] local = ["llama-cpp-python", "torch", "transformers"] pinecone = ["pinecone-client"] -vision = ["pillow", "torchvision"] +vision = ["pillow", "torch", "torchvision", "transformers"] [metadata] lock-version = "2.0" python-versions = ">=3.9,<3.13" -content-hash = "8e996c0bf391fd54ea5a52867a097339a2e00f6ddec661336a57e325d4c6c895" +content-hash = "26f85562a59d475cc411ed0aa003cc84cd8ebc328cfafed1c74e77d0aaa544d3" diff --git a/semantic_router/encoders/cohere.py b/semantic_router/encoders/cohere.py index 6bc7d661b1794fc0c23443e06dab78a977fa9d28..b49769eb4c1b32c36467d299f4905477b522bb1a 100644 --- a/semantic_router/encoders/cohere.py +++ b/semantic_router/encoders/cohere.py @@ -4,6 +4,7 @@ from typing import List, Optional import cohere from semantic_router.encoders import BaseEncoder +from semantic_router.utils.defaults import EncoderDefault class CohereEncoder(BaseEncoder): @@ -19,7 +20,7 @@ class CohereEncoder(BaseEncoder): input_type: Optional[str] = "search_query", ): if name is None: - name = os.getenv("COHERE_MODEL_NAME", "embed-english-v3.0") + name = EncoderDefault.COHERE.value["embedding_model"] super().__init__( name=name, score_threshold=score_threshold, diff --git a/semantic_router/encoders/mistral.py b/semantic_router/encoders/mistral.py index 88857de3e61e19984f5ee1036c1097bd9245c8b2..c76f1e74a1e86ede34f87ca6857c17dd71487ccd 100644 --- a/semantic_router/encoders/mistral.py +++ b/semantic_router/encoders/mistral.py @@ -8,6 +8,7 @@ from mistralai.exceptions import MistralException from mistralai.models.embeddings import EmbeddingResponse from semantic_router.encoders import BaseEncoder +from semantic_router.utils.defaults import EncoderDefault class MistralEncoder(BaseEncoder): @@ -23,7 +24,7 @@ class MistralEncoder(BaseEncoder): score_threshold: float = 0.82, ): if name is None: - name = os.getenv("MISTRAL_MODEL_NAME", "mistral-embed") + name = EncoderDefault.MISTRAL.value["embedding_model"] super().__init__(name=name, score_threshold=score_threshold) api_key = mistralai_api_key or os.getenv("MISTRALAI_API_KEY") if api_key is None: diff --git a/semantic_router/encoders/openai.py b/semantic_router/encoders/openai.py index 14fda1c99adee1a60a9f03621ade6f93151410db..7699c3c1558cde828055d28b1c313424d3253a54 100644 --- a/semantic_router/encoders/openai.py +++ b/semantic_router/encoders/openai.py @@ -8,6 +8,7 @@ from openai._types import NotGiven from openai.types import CreateEmbeddingResponse from semantic_router.encoders import BaseEncoder +from semantic_router.utils.defaults import EncoderDefault from semantic_router.utils.logger import logger @@ -25,7 +26,7 @@ class OpenAIEncoder(BaseEncoder): dimensions: Union[int, NotGiven] = NotGiven(), ): if name is None: - name = os.getenv("OPENAI_MODEL_NAME", "text-embedding-ada-002") + name = EncoderDefault.OPENAI.value["embedding_model"] super().__init__(name=name, score_threshold=score_threshold) api_key = openai_api_key or os.getenv("OPENAI_API_KEY") openai_org_id = openai_org_id or os.getenv("OPENAI_ORG_ID") diff --git a/semantic_router/encoders/zure.py b/semantic_router/encoders/zure.py index b53fb66259ba38879827594dc7fdd6b106eb9409..8a43e361e43fa1228fd57b737237d8e02aba099f 100644 --- a/semantic_router/encoders/zure.py +++ b/semantic_router/encoders/zure.py @@ -7,6 +7,7 @@ from openai import OpenAIError from openai.types import CreateEmbeddingResponse from semantic_router.encoders import BaseEncoder +from semantic_router.utils.defaults import EncoderDefault from semantic_router.utils.logger import logger @@ -30,7 +31,7 @@ class AzureOpenAIEncoder(BaseEncoder): ): name = deployment_name if name is None: - name = os.getenv("AZURE_OPENAI_DEPLOYMENT_NAME", "text-embedding-ada-002") + name = EncoderDefault.AZURE.value["embedding_model"] super().__init__(name=name, score_threshold=score_threshold) self.api_key = api_key self.deployment_name = deployment_name @@ -42,9 +43,7 @@ class AzureOpenAIEncoder(BaseEncoder): if self.api_key is None: raise ValueError("No Azure OpenAI API key provided.") if self.deployment_name is None: - self.deployment_name = os.getenv( - "AZURE_OPENAI_DEPLOYMENT_NAME", "text-embedding-ada-002" - ) + self.deployment_name = EncoderDefault.AZURE.value["deployment_name"] # deployment_name may still be None, but it is optional in the API if self.azure_endpoint is None: self.azure_endpoint = os.getenv("AZURE_OPENAI_ENDPOINT") diff --git a/semantic_router/layer.py b/semantic_router/layer.py index 186b32d0e8b829aced4fa1e2caeb7d75bf048b14..0635c1ea9beef2afb4437b2406dc421ca831fbfd 100644 --- a/semantic_router/layer.py +++ b/semantic_router/layer.py @@ -14,6 +14,7 @@ from semantic_router.index.local import LocalIndex from semantic_router.llms import BaseLLM, OpenAILLM from semantic_router.route import Route from semantic_router.schema import Encoder, EncoderType, RouteChoice +from semantic_router.utils.defaults import EncoderDefault from semantic_router.utils.logger import logger @@ -62,17 +63,16 @@ class LayerConfig: ): self.encoder_type = encoder_type if encoder_name is None: - # if encoder_name is not provided, use the default encoder for type - # TODO base these values on default values in encoders themselves.. - # TODO without initializing them (as this is just config) - if encoder_type == EncoderType.OPENAI: - encoder_name = "text-embedding-ada-002" - elif encoder_type == EncoderType.COHERE: - encoder_name = "embed-english-v3.0" - elif encoder_type == EncoderType.FASTEMBED: - encoder_name = "BAAI/bge-small-en-v1.5" - elif encoder_type == EncoderType.HUGGINGFACE: - raise NotImplementedError + for encode_type in EncoderType: + if encode_type.value == self.encoder_type: + if self.encoder_type == EncoderType.HUGGINGFACE.value: + raise NotImplementedError( + "HuggingFace encoder not supported by LayerConfig yet." + ) + encoder_name = EncoderDefault[encode_type.name].value[ + "embedding_model" + ] + break logger.info(f"Using default {encoder_type} encoder: {encoder_name}") self.encoder_name = encoder_name self.routes = routes diff --git a/semantic_router/llms/mistral.py b/semantic_router/llms/mistral.py index 0f74bcbde93e17f3faf1e95dd4d3bbe791a4155c..e17ba8bab050d6dbdccf3f22376729fd921c692e 100644 --- a/semantic_router/llms/mistral.py +++ b/semantic_router/llms/mistral.py @@ -5,6 +5,7 @@ from mistralai.client import MistralClient from semantic_router.llms import BaseLLM from semantic_router.schema import Message +from semantic_router.utils.defaults import EncoderDefault from semantic_router.utils.logger import logger @@ -21,7 +22,7 @@ class MistralAILLM(BaseLLM): max_tokens: int = 200, ): if name is None: - name = os.getenv("MISTRALAI_CHAT_MODEL_NAME", "mistral-tiny") + name = EncoderDefault.MISTRAL.value["language_model"] super().__init__(name=name) api_key = mistralai_api_key or os.getenv("MISTRALAI_API_KEY") if api_key is None: diff --git a/semantic_router/llms/openai.py b/semantic_router/llms/openai.py index a93ce0e7ab2747fc77e537e485b7699779919e04..892375945f4064c4b9af1f70e4be3463a4993d0d 100644 --- a/semantic_router/llms/openai.py +++ b/semantic_router/llms/openai.py @@ -5,6 +5,7 @@ import openai from semantic_router.llms import BaseLLM from semantic_router.schema import Message +from semantic_router.utils.defaults import EncoderDefault from semantic_router.utils.logger import logger @@ -21,7 +22,7 @@ class OpenAILLM(BaseLLM): max_tokens: int = 200, ): if name is None: - name = os.getenv("OPENAI_CHAT_MODEL_NAME", "gpt-3.5-turbo") + name = EncoderDefault.OPENAI.value["language_model"] super().__init__(name=name) api_key = openai_api_key or os.getenv("OPENAI_API_KEY") if api_key is None: diff --git a/semantic_router/llms/zure.py b/semantic_router/llms/zure.py index d3af1cdadcae57460c6a94491bfd6e7960e2b5f8..26b7901f7b595ed1705a81484598f4389a242d26 100644 --- a/semantic_router/llms/zure.py +++ b/semantic_router/llms/zure.py @@ -5,6 +5,7 @@ import openai from semantic_router.llms import BaseLLM from semantic_router.schema import Message +from semantic_router.utils.defaults import EncoderDefault from semantic_router.utils.logger import logger @@ -23,7 +24,7 @@ class AzureOpenAILLM(BaseLLM): api_version="2023-07-01-preview", ): if name is None: - name = os.getenv("OPENAI_CHAT_MODEL_NAME", "gpt-3.5-turbo") + name = EncoderDefault.AZURE.value["language_model"] super().__init__(name=name) api_key = openai_api_key or os.getenv("AZURE_OPENAI_API_KEY") if api_key is None: diff --git a/semantic_router/utils/defaults.py b/semantic_router/utils/defaults.py new file mode 100644 index 0000000000000000000000000000000000000000..7b5a3b5f9485ab5fe4b1f31d9fd391e944da09b6 --- /dev/null +++ b/semantic_router/utils/defaults.py @@ -0,0 +1,28 @@ +import os +from enum import Enum + + +class EncoderDefault(Enum): + FASTEMBED = { + "embedding_model": "BAAI/bge-small-en-v1.5", + "language_model": "BAAI/bge-small-en-v1.5", + } + OPENAI = { + "embedding_model": os.getenv("OPENAI_MODEL_NAME", "text-embedding-ada-002"), + "language_model": os.getenv("OPENAI_CHAT_MODEL_NAME", "gpt-3.5-turbo"), + } + COHERE = { + "embedding_model": os.getenv("COHERE_MODEL_NAME", "embed-english-v3.0"), + "language_model": os.getenv("COHERE_CHAT_MODEL_NAME", "command"), + } + MISTRAL = { + "embedding_model": os.getenv("MISTRAL_MODEL_NAME", "mistral-embed"), + "language_model": os.getenv("MISTRALAI_CHAT_MODEL_NAME", "mistral-tiny"), + } + AZURE = { + "embedding_model": os.getenv("AZURE_OPENAI_MODEL", "text-embedding-ada-002"), + "language_model": os.getenv("OPENAI_CHAT_MODEL_NAME", "gpt-3.5-turbo"), + "deployment_name": os.getenv( + "AZURE_OPENAI_DEPLOYMENT_NAME", "text-embedding-ada-002" + ), + }