semantic-router 0.1.0.dev8__tar.gz → 0.1.0.dev10__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.dev8 → semantic_router-0.1.0.dev10}/PKG-INFO +2 -2
- {semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/pyproject.toml +2 -2
- {semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/__init__.py +1 -1
- {semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/index/pinecone.py +190 -58
- {semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/routers/base.py +9 -1
- {semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/schema.py +2 -2
- {semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/LICENSE +0 -0
- {semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/README.md +0 -0
- {semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/encoders/__init__.py +0 -0
- {semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/encoders/aurelio.py +0 -0
- {semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/encoders/base.py +0 -0
- {semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/encoders/bedrock.py +0 -0
- {semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/encoders/bm25.py +0 -0
- {semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/encoders/clip.py +0 -0
- {semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/encoders/cohere.py +0 -0
- {semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/encoders/fastembed.py +0 -0
- {semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/encoders/google.py +0 -0
- {semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/encoders/huggingface.py +0 -0
- {semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/encoders/mistral.py +0 -0
- {semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/encoders/openai.py +0 -0
- {semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/encoders/tfidf.py +0 -0
- {semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/encoders/vit.py +0 -0
- {semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/encoders/zure.py +0 -0
- {semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/index/__init__.py +0 -0
- {semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/index/base.py +0 -0
- {semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/index/hybrid_local.py +0 -0
- {semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/index/local.py +0 -0
- {semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/index/postgres.py +0 -0
- {semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/index/qdrant.py +0 -0
- {semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/linear.py +0 -0
- {semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/llms/__init__.py +0 -0
- {semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/llms/base.py +0 -0
- {semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/llms/cohere.py +0 -0
- {semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/llms/grammars/json.gbnf +0 -0
- {semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/llms/llamacpp.py +0 -0
- {semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/llms/mistral.py +0 -0
- {semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/llms/ollama.py +0 -0
- {semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/llms/openai.py +0 -0
- {semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/llms/openrouter.py +0 -0
- {semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/llms/zure.py +0 -0
- {semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/py.typed +0 -0
- {semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/route.py +0 -0
- {semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/routers/__init__.py +0 -0
- {semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/routers/hybrid.py +0 -0
- {semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/routers/semantic.py +0 -0
- {semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/utils/__init__.py +0 -0
- {semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/utils/defaults.py +0 -0
- {semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/utils/function_call.py +0 -0
- {semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/utils/llm.py +0 -0
- {semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/utils/logger.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: semantic-router
|
|
3
|
-
Version: 0.1.0.
|
|
3
|
+
Version: 0.1.0.dev10
|
|
4
4
|
Summary: Super fast semantic router for AI decision making
|
|
5
5
|
License: MIT
|
|
6
6
|
Author: Aurelio AI
|
|
@@ -26,7 +26,7 @@ Provides-Extra: postgres
|
|
|
26
26
|
Provides-Extra: qdrant
|
|
27
27
|
Provides-Extra: vision
|
|
28
28
|
Requires-Dist: aiohttp (>=3.10.11,<4.0.0)
|
|
29
|
-
Requires-Dist: aurelio-sdk (>=0.0.
|
|
29
|
+
Requires-Dist: aurelio-sdk (>=0.0.18,<0.0.19)
|
|
30
30
|
Requires-Dist: boto3 (>=1.34.98,<2.0.0) ; extra == "bedrock"
|
|
31
31
|
Requires-Dist: botocore (>=1.34.110,<2.0.0) ; extra == "bedrock"
|
|
32
32
|
Requires-Dist: cohere (>=5.9.4,<6.00) ; extra == "cohere"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "semantic-router"
|
|
3
|
-
version = "0.1.0.
|
|
3
|
+
version = "0.1.0.dev10"
|
|
4
4
|
description = "Super fast semantic router for AI decision making"
|
|
5
5
|
authors = ["Aurelio AI <hello@aurelio.ai>"]
|
|
6
6
|
readme = "README.md"
|
|
@@ -16,7 +16,7 @@ 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.
|
|
19
|
+
aurelio-sdk = {version = "^0.0.18"}
|
|
20
20
|
pinecone-text = {version = ">=0.7.1", optional = true}
|
|
21
21
|
torch = {version = ">=2.1.0,<2.6.0", optional = true, python = "<3.13" }
|
|
22
22
|
transformers = {version = ">=4.36.2", optional = true, python = "<3.13" }
|
{semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/index/pinecone.py
RENAMED
|
@@ -3,6 +3,8 @@ import hashlib
|
|
|
3
3
|
import json
|
|
4
4
|
import os
|
|
5
5
|
import time
|
|
6
|
+
import requests
|
|
7
|
+
from json.decoder import JSONDecodeError
|
|
6
8
|
from typing import Any, Dict, List, Optional, Tuple, Union
|
|
7
9
|
|
|
8
10
|
import aiohttp
|
|
@@ -18,6 +20,13 @@ def clean_route_name(route_name: str) -> str:
|
|
|
18
20
|
return route_name.strip().replace(" ", "-")
|
|
19
21
|
|
|
20
22
|
|
|
23
|
+
class DeleteRequest(BaseModel):
|
|
24
|
+
ids: list[str] | None = None
|
|
25
|
+
delete_all: bool = False
|
|
26
|
+
namespace: str | None = None
|
|
27
|
+
filter: dict[str, Any] | None = None
|
|
28
|
+
|
|
29
|
+
|
|
21
30
|
def build_records(
|
|
22
31
|
embeddings: List[List[float]],
|
|
23
32
|
routes: List[str],
|
|
@@ -114,8 +123,9 @@ class PineconeIndex(BaseIndex):
|
|
|
114
123
|
index: Optional[Any] = Field(default=None, exclude=True)
|
|
115
124
|
ServerlessSpec: Any = Field(default=None, exclude=True)
|
|
116
125
|
namespace: Optional[str] = ""
|
|
117
|
-
base_url: Optional[str] =
|
|
126
|
+
base_url: Optional[str] = None
|
|
118
127
|
headers: dict[str, str] = {}
|
|
128
|
+
index_host: Optional[str] = "http://localhost:5080"
|
|
119
129
|
|
|
120
130
|
def __init__(
|
|
121
131
|
self,
|
|
@@ -134,12 +144,23 @@ class PineconeIndex(BaseIndex):
|
|
|
134
144
|
self.api_key = api_key or os.getenv("PINECONE_API_KEY")
|
|
135
145
|
if not self.api_key:
|
|
136
146
|
raise ValueError("Pinecone API key is required.")
|
|
147
|
+
|
|
137
148
|
self.headers = {
|
|
138
149
|
"Api-Key": self.api_key,
|
|
139
150
|
"Content-Type": "application/json",
|
|
140
|
-
"X-Pinecone-API-Version": "2024-07",
|
|
141
151
|
"User-Agent": "source_tag=semanticrouter",
|
|
142
152
|
}
|
|
153
|
+
|
|
154
|
+
if base_url is not None or os.getenv("PINECONE_API_BASE_URL"):
|
|
155
|
+
logger.info("Using pinecone remote API.")
|
|
156
|
+
if os.getenv("PINECONE_API_BASE_URL"):
|
|
157
|
+
self.base_url = os.getenv("PINECONE_API_BASE_URL")
|
|
158
|
+
else:
|
|
159
|
+
self.base_url = base_url
|
|
160
|
+
|
|
161
|
+
if self.base_url and "api.pinecone.io" in self.base_url:
|
|
162
|
+
self.headers["X-Pinecone-API-Version"] = "2024-07"
|
|
163
|
+
|
|
143
164
|
self.index_name = index_name
|
|
144
165
|
self.dimensions = dimensions
|
|
145
166
|
self.metric = metric
|
|
@@ -150,16 +171,11 @@ class PineconeIndex(BaseIndex):
|
|
|
150
171
|
raise ValueError("Namespace 'sr_config' is reserved for internal use.")
|
|
151
172
|
self.namespace = namespace
|
|
152
173
|
self.type = "pinecone"
|
|
153
|
-
self.api_key = api_key or os.getenv("PINECONE_API_KEY")
|
|
154
|
-
self.base_url = base_url
|
|
155
174
|
|
|
156
175
|
logger.warning(
|
|
157
176
|
"Default region changed from us-west-2 to us-east-1 in v0.1.0.dev6"
|
|
158
177
|
)
|
|
159
178
|
|
|
160
|
-
if self.api_key is None:
|
|
161
|
-
raise ValueError("Pinecone API key is required.")
|
|
162
|
-
|
|
163
179
|
self.client = self._initialize_client(api_key=self.api_key)
|
|
164
180
|
|
|
165
181
|
# try initializing index
|
|
@@ -186,6 +202,20 @@ class PineconeIndex(BaseIndex):
|
|
|
186
202
|
|
|
187
203
|
return Pinecone(**pinecone_args)
|
|
188
204
|
|
|
205
|
+
def _calculate_index_host(self):
|
|
206
|
+
if self.index_host and self.base_url:
|
|
207
|
+
if "api.pinecone.io" in self.base_url:
|
|
208
|
+
if not self.index_host.startswith("http"):
|
|
209
|
+
self.index_host = f"https://{self.index_host}"
|
|
210
|
+
else:
|
|
211
|
+
if "http" not in self.index_host:
|
|
212
|
+
self.index_host = f"http://{self.base_url.split(':')[-2].strip('/')}:{self.index_host.split(':')[-1]}"
|
|
213
|
+
elif not self.index_host.startswith("http://"):
|
|
214
|
+
if "localhost" in self.index_host:
|
|
215
|
+
self.index_host = f"http://{self.base_url.split(':')[-2].strip('/')}:{self.index_host.split(':')[-1]}"
|
|
216
|
+
else:
|
|
217
|
+
self.index_host = f"http://{self.index_host}"
|
|
218
|
+
|
|
189
219
|
def _init_index(self, force_create: bool = False) -> Union[Any, None]:
|
|
190
220
|
"""Initializing the index can be done after the object has been created
|
|
191
221
|
to allow for the user to set the dimensions and other parameters.
|
|
@@ -199,43 +229,59 @@ class PineconeIndex(BaseIndex):
|
|
|
199
229
|
dimensions are not given (which will raise an error).
|
|
200
230
|
:type force_create: bool, optional
|
|
201
231
|
"""
|
|
202
|
-
index_exists = self.index_name in self.client.list_indexes().names()
|
|
203
232
|
dimensions_given = self.dimensions is not None
|
|
204
|
-
if
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
233
|
+
if self.index is None:
|
|
234
|
+
index_exists = self.index_name in self.client.list_indexes().names()
|
|
235
|
+
if dimensions_given and not index_exists:
|
|
236
|
+
# if the index doesn't exist and we have dimension value
|
|
237
|
+
# we create the index
|
|
238
|
+
self.client.create_index(
|
|
239
|
+
name=self.index_name,
|
|
240
|
+
dimension=self.dimensions,
|
|
241
|
+
metric=self.metric,
|
|
242
|
+
spec=self.ServerlessSpec(cloud=self.cloud, region=self.region),
|
|
243
|
+
)
|
|
244
|
+
# wait for index to be created
|
|
245
|
+
while not self.client.describe_index(self.index_name).status["ready"]:
|
|
246
|
+
time.sleep(0.2)
|
|
247
|
+
index = self.client.Index(self.index_name)
|
|
248
|
+
self.index = index
|
|
249
|
+
time.sleep(0.2)
|
|
250
|
+
elif index_exists:
|
|
251
|
+
# if the index exists we just return it
|
|
252
|
+
# index = self.client.Index(self.index_name)
|
|
253
|
+
|
|
254
|
+
self.index_host = self.client.describe_index(self.index_name).host
|
|
255
|
+
self._calculate_index_host()
|
|
256
|
+
index = self.client.Index(self.index_name, host=self.index_host)
|
|
257
|
+
self.index = index
|
|
258
|
+
|
|
259
|
+
# grab the dimensions from the index
|
|
260
|
+
self.dimensions = index.describe_index_stats()["dimension"]
|
|
261
|
+
elif force_create and not dimensions_given:
|
|
262
|
+
raise ValueError(
|
|
263
|
+
"Cannot create an index without specifying the dimensions."
|
|
264
|
+
)
|
|
265
|
+
else:
|
|
266
|
+
# if the index doesn't exist and we don't have the dimensions
|
|
267
|
+
# we return None
|
|
268
|
+
logger.warning(
|
|
269
|
+
"Index could not be initialized. Init parameters: "
|
|
270
|
+
f"{self.index_name=}, {self.dimensions=}, {self.metric=}, "
|
|
271
|
+
f"{self.cloud=}, {self.region=}, {self.host=}, {self.namespace=}, "
|
|
272
|
+
f"{force_create=}"
|
|
273
|
+
)
|
|
274
|
+
index = None
|
|
227
275
|
else:
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
if index is not None:
|
|
238
|
-
self.host = self.client.describe_index(self.index_name)["host"]
|
|
276
|
+
index = self.index
|
|
277
|
+
if self.index is not None and self.host == "":
|
|
278
|
+
# if the index exists we just return it
|
|
279
|
+
self.index_host = self.client.describe_index(self.index_name).host
|
|
280
|
+
|
|
281
|
+
if self.index_host and self.base_url:
|
|
282
|
+
self._calculate_index_host()
|
|
283
|
+
index = self.client.Index(self.index_name, host=self.index_host)
|
|
284
|
+
self.host = self.index_host
|
|
239
285
|
return index
|
|
240
286
|
|
|
241
287
|
async def _init_async_index(self, force_create: bool = False):
|
|
@@ -442,12 +488,37 @@ class PineconeIndex(BaseIndex):
|
|
|
442
488
|
def delete(self, route_name: str):
|
|
443
489
|
route_vec_ids = self._get_route_ids(route_name=route_name)
|
|
444
490
|
if self.index is not None:
|
|
445
|
-
|
|
491
|
+
logger.info("index is not None, deleting...")
|
|
492
|
+
if self.base_url and "api.pinecone.io" in self.base_url:
|
|
493
|
+
self.index.delete(ids=route_vec_ids, namespace=self.namespace)
|
|
494
|
+
else:
|
|
495
|
+
|
|
496
|
+
response = requests.post(
|
|
497
|
+
f"{self.index_host}/vectors/delete",
|
|
498
|
+
json=DeleteRequest(
|
|
499
|
+
ids=route_vec_ids,
|
|
500
|
+
delete_all=True,
|
|
501
|
+
namespace=self.namespace,
|
|
502
|
+
).model_dump(exclude_none=True),
|
|
503
|
+
timeout=10,
|
|
504
|
+
)
|
|
505
|
+
if response.status_code == 200:
|
|
506
|
+
logger.info(
|
|
507
|
+
f"Deleted {len(route_vec_ids)} vectors from index {self.index_name}."
|
|
508
|
+
)
|
|
509
|
+
else:
|
|
510
|
+
error_message = response.text
|
|
511
|
+
raise Exception(
|
|
512
|
+
f"Failed to delete vectors: {response.status_code} : {error_message}"
|
|
513
|
+
)
|
|
446
514
|
else:
|
|
447
515
|
raise ValueError("Index is None, could not delete.")
|
|
448
516
|
|
|
449
517
|
def delete_all(self):
|
|
450
|
-
self.index
|
|
518
|
+
if self.index is not None:
|
|
519
|
+
self.index.delete(delete_all=True, namespace=self.namespace)
|
|
520
|
+
else:
|
|
521
|
+
raise ValueError("Index is None, could not delete.")
|
|
451
522
|
|
|
452
523
|
def describe(self) -> IndexConfig:
|
|
453
524
|
if self.index is not None:
|
|
@@ -501,19 +572,31 @@ class PineconeIndex(BaseIndex):
|
|
|
501
572
|
else:
|
|
502
573
|
filter_query = None
|
|
503
574
|
if sparse_vector is not None:
|
|
575
|
+
logger.error(f"sparse_vector exists:{sparse_vector}")
|
|
504
576
|
if isinstance(sparse_vector, dict):
|
|
505
577
|
sparse_vector = SparseEmbedding.from_dict(sparse_vector)
|
|
506
578
|
if isinstance(sparse_vector, SparseEmbedding):
|
|
507
579
|
# unnecessary if-statement but mypy didn't like this otherwise
|
|
508
580
|
sparse_vector = sparse_vector.to_pinecone()
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
581
|
+
try:
|
|
582
|
+
results = self.index.query(
|
|
583
|
+
vector=[query_vector_list],
|
|
584
|
+
sparse_vector=sparse_vector,
|
|
585
|
+
top_k=top_k,
|
|
586
|
+
filter=filter_query,
|
|
587
|
+
include_metadata=True,
|
|
588
|
+
namespace=self.namespace,
|
|
589
|
+
)
|
|
590
|
+
except Exception:
|
|
591
|
+
logger.error("retrying query with vector as str")
|
|
592
|
+
results = self.index.query(
|
|
593
|
+
vector=query_vector_list,
|
|
594
|
+
sparse_vector=sparse_vector,
|
|
595
|
+
top_k=top_k,
|
|
596
|
+
filter=filter_query,
|
|
597
|
+
include_metadata=True,
|
|
598
|
+
namespace=self.namespace,
|
|
599
|
+
)
|
|
517
600
|
scores = [result["score"] for result in results["matches"]]
|
|
518
601
|
route_names = [result["metadata"]["sr_route"] for result in results["matches"]]
|
|
519
602
|
return np.array(scores), route_names
|
|
@@ -710,16 +793,35 @@ class PineconeIndex(BaseIndex):
|
|
|
710
793
|
"filter": filter,
|
|
711
794
|
"top_k": top_k,
|
|
712
795
|
"include_metadata": include_metadata,
|
|
796
|
+
"topK": top_k,
|
|
797
|
+
"includeMetadata": include_metadata,
|
|
713
798
|
}
|
|
714
799
|
if self.host == "":
|
|
715
800
|
raise ValueError("self.host is not initialized.")
|
|
801
|
+
elif self.base_url and "api.pinecone.io" in self.base_url:
|
|
802
|
+
if not self.host.startswith("http"):
|
|
803
|
+
logger.error(f"host exists:{self.host}")
|
|
804
|
+
|
|
805
|
+
self.host = f"https://{self.host}"
|
|
806
|
+
elif self.host.startswith("localhost") and self.base_url:
|
|
807
|
+
self.host = f"http://{self.base_url.split(':')[-2].strip('/')}:{self.host.split(':')[-1]}"
|
|
808
|
+
|
|
716
809
|
async with aiohttp.ClientSession() as session:
|
|
717
810
|
async with session.post(
|
|
718
|
-
f"
|
|
811
|
+
f"{self.host}/query",
|
|
719
812
|
json=params,
|
|
720
813
|
headers=self.headers,
|
|
721
814
|
) as response:
|
|
722
|
-
|
|
815
|
+
if response.status != 200:
|
|
816
|
+
error_text = await response.text()
|
|
817
|
+
logger.error(f"Error in query response: {error_text}")
|
|
818
|
+
return {} # or handle the error as needed
|
|
819
|
+
|
|
820
|
+
try:
|
|
821
|
+
return await response.json(content_type=None)
|
|
822
|
+
except JSONDecodeError as e:
|
|
823
|
+
logger.error(f"JSON decode error: {e}")
|
|
824
|
+
return {}
|
|
723
825
|
|
|
724
826
|
async def _async_list_indexes(self):
|
|
725
827
|
async with aiohttp.ClientSession() as session:
|
|
@@ -738,9 +840,17 @@ class PineconeIndex(BaseIndex):
|
|
|
738
840
|
"vectors": vectors,
|
|
739
841
|
"namespace": namespace,
|
|
740
842
|
}
|
|
843
|
+
|
|
844
|
+
if self.base_url and "api.pinecone.io" in self.base_url:
|
|
845
|
+
if not self.host.startswith("http"):
|
|
846
|
+
logger.error(f"host exists:{self.host}")
|
|
847
|
+
self.host = f"https://{self.host}"
|
|
848
|
+
|
|
849
|
+
elif self.host.startswith("localhost") and self.base_url:
|
|
850
|
+
self.host = f"http://{self.base_url.split(':')[-2].strip('/')}:{self.host.split(':')[-1]}"
|
|
741
851
|
async with aiohttp.ClientSession() as session:
|
|
742
852
|
async with session.post(
|
|
743
|
-
f"
|
|
853
|
+
f"{self.host}/vectors/upsert",
|
|
744
854
|
json=params,
|
|
745
855
|
headers=self.headers,
|
|
746
856
|
) as response:
|
|
@@ -774,9 +884,16 @@ class PineconeIndex(BaseIndex):
|
|
|
774
884
|
"ids": ids,
|
|
775
885
|
"namespace": namespace,
|
|
776
886
|
}
|
|
887
|
+
if self.base_url and "api.pinecone.io" in self.base_url:
|
|
888
|
+
if not self.host.startswith("http"):
|
|
889
|
+
logger.error(f"host exists:{self.host}")
|
|
890
|
+
self.host = f"https://{self.host}"
|
|
891
|
+
elif self.host.startswith("localhost") and self.base_url:
|
|
892
|
+
self.host = f"http://{self.base_url.split(':')[-2].strip('/')}:{self.host.split(':')[-1]}"
|
|
893
|
+
|
|
777
894
|
async with aiohttp.ClientSession() as session:
|
|
778
895
|
async with session.post(
|
|
779
|
-
f"
|
|
896
|
+
f"{self.host}/vectors/delete",
|
|
780
897
|
json=params,
|
|
781
898
|
headers=self.headers,
|
|
782
899
|
) as response:
|
|
@@ -816,7 +933,15 @@ class PineconeIndex(BaseIndex):
|
|
|
816
933
|
else:
|
|
817
934
|
prefix_str = ""
|
|
818
935
|
|
|
819
|
-
|
|
936
|
+
if self.base_url and "api.pinecone.io" in self.base_url:
|
|
937
|
+
if not self.host.startswith("http"):
|
|
938
|
+
logger.error(f"host exists:{self.host}")
|
|
939
|
+
self.host = f"https://{self.host}"
|
|
940
|
+
|
|
941
|
+
elif self.host.startswith("localhost") and self.base_url:
|
|
942
|
+
self.host = f"http://{self.base_url.split(':')[-2].strip('/')}:{self.host.split(':')[-1]}"
|
|
943
|
+
|
|
944
|
+
list_url = f"{self.host}/vectors/list{prefix_str}"
|
|
820
945
|
params: dict = {}
|
|
821
946
|
if self.namespace:
|
|
822
947
|
params["namespace"] = self.namespace
|
|
@@ -874,7 +999,14 @@ class PineconeIndex(BaseIndex):
|
|
|
874
999
|
"""
|
|
875
1000
|
if self.host == "":
|
|
876
1001
|
raise ValueError("self.host is not initialized.")
|
|
877
|
-
|
|
1002
|
+
if self.base_url and "api.pinecone.io" in self.base_url:
|
|
1003
|
+
if not self.host.startswith("http"):
|
|
1004
|
+
logger.error(f"host exists:{self.host}")
|
|
1005
|
+
self.host = f"https://{self.host}"
|
|
1006
|
+
elif self.host.startswith("localhost") and self.base_url:
|
|
1007
|
+
self.host = f"http://{self.base_url.split(':')[-2].strip('/')}:{self.host.split(':')[-1]}"
|
|
1008
|
+
|
|
1009
|
+
url = f"{self.host}/vectors/fetch"
|
|
878
1010
|
|
|
879
1011
|
params = {
|
|
880
1012
|
"ids": [vector_id],
|
|
@@ -397,7 +397,11 @@ class BaseRouter(BaseModel):
|
|
|
397
397
|
self.index.dimensions = dims
|
|
398
398
|
# now init index
|
|
399
399
|
if isinstance(self.index, PineconeIndex):
|
|
400
|
+
# _init_index will not create index if already exists — it will also check
|
|
401
|
+
# for required attributes like self.index.host and self.index.dimensions and
|
|
402
|
+
# fetch them if not set
|
|
400
403
|
self.index.index = self.index._init_index(force_create=True)
|
|
404
|
+
|
|
401
405
|
# run auto sync if active
|
|
402
406
|
if self.auto_sync:
|
|
403
407
|
local_utterances = self.to_config().to_utterances()
|
|
@@ -1086,7 +1090,11 @@ class BaseRouter(BaseModel):
|
|
|
1086
1090
|
route_names = [route.name for route in routes for _ in route.utterances]
|
|
1087
1091
|
utterances = [utterance for route in routes for utterance in route.utterances]
|
|
1088
1092
|
function_schemas = [
|
|
1089
|
-
|
|
1093
|
+
(
|
|
1094
|
+
route.function_schemas[0]
|
|
1095
|
+
if route.function_schemas and len(route.function_schemas) > 0
|
|
1096
|
+
else {}
|
|
1097
|
+
)
|
|
1090
1098
|
for route in routes
|
|
1091
1099
|
for _ in route.utterances
|
|
1092
1100
|
]
|
|
@@ -5,10 +5,10 @@ from enum import Enum
|
|
|
5
5
|
from typing import Any, Dict, List, Optional, Tuple, Union
|
|
6
6
|
|
|
7
7
|
import numpy as np
|
|
8
|
-
from aurelio_sdk.schema import BM25Embedding
|
|
9
8
|
from pydantic import BaseModel, Field
|
|
10
9
|
|
|
11
10
|
from semantic_router.utils.logger import logger
|
|
11
|
+
from aurelio_sdk.schema import SparseEmbedding as BM25SparseEmbedding
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
class EncoderType(Enum):
|
|
@@ -450,7 +450,7 @@ class SparseEmbedding(BaseModel):
|
|
|
450
450
|
return cls.from_compact_array(np.array([np.arange(len(vector)), vector]).T)
|
|
451
451
|
|
|
452
452
|
@classmethod
|
|
453
|
-
def from_aurelio(cls, embedding:
|
|
453
|
+
def from_aurelio(cls, embedding: BM25SparseEmbedding):
|
|
454
454
|
arr = np.array([embedding.indices, embedding.values]).T
|
|
455
455
|
return cls.from_compact_array(arr)
|
|
456
456
|
|
|
File without changes
|
|
File without changes
|
{semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/encoders/__init__.py
RENAMED
|
File without changes
|
{semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/encoders/aurelio.py
RENAMED
|
File without changes
|
|
File without changes
|
{semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/encoders/bedrock.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/encoders/cohere.py
RENAMED
|
File without changes
|
{semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/encoders/fastembed.py
RENAMED
|
File without changes
|
{semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/encoders/google.py
RENAMED
|
File without changes
|
{semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/encoders/huggingface.py
RENAMED
|
File without changes
|
{semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/encoders/mistral.py
RENAMED
|
File without changes
|
{semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/encoders/openai.py
RENAMED
|
File without changes
|
{semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/encoders/tfidf.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/index/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/index/hybrid_local.py
RENAMED
|
File without changes
|
|
File without changes
|
{semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/index/postgres.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/llms/grammars/json.gbnf
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/llms/openrouter.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/routers/__init__.py
RENAMED
|
File without changes
|
{semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/routers/hybrid.py
RENAMED
|
File without changes
|
{semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/routers/semantic.py
RENAMED
|
File without changes
|
{semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/utils/__init__.py
RENAMED
|
File without changes
|
{semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/utils/defaults.py
RENAMED
|
File without changes
|
{semantic_router-0.1.0.dev8 → semantic_router-0.1.0.dev10}/semantic_router/utils/function_call.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|