semantic-router 0.1.0.dev1__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.dev1 → semantic_router-0.1.0.dev3}/LICENSE +1 -1
- {semantic_router-0.1.0.dev1 → semantic_router-0.1.0.dev3}/PKG-INFO +16 -14
- {semantic_router-0.1.0.dev1 → semantic_router-0.1.0.dev3}/pyproject.toml +16 -15
- semantic_router-0.1.0.dev3/semantic_router/__init__.py +6 -0
- {semantic_router-0.1.0.dev1 → semantic_router-0.1.0.dev3}/semantic_router/encoders/__init__.py +10 -5
- semantic_router-0.1.0.dev3/semantic_router/encoders/aurelio.py +47 -0
- semantic_router-0.1.0.dev3/semantic_router/encoders/base.py +53 -0
- {semantic_router-0.1.0.dev1 → semantic_router-0.1.0.dev3}/semantic_router/encoders/bedrock.py +3 -3
- {semantic_router-0.1.0.dev1 → semantic_router-0.1.0.dev3}/semantic_router/encoders/bm25.py +26 -20
- {semantic_router-0.1.0.dev1 → semantic_router-0.1.0.dev3}/semantic_router/encoders/clip.py +5 -4
- {semantic_router-0.1.0.dev1 → semantic_router-0.1.0.dev3}/semantic_router/encoders/cohere.py +3 -3
- {semantic_router-0.1.0.dev1 → semantic_router-0.1.0.dev3}/semantic_router/encoders/fastembed.py +3 -3
- {semantic_router-0.1.0.dev1 → semantic_router-0.1.0.dev3}/semantic_router/encoders/google.py +3 -3
- {semantic_router-0.1.0.dev1 → semantic_router-0.1.0.dev3}/semantic_router/encoders/huggingface.py +9 -7
- {semantic_router-0.1.0.dev1 → semantic_router-0.1.0.dev3}/semantic_router/encoders/mistral.py +3 -3
- {semantic_router-0.1.0.dev1 → semantic_router-0.1.0.dev3}/semantic_router/encoders/openai.py +11 -11
- {semantic_router-0.1.0.dev1 → semantic_router-0.1.0.dev3}/semantic_router/encoders/tfidf.py +24 -11
- {semantic_router-0.1.0.dev1 → semantic_router-0.1.0.dev3}/semantic_router/encoders/vit.py +6 -5
- {semantic_router-0.1.0.dev1 → semantic_router-0.1.0.dev3}/semantic_router/encoders/zure.py +2 -2
- {semantic_router-0.1.0.dev1 → semantic_router-0.1.0.dev3}/semantic_router/index/__init__.py +4 -0
- {semantic_router-0.1.0.dev1 → semantic_router-0.1.0.dev3}/semantic_router/index/base.py +5 -3
- semantic_router-0.1.0.dev3/semantic_router/index/hybrid_local.py +212 -0
- {semantic_router-0.1.0.dev1 → semantic_router-0.1.0.dev3}/semantic_router/index/local.py +27 -11
- {semantic_router-0.1.0.dev1 → semantic_router-0.1.0.dev3}/semantic_router/index/pinecone.py +64 -29
- {semantic_router-0.1.0.dev1 → semantic_router-0.1.0.dev3}/semantic_router/index/postgres.py +20 -7
- {semantic_router-0.1.0.dev1 → semantic_router-0.1.0.dev3}/semantic_router/index/qdrant.py +5 -3
- {semantic_router-0.1.0.dev1 → semantic_router-0.1.0.dev3}/semantic_router/llms/base.py +3 -1
- {semantic_router-0.1.0.dev1 → semantic_router-0.1.0.dev3}/semantic_router/llms/cohere.py +1 -1
- {semantic_router-0.1.0.dev1 → semantic_router-0.1.0.dev3}/semantic_router/llms/llamacpp.py +1 -3
- {semantic_router-0.1.0.dev1 → semantic_router-0.1.0.dev3}/semantic_router/llms/mistral.py +1 -3
- {semantic_router-0.1.0.dev1 → semantic_router-0.1.0.dev3}/semantic_router/llms/ollama.py +5 -10
- {semantic_router-0.1.0.dev1 → semantic_router-0.1.0.dev3}/semantic_router/llms/openai.py +9 -10
- {semantic_router-0.1.0.dev1 → semantic_router-0.1.0.dev3}/semantic_router/llms/openrouter.py +8 -8
- {semantic_router-0.1.0.dev1 → semantic_router-0.1.0.dev3}/semantic_router/llms/zure.py +5 -6
- {semantic_router-0.1.0.dev1 → semantic_router-0.1.0.dev3}/semantic_router/route.py +2 -7
- semantic_router-0.1.0.dev3/semantic_router/routers/__init__.py +10 -0
- semantic_router-0.1.0.dev1/semantic_router/layer.py → semantic_router-0.1.0.dev3/semantic_router/routers/base.py +267 -218
- semantic_router-0.1.0.dev3/semantic_router/routers/hybrid.py +254 -0
- semantic_router-0.1.0.dev3/semantic_router/routers/semantic.py +87 -0
- {semantic_router-0.1.0.dev1 → semantic_router-0.1.0.dev3}/semantic_router/schema.py +77 -2
- {semantic_router-0.1.0.dev1 → semantic_router-0.1.0.dev3}/semantic_router/utils/function_call.py +1 -1
- semantic_router-0.1.0.dev1/semantic_router/__init__.py +0 -7
- semantic_router-0.1.0.dev1/semantic_router/encoders/base.py +0 -22
- semantic_router-0.1.0.dev1/semantic_router/hybrid_layer.py +0 -220
- {semantic_router-0.1.0.dev1 → semantic_router-0.1.0.dev3}/README.md +0 -0
- {semantic_router-0.1.0.dev1 → semantic_router-0.1.0.dev3}/semantic_router/linear.py +0 -0
- {semantic_router-0.1.0.dev1 → semantic_router-0.1.0.dev3}/semantic_router/llms/__init__.py +0 -0
- {semantic_router-0.1.0.dev1 → semantic_router-0.1.0.dev3}/semantic_router/llms/grammars/json.gbnf +0 -0
- {semantic_router-0.1.0.dev1 → semantic_router-0.1.0.dev3}/semantic_router/utils/__init__.py +0 -0
- {semantic_router-0.1.0.dev1 → semantic_router-0.1.0.dev3}/semantic_router/utils/defaults.py +0 -0
- {semantic_router-0.1.0.dev1 → semantic_router-0.1.0.dev3}/semantic_router/utils/llm.py +0 -0
- {semantic_router-0.1.0.dev1 → 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
|
|
@@ -21,27 +23,26 @@ Provides-Extra: local
|
|
|
21
23
|
Provides-Extra: mistralai
|
|
22
24
|
Provides-Extra: pinecone
|
|
23
25
|
Provides-Extra: postgres
|
|
24
|
-
Provides-Extra: processing
|
|
25
26
|
Provides-Extra: qdrant
|
|
26
27
|
Provides-Extra: vision
|
|
27
|
-
Requires-Dist: aiohttp (>=3.
|
|
28
|
+
Requires-Dist: aiohttp (>=3.10.11,<4.0.0)
|
|
29
|
+
Requires-Dist: aurelio-sdk (>=0.0.16,<0.0.17)
|
|
28
30
|
Requires-Dist: boto3 (>=1.34.98,<2.0.0) ; extra == "bedrock"
|
|
29
31
|
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"
|
|
36
|
-
Requires-Dist: matplotlib (>=3.8.3,<4.0.0) ; extra == "processing"
|
|
37
|
+
Requires-Dist: llama-cpp-python (>=0.2.28,<0.2.86) ; (python_version < "3.13") and (extra == "local")
|
|
37
38
|
Requires-Dist: mistralai (>=0.0.12,<0.1.0) ; extra == "mistralai"
|
|
38
39
|
Requires-Dist: numpy (>=1.25.2,<2.0.0)
|
|
39
40
|
Requires-Dist: openai (>=1.10.0,<2.0.0)
|
|
40
|
-
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")
|
|
41
42
|
Requires-Dist: pinecone (>=5.0.0) ; extra == "pinecone"
|
|
42
43
|
Requires-Dist: pinecone-text (>=0.7.1,<0.10.0) ; extra == "hybrid"
|
|
43
|
-
Requires-Dist: psycopg2 (>=2.9.9,<3.0.0)
|
|
44
|
-
Requires-Dist: pydantic (>=2.
|
|
44
|
+
Requires-Dist: psycopg2-binary (>=2.9.9,<3.0.0)
|
|
45
|
+
Requires-Dist: pydantic (>=2.10.2,<3.0.0)
|
|
45
46
|
Requires-Dist: pyyaml (>=6.0.1,<7.0.0)
|
|
46
47
|
Requires-Dist: qdrant-client (>=1.11.1,<2.0.0) ; extra == "qdrant"
|
|
47
48
|
Requires-Dist: regex (>=2023.12.25)
|
|
@@ -49,10 +50,11 @@ Requires-Dist: requests-mock (>=1.12.1,<2.0.0)
|
|
|
49
50
|
Requires-Dist: sphinx (>=7.0.0,<8.0.0) ; extra == "docs"
|
|
50
51
|
Requires-Dist: sphinxawesome-theme (>=5.2.0,<6.0.0) ; extra == "docs"
|
|
51
52
|
Requires-Dist: tiktoken (>=0.6.0,<1.0.0)
|
|
52
|
-
Requires-Dist: tokenizers (>=0.19) ; extra == "local"
|
|
53
|
-
Requires-Dist: torch (>=2.1.0,<2.6.0) ; extra == "local" or extra == "vision"
|
|
54
|
-
Requires-Dist: torchvision (>=0.17.0,<0.18.0) ; extra == "vision"
|
|
55
|
-
Requires-Dist:
|
|
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")
|
|
56
|
+
Requires-Dist: tornado (>=6.4.2,<7.0.0)
|
|
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,43 +8,43 @@ 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}
|
|
16
16
|
numpy = "^1.25.2"
|
|
17
17
|
colorlog = "^6.8.0"
|
|
18
18
|
pyyaml = "^6.0.1"
|
|
19
|
+
aurelio-sdk = {version = "^0.0.16"}
|
|
19
20
|
pinecone-text = {version = ">=0.7.1,<0.10.0", optional = true}
|
|
20
|
-
torch = {version = ">=2.1.0,<2.6.0", optional = true}
|
|
21
|
-
transformers = {version = ">=4.36.2", optional = true}
|
|
22
|
-
tokenizers = {version = ">=0.19", optional = true}
|
|
23
|
-
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" }
|
|
24
25
|
colorama = "^0.4.6"
|
|
25
26
|
pinecone = {version=">=5.0.0", optional = true}
|
|
26
27
|
regex = ">=2023.12.25"
|
|
27
|
-
torchvision = { version = ">=0.17.0,<0.18.0", optional = true}
|
|
28
|
-
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" }
|
|
29
30
|
tiktoken = ">=0.6.0,<1.0.0"
|
|
30
|
-
matplotlib = { version = "^3.8.3", optional = true}
|
|
31
31
|
qdrant-client = {version = "^1.11.1", optional = true}
|
|
32
32
|
google-cloud-aiplatform = {version = "^1.45.0", optional = true}
|
|
33
33
|
requests-mock = "^1.12.1"
|
|
34
34
|
boto3 = { version = "^1.34.98", optional = true }
|
|
35
35
|
botocore = {version = "^1.34.110", optional = true}
|
|
36
|
-
aiohttp = "^3.
|
|
37
|
-
fastembed = {version = "^0.3.0", optional = true}
|
|
38
|
-
psycopg2 = {version = "^2.9.9", optional = true}
|
|
36
|
+
aiohttp = "^3.10.11"
|
|
37
|
+
fastembed = {version = "^0.3.0", optional = true, python = "<3.13" }
|
|
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}
|
|
41
|
+
tornado = {version = "^6.4.2", optional = true}
|
|
41
42
|
|
|
42
43
|
[tool.poetry.extras]
|
|
43
44
|
hybrid = ["pinecone-text"]
|
|
44
45
|
local = ["torch", "transformers", "tokenizers", "huggingface-hub", "llama-cpp-python"]
|
|
45
46
|
pinecone = ["pinecone"]
|
|
46
47
|
vision = ["torch", "torchvision", "transformers", "pillow"]
|
|
47
|
-
processing = ["matplotlib"]
|
|
48
48
|
mistralai = ["mistralai"]
|
|
49
49
|
qdrant = ["qdrant-client"]
|
|
50
50
|
google = ["google-cloud-aiplatform"]
|
|
@@ -57,10 +57,11 @@ cohere = ["cohere"]
|
|
|
57
57
|
[tool.poetry.group.dev.dependencies]
|
|
58
58
|
ipykernel = "^6.25.0"
|
|
59
59
|
ruff = "^0.1.5"
|
|
60
|
-
pytest = "^
|
|
60
|
+
pytest = "^8.2"
|
|
61
61
|
pytest-mock = "^3.12.0"
|
|
62
62
|
pytest-cov = "^4.1.0"
|
|
63
63
|
pytest-xdist = "^3.5.0"
|
|
64
|
+
pytest-asyncio = "^0.24.0"
|
|
64
65
|
mypy = "^1.7.1"
|
|
65
66
|
types-pyyaml = "^6.0.12.12"
|
|
66
67
|
types-requests = "^2.31.0"
|
{semantic_router-0.1.0.dev1 → semantic_router-0.1.0.dev3}/semantic_router/encoders/__init__.py
RENAMED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from typing import List, Optional
|
|
2
2
|
|
|
3
|
-
from semantic_router.encoders.
|
|
3
|
+
from semantic_router.encoders.aurelio import AurelioSparseEncoder
|
|
4
|
+
from semantic_router.encoders.base import DenseEncoder, SparseEncoder
|
|
4
5
|
from semantic_router.encoders.bedrock import BedrockEncoder
|
|
5
6
|
from semantic_router.encoders.bm25 import BM25Encoder
|
|
6
7
|
from semantic_router.encoders.clip import CLIPEncoder
|
|
@@ -14,10 +15,12 @@ from semantic_router.encoders.openai import OpenAIEncoder
|
|
|
14
15
|
from semantic_router.encoders.tfidf import TfidfEncoder
|
|
15
16
|
from semantic_router.encoders.vit import VitEncoder
|
|
16
17
|
from semantic_router.encoders.zure import AzureOpenAIEncoder
|
|
17
|
-
from semantic_router.schema import EncoderType
|
|
18
|
+
from semantic_router.schema import EncoderType, SparseEmbedding
|
|
18
19
|
|
|
19
20
|
__all__ = [
|
|
20
|
-
"
|
|
21
|
+
"AurelioSparseEncoder",
|
|
22
|
+
"DenseEncoder",
|
|
23
|
+
"SparseEncoder",
|
|
21
24
|
"AzureOpenAIEncoder",
|
|
22
25
|
"CohereEncoder",
|
|
23
26
|
"OpenAIEncoder",
|
|
@@ -37,7 +40,7 @@ __all__ = [
|
|
|
37
40
|
class AutoEncoder:
|
|
38
41
|
type: EncoderType
|
|
39
42
|
name: Optional[str]
|
|
40
|
-
model:
|
|
43
|
+
model: DenseEncoder | SparseEncoder
|
|
41
44
|
|
|
42
45
|
def __init__(self, type: str, name: Optional[str]):
|
|
43
46
|
self.type = EncoderType(type)
|
|
@@ -49,6 +52,8 @@ class AutoEncoder:
|
|
|
49
52
|
self.model = CohereEncoder(name=name)
|
|
50
53
|
elif self.type == EncoderType.OPENAI:
|
|
51
54
|
self.model = OpenAIEncoder(name=name)
|
|
55
|
+
elif self.type == EncoderType.AURELIO:
|
|
56
|
+
self.model = AurelioSparseEncoder(name=name)
|
|
52
57
|
elif self.type == EncoderType.BM25:
|
|
53
58
|
if name is None:
|
|
54
59
|
name = "bm25"
|
|
@@ -74,5 +79,5 @@ class AutoEncoder:
|
|
|
74
79
|
else:
|
|
75
80
|
raise ValueError(f"Encoder type '{type}' not supported")
|
|
76
81
|
|
|
77
|
-
def __call__(self, texts: List[str]) -> List[List[float]]:
|
|
82
|
+
def __call__(self, texts: List[str]) -> List[List[float]] | List[SparseEmbedding]:
|
|
78
83
|
return self.model(texts)
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from typing import Any, List, Optional
|
|
3
|
+
from pydantic import Field
|
|
4
|
+
|
|
5
|
+
from aurelio_sdk import AurelioClient, AsyncAurelioClient, EmbeddingResponse
|
|
6
|
+
|
|
7
|
+
from semantic_router.encoders.base import SparseEncoder
|
|
8
|
+
from semantic_router.schema import SparseEmbedding
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class AurelioSparseEncoder(SparseEncoder):
|
|
12
|
+
model: Optional[Any] = None
|
|
13
|
+
client: AurelioClient = Field(default_factory=AurelioClient, exclude=True)
|
|
14
|
+
async_client: AsyncAurelioClient = Field(
|
|
15
|
+
default_factory=AsyncAurelioClient, exclude=True
|
|
16
|
+
)
|
|
17
|
+
type: str = "sparse"
|
|
18
|
+
|
|
19
|
+
def __init__(
|
|
20
|
+
self,
|
|
21
|
+
name: str | None = None,
|
|
22
|
+
api_key: Optional[str] = None,
|
|
23
|
+
):
|
|
24
|
+
if name is None:
|
|
25
|
+
name = "bm25"
|
|
26
|
+
super().__init__(name=name)
|
|
27
|
+
if api_key is None:
|
|
28
|
+
api_key = os.getenv("AURELIO_API_KEY")
|
|
29
|
+
if api_key is None:
|
|
30
|
+
raise ValueError("AURELIO_API_KEY environment variable is not set.")
|
|
31
|
+
self.client = AurelioClient(api_key=api_key)
|
|
32
|
+
self.async_client = AsyncAurelioClient(api_key=api_key)
|
|
33
|
+
|
|
34
|
+
def __call__(self, docs: list[str]) -> list[SparseEmbedding]:
|
|
35
|
+
res: EmbeddingResponse = self.client.embedding(input=docs, model=self.name)
|
|
36
|
+
embeds = [SparseEmbedding.from_aurelio(r.embedding) for r in res.data]
|
|
37
|
+
return embeds
|
|
38
|
+
|
|
39
|
+
async def acall(self, docs: list[str]) -> list[SparseEmbedding]:
|
|
40
|
+
res: EmbeddingResponse = await self.async_client.embedding(
|
|
41
|
+
input=docs, model=self.name
|
|
42
|
+
)
|
|
43
|
+
embeds = [SparseEmbedding.from_aurelio(r.embedding) for r in res.data]
|
|
44
|
+
return embeds
|
|
45
|
+
|
|
46
|
+
def fit(self, docs: List[str]):
|
|
47
|
+
raise NotImplementedError("AurelioSparseEncoder does not support fit.")
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
from typing import Any, Coroutine, List, Optional
|
|
2
|
+
|
|
3
|
+
from pydantic import BaseModel, Field, field_validator
|
|
4
|
+
import numpy as np
|
|
5
|
+
|
|
6
|
+
from semantic_router.schema import SparseEmbedding
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class DenseEncoder(BaseModel):
|
|
10
|
+
name: str
|
|
11
|
+
score_threshold: Optional[float] = None
|
|
12
|
+
type: str = Field(default="base")
|
|
13
|
+
|
|
14
|
+
class Config:
|
|
15
|
+
arbitrary_types_allowed = True
|
|
16
|
+
|
|
17
|
+
@field_validator("score_threshold")
|
|
18
|
+
def set_score_threshold(cls, v):
|
|
19
|
+
return float(v) if v is not None else None
|
|
20
|
+
|
|
21
|
+
def __call__(self, docs: List[Any]) -> List[List[float]]:
|
|
22
|
+
raise NotImplementedError("Subclasses must implement this method")
|
|
23
|
+
|
|
24
|
+
def acall(self, docs: List[Any]) -> Coroutine[Any, Any, List[List[float]]]:
|
|
25
|
+
raise NotImplementedError("Subclasses must implement this method")
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class SparseEncoder(BaseModel):
|
|
29
|
+
name: str
|
|
30
|
+
type: str = Field(default="base")
|
|
31
|
+
|
|
32
|
+
class Config:
|
|
33
|
+
arbitrary_types_allowed = True
|
|
34
|
+
|
|
35
|
+
def __call__(self, docs: List[str]) -> List[SparseEmbedding]:
|
|
36
|
+
raise NotImplementedError("Subclasses must implement this method")
|
|
37
|
+
|
|
38
|
+
async def acall(self, docs: List[str]) -> list[SparseEmbedding]:
|
|
39
|
+
raise NotImplementedError("Subclasses must implement this method")
|
|
40
|
+
|
|
41
|
+
def _array_to_sparse_embeddings(
|
|
42
|
+
self, sparse_arrays: np.ndarray
|
|
43
|
+
) -> List[SparseEmbedding]:
|
|
44
|
+
"""Consumes several sparse vectors containing zero-values and returns a compact array."""
|
|
45
|
+
if sparse_arrays.ndim != 2:
|
|
46
|
+
raise ValueError(f"Expected a 2D array, got a {sparse_arrays.ndim}D array.")
|
|
47
|
+
# get coordinates of non-zero values
|
|
48
|
+
coords = np.nonzero(sparse_arrays)
|
|
49
|
+
# create compact array
|
|
50
|
+
compact_array = np.array([coords[0], coords[1], sparse_arrays[coords]]).T
|
|
51
|
+
arr_range = range(compact_array[:, 0].max().astype(int) + 1)
|
|
52
|
+
arrs = [compact_array[compact_array[:, 0] == i, :][:, 1:3] for i in arr_range]
|
|
53
|
+
return [SparseEmbedding.from_compact_array(arr) for arr in arrs]
|
{semantic_router-0.1.0.dev1 → semantic_router-0.1.0.dev3}/semantic_router/encoders/bedrock.py
RENAMED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""
|
|
2
2
|
This module provides the BedrockEncoder class for generating embeddings using Amazon's Bedrock Platform.
|
|
3
3
|
|
|
4
|
-
The BedrockEncoder class is a subclass of
|
|
4
|
+
The BedrockEncoder class is a subclass of DenseEncoder and utilizes the TextEmbeddingModel from the
|
|
5
5
|
Amazon's Bedrock Platform to generate embeddings for given documents. It requires an AWS Access Key ID
|
|
6
6
|
and AWS Secret Access Key and supports customization of the pre-trained model, score threshold, and region.
|
|
7
7
|
|
|
@@ -21,12 +21,12 @@ from typing import List, Optional, Any
|
|
|
21
21
|
import os
|
|
22
22
|
from time import sleep
|
|
23
23
|
import tiktoken
|
|
24
|
-
from semantic_router.encoders import
|
|
24
|
+
from semantic_router.encoders import DenseEncoder
|
|
25
25
|
from semantic_router.utils.defaults import EncoderDefault
|
|
26
26
|
from semantic_router.utils.logger import logger
|
|
27
27
|
|
|
28
28
|
|
|
29
|
-
class BedrockEncoder(
|
|
29
|
+
class BedrockEncoder(DenseEncoder):
|
|
30
30
|
client: Any = None
|
|
31
31
|
type: str = "bedrock"
|
|
32
32
|
input_type: Optional[str] = "search_query"
|
|
@@ -1,21 +1,24 @@
|
|
|
1
1
|
from typing import Any, Dict, List, Optional
|
|
2
2
|
|
|
3
|
-
from semantic_router.encoders import
|
|
3
|
+
from semantic_router.encoders.tfidf import TfidfEncoder
|
|
4
4
|
from semantic_router.utils.logger import logger
|
|
5
|
+
from semantic_router.schema import SparseEmbedding
|
|
6
|
+
from semantic_router.route import Route
|
|
5
7
|
|
|
6
8
|
|
|
7
|
-
class BM25Encoder(
|
|
9
|
+
class BM25Encoder(TfidfEncoder):
|
|
8
10
|
model: Optional[Any] = None
|
|
9
11
|
idx_mapping: Optional[Dict[int, int]] = None
|
|
10
12
|
type: str = "sparse"
|
|
11
13
|
|
|
12
14
|
def __init__(
|
|
13
15
|
self,
|
|
14
|
-
name: str =
|
|
15
|
-
score_threshold: float = 0.82,
|
|
16
|
+
name: str | None = None,
|
|
16
17
|
use_default_params: bool = True,
|
|
17
18
|
):
|
|
18
|
-
|
|
19
|
+
if name is None:
|
|
20
|
+
name = "bm25"
|
|
21
|
+
super().__init__(name=name)
|
|
19
22
|
try:
|
|
20
23
|
from pinecone_text.sparse import BM25Encoder as encoder
|
|
21
24
|
except ImportError:
|
|
@@ -32,6 +35,7 @@ class BM25Encoder(BaseEncoder):
|
|
|
32
35
|
self._set_idx_mapping()
|
|
33
36
|
|
|
34
37
|
def _set_idx_mapping(self):
|
|
38
|
+
# TODO JB: this is training the model somehow - not sure how...
|
|
35
39
|
params = self.model.get_params()
|
|
36
40
|
doc_freq = params["doc_freq"]
|
|
37
41
|
if isinstance(doc_freq, dict):
|
|
@@ -40,8 +44,20 @@ class BM25Encoder(BaseEncoder):
|
|
|
40
44
|
else:
|
|
41
45
|
raise TypeError("Expected a dictionary for 'doc_freq'")
|
|
42
46
|
|
|
43
|
-
def
|
|
44
|
-
|
|
47
|
+
def fit(self, routes: List[Route]):
|
|
48
|
+
"""Trains the encoder weights on the provided routes.
|
|
49
|
+
|
|
50
|
+
:param routes: List of routes to train the encoder on.
|
|
51
|
+
:type routes: List[Route]
|
|
52
|
+
"""
|
|
53
|
+
self._fit_validate(routes=routes)
|
|
54
|
+
if self.model is None:
|
|
55
|
+
raise ValueError("Model is not initialized.")
|
|
56
|
+
utterances = [utterance for route in routes for utterance in route.utterances]
|
|
57
|
+
self.model.fit(corpus=utterances)
|
|
58
|
+
|
|
59
|
+
def __call__(self, docs: List[str]) -> list[SparseEmbedding]:
|
|
60
|
+
if self.model is None:
|
|
45
61
|
raise ValueError("Model or index mapping is not initialized.")
|
|
46
62
|
if len(docs) == 1:
|
|
47
63
|
sparse_dicts = self.model.encode_queries(docs)
|
|
@@ -50,18 +66,8 @@ class BM25Encoder(BaseEncoder):
|
|
|
50
66
|
else:
|
|
51
67
|
raise ValueError("No documents to encode.")
|
|
52
68
|
|
|
53
|
-
embeds = [
|
|
69
|
+
embeds = []
|
|
54
70
|
for i, output in enumerate(sparse_dicts):
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
for idx, val in zip(indices, values):
|
|
58
|
-
if idx in self.idx_mapping:
|
|
59
|
-
position = self.idx_mapping[idx]
|
|
60
|
-
embeds[i][position] = val
|
|
71
|
+
if isinstance(output, dict):
|
|
72
|
+
embeds.append(SparseEmbedding.from_pinecone_dict(output))
|
|
61
73
|
return embeds
|
|
62
|
-
|
|
63
|
-
def fit(self, docs: List[str]):
|
|
64
|
-
if self.model is None:
|
|
65
|
-
raise ValueError("Model is not initialized.")
|
|
66
|
-
self.model.fit(docs)
|
|
67
|
-
self._set_idx_mapping()
|
|
@@ -1,15 +1,14 @@
|
|
|
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
|
-
from semantic_router.encoders import
|
|
6
|
+
from semantic_router.encoders import DenseEncoder
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
class CLIPEncoder(
|
|
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(BaseEncoder):
|
|
|
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.dev1 → semantic_router-0.1.0.dev3}/semantic_router/encoders/cohere.py
RENAMED
|
@@ -1,13 +1,13 @@
|
|
|
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
|
-
from semantic_router.encoders import
|
|
6
|
+
from semantic_router.encoders import DenseEncoder
|
|
7
7
|
from semantic_router.utils.defaults import EncoderDefault
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
class CohereEncoder(
|
|
10
|
+
class CohereEncoder(DenseEncoder):
|
|
11
11
|
_client: Any = PrivateAttr()
|
|
12
12
|
_embed_type: Any = PrivateAttr()
|
|
13
13
|
type: str = "cohere"
|
{semantic_router-0.1.0.dev1 → semantic_router-0.1.0.dev3}/semantic_router/encoders/fastembed.py
RENAMED
|
@@ -1,12 +1,12 @@
|
|
|
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
|
|
|
6
|
-
from semantic_router.encoders import
|
|
6
|
+
from semantic_router.encoders import DenseEncoder
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
class FastEmbedEncoder(
|
|
9
|
+
class FastEmbedEncoder(DenseEncoder):
|
|
10
10
|
type: str = "fastembed"
|
|
11
11
|
name: str = "BAAI/bge-small-en-v1.5"
|
|
12
12
|
max_length: int = 512
|
{semantic_router-0.1.0.dev1 → semantic_router-0.1.0.dev3}/semantic_router/encoders/google.py
RENAMED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""
|
|
2
2
|
This module provides the GoogleEncoder class for generating embeddings using Google's AI Platform.
|
|
3
3
|
|
|
4
|
-
The GoogleEncoder class is a subclass of
|
|
4
|
+
The GoogleEncoder class is a subclass of DenseEncoder and utilizes the TextEmbeddingModel from the
|
|
5
5
|
Google AI Platform to generate embeddings for given documents. It requires a Google Cloud project ID
|
|
6
6
|
and supports customization of the pre-trained model, score threshold, location, and API endpoint.
|
|
7
7
|
|
|
@@ -19,11 +19,11 @@ Classes:
|
|
|
19
19
|
import os
|
|
20
20
|
from typing import Any, List, Optional
|
|
21
21
|
|
|
22
|
-
from semantic_router.encoders import
|
|
22
|
+
from semantic_router.encoders import DenseEncoder
|
|
23
23
|
from semantic_router.utils.defaults import EncoderDefault
|
|
24
24
|
|
|
25
25
|
|
|
26
|
-
class GoogleEncoder(
|
|
26
|
+
class GoogleEncoder(DenseEncoder):
|
|
27
27
|
"""GoogleEncoder class for generating embeddings using Google's AI Platform.
|
|
28
28
|
|
|
29
29
|
Attributes:
|
{semantic_router-0.1.0.dev1 → semantic_router-0.1.0.dev3}/semantic_router/encoders/huggingface.py
RENAMED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""
|
|
2
2
|
This module provides the HFEndpointEncoder class to embeddings models using Huggingface's endpoint.
|
|
3
3
|
|
|
4
|
-
The HFEndpointEncoder class is a subclass of
|
|
4
|
+
The HFEndpointEncoder class is a subclass of DenseEncoder and utilizes a specified Huggingface
|
|
5
5
|
endpoint to generate embeddings for given documents. It requires the URL of the Huggingface
|
|
6
6
|
API endpoint and an API key for authentication. The class supports customization of the score
|
|
7
7
|
threshold for filtering or processing the embeddings.
|
|
@@ -25,16 +25,15 @@ 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
|
-
from semantic_router.encoders import
|
|
30
|
+
from semantic_router.encoders import DenseEncoder
|
|
31
31
|
from semantic_router.utils.logger import logger
|
|
32
32
|
|
|
33
33
|
|
|
34
|
-
class HuggingFaceEncoder(
|
|
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(BaseEncoder):
|
|
|
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
|
|
|
@@ -140,7 +141,7 @@ class HuggingFaceEncoder(BaseEncoder):
|
|
|
140
141
|
return self._torch.max(token_embeddings, 1)[0]
|
|
141
142
|
|
|
142
143
|
|
|
143
|
-
class HFEndpointEncoder(
|
|
144
|
+
class HFEndpointEncoder(DenseEncoder):
|
|
144
145
|
"""
|
|
145
146
|
A class to encode documents using a Hugging Face transformer model endpoint.
|
|
146
147
|
|
|
@@ -153,7 +154,6 @@ class HFEndpointEncoder(BaseEncoder):
|
|
|
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(BaseEncoder):
|
|
|
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.dev1 → semantic_router-0.1.0.dev3}/semantic_router/encoders/mistral.py
RENAMED
|
@@ -4,13 +4,13 @@ import os
|
|
|
4
4
|
from time import sleep
|
|
5
5
|
from typing import Any, List, Optional
|
|
6
6
|
|
|
7
|
-
from pydantic
|
|
7
|
+
from pydantic import PrivateAttr
|
|
8
8
|
|
|
9
|
-
from semantic_router.encoders import
|
|
9
|
+
from semantic_router.encoders import DenseEncoder
|
|
10
10
|
from semantic_router.utils.defaults import EncoderDefault
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
class MistralEncoder(
|
|
13
|
+
class MistralEncoder(DenseEncoder):
|
|
14
14
|
"""Class to encode text using MistralAI"""
|
|
15
15
|
|
|
16
16
|
_client: Any = PrivateAttr()
|