fix(entities): entity delete TOCTOU checks - #951
Conversation
|
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughOptimistic locking is added to entity deletion. APIs, SDK clients, services, reconcilers, file locks, schemas, CLI documentation, and tests now pass ChangesOptimistic deletion flow
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
openapi/ga/individual/platform.openapi.yaml (1)
864-928: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick winAdd the 409 response here.
delete_entity_by_nameraisesHTTPException(status_code=409)onEntityVersionConflictError, so this route should document the stale-version conflict alongside 200/422.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@openapi/ga/individual/platform.openapi.yaml` around lines 864 - 928, Add a 409 Conflict response to the delete_entity_by_name operation’s responses, documenting the EntityVersionConflictError stale-version case alongside the existing 200 and 422 responses, using the appropriate conflict response description and schema if one is established.services/core/models/src/nmp/core/models/api/service/prompt_service.py (1)
159-179: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winRace: delete() after get() can raise unhandled
EntityNotFoundError→ 500 instead of 404.
entity_client.delete()is called outside the try/except that only guardsget(). If the prompt is deleted between these two calls, the resultingEntityNotFoundErrorisn't caught here and surfaces as a 500 inprompts.py's endpoint (onlyEntityConflictErroris explicitly handled there).nemo-auditor's andnemo-deployments' equivalent delete handlers avoid this by wrapping both the fetch and the delete in one try block.🐛 Proposed fix
async def delete_prompt(self, request: DeletePromptRequest) -> bool: """Delete a prompt by workspace and name. Returns False if not found.""" logger.debug("Deleting prompt", extra={"workspace": request.workspace, "prompt_name": request.name}) try: prompt = await self.entity_client.get(PromptEntity, workspace=request.workspace, name=request.name) + await self.entity_client.delete( + PromptEntity, + prompt.name, + workspace=request.workspace, + expected_db_version=prompt.db_version, + ) except EntityNotFoundError: logger.warning( "Prompt not found for deletion", extra={"workspace": request.workspace, "prompt_name": request.name}, ) return False - await self.entity_client.delete( - PromptEntity, - prompt.name, - workspace=request.workspace, - expected_db_version=prompt.db_version, - ) logger.info("Prompt deleted", extra={"workspace": request.workspace, "prompt_name": request.name}) return True🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@services/core/models/src/nmp/core/models/api/service/prompt_service.py` around lines 159 - 179, Update delete_prompt so the try/except EntityNotFoundError covers both entity_client.get and the subsequent entity_client.delete calls. Preserve the existing warning and False return when either operation reports the prompt is missing, while keeping successful deletion logging and True return unchanged.
🧹 Nitpick comments (2)
services/core/entities/src/nmp/core/entities/api/v2/entities/endpoints.py (2)
610-622: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick winRoute doesn't declare the new
409response.Conflict handling is correct, but unless the
@router.delete(...)decorator declaresresponses={409: {...}}, FastAPI won't emit this in the OpenAPI schema (confirmed missing in openapi.yaml). See consolidated comment for the fix.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@services/core/entities/src/nmp/core/entities/api/v2/entities/endpoints.py` around lines 610 - 622, Update the `@router.delete` decorator for the endpoint containing `delete_entity_by_name` to declare the `409` response, including an appropriate response description/schema consistent with the raised `HTTPException`, so FastAPI includes the conflict response in the OpenAPI schema.
1-1: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick winUndocumented 409 on entity delete-by-name. The route now raises
HTTPException(409)for version conflicts, but its OpenAPI entry only lists200/422— unlike the VirtualModel delete route, which explicitly documents409.
services/core/entities/src/nmp/core/entities/api/v2/entities/endpoints.py#L610-622: addresponses={409: {"description": "..."}}(or equivalent) to the@router.delete(...)decorator fordelete_entity_by_name.openapi/openapi.yaml#L906-928: regenerate after the decorator fix so the409response appears alongside200/422.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@services/core/entities/src/nmp/core/entities/api/v2/entities/endpoints.py` at line 1, Update the delete_entity_by_name `@router.delete` decorator to document the existing HTTPException(409) version-conflict response alongside the current 200 and 422 responses, matching the VirtualModel delete route’s response documentation. Regenerate the OpenAPI specification so the generated delete-by-name schema includes the 409 response.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@plugins/nemo-agents/src/nemo_agents_plugin/api/v2/agents.py`:
- Around line 183-189: Update the agent deletion flow around
entity_client.delete so it atomically validates that no deployment references
the agent before deletion, preventing a deployment created after the list check
from orphaning it. Alternatively, ensure deployment creation advances the
agent’s db_version so expected_db_version conflicts with concurrent deployment
creation; preserve optimistic concurrency behavior.
In `@plugins/nemo-evaluator/tests/api/v2/test_metrics_routes.py`:
- Around line 88-89: Update the fake delete implementation in async delete to
persist each entity’s version and validate expected_db_version before removal;
reject stale or mismatched versions with the same conflict behavior used by the
service. Add a test covering deletion with an outdated expected_db_version,
ensuring MetricService forwards the guard and the entity remains stored.
In
`@services/core/models/src/nmp/core/models/api/service/model_provider_service.py`:
- Around line 299-304: Reorder the provider deletion flow so the conditional
delete via entity_client.delete completes before invoking
_cleanup_model_entity_references(). Preserve the existing cleanup behavior after
a successful delete, and ensure a stale provider.db_version leaves linked model
references unchanged when deletion raises a 409.
---
Outside diff comments:
In `@openapi/ga/individual/platform.openapi.yaml`:
- Around line 864-928: Add a 409 Conflict response to the delete_entity_by_name
operation’s responses, documenting the EntityVersionConflictError stale-version
case alongside the existing 200 and 422 responses, using the appropriate
conflict response description and schema if one is established.
In `@services/core/models/src/nmp/core/models/api/service/prompt_service.py`:
- Around line 159-179: Update delete_prompt so the try/except
EntityNotFoundError covers both entity_client.get and the subsequent
entity_client.delete calls. Preserve the existing warning and False return when
either operation reports the prompt is missing, while keeping successful
deletion logging and True return unchanged.
---
Nitpick comments:
In `@services/core/entities/src/nmp/core/entities/api/v2/entities/endpoints.py`:
- Around line 610-622: Update the `@router.delete` decorator for the endpoint
containing `delete_entity_by_name` to declare the `409` response, including an
appropriate response description/schema consistent with the raised
`HTTPException`, so FastAPI includes the conflict response in the OpenAPI
schema.
- Line 1: Update the delete_entity_by_name `@router.delete` decorator to document
the existing HTTPException(409) version-conflict response alongside the current
200 and 422 responses, matching the VirtualModel delete route’s response
documentation. Regenerate the OpenAPI specification so the generated
delete-by-name schema includes the 409 response.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 2d10347b-4b63-4370-adb9-b7f033dd51e6
⛔ Files ignored due to path filters (14)
sdk/python/nemo-platform/.nmpcontext/openapi.yamlis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/cli/commands/api/inference/virtual_models.pyis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/resources/entities/entities.pyis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/resources/inference/api.mdis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/resources/inference/virtual_models.pyis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/types/entities/entity_delete_entity_by_name_params.pyis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/types/guardrail/guardrail_config.pyis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/types/inference/__init__.pyis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/types/inference/virtual_model.pyis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/types/inference/virtual_model_delete_params.pyis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/types/jobs/platform_job_step.pyis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/types/jobs/platform_job_task.pyis excluded by!sdk/**sdk/python/nemo-platform/tests/api_resources/inference/test_virtual_models.pyis excluded by!sdk/**sdk/python/nemo-platform/tests/api_resources/test_entities.pyis excluded by!sdk/**
📒 Files selected for processing (79)
docs/cli/reference.mdxopenapi/ga/individual/platform.openapi.yamlopenapi/ga/openapi.yamlopenapi/openapi.yamlpackages/nemo_platform_ext/src/nemo_platform_ext/cli/commands/api/inference/virtual_models.pypackages/nemo_platform_plugin/src/nemo_platform_plugin/entities.pypackages/nmp_common/tests/entities/test_client.pyplugins/example-plugin/src/nemo_example_plugin/middleware_service.pyplugins/example-plugin/src/nemo_example_plugin/service.pyplugins/example-plugin/tests/test_service.pyplugins/nemo-agents/openapi/openapi.yamlplugins/nemo-agents/src/nemo_agents_plugin/api/v2/agents.pyplugins/nemo-agents/src/nemo_agents_plugin/runner/controller.pyplugins/nemo-agents/src/nemo_agents_plugin/runner/deployments_backend.pyplugins/nemo-agents/tests/unit/test_agents_api.pyplugins/nemo-agents/tests/unit/test_runner_deployments.pyplugins/nemo-auditor/openapi/openapi.yamlplugins/nemo-auditor/src/nemo_auditor/api/v2/configs.pyplugins/nemo-auditor/src/nemo_auditor/api/v2/targets.pyplugins/nemo-auditor/tests/test_api_configs.pyplugins/nemo-auditor/tests/test_api_targets.pyplugins/nemo-deployments/openapi/openapi.yamlplugins/nemo-deployments/src/nemo_deployments_plugin/api/v2/deployment_configs.pyplugins/nemo-deployments/src/nemo_deployments_plugin/reconciler/deployment_reconciler.pyplugins/nemo-deployments/src/nemo_deployments_plugin/reconciler/volume_reconciler.pyplugins/nemo-deployments/tests/unit/test_api_deployment_configs.pyplugins/nemo-evaluator/src/nemo_evaluator/api/service/metric_service.pyplugins/nemo-evaluator/src/nemo_evaluator/api/service/result_service.pyplugins/nemo-evaluator/src/nemo_evaluator/api/service/task_service.pyplugins/nemo-evaluator/src/nemo_evaluator/api/service/taskset_service.pyplugins/nemo-evaluator/src/nemo_evaluator/api/v2/metrics.pyplugins/nemo-evaluator/src/nemo_evaluator/api/v2/results.pyplugins/nemo-evaluator/src/nemo_evaluator/api/v2/tasks.pyplugins/nemo-evaluator/src/nemo_evaluator/api/v2/tasksets.pyplugins/nemo-evaluator/tests/api/service/test_metric_service.pyplugins/nemo-evaluator/tests/api/service/test_result_service.pyplugins/nemo-evaluator/tests/api/service/test_task_service.pyplugins/nemo-evaluator/tests/api/service/test_taskset_service.pyplugins/nemo-evaluator/tests/api/v2/test_metrics_routes.pyplugins/nemo-evaluator/tests/api/v2/test_results_routes.pyplugins/nemo-evaluator/tests/api/v2/test_tasks_routes.pyplugins/nemo-evaluator/tests/api/v2/test_tasksets_routes.pyplugins/nemo-insights/src/nemo_insights_plugin/service.pyservices/core/entities/src/nmp/core/entities/api/v2/entities/endpoints.pyservices/core/entities/src/nmp/core/entities/app/repository/entity.pyservices/core/entities/src/nmp/core/entities/app/repository/sqlalchemy/entity.pyservices/core/entities/tests/repository/test_entity_delete_versioning.pyservices/core/files/src/nmp/core/files/app/file_lock.pyservices/core/files/tests/test_file_lock.pyservices/core/inference-gateway/src/nmp/core/inference_gateway/api/v2/virtual_models.pyservices/core/inference-gateway/tests/unit/test_virtual_models_router.pyservices/core/models/src/nmp/core/models/api/service/adapter_entity_service.pyservices/core/models/src/nmp/core/models/api/service/model_deployment_config_service.pyservices/core/models/src/nmp/core/models/api/service/model_deployment_service.pyservices/core/models/src/nmp/core/models/api/service/model_entity_service.pyservices/core/models/src/nmp/core/models/api/service/model_provider_service.pyservices/core/models/src/nmp/core/models/api/service/prompt_service.pyservices/core/models/src/nmp/core/models/api/v2/adapters.pyservices/core/models/src/nmp/core/models/api/v2/deployment_configs.pyservices/core/models/src/nmp/core/models/api/v2/deployments.pyservices/core/models/src/nmp/core/models/api/v2/models.pyservices/core/models/src/nmp/core/models/api/v2/prompts.pyservices/core/models/src/nmp/core/models/api/v2/providers.pyservices/core/models/src/nmp/core/models/controllers/backends/deployments_plugin/backend.pyservices/core/models/src/nmp/core/models/controllers/provider_reconciler.pyservices/core/models/tests/unit/api/test_deployment_configs_api.pyservices/core/models/tests/unit/api/test_deployments_api.pyservices/core/models/tests/unit/api/test_models_api.pyservices/core/models/tests/unit/api/test_prompts_api.pyservices/core/models/tests/unit/api/test_providers_api.pyservices/core/models/tests/unit/controllers/backends/deployments_plugin/test_backend.pyservices/core/models/tests/unit/controllers/test_provider_reconciler.pyservices/core/models/tests/unit/test_model_deployment_config_service_unit.pyservices/core/models/tests/unit/test_model_deployment_service_unit.pyservices/core/models/tests/unit/test_model_entity_service_unit.pyservices/core/models/tests/unit/test_model_provider_service_unit.pyservices/core/models/tests/unit/test_prompt_service_unit.pyservices/guardrails/src/nmp/guardrails/api/v2/configs/endpoints.pyservices/hello-world/src/nmp/hello_world/api/v1/messages/endpoints.py
bb95212 to
ad0ce55
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (1)
plugins/nemo-evaluator/tests/api/service/test_metric_service.py (1)
89-99: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winAlign the metric delete fake with the task/taskset fakes — reject mismatched
expected_db_versionand add a stale-versiondelete_metrictest so a version-check regression is caught.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@plugins/nemo-evaluator/tests/api/service/test_metric_service.py` around lines 89 - 99, Update the fake metric service delete method to validate expected_db_version against the stored entity version and reject mismatches consistently with the task/taskset fakes. Add a delete_metric test covering a stale expected database version and assert the operation is rejected without deleting the metric.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@plugins/nemo-evaluator/tests/api/service/test_metric_service.py`:
- Around line 89-99: Update the fake metric service delete method to validate
expected_db_version against the stored entity version and reject mismatches
consistently with the task/taskset fakes. Add a delete_metric test covering a
stale expected database version and assert the operation is rejected without
deleting the metric.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 6a628907-3d65-4512-8475-59a65206dd1f
⛔ Files ignored due to path filters (14)
sdk/python/nemo-platform/.nmpcontext/openapi.yamlis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/cli/commands/api/inference/virtual_models.pyis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/resources/entities/entities.pyis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/resources/inference/api.mdis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/resources/inference/virtual_models.pyis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/types/entities/entity_delete_entity_by_name_params.pyis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/types/guardrail/guardrail_config.pyis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/types/inference/__init__.pyis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/types/inference/virtual_model.pyis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/types/inference/virtual_model_delete_params.pyis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/types/jobs/platform_job_step.pyis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/types/jobs/platform_job_task.pyis excluded by!sdk/**sdk/python/nemo-platform/tests/api_resources/inference/test_virtual_models.pyis excluded by!sdk/**sdk/python/nemo-platform/tests/api_resources/test_entities.pyis excluded by!sdk/**
📒 Files selected for processing (79)
docs/cli/reference.mdxopenapi/ga/individual/platform.openapi.yamlopenapi/ga/openapi.yamlopenapi/openapi.yamlpackages/nemo_platform_ext/src/nemo_platform_ext/cli/commands/api/inference/virtual_models.pypackages/nemo_platform_plugin/src/nemo_platform_plugin/entities.pypackages/nmp_common/tests/entities/test_client.pyplugins/example-plugin/src/nemo_example_plugin/middleware_service.pyplugins/example-plugin/src/nemo_example_plugin/service.pyplugins/example-plugin/tests/test_service.pyplugins/nemo-agents/openapi/openapi.yamlplugins/nemo-agents/src/nemo_agents_plugin/api/v2/agents.pyplugins/nemo-agents/src/nemo_agents_plugin/runner/controller.pyplugins/nemo-agents/src/nemo_agents_plugin/runner/deployments_backend.pyplugins/nemo-agents/tests/unit/test_agents_api.pyplugins/nemo-agents/tests/unit/test_runner_deployments.pyplugins/nemo-auditor/openapi/openapi.yamlplugins/nemo-auditor/src/nemo_auditor/api/v2/configs.pyplugins/nemo-auditor/src/nemo_auditor/api/v2/targets.pyplugins/nemo-auditor/tests/test_api_configs.pyplugins/nemo-auditor/tests/test_api_targets.pyplugins/nemo-deployments/openapi/openapi.yamlplugins/nemo-deployments/src/nemo_deployments_plugin/api/v2/deployment_configs.pyplugins/nemo-deployments/src/nemo_deployments_plugin/reconciler/deployment_reconciler.pyplugins/nemo-deployments/src/nemo_deployments_plugin/reconciler/volume_reconciler.pyplugins/nemo-deployments/tests/unit/test_api_deployment_configs.pyplugins/nemo-evaluator/src/nemo_evaluator/api/service/metric_service.pyplugins/nemo-evaluator/src/nemo_evaluator/api/service/result_service.pyplugins/nemo-evaluator/src/nemo_evaluator/api/service/task_service.pyplugins/nemo-evaluator/src/nemo_evaluator/api/service/taskset_service.pyplugins/nemo-evaluator/src/nemo_evaluator/api/v2/metrics.pyplugins/nemo-evaluator/src/nemo_evaluator/api/v2/results.pyplugins/nemo-evaluator/src/nemo_evaluator/api/v2/tasks.pyplugins/nemo-evaluator/src/nemo_evaluator/api/v2/tasksets.pyplugins/nemo-evaluator/tests/api/service/test_metric_service.pyplugins/nemo-evaluator/tests/api/service/test_result_service.pyplugins/nemo-evaluator/tests/api/service/test_task_service.pyplugins/nemo-evaluator/tests/api/service/test_taskset_service.pyplugins/nemo-evaluator/tests/api/v2/test_metrics_routes.pyplugins/nemo-evaluator/tests/api/v2/test_results_routes.pyplugins/nemo-evaluator/tests/api/v2/test_tasks_routes.pyplugins/nemo-evaluator/tests/api/v2/test_tasksets_routes.pyplugins/nemo-insights/src/nemo_insights_plugin/service.pyservices/core/entities/src/nmp/core/entities/api/v2/entities/endpoints.pyservices/core/entities/src/nmp/core/entities/app/repository/entity.pyservices/core/entities/src/nmp/core/entities/app/repository/sqlalchemy/entity.pyservices/core/entities/tests/repository/test_entity_delete_versioning.pyservices/core/files/src/nmp/core/files/app/file_lock.pyservices/core/files/tests/test_file_lock.pyservices/core/inference-gateway/src/nmp/core/inference_gateway/api/v2/virtual_models.pyservices/core/inference-gateway/tests/unit/test_virtual_models_router.pyservices/core/models/src/nmp/core/models/api/service/adapter_entity_service.pyservices/core/models/src/nmp/core/models/api/service/model_deployment_config_service.pyservices/core/models/src/nmp/core/models/api/service/model_deployment_service.pyservices/core/models/src/nmp/core/models/api/service/model_entity_service.pyservices/core/models/src/nmp/core/models/api/service/model_provider_service.pyservices/core/models/src/nmp/core/models/api/service/prompt_service.pyservices/core/models/src/nmp/core/models/api/v2/adapters.pyservices/core/models/src/nmp/core/models/api/v2/deployment_configs.pyservices/core/models/src/nmp/core/models/api/v2/deployments.pyservices/core/models/src/nmp/core/models/api/v2/models.pyservices/core/models/src/nmp/core/models/api/v2/prompts.pyservices/core/models/src/nmp/core/models/api/v2/providers.pyservices/core/models/src/nmp/core/models/controllers/backends/deployments_plugin/backend.pyservices/core/models/src/nmp/core/models/controllers/provider_reconciler.pyservices/core/models/tests/unit/api/test_deployment_configs_api.pyservices/core/models/tests/unit/api/test_deployments_api.pyservices/core/models/tests/unit/api/test_models_api.pyservices/core/models/tests/unit/api/test_prompts_api.pyservices/core/models/tests/unit/api/test_providers_api.pyservices/core/models/tests/unit/controllers/backends/deployments_plugin/test_backend.pyservices/core/models/tests/unit/controllers/test_provider_reconciler.pyservices/core/models/tests/unit/test_model_deployment_config_service_unit.pyservices/core/models/tests/unit/test_model_deployment_service_unit.pyservices/core/models/tests/unit/test_model_entity_service_unit.pyservices/core/models/tests/unit/test_model_provider_service_unit.pyservices/core/models/tests/unit/test_prompt_service_unit.pyservices/guardrails/src/nmp/guardrails/api/v2/configs/endpoints.pyservices/hello-world/src/nmp/hello_world/api/v1/messages/endpoints.py
🚧 Files skipped from review as they are similar to previous changes (59)
- services/core/models/src/nmp/core/models/api/service/model_deployment_config_service.py
- services/core/entities/tests/repository/test_entity_delete_versioning.py
- packages/nemo_platform_ext/src/nemo_platform_ext/cli/commands/api/inference/virtual_models.py
- plugins/nemo-deployments/src/nemo_deployments_plugin/reconciler/deployment_reconciler.py
- services/core/models/src/nmp/core/models/api/v2/providers.py
- services/core/models/src/nmp/core/models/api/service/model_deployment_service.py
- plugins/nemo-agents/src/nemo_agents_plugin/runner/controller.py
- plugins/nemo-agents/src/nemo_agents_plugin/runner/deployments_backend.py
- plugins/nemo-agents/openapi/openapi.yaml
- services/core/inference-gateway/tests/unit/test_virtual_models_router.py
- plugins/nemo-agents/src/nemo_agents_plugin/api/v2/agents.py
- services/core/models/tests/unit/api/test_deployment_configs_api.py
- plugins/nemo-agents/tests/unit/test_runner_deployments.py
- docs/cli/reference.mdx
- services/core/models/src/nmp/core/models/controllers/provider_reconciler.py
- services/core/inference-gateway/src/nmp/core/inference_gateway/api/v2/virtual_models.py
- services/core/models/tests/unit/test_prompt_service_unit.py
- services/core/models/tests/unit/test_model_deployment_service_unit.py
- services/core/models/src/nmp/core/models/api/service/model_entity_service.py
- services/core/entities/src/nmp/core/entities/app/repository/entity.py
- plugins/nemo-deployments/src/nemo_deployments_plugin/reconciler/volume_reconciler.py
- services/core/entities/src/nmp/core/entities/app/repository/sqlalchemy/entity.py
- services/core/models/src/nmp/core/models/api/v2/deployments.py
- plugins/nemo-deployments/tests/unit/test_api_deployment_configs.py
- plugins/nemo-evaluator/src/nemo_evaluator/api/v2/tasksets.py
- plugins/example-plugin/src/nemo_example_plugin/service.py
- services/core/models/src/nmp/core/models/api/v2/prompts.py
- plugins/nemo-evaluator/src/nemo_evaluator/api/v2/tasks.py
- services/core/models/src/nmp/core/models/api/v2/models.py
- services/guardrails/src/nmp/guardrails/api/v2/configs/endpoints.py
- plugins/nemo-deployments/openapi/openapi.yaml
- services/core/models/tests/unit/controllers/test_provider_reconciler.py
- services/core/models/src/nmp/core/models/api/v2/deployment_configs.py
- services/core/models/tests/unit/test_model_entity_service_unit.py
- plugins/example-plugin/src/nemo_example_plugin/middleware_service.py
- services/hello-world/src/nmp/hello_world/api/v1/messages/endpoints.py
- services/core/models/tests/unit/controllers/backends/deployments_plugin/test_backend.py
- services/core/models/src/nmp/core/models/api/service/prompt_service.py
- services/core/models/tests/unit/api/test_models_api.py
- services/core/models/tests/unit/test_model_deployment_config_service_unit.py
- packages/nmp_common/tests/entities/test_client.py
- services/core/models/src/nmp/core/models/api/service/model_provider_service.py
- services/core/models/tests/unit/test_model_provider_service_unit.py
- services/core/models/tests/unit/api/test_providers_api.py
- plugins/nemo-evaluator/src/nemo_evaluator/api/v2/results.py
- services/core/models/src/nmp/core/models/controllers/backends/deployments_plugin/backend.py
- services/core/models/tests/unit/api/test_deployments_api.py
- services/core/models/src/nmp/core/models/api/service/adapter_entity_service.py
- plugins/nemo-auditor/src/nemo_auditor/api/v2/configs.py
- plugins/nemo-deployments/src/nemo_deployments_plugin/api/v2/deployment_configs.py
- plugins/nemo-agents/tests/unit/test_agents_api.py
- plugins/nemo-auditor/tests/test_api_configs.py
- plugins/nemo-evaluator/tests/api/v2/test_metrics_routes.py
- services/core/entities/src/nmp/core/entities/api/v2/entities/endpoints.py
- plugins/example-plugin/tests/test_service.py
- services/core/files/tests/test_file_lock.py
- services/core/files/src/nmp/core/files/app/file_lock.py
- openapi/openapi.yaml
- openapi/ga/openapi.yaml
ad0ce55 to
d1ff162
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
web/packages/studio/src/mocks/handlers/guardrails.ts (1)
75-82: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick winAdvance
db_versionon PATCH.Line 81 changes the resource but leaves its version unchanged, so tests cannot observe stale optimistic operations after an update. Increment the stored version with each successful PATCH.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@web/packages/studio/src/mocks/handlers/guardrails.ts` around lines 75 - 82, Update the PATCH handler for guardrail configs to increment the matched config’s stored db_version after applying the request body. Ensure every successful update through this handler advances the version while preserving the existing 404 behavior and response.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@services/core/entities/src/nmp/core/entities/app/repository/sqlalchemy/entity.py`:
- Around line 390-396: In the delete/commit flow, call await sess.rollback() in
the StaleDataError handler before raising EntityVersionConflictError, ensuring
the shared AsyncSession is usable for subsequent operations while preserving the
existing exception translation.
In `@services/hello-world/src/nmp/hello_world/api/v1/messages/endpoints.py`:
- Around line 128-130: Update the exception handling around the delete operation
in the endpoint to catch EntityNotFoundError before the generic Exception
handler and raise an HTTPException with status code 404. Preserve the existing
EntityConflictError mapping to 409 and generic error handling.
---
Outside diff comments:
In `@web/packages/studio/src/mocks/handlers/guardrails.ts`:
- Around line 75-82: Update the PATCH handler for guardrail configs to increment
the matched config’s stored db_version after applying the request body. Ensure
every successful update through this handler advances the version while
preserving the existing 404 behavior and response.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: c0523f78-6cd6-494a-8000-71572d0b48fa
⛔ Files ignored due to path filters (14)
sdk/python/nemo-platform/.nmpcontext/openapi.yamlis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/cli/commands/api/inference/virtual_models.pyis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/resources/entities/entities.pyis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/resources/inference/api.mdis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/resources/inference/virtual_models.pyis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/types/entities/entity_delete_entity_by_name_params.pyis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/types/guardrail/guardrail_config.pyis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/types/inference/__init__.pyis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/types/inference/virtual_model.pyis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/types/inference/virtual_model_delete_params.pyis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/types/jobs/platform_job_step.pyis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/types/jobs/platform_job_task.pyis excluded by!sdk/**sdk/python/nemo-platform/tests/api_resources/inference/test_virtual_models.pyis excluded by!sdk/**sdk/python/nemo-platform/tests/api_resources/test_entities.pyis excluded by!sdk/**
📒 Files selected for processing (81)
docs/cli/reference.mdxopenapi/ga/individual/platform.openapi.yamlopenapi/ga/openapi.yamlopenapi/openapi.yamlpackages/nemo_platform_ext/src/nemo_platform_ext/cli/commands/api/inference/virtual_models.pypackages/nemo_platform_plugin/src/nemo_platform_plugin/entities.pypackages/nmp_common/tests/entities/test_client.pyplugins/example-plugin/src/nemo_example_plugin/middleware_service.pyplugins/example-plugin/src/nemo_example_plugin/service.pyplugins/example-plugin/tests/test_service.pyplugins/nemo-agents/openapi/openapi.yamlplugins/nemo-agents/src/nemo_agents_plugin/api/v2/agents.pyplugins/nemo-agents/src/nemo_agents_plugin/runner/controller.pyplugins/nemo-agents/src/nemo_agents_plugin/runner/deployments_backend.pyplugins/nemo-agents/tests/unit/test_agents_api.pyplugins/nemo-agents/tests/unit/test_runner_deployments.pyplugins/nemo-auditor/openapi/openapi.yamlplugins/nemo-auditor/src/nemo_auditor/api/v2/configs.pyplugins/nemo-auditor/src/nemo_auditor/api/v2/targets.pyplugins/nemo-auditor/tests/test_api_configs.pyplugins/nemo-auditor/tests/test_api_targets.pyplugins/nemo-deployments/openapi/openapi.yamlplugins/nemo-deployments/src/nemo_deployments_plugin/api/v2/deployment_configs.pyplugins/nemo-deployments/src/nemo_deployments_plugin/reconciler/deployment_reconciler.pyplugins/nemo-deployments/src/nemo_deployments_plugin/reconciler/volume_reconciler.pyplugins/nemo-deployments/tests/unit/test_api_deployment_configs.pyplugins/nemo-evaluator/src/nemo_evaluator/api/service/metric_service.pyplugins/nemo-evaluator/src/nemo_evaluator/api/service/result_service.pyplugins/nemo-evaluator/src/nemo_evaluator/api/service/task_service.pyplugins/nemo-evaluator/src/nemo_evaluator/api/service/taskset_service.pyplugins/nemo-evaluator/src/nemo_evaluator/api/v2/metrics.pyplugins/nemo-evaluator/src/nemo_evaluator/api/v2/results.pyplugins/nemo-evaluator/src/nemo_evaluator/api/v2/tasks.pyplugins/nemo-evaluator/src/nemo_evaluator/api/v2/tasksets.pyplugins/nemo-evaluator/tests/api/service/test_metric_service.pyplugins/nemo-evaluator/tests/api/service/test_result_service.pyplugins/nemo-evaluator/tests/api/service/test_task_service.pyplugins/nemo-evaluator/tests/api/service/test_taskset_service.pyplugins/nemo-evaluator/tests/api/v2/test_metrics_routes.pyplugins/nemo-evaluator/tests/api/v2/test_results_routes.pyplugins/nemo-evaluator/tests/api/v2/test_tasks_routes.pyplugins/nemo-evaluator/tests/api/v2/test_tasksets_routes.pyplugins/nemo-insights/src/nemo_insights_plugin/service.pyservices/core/entities/src/nmp/core/entities/api/v2/entities/endpoints.pyservices/core/entities/src/nmp/core/entities/app/repository/entity.pyservices/core/entities/src/nmp/core/entities/app/repository/sqlalchemy/entity.pyservices/core/entities/tests/repository/test_entity_delete_versioning.pyservices/core/files/src/nmp/core/files/app/file_lock.pyservices/core/files/tests/test_file_lock.pyservices/core/inference-gateway/src/nmp/core/inference_gateway/api/v2/virtual_models.pyservices/core/inference-gateway/tests/unit/test_virtual_models_router.pyservices/core/models/src/nmp/core/models/api/service/adapter_entity_service.pyservices/core/models/src/nmp/core/models/api/service/model_deployment_config_service.pyservices/core/models/src/nmp/core/models/api/service/model_deployment_service.pyservices/core/models/src/nmp/core/models/api/service/model_entity_service.pyservices/core/models/src/nmp/core/models/api/service/model_provider_service.pyservices/core/models/src/nmp/core/models/api/service/prompt_service.pyservices/core/models/src/nmp/core/models/api/v2/adapters.pyservices/core/models/src/nmp/core/models/api/v2/deployment_configs.pyservices/core/models/src/nmp/core/models/api/v2/deployments.pyservices/core/models/src/nmp/core/models/api/v2/models.pyservices/core/models/src/nmp/core/models/api/v2/prompts.pyservices/core/models/src/nmp/core/models/api/v2/providers.pyservices/core/models/src/nmp/core/models/controllers/backends/deployments_plugin/backend.pyservices/core/models/src/nmp/core/models/controllers/provider_reconciler.pyservices/core/models/tests/unit/api/test_deployment_configs_api.pyservices/core/models/tests/unit/api/test_deployments_api.pyservices/core/models/tests/unit/api/test_models_api.pyservices/core/models/tests/unit/api/test_prompts_api.pyservices/core/models/tests/unit/api/test_providers_api.pyservices/core/models/tests/unit/controllers/backends/deployments_plugin/test_backend.pyservices/core/models/tests/unit/controllers/test_provider_reconciler.pyservices/core/models/tests/unit/test_model_deployment_config_service_unit.pyservices/core/models/tests/unit/test_model_deployment_service_unit.pyservices/core/models/tests/unit/test_model_entity_service_unit.pyservices/core/models/tests/unit/test_model_provider_service_unit.pyservices/core/models/tests/unit/test_prompt_service_unit.pyservices/guardrails/src/nmp/guardrails/api/v2/configs/endpoints.pyservices/hello-world/src/nmp/hello_world/api/v1/messages/endpoints.pyweb/packages/studio/src/mocks/handlers/guardrails.tsweb/packages/studio/src/routes/VirtualModelsListRoute/VirtualModelDetailsSidePanel/index.test.tsx
🚧 Files skipped from review as they are similar to previous changes (73)
- plugins/example-plugin/src/nemo_example_plugin/service.py
- services/core/models/tests/unit/test_model_deployment_config_service_unit.py
- services/core/entities/tests/repository/test_entity_delete_versioning.py
- services/core/models/src/nmp/core/models/api/service/model_deployment_service.py
- plugins/nemo-deployments/src/nemo_deployments_plugin/reconciler/deployment_reconciler.py
- plugins/nemo-evaluator/src/nemo_evaluator/api/v2/tasks.py
- services/core/models/src/nmp/core/models/api/service/model_entity_service.py
- services/core/models/src/nmp/core/models/api/v2/providers.py
- plugins/nemo-deployments/openapi/openapi.yaml
- services/core/models/src/nmp/core/models/api/v2/adapters.py
- packages/nemo_platform_ext/src/nemo_platform_ext/cli/commands/api/inference/virtual_models.py
- plugins/nemo-agents/openapi/openapi.yaml
- services/core/models/tests/unit/test_prompt_service_unit.py
- plugins/nemo-auditor/openapi/openapi.yaml
- services/core/models/src/nmp/core/models/api/service/adapter_entity_service.py
- plugins/nemo-evaluator/src/nemo_evaluator/api/v2/tasksets.py
- services/core/models/tests/unit/test_model_deployment_service_unit.py
- services/core/models/tests/unit/controllers/backends/deployments_plugin/test_backend.py
- services/core/inference-gateway/tests/unit/test_virtual_models_router.py
- plugins/nemo-evaluator/src/nemo_evaluator/api/service/taskset_service.py
- services/core/models/src/nmp/core/models/api/v2/deployments.py
- plugins/nemo-evaluator/src/nemo_evaluator/api/v2/metrics.py
- plugins/nemo-evaluator/src/nemo_evaluator/api/v2/results.py
- plugins/nemo-evaluator/tests/api/v2/test_tasksets_routes.py
- plugins/nemo-agents/tests/unit/test_runner_deployments.py
- plugins/nemo-insights/src/nemo_insights_plugin/service.py
- plugins/nemo-agents/src/nemo_agents_plugin/api/v2/agents.py
- services/core/models/src/nmp/core/models/api/service/model_provider_service.py
- services/guardrails/src/nmp/guardrails/api/v2/configs/endpoints.py
- services/core/entities/src/nmp/core/entities/api/v2/entities/endpoints.py
- services/core/models/src/nmp/core/models/api/v2/prompts.py
- plugins/nemo-agents/src/nemo_agents_plugin/runner/controller.py
- services/core/models/src/nmp/core/models/api/service/model_deployment_config_service.py
- plugins/nemo-auditor/src/nemo_auditor/api/v2/targets.py
- docs/cli/reference.mdx
- packages/nmp_common/tests/entities/test_client.py
- services/core/models/tests/unit/api/test_deployments_api.py
- plugins/nemo-deployments/src/nemo_deployments_plugin/api/v2/deployment_configs.py
- services/core/models/src/nmp/core/models/controllers/provider_reconciler.py
- plugins/nemo-deployments/src/nemo_deployments_plugin/reconciler/volume_reconciler.py
- services/core/models/src/nmp/core/models/api/v2/deployment_configs.py
- services/core/models/src/nmp/core/models/api/v2/models.py
- services/core/models/src/nmp/core/models/api/service/prompt_service.py
- services/core/files/tests/test_file_lock.py
- services/core/models/tests/unit/api/test_models_api.py
- plugins/nemo-deployments/tests/unit/test_api_deployment_configs.py
- plugins/nemo-evaluator/src/nemo_evaluator/api/service/metric_service.py
- plugins/nemo-auditor/tests/test_api_targets.py
- services/core/models/src/nmp/core/models/controllers/backends/deployments_plugin/backend.py
- plugins/nemo-agents/tests/unit/test_agents_api.py
- plugins/nemo-evaluator/src/nemo_evaluator/api/service/task_service.py
- services/core/models/tests/unit/api/test_deployment_configs_api.py
- services/core/files/src/nmp/core/files/app/file_lock.py
- plugins/nemo-evaluator/tests/api/v2/test_tasks_routes.py
- services/core/models/tests/unit/api/test_prompts_api.py
- services/core/models/tests/unit/test_model_provider_service_unit.py
- plugins/nemo-auditor/tests/test_api_configs.py
- services/core/models/tests/unit/test_model_entity_service_unit.py
- plugins/nemo-evaluator/src/nemo_evaluator/api/service/result_service.py
- plugins/nemo-agents/src/nemo_agents_plugin/runner/deployments_backend.py
- plugins/nemo-evaluator/tests/api/v2/test_metrics_routes.py
- services/core/inference-gateway/src/nmp/core/inference_gateway/api/v2/virtual_models.py
- services/core/models/tests/unit/api/test_providers_api.py
- openapi/ga/individual/platform.openapi.yaml
- plugins/example-plugin/tests/test_service.py
- plugins/nemo-evaluator/tests/api/service/test_result_service.py
- plugins/nemo-evaluator/tests/api/service/test_metric_service.py
- services/core/models/tests/unit/controllers/test_provider_reconciler.py
- plugins/nemo-evaluator/tests/api/service/test_task_service.py
- openapi/ga/openapi.yaml
- packages/nemo_platform_plugin/src/nemo_platform_plugin/entities.py
- openapi/openapi.yaml
- plugins/nemo-evaluator/tests/api/service/test_taskset_service.py
c02ec52 to
cc8c7cb
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@services/guardrails/src/nmp/guardrails/api/v2/configs/endpoints.py`:
- Around line 200-208: Update the guarded delete block in the endpoint to also
catch EntityNotFoundError, mapping it to the same HTTP 404 response used when
the initial lookup cannot find the configuration. Preserve the existing
EntityConflictError handling and 409 response for concurrent modification
conflicts.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 26d780d8-0ead-40bd-a005-86c40212ad58
⛔ Files ignored due to path filters (14)
sdk/python/nemo-platform/.nmpcontext/openapi.yamlis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/cli/commands/api/inference/virtual_models.pyis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/resources/entities/entities.pyis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/resources/inference/api.mdis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/resources/inference/virtual_models.pyis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/types/entities/entity_delete_entity_by_name_params.pyis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/types/guardrail/guardrail_config.pyis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/types/inference/__init__.pyis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/types/inference/virtual_model.pyis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/types/inference/virtual_model_delete_params.pyis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/types/jobs/platform_job_step.pyis excluded by!sdk/**sdk/python/nemo-platform/src/nemo_platform/types/jobs/platform_job_task.pyis excluded by!sdk/**sdk/python/nemo-platform/tests/api_resources/inference/test_virtual_models.pyis excluded by!sdk/**sdk/python/nemo-platform/tests/api_resources/test_entities.pyis excluded by!sdk/**
📒 Files selected for processing (91)
docs/cli/reference.mdxopenapi/ga/individual/platform.openapi.yamlopenapi/ga/openapi.yamlopenapi/openapi.yamlpackages/nemo_platform_ext/src/nemo_platform_ext/cli/commands/api/inference/virtual_models.pypackages/nemo_platform_plugin/src/nemo_platform_plugin/entities.pypackages/nmp_common/tests/entities/test_client.pypackages/nmp_testing/src/nmp/testing/utils.pyplugins/example-plugin/src/nemo_example_plugin/middleware_service.pyplugins/example-plugin/src/nemo_example_plugin/service.pyplugins/example-plugin/tests/test_service.pyplugins/nemo-agents/openapi/openapi.yamlplugins/nemo-agents/src/nemo_agents_plugin/api/v2/agents.pyplugins/nemo-agents/src/nemo_agents_plugin/runner/controller.pyplugins/nemo-agents/src/nemo_agents_plugin/runner/deployments_backend.pyplugins/nemo-agents/tests/unit/test_agents_api.pyplugins/nemo-agents/tests/unit/test_runner_deployments.pyplugins/nemo-auditor/openapi/openapi.yamlplugins/nemo-auditor/src/nemo_auditor/api/v2/configs.pyplugins/nemo-auditor/src/nemo_auditor/api/v2/targets.pyplugins/nemo-auditor/tests/test_api_configs.pyplugins/nemo-auditor/tests/test_api_targets.pyplugins/nemo-deployments/openapi/openapi.yamlplugins/nemo-deployments/src/nemo_deployments_plugin/api/v2/deployment_configs.pyplugins/nemo-deployments/src/nemo_deployments_plugin/reconciler/deployment_reconciler.pyplugins/nemo-deployments/src/nemo_deployments_plugin/reconciler/volume_reconciler.pyplugins/nemo-deployments/tests/unit/test_api_deployment_configs.pyplugins/nemo-evaluator/src/nemo_evaluator/api/service/metric_service.pyplugins/nemo-evaluator/src/nemo_evaluator/api/service/result_service.pyplugins/nemo-evaluator/src/nemo_evaluator/api/service/task_service.pyplugins/nemo-evaluator/src/nemo_evaluator/api/service/taskset_service.pyplugins/nemo-evaluator/src/nemo_evaluator/api/v2/metrics.pyplugins/nemo-evaluator/src/nemo_evaluator/api/v2/results.pyplugins/nemo-evaluator/src/nemo_evaluator/api/v2/tasks.pyplugins/nemo-evaluator/src/nemo_evaluator/api/v2/tasksets.pyplugins/nemo-evaluator/tests/api/service/test_metric_service.pyplugins/nemo-evaluator/tests/api/service/test_result_service.pyplugins/nemo-evaluator/tests/api/service/test_task_service.pyplugins/nemo-evaluator/tests/api/service/test_taskset_service.pyplugins/nemo-evaluator/tests/api/v2/test_metrics_routes.pyplugins/nemo-evaluator/tests/api/v2/test_results_routes.pyplugins/nemo-evaluator/tests/api/v2/test_tasks_routes.pyplugins/nemo-evaluator/tests/api/v2/test_tasksets_routes.pyplugins/nemo-insights/src/nemo_insights_plugin/service.pyservices/core/entities/src/nmp/core/entities/api/v2/entities/endpoints.pyservices/core/entities/src/nmp/core/entities/app/repository/entity.pyservices/core/entities/src/nmp/core/entities/app/repository/sqlalchemy/entity.pyservices/core/entities/tests/repository/test_entity_delete_versioning.pyservices/core/files/src/nmp/core/files/app/file_lock.pyservices/core/files/tests/test_file_lock.pyservices/core/inference-gateway/src/nmp/core/inference_gateway/api/v2/virtual_models.pyservices/core/inference-gateway/tests/integration/test_inference.pyservices/core/inference-gateway/tests/integration/test_middleware_pipeline.pyservices/core/inference-gateway/tests/unit/conftest.pyservices/core/inference-gateway/tests/unit/test_middleware_registry.pyservices/core/inference-gateway/tests/unit/test_model_router.pyservices/core/inference-gateway/tests/unit/test_openai_router.pyservices/core/inference-gateway/tests/unit/test_proxy.pyservices/core/inference-gateway/tests/unit/test_virtual_model_cache.pyservices/core/inference-gateway/tests/unit/test_virtual_models_router.pyservices/core/models/src/nmp/core/models/api/service/adapter_entity_service.pyservices/core/models/src/nmp/core/models/api/service/model_deployment_config_service.pyservices/core/models/src/nmp/core/models/api/service/model_deployment_service.pyservices/core/models/src/nmp/core/models/api/service/model_entity_service.pyservices/core/models/src/nmp/core/models/api/service/model_provider_service.pyservices/core/models/src/nmp/core/models/api/service/prompt_service.pyservices/core/models/src/nmp/core/models/api/v2/adapters.pyservices/core/models/src/nmp/core/models/api/v2/deployment_configs.pyservices/core/models/src/nmp/core/models/api/v2/deployments.pyservices/core/models/src/nmp/core/models/api/v2/models.pyservices/core/models/src/nmp/core/models/api/v2/prompts.pyservices/core/models/src/nmp/core/models/api/v2/providers.pyservices/core/models/src/nmp/core/models/controllers/backends/deployments_plugin/backend.pyservices/core/models/src/nmp/core/models/controllers/provider_reconciler.pyservices/core/models/tests/unit/api/test_deployment_configs_api.pyservices/core/models/tests/unit/api/test_deployments_api.pyservices/core/models/tests/unit/api/test_models_api.pyservices/core/models/tests/unit/api/test_prompts_api.pyservices/core/models/tests/unit/api/test_providers_api.pyservices/core/models/tests/unit/controllers/backends/deployments_plugin/test_backend.pyservices/core/models/tests/unit/controllers/test_provider_reconciler.pyservices/core/models/tests/unit/test_model_deployment_config_service_unit.pyservices/core/models/tests/unit/test_model_deployment_service_unit.pyservices/core/models/tests/unit/test_model_entity_service_unit.pyservices/core/models/tests/unit/test_model_provider_service_unit.pyservices/core/models/tests/unit/test_prompt_service_unit.pyservices/guardrails/src/nmp/guardrails/api/v2/configs/endpoints.pyservices/hello-world/src/nmp/hello_world/api/v1/messages/endpoints.pyservices/hello-world/tests/unit/test_messages_endpoints.pyweb/packages/studio/src/mocks/handlers/guardrails.tsweb/packages/studio/src/routes/VirtualModelsListRoute/VirtualModelDetailsSidePanel/index.test.tsx
🚧 Files skipped from review as they are similar to previous changes (74)
- web/packages/studio/src/mocks/handlers/guardrails.ts
- plugins/nemo-insights/src/nemo_insights_plugin/service.py
- web/packages/studio/src/routes/VirtualModelsListRoute/VirtualModelDetailsSidePanel/index.test.tsx
- services/core/models/src/nmp/core/models/api/v2/adapters.py
- plugins/nemo-deployments/src/nemo_deployments_plugin/reconciler/deployment_reconciler.py
- services/core/models/src/nmp/core/models/api/service/model_deployment_config_service.py
- services/core/models/src/nmp/core/models/api/v2/prompts.py
- services/core/models/src/nmp/core/models/controllers/backends/deployments_plugin/backend.py
- services/core/entities/src/nmp/core/entities/app/repository/entity.py
- docs/cli/reference.mdx
- services/hello-world/src/nmp/hello_world/api/v1/messages/endpoints.py
- services/core/models/src/nmp/core/models/api/service/model_deployment_service.py
- services/core/models/src/nmp/core/models/api/service/model_provider_service.py
- services/core/models/tests/unit/api/test_models_api.py
- services/core/models/tests/unit/test_prompt_service_unit.py
- services/core/models/src/nmp/core/models/api/service/prompt_service.py
- packages/nemo_platform_ext/src/nemo_platform_ext/cli/commands/api/inference/virtual_models.py
- plugins/nemo-auditor/src/nemo_auditor/api/v2/targets.py
- services/core/models/src/nmp/core/models/api/v2/models.py
- services/core/models/tests/unit/api/test_prompts_api.py
- plugins/nemo-agents/src/nemo_agents_plugin/api/v2/agents.py
- services/core/models/tests/unit/controllers/backends/deployments_plugin/test_backend.py
- services/core/models/tests/unit/api/test_providers_api.py
- plugins/nemo-agents/src/nemo_agents_plugin/runner/deployments_backend.py
- services/core/models/tests/unit/test_model_deployment_config_service_unit.py
- services/core/inference-gateway/tests/unit/test_virtual_models_router.py
- plugins/nemo-deployments/src/nemo_deployments_plugin/api/v2/deployment_configs.py
- plugins/nemo-agents/openapi/openapi.yaml
- plugins/nemo-evaluator/tests/api/v2/test_tasks_routes.py
- services/core/models/tests/unit/api/test_deployment_configs_api.py
- services/core/entities/src/nmp/core/entities/app/repository/sqlalchemy/entity.py
- plugins/nemo-evaluator/src/nemo_evaluator/api/v2/tasksets.py
- plugins/nemo-deployments/src/nemo_deployments_plugin/reconciler/volume_reconciler.py
- services/core/entities/src/nmp/core/entities/api/v2/entities/endpoints.py
- services/core/models/src/nmp/core/models/controllers/provider_reconciler.py
- plugins/nemo-evaluator/src/nemo_evaluator/api/service/taskset_service.py
- plugins/nemo-evaluator/tests/api/service/test_task_service.py
- services/core/models/tests/unit/test_model_provider_service_unit.py
- plugins/nemo-auditor/src/nemo_auditor/api/v2/configs.py
- plugins/nemo-agents/src/nemo_agents_plugin/runner/controller.py
- services/core/models/src/nmp/core/models/api/service/adapter_entity_service.py
- plugins/example-plugin/src/nemo_example_plugin/service.py
- services/core/files/tests/test_file_lock.py
- plugins/nemo-evaluator/src/nemo_evaluator/api/v2/metrics.py
- plugins/example-plugin/src/nemo_example_plugin/middleware_service.py
- services/core/models/tests/unit/test_model_entity_service_unit.py
- plugins/nemo-auditor/openapi/openapi.yaml
- plugins/nemo-agents/tests/unit/test_agents_api.py
- services/core/models/src/nmp/core/models/api/service/model_entity_service.py
- plugins/nemo-evaluator/src/nemo_evaluator/api/v2/tasks.py
- plugins/nemo-evaluator/src/nemo_evaluator/api/service/result_service.py
- plugins/nemo-auditor/tests/test_api_targets.py
- plugins/nemo-evaluator/src/nemo_evaluator/api/v2/results.py
- plugins/nemo-evaluator/tests/api/service/test_result_service.py
- plugins/example-plugin/tests/test_service.py
- plugins/nemo-evaluator/tests/api/v2/test_tasksets_routes.py
- plugins/nemo-agents/tests/unit/test_runner_deployments.py
- services/core/models/src/nmp/core/models/api/v2/deployments.py
- plugins/nemo-deployments/openapi/openapi.yaml
- plugins/nemo-evaluator/tests/api/service/test_taskset_service.py
- services/core/models/src/nmp/core/models/api/v2/deployment_configs.py
- services/core/inference-gateway/src/nmp/core/inference_gateway/api/v2/virtual_models.py
- services/core/models/src/nmp/core/models/api/v2/providers.py
- plugins/nemo-evaluator/src/nemo_evaluator/api/service/task_service.py
- services/core/models/tests/unit/api/test_deployments_api.py
- plugins/nemo-evaluator/tests/api/service/test_metric_service.py
- openapi/ga/openapi.yaml
- plugins/nemo-evaluator/src/nemo_evaluator/api/service/metric_service.py
- services/core/models/tests/unit/test_model_deployment_service_unit.py
- packages/nmp_common/tests/entities/test_client.py
- openapi/ga/individual/platform.openapi.yaml
- openapi/openapi.yaml
- services/core/files/src/nmp/core/files/app/file_lock.py
- plugins/nemo-evaluator/tests/api/v2/test_results_routes.py
eff3fdd to
74e60cc
Compare
Signed-off-by: Ryan S <267728323+ironcommit@users.noreply.github.com>
74e60cc to
41f9fe3
Compare
Main dropped the legacy docker and k8s-nim-operator backends (#705) and replaced the reconcilers' per-entity Model Entity reads and writes with ModelEntityCache (#953, #951). The branch's changes to the deleted backends were import rewrites, so they go with the files. Everywhere the cache supersedes a direct read/write, main's semantics win and the calls it makes are routed through the typed client. ModelEntityCache arrived on main built on the umbrella SDK, which left models_controller holding a dangling self._models_sdk after the merge. It is migrated to AsyncModelsClient here, since leaving it on the SDK would make the branch's premise only half true. _load_virtual_models still reached for self._models_sdk. Its bare except Exception reported the AttributeError as a VirtualModel listing failure and skipped orphan cleanup, so the tests stayed green while the cleanup silently never ran. VirtualModel work stays on the umbrella SDK: it is an inference-gateway resource, not a Models one. The SDK exception types are aliased to say so. Signed-off-by: Max Dubrinsky <mdubrinsky@nvidia.com>
Summary by CodeRabbit
expected_db_versionfor entities and VirtualModels, including CLI support.db_versionacross multiple API schemas to enable version-aware deletes.expected_db_versionand the 409 response.