From aa6dceeeceff51fda478769674fca75329acf652 Mon Sep 17 00:00:00 2001 From: Sourav Rajvi <144546710+Souravrajvi0@users.noreply.github.com> Date: Fri, 11 Sep 2026 08:09:48 +0000 Subject: [PATCH] fix(web): send model delete params as query string on DELETE (#42162) Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> --- api/controllers/console/workspace/models.py | 4 +- api/openapi/markdown/console-openapi.md | 17 ++--- .../console/workspace/test_models.py | 35 ++++++++++ .../api/console/workspaces/orpc.gen.ts | 8 +-- .../api/console/workspaces/types.gen.ts | 35 +++++----- .../api/console/workspaces/zod.gen.ts | 67 +++++++++---------- web/service/use-models.ts | 4 +- 7 files changed, 98 insertions(+), 72 deletions(-) diff --git a/api/controllers/console/workspace/models.py b/api/controllers/console/workspace/models.py index 23b38bca57f..463b9e65f5e 100644 --- a/api/controllers/console/workspace/models.py +++ b/api/controllers/console/workspace/models.py @@ -320,7 +320,7 @@ class ModelProviderModelApi(Resource): return SimpleResultResponse(result="success").model_dump(mode="json"), 200 - @console_ns.expect(console_ns.models[ParserDeleteModels.__name__]) + @console_ns.doc(params=query_params_from_model(ParserDeleteModels)) @console_ns.response(204, "Model deleted successfully") @setup_required @login_required @@ -469,7 +469,7 @@ class ModelProviderModelCredentialApi(Resource): return SimpleResultResponse(result="success").model_dump(mode="json") - @console_ns.expect(console_ns.models[ParserDeleteCredential.__name__]) + @console_ns.doc(params=query_params_from_model(ParserDeleteCredential)) @console_ns.response(204, "Credential deleted successfully") @setup_required @login_required diff --git a/api/openapi/markdown/console-openapi.md b/api/openapi/markdown/console-openapi.md index ba29e5160aa..4fcfd3383e4 100644 --- a/api/openapi/markdown/console-openapi.md +++ b/api/openapi/markdown/console-openapi.md @@ -10438,14 +10438,10 @@ Update a plugin endpoint | Name | Located in | Description | Required | Schema | | ---- | ---------- | ----------- | -------- | ------ | +| model | query | | Yes | string | +| model_type | query | Enum class for model type. | Yes | string,
**Available values:** "llm", "moderation", "rerank", "speech2text", "text-embedding", "tts" | | provider | path | | Yes | string | -#### Request Body - -| Required | Schema | -| -------- | ------ | -| Yes | **application/json**: [ParserDeleteModels](#parserdeletemodels)
| - #### Responses | Code | Description | @@ -10489,14 +10485,11 @@ Update a plugin endpoint | Name | Located in | Description | Required | Schema | | ---- | ---------- | ----------- | -------- | ------ | +| credential_id | query | | Yes | string | +| model | query | | Yes | string | +| model_type | query | Enum class for model type. | Yes | string,
**Available values:** "llm", "moderation", "rerank", "speech2text", "text-embedding", "tts" | | provider | path | | Yes | string | -#### Request Body - -| Required | Schema | -| -------- | ------ | -| Yes | **application/json**: [ParserDeleteCredential](#parserdeletecredential)
| - #### Responses | Code | Description | diff --git a/api/tests/unit_tests/controllers/console/workspace/test_models.py b/api/tests/unit_tests/controllers/console/workspace/test_models.py index 84ec2430d7f..9f49e97d3d2 100644 --- a/api/tests/unit_tests/controllers/console/workspace/test_models.py +++ b/api/tests/unit_tests/controllers/console/workspace/test_models.py @@ -154,6 +154,23 @@ class TestModelProviderModelApi: assert status == 204 + def test_delete_model_via_query_params(self, app: Flask): + api = ModelProviderModelApi() + method = unwrap(api.delete) + + payload = { + "model": "gpt-4", + "model_type": ModelType.LLM, + } + + with ( + app.test_request_context("/", method="DELETE", query_string=payload), + patch("controllers.console.workspace.models.ModelProviderService"), + ): + result, status = method(api, ParserDeleteModels.model_validate(payload), "tenant1", "openai") + + assert status == 204 + def test_get_models_returns_empty(self, app: Flask): api = ModelProviderModelApi() method = unwrap(api.get) @@ -262,6 +279,24 @@ class TestModelProviderModelCredentialApi: assert status == 204 + def test_delete_credential_via_query_params(self, app: Flask): + api = ModelProviderModelCredentialApi() + method = unwrap(api.delete) + + payload = { + "model": "gpt", + "model_type": ModelType.LLM, + "credential_id": "123e4567-e89b-12d3-a456-426614174000", + } + + with ( + app.test_request_context("/", method="DELETE", query_string=payload), + patch("controllers.console.workspace.models.ModelProviderService"), + ): + result, status = method(api, ParserDeleteCredential.model_validate(payload), "t1", "openai") + + assert status == 204 + class TestModelProviderModelCredentialSwitchApi: def test_switch_success(self, app: Flask): diff --git a/packages/contracts/generated/api/console/workspaces/orpc.gen.ts b/packages/contracts/generated/api/console/workspaces/orpc.gen.ts index eeadc47516e..0911774b0dc 100644 --- a/packages/contracts/generated/api/console/workspaces/orpc.gen.ts +++ b/packages/contracts/generated/api/console/workspaces/orpc.gen.ts @@ -12,11 +12,11 @@ import { zDeleteWorkspacesCurrentModelProvidersByProviderCredentialsBody, zDeleteWorkspacesCurrentModelProvidersByProviderCredentialsPath, zDeleteWorkspacesCurrentModelProvidersByProviderCredentialsResponse, - zDeleteWorkspacesCurrentModelProvidersByProviderModelsBody, - zDeleteWorkspacesCurrentModelProvidersByProviderModelsCredentialsBody, zDeleteWorkspacesCurrentModelProvidersByProviderModelsCredentialsPath, + zDeleteWorkspacesCurrentModelProvidersByProviderModelsCredentialsQuery, zDeleteWorkspacesCurrentModelProvidersByProviderModelsCredentialsResponse, zDeleteWorkspacesCurrentModelProvidersByProviderModelsPath, + zDeleteWorkspacesCurrentModelProvidersByProviderModelsQuery, zDeleteWorkspacesCurrentModelProvidersByProviderModelsResponse, zDeleteWorkspacesCurrentRbacAccessPoliciesByPolicyIdPath, zDeleteWorkspacesCurrentRbacAccessPoliciesByPolicyIdResponse, @@ -1421,8 +1421,8 @@ export const delete6 = oc }) .input( z.object({ - body: zDeleteWorkspacesCurrentModelProvidersByProviderModelsCredentialsBody, params: zDeleteWorkspacesCurrentModelProvidersByProviderModelsCredentialsPath, + query: zDeleteWorkspacesCurrentModelProvidersByProviderModelsCredentialsQuery, }), ) .output(zDeleteWorkspacesCurrentModelProvidersByProviderModelsCredentialsResponse) @@ -1613,8 +1613,8 @@ export const delete7 = oc }) .input( z.object({ - body: zDeleteWorkspacesCurrentModelProvidersByProviderModelsBody, params: zDeleteWorkspacesCurrentModelProvidersByProviderModelsPath, + query: zDeleteWorkspacesCurrentModelProvidersByProviderModelsQuery, }), ) .output(zDeleteWorkspacesCurrentModelProvidersByProviderModelsResponse) diff --git a/packages/contracts/generated/api/console/workspaces/types.gen.ts b/packages/contracts/generated/api/console/workspaces/types.gen.ts index dabaaf28a73..b6f81460353 100644 --- a/packages/contracts/generated/api/console/workspaces/types.gen.ts +++ b/packages/contracts/generated/api/console/workspaces/types.gen.ts @@ -283,11 +283,6 @@ export type ValidationResultResponse = { result: 'error' | 'success' } -export type ParserDeleteModels = { - model: string - model_type: ModelType -} - export type ProviderModelListResponse = { data: Array } @@ -300,12 +295,6 @@ export type ParserPostModels = { model_type: ModelType } -export type ParserDeleteCredential = { - credential_id: string - model: string - model_type: ModelType -} - export type ModelCredentialResponse = { available_credentials: Array credentials: { @@ -349,6 +338,11 @@ export type ParserValidate = { model_type: ModelType } +export type ParserDeleteModels = { + model: string + model_type: ModelType +} + export type LoadBalancingCredentialPayload = { credentials: { [key: string]: unknown @@ -1446,8 +1440,6 @@ export type ModelProviderPluginSummaryResponse = { version: string } -export type ModelType = 'llm' | 'moderation' | 'rerank' | 'speech2text' | 'text-embedding' | 'tts' - export type ModelWithProviderEntityResponse = { deprecated?: boolean features?: Array | null @@ -1471,6 +1463,8 @@ export type LoadBalancingPayload = { enabled?: boolean | null } +export type ModelType = 'llm' | 'moderation' | 'rerank' | 'speech2text' | 'text-embedding' | 'tts' + export type CredentialConfiguration = { credential_id: string credential_name: string @@ -3594,11 +3588,14 @@ export type PostWorkspacesCurrentModelProvidersByProviderCredentialsValidateResp PostWorkspacesCurrentModelProvidersByProviderCredentialsValidateResponses[keyof PostWorkspacesCurrentModelProvidersByProviderCredentialsValidateResponses] export type DeleteWorkspacesCurrentModelProvidersByProviderModelsData = { - body: ParserDeleteModels + body?: never path: { provider: string } - query?: never + query: { + model: string + model_type: 'llm' | 'moderation' | 'rerank' | 'speech2text' | 'text-embedding' | 'tts' + } url: '/workspaces/current/model-providers/{provider}/models' } @@ -3642,11 +3639,15 @@ export type PostWorkspacesCurrentModelProvidersByProviderModelsResponse = PostWorkspacesCurrentModelProvidersByProviderModelsResponses[keyof PostWorkspacesCurrentModelProvidersByProviderModelsResponses] export type DeleteWorkspacesCurrentModelProvidersByProviderModelsCredentialsData = { - body: ParserDeleteCredential + body?: never path: { provider: string } - query?: never + query: { + credential_id: string + model: string + model_type: 'llm' | 'moderation' | 'rerank' | 'speech2text' | 'text-embedding' | 'tts' + } url: '/workspaces/current/model-providers/{provider}/models/credentials' } diff --git a/packages/contracts/generated/api/console/workspaces/zod.gen.ts b/packages/contracts/generated/api/console/workspaces/zod.gen.ts index 2b3115878af..485b9de83ab 100644 --- a/packages/contracts/generated/api/console/workspaces/zod.gen.ts +++ b/packages/contracts/generated/api/console/workspaces/zod.gen.ts @@ -1045,6 +1045,14 @@ export const zMemberInviteResponse = z.object({ tenant_id: z.string(), }) +/** + * LoadBalancingPayload + */ +export const zLoadBalancingPayload = z.object({ + configs: z.array(z.record(z.string(), z.unknown())).nullish(), + enabled: z.boolean().nullish(), +}) + /** * ModelType * @@ -1060,18 +1068,12 @@ export const zModelType = z.enum([ ]) /** - * ParserDeleteModels + * ParserPostModels */ -export const zParserDeleteModels = z.object({ - model: z.string(), - model_type: zModelType, -}) - -/** - * ParserDeleteCredential - */ -export const zParserDeleteCredential = z.object({ - credential_id: z.string(), +export const zParserPostModels = z.object({ + config_from: z.string().nullish(), + credential_id: z.string().nullish(), + load_balancing: zLoadBalancingPayload.nullish(), model: z.string(), model_type: zModelType, }) @@ -1115,6 +1117,14 @@ export const zParserValidate = z.object({ model_type: zModelType, }) +/** + * ParserDeleteModels + */ +export const zParserDeleteModels = z.object({ + model: z.string(), + model_type: zModelType, +}) + /** * LoadBalancingCredentialPayload */ @@ -1140,25 +1150,6 @@ export const zParserPostDefault = z.object({ model_settings: z.array(zInner), }) -/** - * LoadBalancingPayload - */ -export const zLoadBalancingPayload = z.object({ - configs: z.array(z.record(z.string(), z.unknown())).nullish(), - enabled: z.boolean().nullish(), -}) - -/** - * ParserPostModels - */ -export const zParserPostModels = z.object({ - config_from: z.string().nullish(), - credential_id: z.string().nullish(), - load_balancing: zLoadBalancingPayload.nullish(), - model: z.string(), - model_type: zModelType, -}) - /** * CredentialConfiguration * @@ -4371,12 +4362,15 @@ export const zPostWorkspacesCurrentModelProvidersByProviderCredentialsValidatePa export const zPostWorkspacesCurrentModelProvidersByProviderCredentialsValidateResponse = zValidationResultResponse -export const zDeleteWorkspacesCurrentModelProvidersByProviderModelsBody = zParserDeleteModels - export const zDeleteWorkspacesCurrentModelProvidersByProviderModelsPath = z.object({ provider: z.string(), }) +export const zDeleteWorkspacesCurrentModelProvidersByProviderModelsQuery = z.object({ + model: z.string(), + model_type: z.enum(['llm', 'moderation', 'rerank', 'speech2text', 'text-embedding', 'tts']), +}) + /** * Model deleted successfully */ @@ -4403,13 +4397,16 @@ export const zPostWorkspacesCurrentModelProvidersByProviderModelsPath = z.object */ export const zPostWorkspacesCurrentModelProvidersByProviderModelsResponse = zSimpleResultResponse -export const zDeleteWorkspacesCurrentModelProvidersByProviderModelsCredentialsBody = - zParserDeleteCredential - export const zDeleteWorkspacesCurrentModelProvidersByProviderModelsCredentialsPath = z.object({ provider: z.string(), }) +export const zDeleteWorkspacesCurrentModelProvidersByProviderModelsCredentialsQuery = z.object({ + credential_id: z.string(), + model: z.string(), + model_type: z.enum(['llm', 'moderation', 'rerank', 'speech2text', 'text-embedding', 'tts']), +}) + /** * Credential deleted successfully */ diff --git a/web/service/use-models.ts b/web/service/use-models.ts index 21e40356d48..f4864e0b167 100644 --- a/web/service/use-models.ts +++ b/web/service/use-models.ts @@ -127,7 +127,7 @@ export const useDeleteModelCredential = (provider: string) => { del<{ result: string }>( `/workspaces/current/model-providers/${provider}/models/credentials`, { - body: data, + params: data, }, ), }) @@ -137,7 +137,7 @@ export const useDeleteModel = (provider: string) => { return useMutation({ mutationFn: (data: { model: string; model_type: ModelTypeEnum }) => del<{ result: string }>(`/workspaces/current/model-providers/${provider}/models`, { - body: data, + params: data, }), }) }