Add local model asset catalog
This commit is contained in:
@@ -5,15 +5,19 @@ import type {
|
||||
DetectionRead,
|
||||
DetectionRunRead,
|
||||
DetectionRunResponse,
|
||||
ModelAssetRead,
|
||||
YoloPreflightResponse,
|
||||
} from '../../types'
|
||||
|
||||
interface DetectionLabProps {
|
||||
detectionModels: DetectionModelCapability[]
|
||||
modelAssets: ModelAssetRead[]
|
||||
loadingDetectionModels: boolean
|
||||
detectionModelError: string | null
|
||||
modelAssetError: string | null
|
||||
selectedDetectionDatasetId: string
|
||||
selectedDetectionModelId: string
|
||||
selectedModelAssetId: string
|
||||
detectionTileManifestPath: string
|
||||
detectionConfidenceThreshold: number
|
||||
runningDetection: boolean
|
||||
@@ -39,6 +43,7 @@ interface DetectionLabProps {
|
||||
onRefreshYoloPreflight: () => void
|
||||
onSelectDataset: (datasetId: string) => void
|
||||
onSelectModel: (modelId: string) => void
|
||||
onSelectModelAsset: (modelAssetId: string) => void
|
||||
onSetConfidenceThreshold: (value: number) => void
|
||||
onSetTileManifestPath: (value: string) => void
|
||||
onRunDetection: () => void
|
||||
@@ -53,10 +58,13 @@ interface DetectionLabProps {
|
||||
|
||||
export function DetectionLab({
|
||||
detectionModels,
|
||||
modelAssets,
|
||||
loadingDetectionModels,
|
||||
detectionModelError,
|
||||
modelAssetError,
|
||||
selectedDetectionDatasetId,
|
||||
selectedDetectionModelId,
|
||||
selectedModelAssetId,
|
||||
detectionTileManifestPath,
|
||||
detectionConfidenceThreshold,
|
||||
runningDetection,
|
||||
@@ -82,6 +90,7 @@ export function DetectionLab({
|
||||
onRefreshYoloPreflight,
|
||||
onSelectDataset,
|
||||
onSelectModel,
|
||||
onSelectModelAsset,
|
||||
onSetConfidenceThreshold,
|
||||
onSetTileManifestPath,
|
||||
onRunDetection,
|
||||
@@ -94,6 +103,7 @@ export function DetectionLab({
|
||||
onRunQa,
|
||||
}: DetectionLabProps): JSX.Element {
|
||||
const selectedDetectionModel = detectionModels.find((model) => model.model_id === selectedDetectionModelId) ?? null
|
||||
const selectedModelAsset = modelAssets.find((asset) => asset.model_asset_id === selectedModelAssetId) ?? null
|
||||
const detectionRequiresTileManifest = selectedDetectionModelId === 'yolo-configured'
|
||||
const detectionHasDataset = selectedDetectionDatasetId.length > 0
|
||||
const detectionHasModel = selectedDetectionModel !== null
|
||||
@@ -149,6 +159,12 @@ export function DetectionLab({
|
||||
<p>{detectionModelError}</p>
|
||||
</div>
|
||||
) : null}
|
||||
{modelAssetError ? (
|
||||
<div className="result-state result-state-error">
|
||||
<strong>Local model assets unavailable.</strong>
|
||||
<p>{modelAssetError}</p>
|
||||
</div>
|
||||
) : null}
|
||||
{detectionModels.length === 0 && !loadingDetectionModels ? (
|
||||
<div className="result-state result-state-empty">
|
||||
<strong>No detection models reported by backend.</strong>
|
||||
@@ -173,6 +189,47 @@ export function DetectionLab({
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{selectedDetectionModelId === 'yolo-configured' ? (
|
||||
<div className="ai-lab-model-surface" aria-label="Local model asset selection">
|
||||
<div className="ai-lab-section-header">
|
||||
<div>
|
||||
<h3>Local model assets</h3>
|
||||
<p>Select an existing model file mounted into the backend runtime. GeoIntel does not download model weights.</p>
|
||||
</div>
|
||||
<span className={selectedModelAsset ? 'status-badge status-badge-ready' : 'status-badge'}>
|
||||
{selectedModelAsset ? 'asset selected' : 'using configured path'}
|
||||
</span>
|
||||
</div>
|
||||
<label>
|
||||
Local model file
|
||||
<select value={selectedModelAssetId} onChange={(event) => onSelectModelAsset(event.target.value)}>
|
||||
<option value="">Use configured YOLO_MODEL_PATH</option>
|
||||
{modelAssets.map((asset) => (
|
||||
<option key={asset.model_asset_id} value={asset.model_asset_id}>
|
||||
{asset.display_name} {asset.active ? '(active)' : ''}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</label>
|
||||
{modelAssets.length === 0 && !loadingDetectionModels ? (
|
||||
<div className="result-state result-state-empty">
|
||||
<strong>No local model assets found.</strong>
|
||||
<p>Mount model files into the backend model directory or continue with the configured YOLO_MODEL_PATH.</p>
|
||||
</div>
|
||||
) : null}
|
||||
{selectedModelAsset ? (
|
||||
<div className="result-summary-card">
|
||||
<p>File: {selectedModelAsset.filename}</p>
|
||||
<p>Status: {selectedModelAsset.status}</p>
|
||||
<p>Size: {formatModelAssetSize(selectedModelAsset.size_bytes)}</p>
|
||||
<p>SHA-256: {selectedModelAsset.sha256.slice(0, 12)}</p>
|
||||
<p>Path: {selectedModelAsset.model_path}</p>
|
||||
<p>{selectedModelAsset.limitation_message}</p>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
<div className="ai-lab-model-surface" aria-label="YOLO runtime preflight">
|
||||
<div className="ai-lab-section-header">
|
||||
<div>
|
||||
@@ -238,6 +295,7 @@ export function DetectionLab({
|
||||
<span>cuda_available: {String(yoloPreflight.runtime.cuda_available ?? 'unknown')}</span>
|
||||
<span>YOLO_CONFIG_DIR: {yoloPreflight.runtime.yolo_config_dir ?? 'n/a'}</span>
|
||||
<span>model directory: {yoloPreflight.runtime.model_directory ?? 'n/a'}</span>
|
||||
<span>model_asset_id: {yoloPreflight.model_asset_id ?? 'n/a'}</span>
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
@@ -486,3 +544,13 @@ export function DetectionLab({
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
function formatModelAssetSize(sizeBytes: number): string {
|
||||
if (sizeBytes >= 1024 * 1024) {
|
||||
return `${(sizeBytes / (1024 * 1024)).toFixed(1)} MB`
|
||||
}
|
||||
if (sizeBytes >= 1024) {
|
||||
return `${(sizeBytes / 1024).toFixed(1)} KB`
|
||||
}
|
||||
return `${sizeBytes} B`
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user