semantic-router 0.1.0.dev2__tar.gz → 0.1.0.dev3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/LICENSE +1 -1
- {semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/PKG-INFO +12 -10
- {semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/pyproject.toml +10 -10
- {semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/__init__.py +1 -1
- {semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/encoders/aurelio.py +1 -1
- {semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/encoders/base.py +2 -2
- {semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/encoders/clip.py +3 -2
- {semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/encoders/cohere.py +1 -1
- {semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/encoders/fastembed.py +1 -1
- {semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/encoders/huggingface.py +5 -3
- {semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/encoders/mistral.py +1 -1
- {semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/encoders/openai.py +9 -9
- {semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/encoders/vit.py +4 -3
- {semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/index/base.py +1 -1
- {semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/index/pinecone.py +1 -1
- {semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/index/postgres.py +3 -2
- {semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/index/qdrant.py +2 -2
- {semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/llms/base.py +3 -1
- {semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/llms/cohere.py +1 -1
- {semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/llms/llamacpp.py +1 -3
- {semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/llms/mistral.py +1 -3
- {semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/llms/ollama.py +5 -10
- {semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/llms/openai.py +9 -10
- {semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/llms/openrouter.py +8 -8
- {semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/llms/zure.py +5 -6
- {semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/route.py +2 -7
- {semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/routers/base.py +1 -1
- {semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/routers/hybrid.py +1 -1
- {semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/schema.py +14 -2
- {semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/utils/function_call.py +1 -1
- {semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/README.md +0 -0
- {semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/encoders/__init__.py +0 -0
- {semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/encoders/bedrock.py +0 -0
- {semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/encoders/bm25.py +0 -0
- {semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/encoders/google.py +0 -0
- {semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/encoders/tfidf.py +0 -0
- {semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/encoders/zure.py +0 -0
- {semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/index/__init__.py +0 -0
- {semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/index/hybrid_local.py +0 -0
- {semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/index/local.py +0 -0
- {semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/linear.py +0 -0
- {semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/llms/__init__.py +0 -0
- {semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/llms/grammars/json.gbnf +0 -0
- {semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/routers/__init__.py +0 -0
- {semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/routers/semantic.py +0 -0
- {semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/utils/__init__.py +0 -0
- {semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/utils/defaults.py +0 -0
- {semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/utils/llm.py +0 -0
- {semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/utils/logger.py +0 -0
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: semantic-router
|
|
3
|
-
Version: 0.1.0.
|
|
3
|
+
Version: 0.1.0.dev3
|
|
4
4
|
Summary: Super fast semantic router for AI decision making
|
|
5
5
|
License: MIT
|
|
6
6
|
Author: Aurelio AI
|
|
7
7
|
Author-email: hello@aurelio.ai
|
|
8
|
-
Requires-Python: >=3.9,<3.
|
|
8
|
+
Requires-Python: >=3.9,<3.14
|
|
9
9
|
Classifier: License :: OSI Approved :: MIT License
|
|
10
10
|
Classifier: Programming Language :: Python :: 3
|
|
11
11
|
Classifier: Programming Language :: Python :: 3.9
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.10
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
14
16
|
Provides-Extra: bedrock
|
|
15
17
|
Provides-Extra: cohere
|
|
16
18
|
Provides-Extra: docs
|
|
@@ -30,17 +32,17 @@ Requires-Dist: botocore (>=1.34.110,<2.0.0) ; extra == "bedrock"
|
|
|
30
32
|
Requires-Dist: cohere (>=5.9.4,<6.00) ; extra == "cohere"
|
|
31
33
|
Requires-Dist: colorama (>=0.4.6,<0.5.0)
|
|
32
34
|
Requires-Dist: colorlog (>=6.8.0,<7.0.0)
|
|
33
|
-
Requires-Dist: fastembed (>=0.3.0,<0.4.0) ; extra == "fastembed"
|
|
35
|
+
Requires-Dist: fastembed (>=0.3.0,<0.4.0) ; (python_version < "3.13") and (extra == "fastembed")
|
|
34
36
|
Requires-Dist: google-cloud-aiplatform (>=1.45.0,<2.0.0) ; extra == "google"
|
|
35
|
-
Requires-Dist: llama-cpp-python (>=0.2.28,<0.2.86) ; extra == "local"
|
|
37
|
+
Requires-Dist: llama-cpp-python (>=0.2.28,<0.2.86) ; (python_version < "3.13") and (extra == "local")
|
|
36
38
|
Requires-Dist: mistralai (>=0.0.12,<0.1.0) ; extra == "mistralai"
|
|
37
39
|
Requires-Dist: numpy (>=1.25.2,<2.0.0)
|
|
38
40
|
Requires-Dist: openai (>=1.10.0,<2.0.0)
|
|
39
|
-
Requires-Dist: pillow (>=10.2.0,<11.0.0) ; extra == "vision"
|
|
41
|
+
Requires-Dist: pillow (>=10.2.0,<11.0.0) ; (python_version < "3.13") and (extra == "vision")
|
|
40
42
|
Requires-Dist: pinecone (>=5.0.0) ; extra == "pinecone"
|
|
41
43
|
Requires-Dist: pinecone-text (>=0.7.1,<0.10.0) ; extra == "hybrid"
|
|
42
44
|
Requires-Dist: psycopg2-binary (>=2.9.9,<3.0.0)
|
|
43
|
-
Requires-Dist: pydantic (>=2.
|
|
45
|
+
Requires-Dist: pydantic (>=2.10.2,<3.0.0)
|
|
44
46
|
Requires-Dist: pyyaml (>=6.0.1,<7.0.0)
|
|
45
47
|
Requires-Dist: qdrant-client (>=1.11.1,<2.0.0) ; extra == "qdrant"
|
|
46
48
|
Requires-Dist: regex (>=2023.12.25)
|
|
@@ -48,11 +50,11 @@ Requires-Dist: requests-mock (>=1.12.1,<2.0.0)
|
|
|
48
50
|
Requires-Dist: sphinx (>=7.0.0,<8.0.0) ; extra == "docs"
|
|
49
51
|
Requires-Dist: sphinxawesome-theme (>=5.2.0,<6.0.0) ; extra == "docs"
|
|
50
52
|
Requires-Dist: tiktoken (>=0.6.0,<1.0.0)
|
|
51
|
-
Requires-Dist: tokenizers (>=0.19) ; extra == "local"
|
|
52
|
-
Requires-Dist: torch (>=2.1.0,<2.6.0) ; extra == "local" or extra == "vision"
|
|
53
|
-
Requires-Dist: torchvision (>=0.17.0,<0.18.0) ; extra == "vision"
|
|
53
|
+
Requires-Dist: tokenizers (>=0.19) ; (python_version < "3.13") and (extra == "local")
|
|
54
|
+
Requires-Dist: torch (>=2.1.0,<2.6.0) ; (python_version < "3.13") and (extra == "local" or extra == "vision")
|
|
55
|
+
Requires-Dist: torchvision (>=0.17.0,<0.18.0) ; (python_version < "3.13") and (extra == "vision")
|
|
54
56
|
Requires-Dist: tornado (>=6.4.2,<7.0.0)
|
|
55
|
-
Requires-Dist: transformers (>=4.36.2) ; extra == "local" or extra == "vision"
|
|
57
|
+
Requires-Dist: transformers (>=4.36.2) ; (python_version < "3.13") and (extra == "local" or extra == "vision")
|
|
56
58
|
Description-Content-Type: text/markdown
|
|
57
59
|
|
|
58
60
|
[](https://aurelio.ai)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "semantic-router"
|
|
3
|
-
version = "0.1.0.
|
|
3
|
+
version = "0.1.0.dev3"
|
|
4
4
|
description = "Super fast semantic router for AI decision making"
|
|
5
5
|
authors = ["Aurelio AI <hello@aurelio.ai>"]
|
|
6
6
|
readme = "README.md"
|
|
@@ -8,8 +8,8 @@ packages = [{include = "semantic_router"}]
|
|
|
8
8
|
license = "MIT"
|
|
9
9
|
|
|
10
10
|
[tool.poetry.dependencies]
|
|
11
|
-
python = ">=3.9,<3.
|
|
12
|
-
pydantic = "^2.
|
|
11
|
+
python = ">=3.9,<3.14"
|
|
12
|
+
pydantic = "^2.10.2"
|
|
13
13
|
openai = ">=1.10.0,<2.0.0"
|
|
14
14
|
cohere = {version = ">=5.9.4,<6.00", optional = true}
|
|
15
15
|
mistralai= {version = ">=0.0.12,<0.1.0", optional = true}
|
|
@@ -18,15 +18,15 @@ colorlog = "^6.8.0"
|
|
|
18
18
|
pyyaml = "^6.0.1"
|
|
19
19
|
aurelio-sdk = {version = "^0.0.16"}
|
|
20
20
|
pinecone-text = {version = ">=0.7.1,<0.10.0", optional = true}
|
|
21
|
-
torch = {version = ">=2.1.0,<2.6.0", optional = true}
|
|
22
|
-
transformers = {version = ">=4.36.2", optional = true}
|
|
23
|
-
tokenizers = {version = ">=0.19", optional = true}
|
|
24
|
-
llama-cpp-python = {version = ">=0.2.28,<0.2.86", optional = true}
|
|
21
|
+
torch = {version = ">=2.1.0,<2.6.0", optional = true, python = "<3.13" }
|
|
22
|
+
transformers = {version = ">=4.36.2", optional = true, python = "<3.13" }
|
|
23
|
+
tokenizers = {version = ">=0.19", optional = true, python = "<3.13" }
|
|
24
|
+
llama-cpp-python = {version = ">=0.2.28,<0.2.86", optional = true, python = "<3.13" }
|
|
25
25
|
colorama = "^0.4.6"
|
|
26
26
|
pinecone = {version=">=5.0.0", optional = true}
|
|
27
27
|
regex = ">=2023.12.25"
|
|
28
|
-
torchvision = { version = ">=0.17.0,<0.18.0", optional = true}
|
|
29
|
-
pillow = { version = ">=10.2.0,<11.0.0", optional = true}
|
|
28
|
+
torchvision = { version = ">=0.17.0,<0.18.0", optional = true, python = "<3.13" }
|
|
29
|
+
pillow = { version = ">=10.2.0,<11.0.0", optional = true, python = "<3.13" }
|
|
30
30
|
tiktoken = ">=0.6.0,<1.0.0"
|
|
31
31
|
qdrant-client = {version = "^1.11.1", optional = true}
|
|
32
32
|
google-cloud-aiplatform = {version = "^1.45.0", optional = true}
|
|
@@ -34,7 +34,7 @@ requests-mock = "^1.12.1"
|
|
|
34
34
|
boto3 = { version = "^1.34.98", optional = true }
|
|
35
35
|
botocore = {version = "^1.34.110", optional = true}
|
|
36
36
|
aiohttp = "^3.10.11"
|
|
37
|
-
fastembed = {version = "^0.3.0", optional = true}
|
|
37
|
+
fastembed = {version = "^0.3.0", optional = true, python = "<3.13" }
|
|
38
38
|
psycopg2-binary = {version = "^2.9.9", optional = true}
|
|
39
39
|
sphinx = {version = "^7.0.0", optional = true}
|
|
40
40
|
sphinxawesome-theme = {version = "^5.2.0", optional = true}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from typing import Any, Coroutine, List, Optional
|
|
2
2
|
|
|
3
|
-
from pydantic
|
|
3
|
+
from pydantic import BaseModel, Field, field_validator
|
|
4
4
|
import numpy as np
|
|
5
5
|
|
|
6
6
|
from semantic_router.schema import SparseEmbedding
|
|
@@ -14,7 +14,7 @@ class DenseEncoder(BaseModel):
|
|
|
14
14
|
class Config:
|
|
15
15
|
arbitrary_types_allowed = True
|
|
16
16
|
|
|
17
|
-
@
|
|
17
|
+
@field_validator("score_threshold")
|
|
18
18
|
def set_score_threshold(cls, v):
|
|
19
19
|
return float(v) if v is not None else None
|
|
20
20
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from typing import Any, List, Optional
|
|
2
2
|
|
|
3
3
|
import numpy as np
|
|
4
|
-
from pydantic
|
|
4
|
+
from pydantic import PrivateAttr
|
|
5
5
|
from typing import Dict
|
|
6
6
|
from semantic_router.encoders import DenseEncoder
|
|
7
7
|
|
|
@@ -9,7 +9,6 @@ from semantic_router.encoders import DenseEncoder
|
|
|
9
9
|
class CLIPEncoder(DenseEncoder):
|
|
10
10
|
name: str = "openai/clip-vit-base-patch16"
|
|
11
11
|
type: str = "huggingface"
|
|
12
|
-
score_threshold: float = 0.2
|
|
13
12
|
tokenizer_kwargs: Dict = {}
|
|
14
13
|
processor_kwargs: Dict = {}
|
|
15
14
|
model_kwargs: Dict = {}
|
|
@@ -21,6 +20,8 @@ class CLIPEncoder(DenseEncoder):
|
|
|
21
20
|
_Image: Any = PrivateAttr()
|
|
22
21
|
|
|
23
22
|
def __init__(self, **data):
|
|
23
|
+
if data.get("score_threshold") is None:
|
|
24
|
+
data["score_threshold"] = 0.2
|
|
24
25
|
super().__init__(**data)
|
|
25
26
|
self._tokenizer, self._processor, self._model = self._initialize_hf_model()
|
|
26
27
|
|
{semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/encoders/huggingface.py
RENAMED
|
@@ -25,7 +25,7 @@ import time
|
|
|
25
25
|
import os
|
|
26
26
|
from typing import Any, List, Optional, Dict
|
|
27
27
|
|
|
28
|
-
from pydantic
|
|
28
|
+
from pydantic import PrivateAttr
|
|
29
29
|
|
|
30
30
|
from semantic_router.encoders import DenseEncoder
|
|
31
31
|
from semantic_router.utils.logger import logger
|
|
@@ -34,7 +34,6 @@ from semantic_router.utils.logger import logger
|
|
|
34
34
|
class HuggingFaceEncoder(DenseEncoder):
|
|
35
35
|
name: str = "sentence-transformers/all-MiniLM-L6-v2"
|
|
36
36
|
type: str = "huggingface"
|
|
37
|
-
score_threshold: float = 0.5
|
|
38
37
|
tokenizer_kwargs: Dict = {}
|
|
39
38
|
model_kwargs: Dict = {}
|
|
40
39
|
device: Optional[str] = None
|
|
@@ -43,6 +42,8 @@ class HuggingFaceEncoder(DenseEncoder):
|
|
|
43
42
|
_torch: Any = PrivateAttr()
|
|
44
43
|
|
|
45
44
|
def __init__(self, **data):
|
|
45
|
+
if data.get("score_threshold") is None:
|
|
46
|
+
data["score_threshold"] = 0.5
|
|
46
47
|
super().__init__(**data)
|
|
47
48
|
self._tokenizer, self._model = self._initialize_hf_model()
|
|
48
49
|
|
|
@@ -153,7 +154,6 @@ class HFEndpointEncoder(DenseEncoder):
|
|
|
153
154
|
name: str = "hugging_face_custom_endpoint"
|
|
154
155
|
huggingface_url: Optional[str] = None
|
|
155
156
|
huggingface_api_key: Optional[str] = None
|
|
156
|
-
score_threshold: float = 0.8
|
|
157
157
|
|
|
158
158
|
def __init__(
|
|
159
159
|
self,
|
|
@@ -180,6 +180,8 @@ class HFEndpointEncoder(DenseEncoder):
|
|
|
180
180
|
"""
|
|
181
181
|
huggingface_url = huggingface_url or os.getenv("HF_API_URL")
|
|
182
182
|
huggingface_api_key = huggingface_api_key or os.getenv("HF_API_KEY")
|
|
183
|
+
if score_threshold is None:
|
|
184
|
+
score_threshold = 0.8
|
|
183
185
|
|
|
184
186
|
super().__init__(name=name, score_threshold=score_threshold) # type: ignore
|
|
185
187
|
|
{semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/encoders/openai.py
RENAMED
|
@@ -2,7 +2,7 @@ from asyncio import sleep as asleep
|
|
|
2
2
|
import os
|
|
3
3
|
from time import sleep
|
|
4
4
|
from typing import Any, List, Optional, Union
|
|
5
|
-
from pydantic
|
|
5
|
+
from pydantic import PrivateAttr
|
|
6
6
|
|
|
7
7
|
import openai
|
|
8
8
|
from openai import OpenAIError
|
|
@@ -36,8 +36,8 @@ model_configs = {
|
|
|
36
36
|
|
|
37
37
|
|
|
38
38
|
class OpenAIEncoder(DenseEncoder):
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
_client: Optional[openai.Client] = PrivateAttr(default=None)
|
|
40
|
+
_async_client: Optional[openai.AsyncClient] = PrivateAttr(default=None)
|
|
41
41
|
dimensions: Union[int, NotGiven] = NotGiven()
|
|
42
42
|
token_limit: int = 8192 # default value, should be replaced by config
|
|
43
43
|
_token_encoder: Any = PrivateAttr()
|
|
@@ -77,10 +77,10 @@ class OpenAIEncoder(DenseEncoder):
|
|
|
77
77
|
if max_retries is not None:
|
|
78
78
|
self.max_retries = max_retries
|
|
79
79
|
try:
|
|
80
|
-
self.
|
|
80
|
+
self._client = openai.Client(
|
|
81
81
|
base_url=base_url, api_key=api_key, organization=openai_org_id
|
|
82
82
|
)
|
|
83
|
-
self.
|
|
83
|
+
self._async_client = openai.AsyncClient(
|
|
84
84
|
base_url=base_url, api_key=api_key, organization=openai_org_id
|
|
85
85
|
)
|
|
86
86
|
except Exception as e:
|
|
@@ -103,7 +103,7 @@ class OpenAIEncoder(DenseEncoder):
|
|
|
103
103
|
False and a document exceeds the token limit, an error will be
|
|
104
104
|
raised.
|
|
105
105
|
:return: List of embeddings for each document."""
|
|
106
|
-
if self.
|
|
106
|
+
if self._client is None:
|
|
107
107
|
raise ValueError("OpenAI client is not initialized.")
|
|
108
108
|
embeds = None
|
|
109
109
|
|
|
@@ -114,7 +114,7 @@ class OpenAIEncoder(DenseEncoder):
|
|
|
114
114
|
# Exponential backoff
|
|
115
115
|
for j in range(self.max_retries + 1):
|
|
116
116
|
try:
|
|
117
|
-
embeds = self.
|
|
117
|
+
embeds = self._client.embeddings.create(
|
|
118
118
|
input=docs,
|
|
119
119
|
model=self.name,
|
|
120
120
|
dimensions=self.dimensions,
|
|
@@ -160,7 +160,7 @@ class OpenAIEncoder(DenseEncoder):
|
|
|
160
160
|
return text
|
|
161
161
|
|
|
162
162
|
async def acall(self, docs: List[str], truncate: bool = True) -> List[List[float]]:
|
|
163
|
-
if self.
|
|
163
|
+
if self._async_client is None:
|
|
164
164
|
raise ValueError("OpenAI async client is not initialized.")
|
|
165
165
|
embeds = None
|
|
166
166
|
|
|
@@ -171,7 +171,7 @@ class OpenAIEncoder(DenseEncoder):
|
|
|
171
171
|
# Exponential backoff
|
|
172
172
|
for j in range(self.max_retries + 1):
|
|
173
173
|
try:
|
|
174
|
-
embeds = await self.
|
|
174
|
+
embeds = await self._async_client.embeddings.create(
|
|
175
175
|
input=docs,
|
|
176
176
|
model=self.name,
|
|
177
177
|
dimensions=self.dimensions,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
from typing import Any, List, Optional
|
|
1
|
+
from typing import Any, Dict, List, Optional
|
|
2
2
|
|
|
3
|
-
from pydantic
|
|
3
|
+
from pydantic import PrivateAttr
|
|
4
4
|
|
|
5
5
|
from semantic_router.encoders import DenseEncoder
|
|
6
6
|
|
|
@@ -8,7 +8,6 @@ from semantic_router.encoders import DenseEncoder
|
|
|
8
8
|
class VitEncoder(DenseEncoder):
|
|
9
9
|
name: str = "google/vit-base-patch16-224"
|
|
10
10
|
type: str = "huggingface"
|
|
11
|
-
score_threshold: float = 0.5
|
|
12
11
|
processor_kwargs: Dict = {}
|
|
13
12
|
model_kwargs: Dict = {}
|
|
14
13
|
device: Optional[str] = None
|
|
@@ -19,6 +18,8 @@ class VitEncoder(DenseEncoder):
|
|
|
19
18
|
_Image: Any = PrivateAttr()
|
|
20
19
|
|
|
21
20
|
def __init__(self, **data):
|
|
21
|
+
if data.get("score_threshold") is None:
|
|
22
|
+
data["score_threshold"] = 0.5
|
|
22
23
|
super().__init__(**data)
|
|
23
24
|
self._processor, self._model = self._initialize_hf_model()
|
|
24
25
|
|
|
@@ -2,7 +2,7 @@ from typing import Any, List, Optional, Tuple, Union, Dict
|
|
|
2
2
|
import json
|
|
3
3
|
|
|
4
4
|
import numpy as np
|
|
5
|
-
from pydantic
|
|
5
|
+
from pydantic import BaseModel
|
|
6
6
|
|
|
7
7
|
from semantic_router.schema import ConfigParameter, SparseEmbedding, Utterance
|
|
8
8
|
from semantic_router.route import Route
|
|
@@ -8,7 +8,7 @@ import json
|
|
|
8
8
|
from typing import Any, Dict, List, Optional, Union, Tuple
|
|
9
9
|
|
|
10
10
|
import numpy as np
|
|
11
|
-
from pydantic
|
|
11
|
+
from pydantic import BaseModel, Field
|
|
12
12
|
|
|
13
13
|
from semantic_router.index.base import BaseIndex
|
|
14
14
|
from semantic_router.schema import ConfigParameter, SparseEmbedding
|
|
@@ -103,7 +103,6 @@ class PostgresIndex(BaseIndex):
|
|
|
103
103
|
connection_string: Optional[str] = None
|
|
104
104
|
index_prefix: str = "semantic_router_"
|
|
105
105
|
index_name: str = "index"
|
|
106
|
-
dimensions: int = 1536
|
|
107
106
|
metric: Metric = Metric.COSINE
|
|
108
107
|
namespace: Optional[str] = ""
|
|
109
108
|
conn: Optional["psycopg2.extensions.connection"] = None
|
|
@@ -115,9 +114,9 @@ class PostgresIndex(BaseIndex):
|
|
|
115
114
|
connection_string: Optional[str] = None,
|
|
116
115
|
index_prefix: str = "semantic_router_",
|
|
117
116
|
index_name: str = "index",
|
|
118
|
-
dimensions: int = 1536,
|
|
119
117
|
metric: Metric = Metric.COSINE,
|
|
120
118
|
namespace: Optional[str] = "",
|
|
119
|
+
dimensions: int | None = None,
|
|
121
120
|
):
|
|
122
121
|
"""
|
|
123
122
|
Initializes the Postgres index with the specified parameters.
|
|
@@ -135,6 +134,8 @@ class PostgresIndex(BaseIndex):
|
|
|
135
134
|
:param namespace: An optional namespace for the index.
|
|
136
135
|
:type namespace: Optional[str]
|
|
137
136
|
"""
|
|
137
|
+
if dimensions is None:
|
|
138
|
+
dimensions = 1536
|
|
138
139
|
super().__init__()
|
|
139
140
|
# try and import psycopg2
|
|
140
141
|
try:
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from typing import Any, Dict, List, Optional, Tuple, Union
|
|
2
2
|
|
|
3
3
|
import numpy as np
|
|
4
|
-
from pydantic
|
|
4
|
+
from pydantic import Field
|
|
5
5
|
|
|
6
6
|
from semantic_router.index.base import BaseIndex
|
|
7
7
|
from semantic_router.schema import ConfigParameter, Metric, SparseEmbedding, Utterance
|
|
@@ -40,7 +40,7 @@ class QdrantIndex(BaseIndex):
|
|
|
40
40
|
default=6334,
|
|
41
41
|
description="Port of the gRPC interface.",
|
|
42
42
|
)
|
|
43
|
-
prefer_grpc: bool = Field(
|
|
43
|
+
prefer_grpc: Optional[bool] = Field(
|
|
44
44
|
default=None,
|
|
45
45
|
description="Whether to use gPRC interface whenever possible in methods",
|
|
46
46
|
)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import json
|
|
2
2
|
from typing import Any, List, Optional, Dict
|
|
3
3
|
|
|
4
|
-
from pydantic
|
|
4
|
+
from pydantic import BaseModel
|
|
5
5
|
|
|
6
6
|
from semantic_router.schema import Message
|
|
7
7
|
from semantic_router.utils.logger import logger
|
|
@@ -9,6 +9,8 @@ from semantic_router.utils.logger import logger
|
|
|
9
9
|
|
|
10
10
|
class BaseLLM(BaseModel):
|
|
11
11
|
name: str
|
|
12
|
+
temperature: Optional[float] = 0.0
|
|
13
|
+
max_tokens: Optional[int] = None
|
|
12
14
|
|
|
13
15
|
class Config:
|
|
14
16
|
arbitrary_types_allowed = True
|
|
@@ -2,7 +2,7 @@ from contextlib import contextmanager
|
|
|
2
2
|
from pathlib import Path
|
|
3
3
|
from typing import Any, Optional, List, Dict
|
|
4
4
|
|
|
5
|
-
from pydantic
|
|
5
|
+
from pydantic import PrivateAttr
|
|
6
6
|
|
|
7
7
|
from semantic_router.llms.base import BaseLLM
|
|
8
8
|
from semantic_router.schema import Message
|
|
@@ -11,8 +11,6 @@ from semantic_router.utils.logger import logger
|
|
|
11
11
|
|
|
12
12
|
class LlamaCppLLM(BaseLLM):
|
|
13
13
|
llm: Any
|
|
14
|
-
temperature: float
|
|
15
|
-
max_tokens: Optional[int] = 200
|
|
16
14
|
grammar: Optional[Any] = None
|
|
17
15
|
_llama_cpp: Any = PrivateAttr()
|
|
18
16
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import os
|
|
2
2
|
from typing import Any, List, Optional
|
|
3
3
|
|
|
4
|
-
from pydantic
|
|
4
|
+
from pydantic import PrivateAttr
|
|
5
5
|
|
|
6
6
|
from semantic_router.llms import BaseLLM
|
|
7
7
|
from semantic_router.schema import Message
|
|
@@ -11,8 +11,6 @@ from semantic_router.utils.logger import logger
|
|
|
11
11
|
|
|
12
12
|
class MistralAILLM(BaseLLM):
|
|
13
13
|
_client: Any = PrivateAttr()
|
|
14
|
-
temperature: Optional[float]
|
|
15
|
-
max_tokens: Optional[int]
|
|
16
14
|
_mistralai: Any = PrivateAttr()
|
|
17
15
|
|
|
18
16
|
def __init__(
|
|
@@ -8,22 +8,17 @@ from semantic_router.utils.logger import logger
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
class OllamaLLM(BaseLLM):
|
|
11
|
-
|
|
12
|
-
llm_name: Optional[str]
|
|
13
|
-
max_tokens: Optional[int]
|
|
14
|
-
stream: Optional[bool]
|
|
11
|
+
stream: bool = False
|
|
15
12
|
|
|
16
13
|
def __init__(
|
|
17
14
|
self,
|
|
18
|
-
name: str = "
|
|
15
|
+
name: str = "openhermes",
|
|
19
16
|
temperature: float = 0.2,
|
|
20
|
-
llm_name: str = "openhermes",
|
|
21
17
|
max_tokens: Optional[int] = 200,
|
|
22
18
|
stream: bool = False,
|
|
23
19
|
):
|
|
24
20
|
super().__init__(name=name)
|
|
25
21
|
self.temperature = temperature
|
|
26
|
-
self.llm_name = llm_name
|
|
27
22
|
self.max_tokens = max_tokens
|
|
28
23
|
self.stream = stream
|
|
29
24
|
|
|
@@ -31,19 +26,19 @@ class OllamaLLM(BaseLLM):
|
|
|
31
26
|
self,
|
|
32
27
|
messages: List[Message],
|
|
33
28
|
temperature: Optional[float] = None,
|
|
34
|
-
|
|
29
|
+
name: Optional[str] = None,
|
|
35
30
|
max_tokens: Optional[int] = None,
|
|
36
31
|
stream: Optional[bool] = None,
|
|
37
32
|
) -> str:
|
|
38
33
|
# Use instance defaults if not overridden
|
|
39
34
|
temperature = temperature if temperature is not None else self.temperature
|
|
40
|
-
|
|
35
|
+
name = name if name is not None else self.name
|
|
41
36
|
max_tokens = max_tokens if max_tokens is not None else self.max_tokens
|
|
42
37
|
stream = stream if stream is not None else self.stream
|
|
43
38
|
|
|
44
39
|
try:
|
|
45
40
|
payload = {
|
|
46
|
-
"model":
|
|
41
|
+
"model": name,
|
|
47
42
|
"messages": [m.to_openai() for m in messages],
|
|
48
43
|
"options": {"temperature": temperature, "num_predict": max_tokens},
|
|
49
44
|
"format": "json",
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import os
|
|
2
2
|
from typing import List, Optional, Any, Callable, Dict, Union
|
|
3
|
+
from pydantic import PrivateAttr
|
|
3
4
|
|
|
4
5
|
import openai
|
|
5
6
|
from openai._types import NotGiven, NOT_GIVEN
|
|
@@ -21,10 +22,8 @@ from openai.types.chat.chat_completion_message_tool_call import (
|
|
|
21
22
|
|
|
22
23
|
|
|
23
24
|
class OpenAILLM(BaseLLM):
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
temperature: Optional[float]
|
|
27
|
-
max_tokens: Optional[int]
|
|
25
|
+
_client: Optional[openai.OpenAI] = PrivateAttr(default=None)
|
|
26
|
+
_async_client: Optional[openai.AsyncOpenAI] = PrivateAttr(default=None)
|
|
28
27
|
|
|
29
28
|
def __init__(
|
|
30
29
|
self,
|
|
@@ -40,8 +39,8 @@ class OpenAILLM(BaseLLM):
|
|
|
40
39
|
if api_key is None:
|
|
41
40
|
raise ValueError("OpenAI API key cannot be 'None'.")
|
|
42
41
|
try:
|
|
43
|
-
self.
|
|
44
|
-
self.
|
|
42
|
+
self._async_client = openai.AsyncOpenAI(api_key=api_key)
|
|
43
|
+
self._client = openai.OpenAI(api_key=api_key)
|
|
45
44
|
except Exception as e:
|
|
46
45
|
raise ValueError(
|
|
47
46
|
f"OpenAI API client failed to initialize. Error: {e}"
|
|
@@ -88,14 +87,14 @@ class OpenAILLM(BaseLLM):
|
|
|
88
87
|
messages: List[Message],
|
|
89
88
|
function_schemas: Optional[List[Dict[str, Any]]] = None,
|
|
90
89
|
) -> str:
|
|
91
|
-
if self.
|
|
90
|
+
if self._client is None:
|
|
92
91
|
raise ValueError("OpenAI client is not initialized.")
|
|
93
92
|
try:
|
|
94
93
|
tools: Union[List[Dict[str, Any]], NotGiven] = (
|
|
95
94
|
function_schemas if function_schemas else NOT_GIVEN
|
|
96
95
|
)
|
|
97
96
|
|
|
98
|
-
completion = self.
|
|
97
|
+
completion = self._client.chat.completions.create(
|
|
99
98
|
model=self.name,
|
|
100
99
|
messages=[m.to_openai() for m in messages],
|
|
101
100
|
temperature=self.temperature,
|
|
@@ -132,14 +131,14 @@ class OpenAILLM(BaseLLM):
|
|
|
132
131
|
messages: List[Message],
|
|
133
132
|
function_schemas: Optional[List[Dict[str, Any]]] = None,
|
|
134
133
|
) -> str:
|
|
135
|
-
if self.
|
|
134
|
+
if self._async_client is None:
|
|
136
135
|
raise ValueError("OpenAI async_client is not initialized.")
|
|
137
136
|
try:
|
|
138
137
|
tools: Union[List[Dict[str, Any]], NotGiven] = (
|
|
139
138
|
function_schemas if function_schemas is not None else NOT_GIVEN
|
|
140
139
|
)
|
|
141
140
|
|
|
142
|
-
completion = await self.
|
|
141
|
+
completion = await self._async_client.chat.completions.create(
|
|
143
142
|
model=self.name,
|
|
144
143
|
messages=[m.to_openai() for m in messages],
|
|
145
144
|
temperature=self.temperature,
|
{semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/llms/openrouter.py
RENAMED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import os
|
|
2
2
|
from typing import List, Optional
|
|
3
3
|
|
|
4
|
+
from pydantic import PrivateAttr
|
|
5
|
+
|
|
4
6
|
import openai
|
|
5
7
|
|
|
6
8
|
from semantic_router.llms import BaseLLM
|
|
@@ -9,10 +11,8 @@ from semantic_router.utils.logger import logger
|
|
|
9
11
|
|
|
10
12
|
|
|
11
13
|
class OpenRouterLLM(BaseLLM):
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
temperature: Optional[float]
|
|
15
|
-
max_tokens: Optional[int]
|
|
14
|
+
_client: Optional[openai.OpenAI] = PrivateAttr(default=None)
|
|
15
|
+
_base_url: str = PrivateAttr(default="https://openrouter.ai/api/v1")
|
|
16
16
|
|
|
17
17
|
def __init__(
|
|
18
18
|
self,
|
|
@@ -27,12 +27,12 @@ class OpenRouterLLM(BaseLLM):
|
|
|
27
27
|
"OPENROUTER_CHAT_MODEL_NAME", "mistralai/mistral-7b-instruct"
|
|
28
28
|
)
|
|
29
29
|
super().__init__(name=name)
|
|
30
|
-
self.
|
|
30
|
+
self._base_url = base_url
|
|
31
31
|
api_key = openrouter_api_key or os.getenv("OPENROUTER_API_KEY")
|
|
32
32
|
if api_key is None:
|
|
33
33
|
raise ValueError("OpenRouter API key cannot be 'None'.")
|
|
34
34
|
try:
|
|
35
|
-
self.
|
|
35
|
+
self._client = openai.OpenAI(api_key=api_key, base_url=self._base_url)
|
|
36
36
|
except Exception as e:
|
|
37
37
|
raise ValueError(
|
|
38
38
|
f"OpenRouter API client failed to initialize. Error: {e}"
|
|
@@ -41,10 +41,10 @@ class OpenRouterLLM(BaseLLM):
|
|
|
41
41
|
self.max_tokens = max_tokens
|
|
42
42
|
|
|
43
43
|
def __call__(self, messages: List[Message]) -> str:
|
|
44
|
-
if self.
|
|
44
|
+
if self._client is None:
|
|
45
45
|
raise ValueError("OpenRouter client is not initialized.")
|
|
46
46
|
try:
|
|
47
|
-
completion = self.
|
|
47
|
+
completion = self._client.chat.completions.create(
|
|
48
48
|
model=self.name,
|
|
49
49
|
messages=[m.to_openai() for m in messages],
|
|
50
50
|
temperature=self.temperature,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import os
|
|
2
2
|
from typing import List, Optional
|
|
3
|
+
from pydantic import PrivateAttr
|
|
3
4
|
|
|
4
5
|
import openai
|
|
5
6
|
|
|
@@ -10,9 +11,7 @@ from semantic_router.utils.logger import logger
|
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
class AzureOpenAILLM(BaseLLM):
|
|
13
|
-
|
|
14
|
-
temperature: Optional[float]
|
|
15
|
-
max_tokens: Optional[int]
|
|
14
|
+
_client: Optional[openai.AzureOpenAI] = PrivateAttr(default=None)
|
|
16
15
|
|
|
17
16
|
def __init__(
|
|
18
17
|
self,
|
|
@@ -33,7 +32,7 @@ class AzureOpenAILLM(BaseLLM):
|
|
|
33
32
|
if azure_endpoint is None:
|
|
34
33
|
raise ValueError("Azure endpoint API key cannot be 'None'.")
|
|
35
34
|
try:
|
|
36
|
-
self.
|
|
35
|
+
self._client = openai.AzureOpenAI(
|
|
37
36
|
api_key=api_key, azure_endpoint=azure_endpoint, api_version=api_version
|
|
38
37
|
)
|
|
39
38
|
except Exception as e:
|
|
@@ -42,10 +41,10 @@ class AzureOpenAILLM(BaseLLM):
|
|
|
42
41
|
self.max_tokens = max_tokens
|
|
43
42
|
|
|
44
43
|
def __call__(self, messages: List[Message]) -> str:
|
|
45
|
-
if self.
|
|
44
|
+
if self._client is None:
|
|
46
45
|
raise ValueError("AzureOpenAI client is not initialized.")
|
|
47
46
|
try:
|
|
48
|
-
completion = self.
|
|
47
|
+
completion = self._client.chat.completions.create(
|
|
49
48
|
model=self.name,
|
|
50
49
|
messages=[m.to_openai() for m in messages],
|
|
51
50
|
temperature=self.temperature,
|
|
@@ -2,18 +2,13 @@ import json
|
|
|
2
2
|
import re
|
|
3
3
|
from typing import Any, Callable, Dict, List, Optional, Union
|
|
4
4
|
|
|
5
|
-
from pydantic
|
|
5
|
+
from pydantic import BaseModel
|
|
6
6
|
|
|
7
7
|
from semantic_router.llms import BaseLLM
|
|
8
8
|
from semantic_router.schema import Message, RouteChoice
|
|
9
9
|
from semantic_router.utils import function_call
|
|
10
10
|
from semantic_router.utils.logger import logger
|
|
11
11
|
|
|
12
|
-
try:
|
|
13
|
-
from PIL.Image import Image
|
|
14
|
-
except ImportError:
|
|
15
|
-
pass
|
|
16
|
-
|
|
17
12
|
|
|
18
13
|
def is_valid(route_config: str) -> bool:
|
|
19
14
|
try:
|
|
@@ -45,7 +40,7 @@ def is_valid(route_config: str) -> bool:
|
|
|
45
40
|
|
|
46
41
|
class Route(BaseModel):
|
|
47
42
|
name: str
|
|
48
|
-
utterances: Union[List[str], List[
|
|
43
|
+
utterances: Union[List[str], List[Any]]
|
|
49
44
|
description: Optional[str] = None
|
|
50
45
|
function_schemas: Optional[List[Dict[str, Any]]] = None
|
|
51
46
|
llm: Optional[BaseLLM] = None
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
from datetime import datetime
|
|
2
2
|
from difflib import Differ
|
|
3
3
|
from enum import Enum
|
|
4
|
+
import json
|
|
4
5
|
import numpy as np
|
|
5
6
|
from typing import List, Optional, Union, Any, Dict, Tuple
|
|
6
|
-
from pydantic
|
|
7
|
+
from pydantic import BaseModel, Field
|
|
7
8
|
from semantic_router.utils.logger import logger
|
|
8
9
|
from aurelio_sdk.schema import BM25Embedding
|
|
9
10
|
|
|
@@ -126,7 +127,18 @@ class Utterance(BaseModel):
|
|
|
126
127
|
|
|
127
128
|
def to_str(self, include_metadata: bool = False):
|
|
128
129
|
if include_metadata:
|
|
129
|
-
|
|
130
|
+
# we sort the dicts to ensure consistent order as we need this to compare
|
|
131
|
+
# stringified function schemas accurately
|
|
132
|
+
if self.function_schemas is not None:
|
|
133
|
+
function_schemas_sorted: List[str] | None = [
|
|
134
|
+
json.dumps(schema, sort_keys=True)
|
|
135
|
+
for schema in self.function_schemas
|
|
136
|
+
]
|
|
137
|
+
else:
|
|
138
|
+
function_schemas_sorted = None
|
|
139
|
+
# we must do the same for metadata
|
|
140
|
+
metadata_sorted = json.dumps(self.metadata, sort_keys=True)
|
|
141
|
+
return f"{self.route}: {self.utterance} | {function_schemas_sorted} | {metadata_sorted}"
|
|
130
142
|
return f"{self.route}: {self.utterance}"
|
|
131
143
|
|
|
132
144
|
def to_diff_str(self, include_metadata: bool = False):
|
|
File without changes
|
{semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/encoders/__init__.py
RENAMED
|
File without changes
|
{semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/encoders/bedrock.py
RENAMED
|
File without changes
|
|
File without changes
|
{semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/encoders/google.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/index/hybrid_local.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/llms/grammars/json.gbnf
RENAMED
|
File without changes
|
{semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/routers/__init__.py
RENAMED
|
File without changes
|
{semantic_router-0.1.0.dev2 → semantic_router-0.1.0.dev3}/semantic_router/routers/semantic.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|