Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 37 additions & 1 deletion src/solace_agent_mesh/services/platform/api/dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,4 +214,40 @@ def get_model_list_service() -> "ModelListService":
"""
from solace_agent_mesh.services.platform.services import ModelListService

return ModelListService()
return ModelListService()


class ModelDependentsHandler:
"""Interface for handling model-dependent agents on delete.

The community default is a no-op. Enterprise overrides this to find
and undeploy agents that depend on a given model configuration.
"""

async def undeploy_dependents(self, model_alias: str, model_id: str, component) -> list[dict]:
"""Undeploy agents depending on the given model (by alias or ID).

Args:
model_alias: The model alias being deleted.
model_id: The model UUID being deleted.
component: PlatformServiceComponent instance for publishing.

Returns:
List of dicts with info about undeployed agents.
"""
return []


_model_dependents_handler: ModelDependentsHandler = ModelDependentsHandler()


def set_model_dependents_handler(handler: ModelDependentsHandler):
"""Register an enterprise handler for model-dependent agent management."""
global _model_dependents_handler
_model_dependents_handler = handler
log.info("Model dependents handler registered.")


def get_model_dependents_handler() -> ModelDependentsHandler:
"""FastAPI dependency for the model dependents handler."""
return _model_dependents_handler
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@
from solace_agent_mesh.services.platform.api.dependencies import (
get_model_config_service,
get_model_list_service,
get_model_dependents_handler,
get_platform_db,
get_component_instance,
ModelDependentsHandler,
)
from solace_agent_mesh.services.platform.api.routers.dto.responses import (
ModelConfigurationResponse,
Expand Down Expand Up @@ -215,11 +217,57 @@ async def update_model(
return create_data_response(config)


@router.get(
"/models/{alias}/dependents",
response_model=DataResponse[list[dict]],
summary="Get agents that depend on a model",
description="Return deployed agents whose model_provider references the given model alias or ID. Requires enterprise package.",
)
async def get_model_dependents(
alias: str,
_: None = Depends(_require_model_config_ui_enabled),
db: Session = Depends(get_platform_db),
service: ModelConfigService = Depends(get_model_config_service),
) -> DataResponse[list[dict]]:
"""Return agents that depend on the given model configuration.

Attempts to import the enterprise ModelDependentsService. If the enterprise
package is not installed, returns an empty list.
"""
config = service.get_by_alias(db, alias)

try:
from solace_agent_mesh_enterprise.platform_service.services.model_dependents_service import (
ModelDependentsService,
)
from solace_agent_mesh_enterprise.platform_service.repositories.agent_repository import (
AgentRepository,
)
from solace_agent_mesh_enterprise.platform_service.repositories.deployment_repository import (
DeploymentRepository,
)

dependents_service = ModelDependentsService(AgentRepository(), DeploymentRepository())
dependents = dependents_service.get_dependents(db, config.alias, config.id)

return create_data_response([
{
"id": str(agent.id),
"name": agent.name,
"type": agent.type,
"deploymentStatus": agent.deployment_status,
}
for agent in dependents
])
except ImportError:
return create_data_response([])


@router.delete(
"/models/{alias}",
status_code=status.HTTP_204_NO_CONTENT,
summary="Delete a model configuration",
description="Delete a model configuration by alias. This action cannot be undone.",
description="Delete a model configuration by alias. Automatically undeploys any agents that depend on this model. This action cannot be undone.",
)
async def delete_model(
alias: str,
Expand All @@ -228,8 +276,10 @@ async def delete_model(
user: dict = Depends(get_current_user),
service: ModelConfigService = Depends(get_model_config_service),
component=Depends(get_component_instance),
dependents_handler: ModelDependentsHandler = Depends(get_model_dependents_handler),
) -> None:
config = service.get_by_alias(db, alias)
await dependents_handler.undeploy_dependents(config.alias, config.id, component)
service.delete(db, alias)
_emit_model_config_update(component, config.id, alias, None)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,13 +188,16 @@ async def test_emits_update_with_none_after_delete(self, mock_emit):
mock_component = Mock()
mock_user = {"id": "user-1"}

from solace_agent_mesh.services.platform.api.dependencies import ModelDependentsHandler

await delete_model(
alias="my-alias",
_=None,
db=Mock(),
user=mock_user,
service=mock_service,
component=mock_component,
dependents_handler=ModelDependentsHandler(),
)

mock_service.get_by_alias.assert_called_once()
Expand Down
Loading
Loading