Files

125 lines
3.9 KiB
Markdown

# Plan 04-02: Path and Model File Validation
**Wave:** 1
**Phase:** 4
**Requirements addressed:** MODL-02
---
## Objective
Add path existence validation and model file scanning integration so users receive immediate feedback when their selected model path or models directory is invalid.
---
## Read First
- `tauri-app/src-tauri/src/model_files.rs` — scan_models, pick_models_dir commands
- `tauri-app/src/features/runtime/api.ts` — invoke wrappers for Tauri commands
- `tauri-app/src/features/runtime/runtime-settings-form.ts` — RuntimeSettingsFormState, scanned models
- `tauri-app/src/features/runtime/types.ts` — RuntimeModelFile, RuntimePickDirResult
- `.planning/phases/04-model-source-validation/04-RESEARCH.md` — path validation patterns
---
## Action
1. **Add Tauri command wrappers** in `api.ts`:
```typescript
export interface ScannedModelsResult {
dir: string;
models: RuntimeModelFile[];
}
export async function scanModelsDir(dirPath: string): Promise<RuntimeModelFile[]> {
return await invoke<RuntimeModelFile[]>("scan_models", { dir: dirPath });
}
export async function pickModelsDirectory(): Promise<ScannedModelsResult> {
return await invoke<ScannedModelsResult>("pick_models_dir");
}
```
2. **Extend runtime-utils.ts with path validation**:
```typescript
import { scanModelsDir } from "./api";
export async function validateModelsDirectory(
path: string | null
): Promise<{ valid: boolean; modelCount: number; error: string | null }> {
if (!path) {
return { valid: false, modelCount: 0, error: "No models directory selected" };
}
try {
const models = await scanModelsDir(path);
return {
valid: true,
modelCount: models.length,
error: null
};
} catch (e) {
return {
valid: false,
modelCount: 0,
error: e instanceof Error ? e.message : String(e)
};
}
}
export async function validateModelFile(
path: string | null,
scannedModels: RuntimeModelFile[]
): Promise<{ valid: boolean; exists: boolean; error: string | null }> {
if (!path) {
return { valid: false, exists: false, error: "No model selected" };
}
const exists = scannedModels.some(m => m.path === path);
return {
valid: exists,
exists,
error: exists ? null : "Model file not found in current models directory"
};
}
```
3. **Add model scanning to runtime-settings-form.ts**:
- Add `scannedModels: RuntimeModelFile[]` to RuntimeSettingsFormState
- Add `scanModels(dir: string)` function that calls api.scanModelsDir
- Update `resolveDraftModelSelection` to use scanned models for validation
4. **Integrate into useRuntimeManager.ts**:
- Add `scannedModels` to draft state
- When `models_dir` field changes, trigger rescan
- When rescan completes, validate `model_path` against new scan results
- Update field validation state with path-specific errors
5. **Add validation display in UI components**:
- In runtime settings form, show validation message when models_dir is invalid
- Show "X models found" when scan succeeds
- Show "Model not in directory" when selected model is invalid after scan
---
## Acceptance Criteria
- [ ] `api.ts` exports `scanModelsDir(path)` and `pickModelsDirectory()`
- [ ] `runtime-utils.ts` exports async validators that check directory and file existence
- [ ] Changing `models_dir` triggers rescan and updates validation state
- [ ] Selected model is validated against scanned models list
- [ ] Invalid paths show clear error messages in the UI
- [ ] User can see "X models found" feedback after scanning
---
## Notes
- Reuse existing scan_models Rust command - no backend changes needed
- Keep validation async to support filesystem checks
- Show appropriate loading state during scan
- Handle scan errors gracefully (directory not found, permission denied)