crewplus 0.2.46__py3-none-any.whl → 0.2.50__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 crewplus might be problematic. Click here for more details.

@@ -330,22 +330,22 @@ class GeminiChatModel(BaseChatModel):
330
330
 
331
331
  def invoke(self, input, config=None, **kwargs):
332
332
  """Override invoke to add tracing callbacks automatically."""
333
- config = self._tracing_manager.add_callbacks_to_config(config)
333
+ config = self._tracing_manager.add_sync_callbacks_to_config(config)
334
334
  return super().invoke(input, config=config, **kwargs)
335
335
 
336
336
  async def ainvoke(self, input, config=None, **kwargs):
337
337
  """Override ainvoke to add tracing callbacks automatically."""
338
- config = self._tracing_manager.add_callbacks_to_config(config)
338
+ config = self._tracing_manager.add_async_callbacks_to_config(config)
339
339
  return await super().ainvoke(input, config=config, **kwargs)
340
340
 
341
341
  def stream(self, input, config=None, **kwargs):
342
342
  """Override stream to add tracing callbacks automatically."""
343
- config = self._tracing_manager.add_callbacks_to_config(config)
343
+ config = self._tracing_manager.add_sync_callbacks_to_config(config)
344
344
  return super().stream(input, config=config, **kwargs)
345
345
 
346
346
  async def astream(self, input, config=None, **kwargs):
347
347
  """Override astream to add tracing callbacks automatically."""
348
- config = self._tracing_manager.add_callbacks_to_config(config)
348
+ config = self._tracing_manager.add_async_callbacks_to_config(config)
349
349
  # We must call an async generator,
350
350
  async for chunk in super().astream(input, config=config, **kwargs):
351
351
  yield chunk
@@ -1,4 +1,4 @@
1
- from pymilvus import DataType, MilvusClient
1
+ from pymilvus import DataType, MilvusClient, AsyncMilvusClient
2
2
  import json
3
3
  import logging
4
4
  from typing import Any
@@ -11,17 +11,19 @@ class MilvusSchemaManager:
11
11
  and index parameters based on a JSON definition. It interacts with a
12
12
  MilvusClient instance to perform these operations.
13
13
  """
14
- def __init__(self, client: MilvusClient, logger=None):
14
+ def __init__(self, client: MilvusClient = None, async_client: AsyncMilvusClient = None, logger=None):
15
15
  """
16
16
  Initializes the MilvusSchemaManager.
17
17
 
18
18
  Args:
19
19
  client (MilvusClient): An instance of the Milvus client.
20
+ async_client (AsyncMilvusClient): An instance of the async Milvus client.
20
21
  logger (logging.Logger, optional): A logger instance. If not provided,
21
22
  a default logger will be created.
22
23
  Defaults to None.
23
24
  """
24
25
  self.client = client
26
+ self.async_client = async_client
25
27
  self.logger = logger or logging.getLogger(__name__)
26
28
 
27
29
  def bind_client(self, client: MilvusClient):
@@ -33,6 +35,15 @@ class MilvusSchemaManager:
33
35
  """
34
36
  self.client = client
35
37
 
38
+ def bind_async_client(self, async_client: AsyncMilvusClient):
39
+ """
40
+ Binds a new AsyncMilvusClient instance to the manager.
41
+
42
+ Args:
43
+ async_client (AsyncMilvusClient): The Milvus async client instance to use.
44
+ """
45
+ self.async_client = async_client
46
+
36
47
  def _add_array_field(self, schema, field_name, field_info):
37
48
  """
38
49
  Adds an ARRAY field to the schema based on field information.
@@ -82,23 +93,8 @@ class MilvusSchemaManager:
82
93
 
83
94
  schema.add_field(**field_args)
84
95
 
85
- def create_collection_schema(self, json_schema: str):
86
- """
87
- Creates a Milvus collection schema from a JSON string.
88
-
89
- Args:
90
- json_schema (str): A JSON string defining the schema.
91
-
92
- Returns:
93
- A Milvus schema object.
94
-
95
- Raises:
96
- ValueError: If an unknown field type is encountered in the schema.
97
- """
98
- schema_data = json.loads(json_schema)
96
+ def _build_collection_schema_from_dict(self, schema, schema_data):
99
97
  fields = schema_data['node_types']['Document']['properties']
100
-
101
- schema = self.client.create_schema(auto_id=False, enable_dynamic_fields=True)
102
98
  for field_name, field_info in fields.items():
103
99
  field_type = field_info['type']
104
100
  if field_type == "STRING" or field_type == "VARCHAR" or field_type == "TEXT":
@@ -123,28 +119,36 @@ class MilvusSchemaManager:
123
119
  schema.add_field(field_name=field_name, datatype=DataType.FLOAT_VECTOR, dim=dim)
124
120
  else:
125
121
  raise ValueError(f"Unknown field type: {field_type}")
126
-
127
122
  return schema
128
123
 
129
- def create_index_params(self, json_schema: str):
124
+ def create_collection_schema(self, json_schema: str):
130
125
  """
131
- Creates index parameters from a JSON schema string.
132
-
133
- This method defines indexes based on the 'indexes' section of the schema
134
- and automatically creates an 'AUTOINDEX' for any FLOAT_VECTOR fields.
126
+ Creates a Milvus collection schema from a JSON string.
135
127
 
136
128
  Args:
137
- json_schema (str): A JSON string defining the schema and indexes.
129
+ json_schema (str): A JSON string defining the schema.
138
130
 
139
131
  Returns:
140
- Milvus index parameters object.
132
+ A Milvus schema object.
133
+
134
+ Raises:
135
+ ValueError: If an unknown field type is encountered in the schema.
141
136
  """
142
137
  schema_data = json.loads(json_schema)
138
+ schema = self.client.create_schema(auto_id=False, enable_dynamic_fields=True)
139
+ return self._build_collection_schema_from_dict(schema, schema_data)
140
+
141
+ async def acreate_collection_schema(self, json_schema: str):
142
+ """
143
+ Asynchronously creates a Milvus collection schema from a JSON string.
144
+ """
145
+ schema_data = json.loads(json_schema)
146
+ schema = AsyncMilvusClient.create_schema(auto_id=False, enable_dynamic_fields=True)
147
+ return self._build_collection_schema_from_dict(schema, schema_data)
148
+
149
+ def _build_index_params_from_dict(self, index_params, schema_data):
143
150
  fields = schema_data['node_types']['Document']['properties']
144
-
145
- index_params = self.client.prepare_index_params()
146
151
 
147
- # Check if 'indexes' key exists
148
152
  if 'indexes' in schema_data['node_types']['Document']:
149
153
  indexes = schema_data['node_types']['Document']['indexes']
150
154
  for index_name, index_details in indexes.items():
@@ -158,7 +162,6 @@ class MilvusSchemaManager:
158
162
  params=params
159
163
  )
160
164
 
161
- # Automatic indexing for FLOAT_VECTOR fields
162
165
  for field_name, field_info in fields.items():
163
166
  if field_info['type'] == "FLOAT_VECTOR":
164
167
  index_params.add_index(
@@ -167,9 +170,33 @@ class MilvusSchemaManager:
167
170
  index_type="AUTOINDEX",
168
171
  metric_type="L2"
169
172
  )
170
-
171
173
  return index_params
172
174
 
175
+ def create_index_params(self, json_schema: str):
176
+ """
177
+ Creates index parameters from a JSON schema string.
178
+
179
+ This method defines indexes based on the 'indexes' section of the schema
180
+ and automatically creates an 'AUTOINDEX' for any FLOAT_VECTOR fields.
181
+
182
+ Args:
183
+ json_schema (str): A JSON string defining the schema and indexes.
184
+
185
+ Returns:
186
+ Milvus index parameters object.
187
+ """
188
+ schema_data = json.loads(json_schema)
189
+ index_params = self.client.prepare_index_params()
190
+ return self._build_index_params_from_dict(index_params, schema_data)
191
+
192
+ async def acreate_index_params(self, json_schema: str):
193
+ """
194
+ Asynchronously creates index parameters from a JSON schema string.
195
+ """
196
+ schema_data = json.loads(json_schema)
197
+ index_params = AsyncMilvusClient.prepare_index_params()
198
+ return self._build_index_params_from_dict(index_params, schema_data)
199
+
173
200
  def create_collection(self, collection_name: str, json_schema: str):
174
201
  """
175
202
  Creates a new collection in Milvus.
@@ -182,6 +209,8 @@ class MilvusSchemaManager:
182
209
  json_schema (str): The JSON string defining the collection's schema
183
210
  and indexes.
184
211
  """
212
+ if not self.client:
213
+ raise ValueError("Synchronous client not provided for create_collection.")
185
214
  schema = self.create_collection_schema(json_schema)
186
215
  index_params = self.create_index_params(json_schema)
187
216
 
@@ -192,6 +221,23 @@ class MilvusSchemaManager:
192
221
  enable_dynamic_fields=True # we need to enable dynamic fields for schema updates
193
222
  )
194
223
 
224
+ async def acreate_collection(self, collection_name: str, json_schema: str):
225
+ """
226
+ Asynchronously creates a new collection in Milvus.
227
+ """
228
+ if not self.async_client:
229
+ raise ValueError("Asynchronous client not provided for acreate_collection.")
230
+
231
+ schema = await self.acreate_collection_schema(json_schema)
232
+ index_params = await self.acreate_index_params(json_schema)
233
+
234
+ await self.async_client.create_collection(
235
+ collection_name=collection_name,
236
+ schema=schema,
237
+ index_params=index_params,
238
+ enable_dynamic_fields=True
239
+ )
240
+
195
241
  def validate_schema(self, json_schema: str) -> bool:
196
242
  """
197
243
  Validates the given schema by attempting to create a collection schema and index params.
@@ -91,7 +91,7 @@ class SchemaMilvus(Milvus):
91
91
  )
92
92
  self.logger = logger or logging.getLogger(__name__)
93
93
  self.collection_schema = None
94
- self.schema_manager = MilvusSchemaManager(client=self.client)
94
+ self.schema_manager = MilvusSchemaManager(client=self.client, async_client=self.aclient)
95
95
 
96
96
  def set_schema(self, schema: str):
97
97
  """
@@ -149,6 +149,29 @@ class SchemaMilvus(Milvus):
149
149
  self.logger.error(f"Failed to create collection: {e}")
150
150
  return False
151
151
 
152
+ async def acreate_collection(self) -> bool:
153
+ """
154
+ Asynchronously validates the schema and creates the collection using the MilvusSchemaManager.
155
+
156
+ Returns:
157
+ bool: True if the collection is successfully created, False otherwise.
158
+ """
159
+ if self.collection_schema is None:
160
+ self.logger.error("Collection schema is not set. Please set a schema using set_schema().")
161
+ return False
162
+
163
+ self.schema_manager.bind_async_client(self.aclient)
164
+ if not self.schema_manager.validate_schema(self.collection_schema):
165
+ self.logger.error("Failed to validate schema")
166
+ return False
167
+ try:
168
+ await self.schema_manager.acreate_collection(self.collection_name, self.collection_schema)
169
+ self.logger.info(f"Collection {self.collection_name} created successfully")
170
+ return True
171
+ except Exception as e:
172
+ self.logger.error(f"Failed to create collection asynchronously: {e}")
173
+ return False
174
+
152
175
  def drop_collection(self, collection_name: Optional[str] = None) -> bool:
153
176
  """
154
177
  Drops the collection using the Milvus client.
@@ -2,18 +2,20 @@
2
2
  # @Author: Cursor
3
3
  # @Date: 2025-02-12
4
4
  # @Last Modified by: Gemini
5
- # @Last Modified time: 2025-07-04
5
+ # @Last Modified time: 2025-10-09
6
6
 
7
7
  import logging
8
8
  from typing import List, Dict, Union, Optional
9
9
  from langchain_milvus import Milvus
10
10
  from langchain_core.embeddings import Embeddings
11
11
  from langchain_openai import AzureOpenAIEmbeddings
12
- from pymilvus import MilvusClient
12
+ from pymilvus import MilvusClient, AsyncMilvusClient
13
13
  import time
14
+ import asyncio
14
15
 
15
16
  from ...services.init_services import get_model_balancer
16
17
  from .schema_milvus import SchemaMilvus, DEFAULT_SCHEMA
18
+ from .milvus_schema_manager import MilvusSchemaManager
17
19
 
18
20
  class VDBService(object):
19
21
  """
@@ -41,9 +43,9 @@ class VDBService(object):
41
43
  >>> # Initialize with a full settings dictionary
42
44
  >>> settings = {
43
45
  ... "embedder": {
44
- ... "provider": "azure-openai",
46
+ ... "provider": "azure-openai-embeddings",
45
47
  ... "config": {
46
- ... "model": "text-embedding-3-small",
48
+ ... "model": "text-embedding-ada-002",
47
49
  ... "api_version": "2023-05-15",
48
50
  ... "api_key": "YOUR_AZURE_OPENAI_KEY",
49
51
  ... "openai_base_url": "YOUR_AZURE_OPENAI_ENDPOINT",
@@ -84,6 +86,7 @@ class VDBService(object):
84
86
  >>> assert vector_store is same_vector_store
85
87
  """
86
88
  _client: MilvusClient
89
+ _async_client: AsyncMilvusClient
87
90
  _instances: Dict[str, Milvus] = {}
88
91
 
89
92
  schema: str
@@ -111,6 +114,8 @@ class VDBService(object):
111
114
  logger (logging.Logger, optional): Logger instance. Defaults to None.
112
115
  """
113
116
  self.logger = logger or logging.getLogger(__name__)
117
+ self.collection_schema = None
118
+ self.schema_manager = MilvusSchemaManager(client=self.client, async_client=self.aclient)
114
119
 
115
120
  if settings:
116
121
  self.settings = settings
@@ -143,17 +148,17 @@ class VDBService(object):
143
148
  raise ValueError(msg)
144
149
 
145
150
  self._client = self._initialize_milvus_client(provider)
151
+ self._async_client = self._initialize_async_milvus_client(provider)
146
152
 
147
153
  self.schema = schema
148
154
  self.index_params = self.settings.get("index_params")
149
155
 
150
156
  self.logger.info("VDBService initialized successfully")
151
157
 
152
- def _initialize_milvus_client(self, provider: str) -> MilvusClient:
158
+ def _get_milvus_client_args(self, provider: str) -> dict:
153
159
  """
154
- Initializes and returns a MilvusClient with a retry mechanism.
160
+ Constructs the arguments for Milvus/AsyncMilvus client initialization based on the provider.
155
161
  """
156
- client_args = {}
157
162
  if provider == "milvus":
158
163
  host = self.connection_args.get("host", "localhost")
159
164
  port = self.connection_args.get("port", 19530)
@@ -168,15 +173,20 @@ class VDBService(object):
168
173
  "password": self.connection_args.get("password"),
169
174
  "db_name": self.connection_args.get("db_name")
170
175
  }
171
- # Filter out None values to use client defaults
172
- client_args = {k: v for k, v in client_args.items() if v is not None}
176
+ return {k: v for k, v in client_args.items() if v is not None}
173
177
 
174
178
  elif provider == "zilliz":
175
- client_args = self.connection_args
179
+ return self.connection_args
176
180
  else:
177
181
  self.logger.error(f"Unsupported vector store provider: {provider}")
178
182
  raise NotImplementedError(f"Vector store provider '{provider}' is not supported.")
179
183
 
184
+ def _initialize_milvus_client(self, provider: str) -> MilvusClient:
185
+ """
186
+ Initializes and returns a MilvusClient with a retry mechanism.
187
+ """
188
+ client_args = self._get_milvus_client_args(provider)
189
+
180
190
  try:
181
191
  # First attempt to connect
182
192
  return MilvusClient(**client_args)
@@ -189,6 +199,22 @@ class VDBService(object):
189
199
  self.logger.error(f"Failed to initialize MilvusClient on retry. Final error: {e_retry}")
190
200
  raise RuntimeError(f"Could not initialize MilvusClient after retry: {e_retry}")
191
201
 
202
+ def _initialize_async_milvus_client(self, provider: str) -> AsyncMilvusClient:
203
+ """
204
+ Initializes and returns an AsyncMilvusClient with a retry mechanism.
205
+ """
206
+ client_args = self._get_milvus_client_args(provider)
207
+ try:
208
+ return AsyncMilvusClient(**client_args)
209
+ except Exception as e:
210
+ self.logger.error(f"Failed to initialize AsyncMilvusClient, trying again. Error: {e}")
211
+ # Second attempt after failure
212
+ try:
213
+ return AsyncMilvusClient(**client_args)
214
+ except Exception as e_retry:
215
+ self.logger.error(f"Failed to initialize AsyncMilvusClient on retry. Final error: {e_retry}")
216
+ raise RuntimeError(f"Could not initialize AsyncMilvusClient after retry: {e_retry}") from e_retry
217
+
192
218
  def get_vector_client(self) -> MilvusClient:
193
219
  """
194
220
  Returns the active MilvusClient instance.
@@ -198,6 +224,15 @@ class VDBService(object):
198
224
  """
199
225
  return self._client
200
226
 
227
+ def get_async_vector_client(self) -> AsyncMilvusClient:
228
+ """
229
+ Returns the active AsyncMilvusClient instance.
230
+
231
+ Returns:
232
+ AsyncMilvusClient: The initialized async client for interacting with the vector database.
233
+ """
234
+ return self._async_client
235
+
201
236
  def get_embeddings(self, from_model_balancer: bool = False, provider: Optional[str] = "azure-openai", model_type: Optional[str] = "embedding-large") -> Embeddings:
202
237
  """
203
238
  Gets an embedding function, either from the model balancer or directly from settings.
@@ -276,6 +311,34 @@ class VDBService(object):
276
311
  self.logger.error(f"An error occurred while ensuring collection '{collection_name}' : {e}")
277
312
  raise RuntimeError(f"Failed to ensure collection '{collection_name}' .") from e
278
313
 
314
+ async def _aensure_collection_exists(self, collection_name: str, embeddings: Embeddings, check_existence: bool = True):
315
+ """
316
+ Asynchronously checks if a collection exists and creates it if it doesn't.
317
+ """
318
+ try:
319
+ client = self.get_async_vector_client()
320
+ if check_existence and not await client.has_collection(collection_name):
321
+ self.logger.info(f"Collection '{collection_name}' does not exist. Creating it.")
322
+
323
+ schema_milvus = SchemaMilvus(
324
+ embedding_function=embeddings,
325
+ collection_name=collection_name,
326
+ connection_args=self.connection_args,
327
+ index_params=self.index_params
328
+ )
329
+
330
+ schema_to_use = self.schema or DEFAULT_SCHEMA
331
+ if not self.schema:
332
+ self.logger.warning(f"No schema provided for VDBService. Using DEFAULT_SCHEMA for collection '{collection_name}'.")
333
+
334
+ schema_milvus.set_schema(schema_to_use)
335
+
336
+ if not await schema_milvus.acreate_collection():
337
+ raise RuntimeError(f"SchemaMilvus failed to create collection '{collection_name}'.")
338
+ except Exception as e:
339
+ self.logger.error(f"An error occurred while ensuring collection '{collection_name}' : {e}")
340
+ raise RuntimeError(f"Failed to ensure collection '{collection_name}' .") from e
341
+
279
342
  def _is_good_connection(self, vdb_instance: Milvus, collection_name: str) -> tuple[bool, bool | None]:
280
343
  """
281
344
  Checks if the Milvus instance has a good connection by verifying collection existence.
@@ -301,6 +364,21 @@ class VDBService(object):
301
364
  self.logger.warning(f"Connection check failed for cached instance of '{collection_name}': {e}")
302
365
  return False, None
303
366
 
367
+ async def _ais_good_connection(self, vdb_instance: Milvus, collection_name: str) -> tuple[bool, bool | None]:
368
+ """
369
+ Asynchronously checks if the Milvus instance has a good connection.
370
+ """
371
+ try:
372
+ collection_exists = await vdb_instance.aclient.has_collection(collection_name)
373
+ if collection_exists:
374
+ self.logger.debug(f"Connection for cached instance of '{collection_name}' is alive.")
375
+ else:
376
+ self.logger.warning(f"Collection '{collection_name}' not found for cached instance. It may have been dropped.")
377
+ return True, collection_exists
378
+ except Exception as e:
379
+ self.logger.warning(f"Connection check failed for cached instance of '{collection_name}': {e}")
380
+ return False, None
381
+
304
382
  def get_vector_store(self, collection_name: str, embeddings: Embeddings = None, metric_type: str = "IP") -> Milvus:
305
383
  """
306
384
  Gets a vector store instance, creating it if it doesn't exist for the collection.
@@ -373,6 +451,63 @@ class VDBService(object):
373
451
 
374
452
  return vdb
375
453
 
454
+ async def aget_vector_store(self, collection_name: str, embeddings: Embeddings = None, metric_type: str = "IP") -> Milvus:
455
+ """
456
+ Asynchronously gets a vector store instance, creating it if it doesn't exist.
457
+ """
458
+ if not collection_name:
459
+ self.logger.error("aget_vector_store called with no collection_name.")
460
+ raise ValueError("collection_name must be provided.")
461
+
462
+ check_existence = True
463
+ if collection_name in self._instances:
464
+ instance = self._instances[collection_name]
465
+ is_connected, collection_exists = await self._ais_good_connection(instance, collection_name)
466
+
467
+ if is_connected and collection_exists:
468
+ self.logger.info(f"Returning existing vector store instance for collection: {collection_name}")
469
+ return instance
470
+
471
+ self.logger.warning(f"Cached instance for '{collection_name}' is invalid. Removing it from cache.")
472
+ del self._instances[collection_name]
473
+
474
+ if is_connected and not collection_exists:
475
+ check_existence = False
476
+
477
+ self.logger.info(f"Creating new vector store instance for collection: {collection_name}")
478
+ if embeddings is None:
479
+ embeddings = self.get_embeddings()
480
+
481
+ await self._aensure_collection_exists(collection_name, embeddings, check_existence=check_existence)
482
+
483
+ try:
484
+ self.logger.debug(f"Testing embedding function for collection '{collection_name}'...")
485
+ await embeddings.aembed_query("validation_test_string")
486
+ self.logger.debug("Embedding function is valid.")
487
+ except Exception as e:
488
+ self.logger.error(
489
+ f"The provided embedding function is invalid and failed with error: {e}. "
490
+ f"Cannot create a vector store for collection '{collection_name}'."
491
+ )
492
+ raise RuntimeError(f"Invalid embedding function provided.") from e
493
+
494
+ index_params = self.index_params or {
495
+ "metric_type": metric_type,
496
+ "index_type": "AUTOINDEX",
497
+ "params": {}
498
+ }
499
+
500
+ vdb = await asyncio.to_thread(
501
+ self._create_milvus_instance_with_retry,
502
+ collection_name=collection_name,
503
+ embeddings=embeddings,
504
+ index_params=index_params
505
+ )
506
+
507
+ self._instances[collection_name] = vdb
508
+
509
+ return vdb
510
+
376
511
  def _create_milvus_instance_with_retry(self, collection_name: str, embeddings: Embeddings, index_params: dict) -> Milvus:
377
512
  """
378
513
  Creates a Milvus instance with a retry mechanism for connection failures.
@@ -429,6 +564,36 @@ class VDBService(object):
429
564
  del self._instances[collection_name]
430
565
  self.logger.info(f"Removed '{collection_name}' from instance cache.")
431
566
 
567
+ async def adrop_collection(self, collection_name: str) -> None:
568
+ """
569
+ Asynchronously deletes a collection from the vector database and removes it from the cache.
570
+
571
+ Args:
572
+ collection_name (str): The name of the collection to drop.
573
+
574
+ Raises:
575
+ ValueError: If collection_name is not provided.
576
+ RuntimeError: If the operation fails on the database side.
577
+ """
578
+ if not collection_name:
579
+ self.logger.error("adrop_collection called without a collection_name.")
580
+ raise ValueError("collection_name must be provided.")
581
+
582
+ self.logger.info(f"Attempting to drop collection asynchronously: {collection_name}")
583
+
584
+ try:
585
+ client = self.get_async_vector_client()
586
+ await client.drop_collection(collection_name=collection_name)
587
+ self.logger.info(f"Successfully dropped collection asynchronously: {collection_name}")
588
+ except Exception as e:
589
+ self.logger.error(f"Failed to drop collection '{collection_name}' asynchronously: {e}")
590
+ raise RuntimeError(f"An error occurred while dropping collection '{collection_name}' asynchronously.") from e
591
+ finally:
592
+ # Whether successful or not, remove the stale instance from the cache.
593
+ if collection_name in self._instances:
594
+ del self._instances[collection_name]
595
+ self.logger.info(f"Removed '{collection_name}' from instance cache.")
596
+
432
597
  def delete_data_by_filter(self, collection_name: str = None, filter: str = None) -> None:
433
598
  """ Delete data by filter
434
599
 
@@ -446,6 +611,23 @@ class VDBService(object):
446
611
  except Exception as e:
447
612
  raise RuntimeError(f"delete collection data failed: {str(e)}")
448
613
 
614
+ async def adelete_data_by_filter(self, collection_name: str = None, filter: str = None) -> None:
615
+ """ Asynchronously delete data by filter
616
+
617
+ Args:
618
+ collection_name (str): collection_name
619
+ filter (str): filter
620
+ """
621
+ self.logger.info(f"Delete data by filter asynchronously:{filter}")
622
+
623
+ try:
624
+ client=self.get_async_vector_client()
625
+ if collection_name is None or client is None or filter is None:
626
+ return RuntimeError(f"collection_name must be not null or check out your client to link milvus")
627
+ await client.delete(collection_name=collection_name, filter=filter)
628
+ except Exception as e:
629
+ raise RuntimeError(f"delete collection data failed: {str(e)}")
630
+
449
631
  @staticmethod
450
632
  def delete_old_indexes(url: str = None, vdb: Milvus = None) -> (bool | None):
451
633
  """ Delete old indexes of the same source_url
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: crewplus
3
- Version: 0.2.46
3
+ Version: 0.2.50
4
4
  Summary: Base services for CrewPlus AI applications
5
5
  Author-Email: Tim Liu <tim@opsmateai.com>
6
6
  License: MIT
@@ -116,6 +116,11 @@ crewplus-base/ # GitHub repo name
116
116
 
117
117
  ```
118
118
 
119
+ ## Version Update
120
+
121
+ 0.2.50
122
+ Add async aget_vector_store to enable async vector search
123
+
119
124
  ## Deploy to PyPI
120
125
 
121
126
  Clean Previous Build Artifacts:
@@ -123,17 +128,17 @@ Remove the dist/, build/, and *.egg-info/ directories to ensure that no old file
123
128
 
124
129
  rm -rf dist build *.egg-info
125
130
 
126
- # install deployment tool
131
+ ### install deployment tool
127
132
  pip install twine
128
133
 
129
- # build package
134
+ ### build package
130
135
  python -m build
131
136
 
132
- # deploy to TestPyPI (Test first)
137
+ ### deploy to TestPyPI (Test first)
133
138
  python -m twine upload --repository testpypi dist/*
134
139
 
135
- # install from TestPyPI
140
+ ### install from TestPyPI
136
141
  pip install -i https://test.pypi.org/simple/ crewplus
137
142
 
138
- # Deploy to official PyPI
143
+ ### Deploy to official PyPI
139
144
  python -m twine upload dist/*
@@ -1,13 +1,13 @@
1
- crewplus-0.2.46.dist-info/METADATA,sha256=QSaSV8WkRmj_qHybxSCTNlyESu9UNuiYNxeLgolNBAA,5362
2
- crewplus-0.2.46.dist-info/WHEEL,sha256=9P2ygRxDrTJz3gsagc0Z96ukrxjr-LFBGOgv3AuKlCA,90
3
- crewplus-0.2.46.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
4
- crewplus-0.2.46.dist-info/licenses/LICENSE,sha256=2_NHSHRTKB_cTcT_GXgcenOCtIZku8j343mOgAguTfc,1087
1
+ crewplus-0.2.50.dist-info/METADATA,sha256=3OENJXKgtX-YS5olItAqzqdGYcZxEEzxMl7r3u2xuKU,5459
2
+ crewplus-0.2.50.dist-info/WHEEL,sha256=9P2ygRxDrTJz3gsagc0Z96ukrxjr-LFBGOgv3AuKlCA,90
3
+ crewplus-0.2.50.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
4
+ crewplus-0.2.50.dist-info/licenses/LICENSE,sha256=2_NHSHRTKB_cTcT_GXgcenOCtIZku8j343mOgAguTfc,1087
5
5
  crewplus/__init__.py,sha256=m46HkZL1Y4toD619NL47Sn2Qe084WFFSFD7e6VoYKZc,284
6
6
  crewplus/callbacks/__init__.py,sha256=YG7ieeb91qEjp1zF0-inEN7mjZ7yT_D2yzdWFT8Z1Ws,63
7
7
  crewplus/callbacks/async_langfuse_handler.py,sha256=A4uFeLpvOUdc58M7sZoE65_C1V98u0QCvx5jUquM0pM,7006
8
8
  crewplus/services/__init__.py,sha256=V1CG8b2NOmRzNgQH7BPl4KVxWSYJH5vfEsW1wVErKNE,375
9
9
  crewplus/services/azure_chat_model.py,sha256=iWzJ2GQFSNmwJx-2O5_xKPSB6VVc-7T6bcfFI8_WezA,5521
10
- crewplus/services/gemini_chat_model.py,sha256=VsOB_st1qRmDkwLXzo-gCShhUsZHpk0V-G-ulQXGN3g,40081
10
+ crewplus/services/gemini_chat_model.py,sha256=DYqz01H2TIHiCDQesSozVfOsMigno6QGwOtIweg7UHk,40103
11
11
  crewplus/services/init_services.py,sha256=7oZ1GmesK32EDB_DYnTzW17MEpXjXK41_U_1pmqu_m4,2183
12
12
  crewplus/services/model_load_balancer.py,sha256=Q9Gx3GrbKworU-Ytxeqp0ggHSgZ1Q6brtTk-nCl4sak,12095
13
13
  crewplus/services/tracing_manager.py,sha256=0KR-F0BKYEMdADANWofFZH9D9jcWDHzDICUE7nDhzJc,6579
@@ -15,11 +15,11 @@ crewplus/utils/__init__.py,sha256=2Gk1n5srFJQnFfBuYTxktdtKOVZyNrFcNaZKhXk35Pw,14
15
15
  crewplus/utils/schema_action.py,sha256=GDaBoVFQD1rXqrLVSMTfXYW1xcUu7eDcHsn57XBSnIg,422
16
16
  crewplus/utils/schema_document_updater.py,sha256=frvffxn2vbi71fHFPoGb9hq7gH2azmmdq17p-Fumnvg,7322
17
17
  crewplus/vectorstores/milvus/__init__.py,sha256=OeYv2rdyG7tcREIjBJPyt2TbE54NvyeRoWMe7LwopRE,245
18
- crewplus/vectorstores/milvus/milvus_schema_manager.py,sha256=2IZT61LVui21Pt5Z3y8YYS2dYcwzkgUKxMq2NA0-lQE,9222
19
- crewplus/vectorstores/milvus/schema_milvus.py,sha256=DtHP8jHRSpLqt9ixAnJE5R4CId9NLYXxOVqRxPCEyv4,26131
20
- crewplus/vectorstores/milvus/vdb_service.py,sha256=CaUMLIMeOCm2R4t5EKtAupIddFXQu0NSb8RpTkInGd4,22498
18
+ crewplus/vectorstores/milvus/milvus_schema_manager.py,sha256=-QRav-hzu-XWeJ_yKUMolal_EyMUspSg-nvh5sqlrlQ,11442
19
+ crewplus/vectorstores/milvus/schema_milvus.py,sha256=wwNpfqsKS0xeozZES40IvB0iNwUtpCall_7Hkg0dL1g,27223
20
+ crewplus/vectorstores/milvus/vdb_service.py,sha256=IQAemHKczKcD9UyjPnBVaJhL9YSOyapreWkpqbfc3Xg,31330
21
21
  docs/GeminiChatModel.md,sha256=zZYyl6RmjZTUsKxxMiC9O4yV70MC4TD-IGUmWhIDBKA,8677
22
22
  docs/ModelLoadBalancer.md,sha256=aGHES1dcXPz4c7Y8kB5-vsCNJjriH2SWmjBkSGoYKiI,4398
23
23
  docs/VDBService.md,sha256=Dw286Rrf_fsi13jyD3Bo4Sy7nZ_G7tYm7d8MZ2j9hxk,9375
24
24
  docs/index.md,sha256=3tlc15uR8lzFNM5WjdoZLw0Y9o1P1gwgbEnOdIBspqc,1643
25
- crewplus-0.2.46.dist-info/RECORD,,
25
+ crewplus-0.2.50.dist-info/RECORD,,