Files
ForgeLM/.planning/phases/04-model-source-validation/04-02-PLAN.md
T

3.9 KiB

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:

    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:

    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)