99 create_model_record ,
1010 delete_model_record ,
1111 get_model_by_display_name ,
12+ get_models_by_display_name ,
1213 get_model_records ,
1314 get_models_by_tenant_factory_type ,
1415 update_model_record ,
@@ -198,20 +199,63 @@ async def list_provider_models_for_tenant(tenant_id: str, provider: str, model_t
198199 raise Exception (f"Failed to list provider models: { str (e )} " )
199200
200201
201- async def update_single_model_for_tenant (user_id : str , tenant_id : str , model_data : Dict [str , Any ]):
202- """Update a single model by its model_id, ensuring display_name uniqueness."""
202+ async def update_single_model_for_tenant (
203+ user_id : str ,
204+ tenant_id : str ,
205+ current_display_name : str ,
206+ model_data : Dict [str , Any ]
207+ ):
208+ """Update model(s) by current display_name. If embedding/multi_embedding, update both types.
209+
210+ Args:
211+ user_id: The user performing the update.
212+ tenant_id: The tenant context.
213+ current_display_name: The current display_name used to look up the model(s).
214+ model_data: The fields to update, which may include a new display_name.
215+
216+ Raises:
217+ LookupError: If no model is found with the current_display_name.
218+ ValueError: If a new display_name conflicts with an existing model.
219+ """
203220 try :
204- existing_model_by_display = get_model_by_display_name (model_data ["display_name" ], tenant_id )
205- current_model_id = int (model_data ["model_id" ])
206- existing_model_id = existing_model_by_display ["model_id" ] if existing_model_by_display else None
207-
208- if existing_model_by_display and existing_model_id != current_model_id :
209- raise ValueError (
210- f"Name { model_data ['display_name' ]} is already in use, please choose another display name" )
221+ # Get all models with the current display_name (may be 1 or 2 for embedding types)
222+ existing_models = get_models_by_display_name (current_display_name , tenant_id )
211223
212- update_model_record (current_model_id , model_data , user_id )
213- logging .debug (
214- f"Model { model_data ['display_name' ]} updated successfully" )
224+ if not existing_models :
225+ raise LookupError (f"Model not found: { current_display_name } " )
226+
227+ # Check if a new display_name is being set and if it conflicts
228+ new_display_name = model_data .get ("display_name" )
229+ if new_display_name and new_display_name != current_display_name :
230+ conflict_models = get_models_by_display_name (new_display_name , tenant_id )
231+ if conflict_models :
232+ raise ValueError (
233+ f"Name { new_display_name } is already in use, please choose another display name"
234+ )
235+
236+ # Check if any of the existing models is multi_embedding
237+ has_multi_embedding = any (
238+ m .get ("model_type" ) == "multi_embedding" for m in existing_models
239+ )
240+
241+ if has_multi_embedding :
242+ # Update both embedding and multi_embedding records
243+ for model in existing_models :
244+ # Prepare update data, excluding model_type to preserve original type
245+ update_data = {k : v for k , v in model_data .items () if k not in ["model_id" , "model_type" ]}
246+ update_model_record (model ["model_id" ], update_data , user_id )
247+ logging .debug (
248+ f"Model { current_display_name } (embedding + multi_embedding) updated successfully" )
249+ else :
250+ # Single model update
251+ current_model_id = existing_models [0 ]["model_id" ]
252+ update_data = {k : v for k , v in model_data .items () if k != "model_id" }
253+ update_model_record (current_model_id , update_data , user_id )
254+ logging .debug (f"Model { current_display_name } updated successfully" )
255+ except LookupError :
256+ raise
257+ except ValueError :
258+ raise
215259 except Exception as e :
216260 logging .error (f"Failed to update model: { str (e )} " )
217261 raise Exception (f"Failed to update model: { str (e )} " )
@@ -221,7 +265,7 @@ async def batch_update_models_for_tenant(user_id: str, tenant_id: str, model_lis
221265 """Batch update models for a tenant."""
222266 try :
223267 for model in model_list :
224- update_model_record (model ["model_id" ], model , user_id )
268+ update_model_record (model ["model_id" ], model , user_id , tenant_id )
225269
226270 logging .debug ("Batch update models successfully" )
227271 except Exception as e :
@@ -232,24 +276,24 @@ async def batch_update_models_for_tenant(user_id: str, tenant_id: str, model_lis
232276async def delete_model_for_tenant (user_id : str , tenant_id : str , display_name : str ):
233277 """Delete model(s) by display_name. If embedding/multi_embedding, delete both types."""
234278 try :
235- model = get_model_by_display_name (display_name , tenant_id )
236- if not model :
279+ # Get all models with this display_name (may be 1 or 2 for embedding types)
280+ models = get_models_by_display_name (display_name , tenant_id )
281+ if not models :
237282 raise LookupError (f"Model not found: { display_name } " )
238283
239284 deleted_types : List [str ] = []
240- if model .get ("model_type" ) in ["embedding" , "multi_embedding" ]:
241- # Fetch both variants once to avoid repeated lookups
242- models_by_type : Dict [str , Dict [str , Any ]] = {}
243- for t in ["embedding" , "multi_embedding" ]:
244- m = get_model_by_display_name (display_name , tenant_id )
245- if m and m .get ("model_type" ) == t :
246- models_by_type [t ] = m
247-
248- # Best-effort memory cleanup using the fetched variants
285+
286+ # Check if any of the models is multi_embedding (which means we have both types)
287+ has_multi_embedding = any (
288+ m .get ("model_type" ) == "multi_embedding" for m in models
289+ )
290+
291+ if has_multi_embedding :
292+ # Best-effort memory cleanup for embedding models
249293 try :
250294 vdb_core = get_vector_db_core ()
251295 base_memory_config = build_memory_config_for_tenant (tenant_id )
252- for t , m in models_by_type . items () :
296+ for m in models :
253297 try :
254298 await clear_model_memories (
255299 vdb_core = vdb_core ,
@@ -270,17 +314,21 @@ async def delete_model_for_tenant(user_id: str, tenant_id: str, display_name: st
270314 logger .warning (
271315 "Memory cleanup preparation failed: %s" , outer_cleanup_exc )
272316
273- # Delete the fetched variants
274- for t , m in models_by_type . items () :
317+ # Delete all records with the same display_name
318+ for m in models :
275319 delete_model_record (m ["model_id" ], user_id , tenant_id )
276- deleted_types .append (t )
320+ deleted_types .append (m . get ( "model_type" , "unknown" ) )
277321 else :
322+ # Single model delete
323+ model = models [0 ]
278324 delete_model_record (model ["model_id" ], user_id , tenant_id )
279325 deleted_types .append (model .get ("model_type" , "unknown" ))
280326
281327 logging .debug (
282328 f"Successfully deleted model(s) in types: { ', ' .join (deleted_types )} " )
283329 return display_name
330+ except LookupError :
331+ raise
284332 except Exception as e :
285333 logging .error (f"Failed to delete model: { str (e )} " )
286334 raise Exception (f"Failed to delete model: { str (e )} " )
0 commit comments