Commit 7d762f1
committed
Resolves #7283 (FR-2832)
## Summary
When creating a deployment revision, the WebUI was sending the literal string `"model-definition.yaml"` as `modelMountConfig.definitionPath`. This forced the backend to look for that exact filename and broke model folders that use `model-definition.yml`. After this change, the frontend **omits** `definitionPath` when the user has not explicitly customized the filename, so the backend can fall back to its own resolution logic and accept either extension.
## Changes (single file: `react/src/components/DeploymentAddRevisionModal.tsx`)
1. **`initialValues`** — dropped the `definitionPath: 'model-definition.yaml'` seed. The form field now starts empty; the existing `placeholder="model-definition.yaml"` on the Input still hints the default.
2. **Submit handler** — for the non-custom / non-command-mode branch, **omit** `definitionPath` from the `modelMountConfig` payload when the trimmed user input is empty. The `isCustom && isCommandMode` branch still sends the literal `'model-definition.yaml'` because we generate that file ourselves before submission.
3. **Edit-mode pre-population** — dropped the `?? 'model-definition.yaml'` fallback so when an existing revision had `definitionPath: null/empty`, the form leaves the field empty and a re-submit continues to omit the field.
4. **Required rule removed** — the `definitionPath` Form.Item no longer has `rules={[{ required: true }]}` so users can submit an empty value (which is now the explicit "use server default" signal).
## Backend dependency
> **Requires backend to accept an absent / nullable `modelMountConfig.definitionPath` and resolve both `.yaml`/`.yml` server-side.**
The current GraphQL schema declares `ModelMountConfigInput.definitionPath: String!` (non-null). The submit handler uses a conditional spread to omit the field when not customized; this works at runtime because most GraphQL backends treat an absent input field as "use default." A small `as { definitionPath: string }` cast on the spread is needed to satisfy the current strict type — flagged with `TODO(needs-backend): FR-2832`. The backend must relax the schema field to nullable and update the resolver to try `model-definition.yaml` then `model-definition.yml` (or vice versa) when this field is absent.
## Out of scope
Other call sites of `'model-definition.yaml'` (`ServiceLauncherPageContent.tsx`, `LegacyModelTryContentButton.tsx`, `DeploymentLauncherPageContent.tsx`, `VFolderTextFileEditorModal.tsx`, `DeploymentLauncherPage.tsx`) are intentionally untouched per the issue triage. A follow-up issue tracks applying the same pattern to the launcher components.
## Verification
`bash scripts/verify.sh`:
- Relay: PASS
- Lint: PASS
- Format: PASS
- TypeScript: only **pre-existing** errors remain (`packages/backend.ai-client/src/client.ts`, `src/components/DeleteForeverVFolderModalV2.tsx`) — confirmed identical against `main` before this change.
## Test plan
- [ ] Create a new deployment revision **without** typing anything in the "Model Definition Path" field → mutation payload should **omit** `modelMountConfig.definitionPath`.
- [ ] Create a new deployment revision with **whitespace only** (e.g. `" "`) → mutation payload should **omit** `modelMountConfig.definitionPath` (whitespace is trimmed).
- [ ] Create a new deployment revision **with** an explicit value (e.g. `custom.yaml`) → mutation payload should send `modelMountConfig.definitionPath: "custom.yaml"`.
- [ ] Edit an existing revision whose previous `definitionPath` is empty/null → form field stays empty, re-submit keeps omitting the field.
- [ ] Edit an existing revision whose previous `definitionPath` is `"model-definition.yaml"` → form field shows that value, re-submit sends it back unchanged.
- [ ] Custom variant + command mode → literal `"model-definition.yaml"` is still sent (since we generate that file ourselves).
- [ ] Once backend lands its companion change, verify that a model folder containing only `model-definition.yml` deploys successfully via this UI.
## Review feedback applied
- **Replaced `as string` cast with conditional spread.** The submit handler no longer lies to TypeScript by asserting `null` is a `string`. Instead, the field is omitted entirely from the input object when the user has not customized it (`...(resolvedDefinitionPath ? { definitionPath: resolvedDefinitionPath } : {})`). A narrower `as { definitionPath: string }` cast on the spread expression remains until the schema is relaxed to nullable.
- **Trim whitespace before truthiness check.** `values.definitionPath?.trim()` is computed once into `trimmedDefinitionPath`, so whitespace-only inputs (`" "`) collapse to "not customized" and the backend default applies.
- **Comment consolidation.** The two multi-paragraph FR-2832 comments now share a single `TODO(needs-backend)` block at the spread site; the resolver site has a one-line back-reference.
1 parent 004104b commit 7d762f1
2 files changed
Lines changed: 37 additions & 21 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9235 | 9235 | | |
9236 | 9236 | | |
9237 | 9237 | | |
9238 | | - | |
| 9238 | + | |
9239 | 9239 | | |
9240 | 9240 | | |
9241 | | - | |
| 9241 | + | |
9242 | 9242 | | |
9243 | 9243 | | |
9244 | 9244 | | |
| |||
9264 | 9264 | | |
9265 | 9265 | | |
9266 | 9266 | | |
9267 | | - | |
| 9267 | + | |
9268 | 9268 | | |
9269 | 9269 | | |
9270 | 9270 | | |
| |||
9431 | 9431 | | |
9432 | 9432 | | |
9433 | 9433 | | |
9434 | | - | |
| 9434 | + | |
9435 | 9435 | | |
9436 | 9436 | | |
9437 | | - | |
| 9437 | + | |
9438 | 9438 | | |
9439 | 9439 | | |
9440 | | - | |
| 9440 | + | |
9441 | 9441 | | |
9442 | 9442 | | |
9443 | | - | |
| 9443 | + | |
9444 | 9444 | | |
9445 | 9445 | | |
9446 | | - | |
| 9446 | + | |
9447 | 9447 | | |
9448 | 9448 | | |
9449 | | - | |
| 9449 | + | |
9450 | 9450 | | |
9451 | 9451 | | |
9452 | 9452 | | |
| |||
9558 | 9558 | | |
9559 | 9559 | | |
9560 | 9560 | | |
9561 | | - | |
| 9561 | + | |
9562 | 9562 | | |
9563 | 9563 | | |
9564 | 9564 | | |
| |||
9808 | 9808 | | |
9809 | 9809 | | |
9810 | 9810 | | |
9811 | | - | |
| 9811 | + | |
9812 | 9812 | | |
9813 | 9813 | | |
9814 | 9814 | | |
9815 | 9815 | | |
9816 | 9816 | | |
9817 | | - | |
| 9817 | + | |
9818 | 9818 | | |
9819 | | - | |
9820 | | - | |
| 9819 | + | |
| 9820 | + | |
9821 | 9821 | | |
9822 | 9822 | | |
9823 | 9823 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
502 | 502 | | |
503 | 503 | | |
504 | 504 | | |
505 | | - | |
506 | | - | |
| 505 | + | |
| 506 | + | |
| 507 | + | |
| 508 | + | |
| 509 | + | |
507 | 510 | | |
508 | 511 | | |
509 | 512 | | |
| |||
771 | 774 | | |
772 | 775 | | |
773 | 776 | | |
774 | | - | |
| 777 | + | |
| 778 | + | |
| 779 | + | |
| 780 | + | |
| 781 | + | |
| 782 | + | |
775 | 783 | | |
776 | 784 | | |
777 | | - | |
| 785 | + | |
778 | 786 | | |
779 | 787 | | |
780 | 788 | | |
| |||
804 | 812 | | |
805 | 813 | | |
806 | 814 | | |
807 | | - | |
| 815 | + | |
| 816 | + | |
| 817 | + | |
| 818 | + | |
| 819 | + | |
| 820 | + | |
808 | 821 | | |
809 | 822 | | |
810 | 823 | | |
| |||
888 | 901 | | |
889 | 902 | | |
890 | 903 | | |
891 | | - | |
| 904 | + | |
| 905 | + | |
| 906 | + | |
| 907 | + | |
| 908 | + | |
892 | 909 | | |
893 | 910 | | |
894 | 911 | | |
| |||
1083 | 1100 | | |
1084 | 1101 | | |
1085 | 1102 | | |
1086 | | - | |
1087 | 1103 | | |
1088 | 1104 | | |
1089 | 1105 | | |
| |||
0 commit comments