agentic-kit-common 0.0.4__py3-none-any.whl → 0.0.5__py3-none-any.whl

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.

Potentially problematic release.


This version of agentic-kit-common might be problematic. Click here for more details.

File without changes
@@ -0,0 +1 @@
1
+ from .embedding import EmbeddingFactory
@@ -0,0 +1,40 @@
1
+ import abc
2
+
3
+ from langchain_community.embeddings import XinferenceEmbeddings
4
+
5
+
6
+ class EmbeddingFactoryBase:
7
+ provider: str
8
+
9
+ @classmethod
10
+ @abc.abstractmethod
11
+ def create_embedding(cls, base_url: str, model_uid: str, api_key: str = '', dims: int = 1024):
12
+ raise NotImplemented
13
+
14
+
15
+ class XinferenceEmbeddingFactory(EmbeddingFactoryBase):
16
+ provider: str = 'xinference'
17
+
18
+ @classmethod
19
+ def create_embedding(cls, base_url: str, model_uid: str, api_key: str = '', dims: int = 1024):
20
+ # assert embedding_server_url is not None and embedding_server_url != ''
21
+ # assert embedding_model_uid is not None and embedding_model_uid != ''
22
+ embedding = XinferenceEmbeddings(
23
+ server_url=base_url,
24
+ model_uid=model_uid, # replace model_uid with the model UID return from launching the model
25
+ )
26
+ return embedding
27
+
28
+
29
+ _FACTORY_LIST = [
30
+ XinferenceEmbeddingFactory
31
+ ]
32
+
33
+
34
+ class EmbeddingFactory:
35
+ @classmethod
36
+ def create_embedding(cls, base_url: str, model_uid: str, api_key: str = '', dims: int = 1024, provider: str = 'xinference'):
37
+ for factory in _FACTORY_LIST:
38
+ if factory.provider == provider:
39
+ return factory.create_embedding(base_url=base_url, model_uid=model_uid, api_key=api_key, dims=dims)
40
+ raise Exception(f'不支持的embedding provider配置: [{provider}]')
@@ -0,0 +1 @@
1
+ from .milvus_manager import MilvusManager
@@ -0,0 +1,226 @@
1
+ import logging
2
+ from typing import List, Dict
3
+
4
+ from langchain_core.embeddings import Embeddings
5
+ from pydantic import BaseModel
6
+ from pymilvus import connections, Collection, CollectionSchema, FieldSchema
7
+ from pymilvus.orm import utility
8
+
9
+ from ..schema import default_search_params, default_index_params_auto, default_index_params_vector, default_fields, \
10
+ default_output_fields, default_search_field, default_query_fields
11
+
12
+ logger = logging.getLogger(__name__)
13
+ logger.setLevel(level=logging.DEBUG)
14
+
15
+
16
+ class MilvusManager:
17
+ database_name: str
18
+
19
+ collection_name: str
20
+
21
+ # search_field: str
22
+ #
23
+ # query_fields: List[str]
24
+ #
25
+ # output_fields: List[str]
26
+ #
27
+ # fields: List[FieldSchema]
28
+ #
29
+ model_cls: BaseModel
30
+
31
+ @classmethod
32
+ def create(
33
+ cls,
34
+ embed_model: Embeddings,
35
+ vector_store_uri: str,
36
+ # database_name: str,
37
+ # collection_name: str,
38
+ # model_cls: BaseModel,
39
+ search_field: str = None,
40
+ query_fields: List[str] = None,
41
+ output_fields: List[str] = None,
42
+ fields: List[FieldSchema] = None,
43
+ index_params_vector: Dict = None,
44
+ index_params_auto: Dict = None,
45
+ search_params: Dict = None,
46
+ ):
47
+ if fields is None:
48
+ fields = default_fields
49
+ if output_fields is None:
50
+ output_fields = default_output_fields
51
+ if search_field is None:
52
+ search_field = default_search_field
53
+ if query_fields is None:
54
+ query_fields = default_query_fields
55
+ if index_params_vector is None:
56
+ index_params_vector = default_index_params_vector
57
+ if index_params_auto is None:
58
+ index_params_auto = default_index_params_auto
59
+ if search_params is None:
60
+ search_params = default_search_params
61
+
62
+ return cls(
63
+ embed_model=embed_model,
64
+ vector_store_uri=vector_store_uri,
65
+ # database_name=database_name,
66
+ # collection_name=collection_name,
67
+ search_field=search_field,
68
+ query_fields=query_fields,
69
+ output_fields=output_fields,
70
+ fields=fields,
71
+ # model_cls=model_cls,
72
+ index_params_vector=index_params_vector,
73
+ index_params_auto=index_params_auto,
74
+ search_params=search_params,
75
+ )
76
+
77
+ def __init__(
78
+ self,
79
+ embed_model: Embeddings,
80
+ vector_store_uri: str,
81
+ # database_name: str,
82
+ # collection_name: str,
83
+ search_field: str,
84
+ query_fields: List[str],
85
+ output_fields: List[str],
86
+ fields: List[FieldSchema],
87
+ # model_cls: BaseModel,
88
+ index_params_vector: Dict,
89
+ index_params_auto: Dict,
90
+ search_params: Dict,
91
+ ):
92
+ # self.database_name = database_name
93
+ # self.collection_name = collection_name
94
+ self.embed_model = embed_model
95
+ self.vector_store_uri = vector_store_uri
96
+ self.search_field = search_field
97
+ self.query_fields = query_fields
98
+ self.output_fields = output_fields
99
+ self.fields = fields
100
+ # self.model_cls = model_cls
101
+ self.index_params_vector = index_params_vector
102
+ self.index_params_auto = index_params_auto
103
+ self.search_params = search_params
104
+ self.collection = None
105
+
106
+ self.do_init()
107
+
108
+ def do_init(self):
109
+ res = connections.connect(
110
+ alias="default",
111
+ db_name=self.database_name,
112
+ uri=self.vector_store_uri
113
+ )
114
+ assert res is None # no error
115
+
116
+ if utility.has_collection(self.collection_name):
117
+ self.collection = Collection(self.collection_name)
118
+ else:
119
+ tool_schema = CollectionSchema(self.fields, self.database_name)
120
+ self.collection = Collection(self.collection_name, tool_schema)
121
+ self.collection.create_index(self.search_field, self.index_params_vector)
122
+ for field in self.query_fields:
123
+ self.collection.create_index(field, self.index_params_auto)
124
+ self.collection.load()
125
+
126
+ def delete_by_uid(self, uid: str):
127
+ expr = f"uid=='{uid}'"
128
+ return self.delete(expr=expr)
129
+
130
+ def delete(self, expr: str):
131
+ delete_result = self.collection.delete(expr=expr)
132
+ self.collection.flush()
133
+ return delete_result
134
+
135
+ def search(self, query: str, expr: str = None, top_k: int = 5, score_threshold: float = 0, search_params: dict = None):
136
+ """vector搜索"""
137
+ if search_params is None:
138
+ search_params = self.search_params
139
+ qv = self.embed_model.embed_query(query)
140
+ results = self.collection.search(
141
+ data=[qv], # 查询向量
142
+ anns_field=self.search_field, # 指定向量字段名称
143
+ param=search_params, # 搜索参数
144
+ limit=top_k, # 返回最相似的top-k个结果
145
+ expr=expr,
146
+ output_fields=self.output_fields # 返回的字段
147
+ )
148
+ logger.debug(f'search results: {results}')
149
+ return self._parse_result_to_schema(results=results, score_threshold=score_threshold)
150
+
151
+ def query(self, expr: str = '', is_page: bool = False, page_size: int = 20, page: int = 1):
152
+ """表达式查询,支持分页"""
153
+
154
+ # note: 如果没有表达式,必须分页,否则数据太多
155
+ if expr is None or expr == '':
156
+ is_page = True
157
+
158
+ if is_page:
159
+ _total = self.collection.query(
160
+ expr=expr,
161
+ output_fields=["count(*)"]
162
+ )
163
+ total = _total[0]['count(*)']
164
+
165
+ results = self.collection.query(
166
+ expr=expr,
167
+ limit=page_size,
168
+ offset=(page - 1) * page_size,
169
+ output_fields=self.output_fields # 返回的字段
170
+ )
171
+ _result = []
172
+ for result in results:
173
+ _result.append(self.model_cls(**result))
174
+ logger.debug(f'query paged results: {results}')
175
+
176
+ data = {
177
+ 'total': total,
178
+ 'page': page,
179
+ 'page_size': page_size if page_size < total else total,
180
+ 'data': _result
181
+ }
182
+ return data
183
+ else:
184
+ results = self.collection.query(
185
+ expr=expr,
186
+ output_fields=self.output_fields # 返回的字段
187
+ )
188
+ _result = []
189
+ for result in results:
190
+ _result.append(self.model_cls(**result))
191
+ logger.debug(f'query not paged results: {results}')
192
+ return _result
193
+
194
+ def clear(self):
195
+ if self.collection:
196
+ self.collection.flush()
197
+ self.collection.release()
198
+ self.collection.drop()
199
+ self.do_init()
200
+
201
+ def insert(self, items: list[dict]):
202
+ uids = []
203
+ vectors = []
204
+ for item in items:
205
+ if 'uid' not in item or 'content' not in item:
206
+ raise Exception(f'insert items must include [uid, content], illegal for {item}')
207
+ uids.append(item['uid'])
208
+ vectors.append(self.embed_model.embed_query(item['content']))
209
+
210
+ insert_fields = [uids, vectors]
211
+ insert_result = self.collection.insert(insert_fields)
212
+ self.collection.flush()
213
+ return insert_result
214
+
215
+ def _parse_result_to_schema(self, results, score_threshold: float = 0):
216
+ """过滤结果"""
217
+ _results = []
218
+ for hits in results:
219
+ for hit in hits:
220
+ if score_threshold != 0:
221
+ if hit.score >= score_threshold:
222
+ _results.append(self.model_cls(score=hit.score, **hit.fields))
223
+ else:
224
+ _results.append(self.model_cls(score=hit.score, **hit.fields))
225
+
226
+ return _results
@@ -0,0 +1,3 @@
1
+ from .base import VectorBaseModel
2
+ from .milvus_schema import default_fields, default_output_fields, default_query_fields, default_search_field, \
3
+ default_index_params_auto, default_index_params_vector, default_search_params
@@ -0,0 +1,7 @@
1
+ from pydantic import BaseModel
2
+
3
+
4
+ class VectorBaseModel(BaseModel):
5
+ uid: str
6
+
7
+ score: float = 0
@@ -0,0 +1,25 @@
1
+ from pymilvus import FieldSchema, DataType
2
+
3
+ default_fields = [
4
+ FieldSchema(name="pk", dtype=DataType.INT64, is_primary=True, auto_id=True),
5
+ FieldSchema(name="uid", dtype=DataType.VARCHAR, max_length=36),
6
+ FieldSchema(name="vectors", dtype=DataType.FLOAT_VECTOR, dim=1024),
7
+ ]
8
+ default_output_fields = ['pk', 'uid']
9
+ default_search_field = "vectors"
10
+ default_query_fields = ['uid']
11
+
12
+ default_index_params_vector = {
13
+ 'metric_type': 'COSINE', # IP 或 COSINE
14
+ 'index_type': 'FLAT', # FLAT
15
+ "params": {"nlist": 128},
16
+ }
17
+
18
+ default_index_params_auto = {
19
+ 'index_type': 'AUTOINDEX'
20
+ }
21
+
22
+ default_search_params = {
23
+ 'metric_type': 'COSINE',
24
+ "params": {"nprobe": 10},
25
+ }
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentic-kit-common
3
- Version: 0.0.4
4
- Summary: Common utilities and tools for agentic kit ecosystem, including MinIO manager and other shared components
3
+ Version: 0.0.5
4
+ Summary: Common utilities and tools for agentic kit ecosystem
5
5
  Home-page:
6
6
  Author: manson
7
7
  Author-email: manson.li3307@gmail.com
@@ -26,6 +26,8 @@ Requires-Dist: langchain_community
26
26
  Requires-Dist: langchain_experimental
27
27
  Requires-Dist: mysql-connector-python
28
28
  Requires-Dist: sqlalchemy
29
+ Requires-Dist: pymilvus
30
+ Requires-Dist: xinference_client
29
31
  Dynamic: author
30
32
  Dynamic: author-email
31
33
  Dynamic: classifier
@@ -0,0 +1,28 @@
1
+ agentic_kit_common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ agentic_kit_common/minio/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ agentic_kit_common/minio/minio_manager.py,sha256=PzoUWn0YqXTHx1UClbkwLkIUmv5O4aSDc7eVf08qOzs,21494
4
+ agentic_kit_common/orm/__init__.py,sha256=wqY81g3P7FftFvLK5SaxFJzNNxrQwtmcb4RCXOSAZa8,71
5
+ agentic_kit_common/orm/base.py,sha256=QIura_i2nIY2XeA3-KkO2loLNbEAoJK2qx0hu_8nhYU,2277
6
+ agentic_kit_common/orm/manager.py,sha256=HU8dHNb76uTo2KMOXdNG3nn3uea7vPYIFPO61SQoNIU,4648
7
+ agentic_kit_common/orm/session.py,sha256=LX4ZUKJNXdcQ0KqRt5L0pJX-QG-tDyKXEDijcPUkGD0,2716
8
+ agentic_kit_common/vector/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
+ agentic_kit_common/vector/embedding/__init__.py,sha256=mp--cfCDzTn5hNxzcIAU4m0g4F0d0rrZErFVWsGDvx4,40
10
+ agentic_kit_common/vector/embedding/embedding.py,sha256=k1hHNkBcucu6lSe2hYSrCal-ML26Eo6Bfe8cVkXSww8,1380
11
+ agentic_kit_common/vector/manager/__init__.py,sha256=w2uAmKGRx9Nv3QySXIAgxQGlYR549AQvbBuBFsQttKI,42
12
+ agentic_kit_common/vector/manager/milvus_manager.py,sha256=HaoKKsyMOfmA3jX45XEVhmK6SprjTmwULOyhCqqAIGg,7840
13
+ agentic_kit_common/vector/schema/__init__.py,sha256=F8WCi4ybnujFW-qHcDI9KOqzw7i8r07dmBUO2R2_Iu0,228
14
+ agentic_kit_common/vector/schema/base.py,sha256=oo5OSFCX9UeQuWskiebqctF1dyXISD7_czzoKYoHnKg,102
15
+ agentic_kit_common/vector/schema/milvus_schema.py,sha256=V8igxe6_FmZ46jicNdKxBbf0vl3bwTC4AyRf9gqB_VA,684
16
+ agentic_kit_common/web/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
+ agentic_kit_common/web/http/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
+ agentic_kit_common/web/http/response.py,sha256=uxd_MRHsFfQ0pUeHITDQD8tuOY6fo6IJ0MO6uL62AlM,1347
19
+ test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
+ test/config.py,sha256=VMcvfWnuWZKr_p0rC57i90jTq-XVsRuVzfEIe1C7Drg,3804
21
+ test/settings.py,sha256=vU1dqUvGzshi6MG7JbGfW4jKfUsfAObgUfky-LMjUNs,344
22
+ test/test_embedding.py,sha256=78M6t9tt6-oCfdQZfOartCIkUFZMvogcu5UKJh1lJb8,609
23
+ test/test_minio.py,sha256=TOkX8A2pPkjrwAIH88xBZmFpDc1ZgTk1QS6mtubOZ-Y,2308
24
+ test/test_vector.py,sha256=4sJ7bXt5iRhc6j1Ig0bZ1j0huPU-clnsnT7O0-uFbkw,1311
25
+ agentic_kit_common-0.0.5.dist-info/METADATA,sha256=YBhN8h9vA8H2kYHP0SyGh0Vgj-f1PiCjQLmVhoYCRG4,7496
26
+ agentic_kit_common-0.0.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
27
+ agentic_kit_common-0.0.5.dist-info/top_level.txt,sha256=nEKDlp84vqKSVWssGcxyuIsTqWLhMo45xqMs2GK4Dgg,24
28
+ agentic_kit_common-0.0.5.dist-info/RECORD,,
test/settings.py ADDED
@@ -0,0 +1,18 @@
1
+ from dotenv import load_dotenv
2
+ from pydantic_settings import BaseSettings
3
+
4
+ load_dotenv()
5
+
6
+ class GlobalSettings(BaseSettings):
7
+ # embedding
8
+ embedding_base_url: str
9
+ embedding_model_uid: str
10
+ embedding_dims: int
11
+ embedding_api_key: str
12
+
13
+ # milvus
14
+ milvus_url: str
15
+
16
+
17
+ global_settings = GlobalSettings()
18
+ print(global_settings)
test/test_embedding.py ADDED
@@ -0,0 +1,21 @@
1
+ import sys
2
+ import unittest
3
+ from pathlib import Path
4
+
5
+ project_root = Path(__file__).parent.parent
6
+ sys.path.insert(0, str(project_root))
7
+
8
+ from agentic_kit_common.vector.embedding import EmbeddingFactory
9
+ from .settings import global_settings
10
+
11
+
12
+ class MyTestCase(unittest.TestCase):
13
+ def test_embedding(self):
14
+ embedding = EmbeddingFactory.create_embedding(base_url=global_settings.embedding_base_url, model_uid=global_settings.embedding_model_uid)
15
+ text = '你好'
16
+ text_vector = embedding.embed_query(text=text)
17
+ print(text_vector)
18
+
19
+
20
+ if __name__ == '__main__':
21
+ unittest.main()
test/test_vector.py ADDED
@@ -0,0 +1,52 @@
1
+ import logging
2
+ import sys
3
+ import unittest
4
+ import uuid
5
+ from pathlib import Path
6
+
7
+ from pydantic import BaseModel
8
+
9
+ project_root = Path(__file__).parent.parent
10
+ sys.path.insert(0, str(project_root))
11
+
12
+ from agentic_kit_common.vector.embedding import EmbeddingFactory
13
+ from agentic_kit_common.vector.manager import MilvusManager
14
+ from agentic_kit_common.vector.schema import VectorBaseModel
15
+ from .settings import global_settings
16
+
17
+
18
+ logging.basicConfig(level=logging.DEBUG)
19
+
20
+ embedding = EmbeddingFactory.create_embedding(base_url=global_settings.embedding_base_url, model_uid=global_settings.embedding_model_uid)
21
+
22
+
23
+ class McpServerManager(MilvusManager):
24
+ database_name: str = 'skill_center'
25
+
26
+ collection_name: str = 'mcp_server'
27
+
28
+ model_cls: BaseModel = VectorBaseModel
29
+
30
+
31
+ class MyTestCase(unittest.TestCase):
32
+ def test_vector(self):
33
+ manager = McpServerManager.create(embed_model=embedding, vector_store_uri=global_settings.milvus_url)
34
+
35
+ manager.query()
36
+
37
+ # manager.search('你好')
38
+
39
+ # uid = str(uuid.uuid4())
40
+ # print(uid)
41
+ # manager.insert([{
42
+ # 'uid': uid,
43
+ # 'content': 'hello',
44
+ # }])
45
+
46
+ manager.delete_by_uid(uid='2050d9a9-b125-42b9-80ce-bd9eee89d9eb')
47
+
48
+ manager.query()
49
+
50
+
51
+ if __name__ == '__main__':
52
+ unittest.main()
@@ -1,17 +0,0 @@
1
- agentic_kit_common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- agentic_kit_common/minio/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- agentic_kit_common/minio/minio_manager.py,sha256=PzoUWn0YqXTHx1UClbkwLkIUmv5O4aSDc7eVf08qOzs,21494
4
- agentic_kit_common/orm/__init__.py,sha256=wqY81g3P7FftFvLK5SaxFJzNNxrQwtmcb4RCXOSAZa8,71
5
- agentic_kit_common/orm/base.py,sha256=QIura_i2nIY2XeA3-KkO2loLNbEAoJK2qx0hu_8nhYU,2277
6
- agentic_kit_common/orm/manager.py,sha256=HU8dHNb76uTo2KMOXdNG3nn3uea7vPYIFPO61SQoNIU,4648
7
- agentic_kit_common/orm/session.py,sha256=LX4ZUKJNXdcQ0KqRt5L0pJX-QG-tDyKXEDijcPUkGD0,2716
8
- agentic_kit_common/web/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
- agentic_kit_common/web/http/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
- agentic_kit_common/web/http/response.py,sha256=uxd_MRHsFfQ0pUeHITDQD8tuOY6fo6IJ0MO6uL62AlM,1347
11
- test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
- test/config.py,sha256=VMcvfWnuWZKr_p0rC57i90jTq-XVsRuVzfEIe1C7Drg,3804
13
- test/test_minio.py,sha256=TOkX8A2pPkjrwAIH88xBZmFpDc1ZgTk1QS6mtubOZ-Y,2308
14
- agentic_kit_common-0.0.4.dist-info/METADATA,sha256=MXCYS7a4zdlactafV82PK_TcW933GqrDOTaspAK_g4Q,7492
15
- agentic_kit_common-0.0.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
16
- agentic_kit_common-0.0.4.dist-info/top_level.txt,sha256=nEKDlp84vqKSVWssGcxyuIsTqWLhMo45xqMs2GK4Dgg,24
17
- agentic_kit_common-0.0.4.dist-info/RECORD,,