Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions web-app/src/containers/ModelInfoHoverCard.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import {

Check warning on line 1 in web-app/src/containers/ModelInfoHoverCard.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

1 line is not covered with tests
HoverCard,
HoverCardContent,
HoverCardTrigger,
} from '@/components/ui/hover-card'
import { IconInfoCircle } from '@tabler/icons-react'

Check warning on line 6 in web-app/src/containers/ModelInfoHoverCard.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

6 line is not covered with tests
import { CatalogModel, ModelQuant } from '@/services/models'

interface ModelInfoHoverCardProps {
Expand All @@ -16,59 +16,59 @@
children?: React.ReactNode
}

export const ModelInfoHoverCard = ({
model,
variant,
isDefaultVariant,
defaultModelQuantizations,
modelSupportStatus,
onCheckModelSupport,
children,
}: ModelInfoHoverCardProps) => {
const displayVariant =
variant ||
model.quants.find((m) =>
defaultModelQuantizations.some((e) =>
m.model_id.toLowerCase().includes(e)
)
) ||
model.quants?.[0]

Check warning on line 35 in web-app/src/containers/ModelInfoHoverCard.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

19-35 lines are not covered with tests

const handleMouseEnter = () => {
if (displayVariant) {
onCheckModelSupport(displayVariant)
}
}

Check warning on line 41 in web-app/src/containers/ModelInfoHoverCard.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

37-41 lines are not covered with tests

const getCompatibilityStatus = () => {
const status = displayVariant
? modelSupportStatus[displayVariant.model_id]
: null

Check warning on line 46 in web-app/src/containers/ModelInfoHoverCard.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

43-46 lines are not covered with tests

if (status === 'LOADING') {
return (
<div className="flex items-start gap-2">
<div className="size-2 shrink-0 border border-main-view-fg/50 border-t-transparent rounded-full animate-spin mt-1"></div>
<span className="text-main-view-fg/50">Checking...</span>
</div>

Check warning on line 53 in web-app/src/containers/ModelInfoHoverCard.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

48-53 lines are not covered with tests
)
} else if (status === 'GREEN') {
return (
<div className="flex items-start gap-2">
<div className="size-2 shrink-0 bg-green-500 rounded-full mt-1"></div>
<span className="text-green-500 font-medium">

Check warning on line 59 in web-app/src/containers/ModelInfoHoverCard.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

55-59 lines are not covered with tests
Recommended for your device
</span>
</div>

Check warning on line 62 in web-app/src/containers/ModelInfoHoverCard.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

61-62 lines are not covered with tests
)
} else if (status === 'YELLOW') {
return (
<div className="flex items-start gap-2">
<div className="size-2 shrink-0 bg-yellow-500 rounded-full mt-1"></div>
<span className="text-yellow-500 font-medium">

Check warning on line 68 in web-app/src/containers/ModelInfoHoverCard.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

64-68 lines are not covered with tests
May be slow on your device
</span>
</div>

Check warning on line 71 in web-app/src/containers/ModelInfoHoverCard.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

70-71 lines are not covered with tests
)
} else if (status === 'RED') {
return (
Expand All @@ -79,6 +79,15 @@
</span>
</div>
)
} else if (status === 'GREY') {
return (
<div className="flex items-start gap-2">
<div className="size-2 shrink-0 bg-neutral-500 rounded-full mt-1"></div>
<span className="text-neutral-500 font-medium">
Unable to determine model compatibility with your current device
</span>
</div>
)
} else {
return (
<div className="flex items-start gap-2">
Expand Down Expand Up @@ -121,9 +130,7 @@
<>
<div>
<span className="text-main-view-fg/50 block">
{isDefaultVariant
? 'Maybe Default Quantization'
: 'Quantization'}
{isDefaultVariant ? 'Default Quantization' : 'Quantization'}
</span>
<span className="text-main-view-fg font-medium mt-1 inline-block">
{variant?.model_id.split('-').pop()?.toUpperCase() || 'N/A'}
Expand Down
4 changes: 2 additions & 2 deletions web-app/src/containers/ModelSupportStatus.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ export const ModelSupportStatus = ({
className,
}: ModelSupportStatusProps) => {
const [modelSupportStatus, setModelSupportStatus] = useState<
'RED' | 'YELLOW' | 'GREEN' | 'LOADING' | null
'RED' | 'YELLOW' | 'GREEN' | 'LOADING' | null | 'GREY'
>(null)

// Helper function to check model support with proper path resolution
const checkModelSupportWithPath = useCallback(
async (
id: string,
ctxSize: number
): Promise<'RED' | 'YELLOW' | 'GREEN' | null> => {
): Promise<'RED' | 'YELLOW' | 'GREEN' | 'GREY' | null> => {
try {
const janDataFolder = await getJanDataFolderPath()

Expand Down
2 changes: 1 addition & 1 deletion web-app/src/routes/hub/$modelId.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ function HubModelDetail() {

// State for model support status
const [modelSupportStatus, setModelSupportStatus] = useState<
Record<string, 'RED' | 'YELLOW' | 'GREEN' | 'LOADING'>
Record<string, 'RED' | 'YELLOW' | 'GREEN' | 'LOADING' | 'GREY'>
>({})

useEffect(() => {
Expand Down
4 changes: 2 additions & 2 deletions web-app/src/services/__tests__/models.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -924,7 +924,7 @@ describe('models service', () => {
expect(result).toBe('YELLOW') // Should use fallback
})

it('should return RED when there is an error', async () => {
it('should return GREY when there is an error', async () => {
const mockEngineWithError = {
...mockEngine,
isModelSupported: vi.fn().mockRejectedValue(new Error('Test error')),
Expand All @@ -934,7 +934,7 @@ describe('models service', () => {

const result = await isModelSupported('/path/to/model.gguf')

expect(result).toBe('RED')
expect(result).toBe('GREY')
})
})
})
4 changes: 2 additions & 2 deletions web-app/src/services/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,7 @@ export const checkMmprojExists = async (modelId: string): Promise<boolean> => {
export const isModelSupported = async (
modelPath: string,
ctxSize?: number
): Promise<'RED' | 'YELLOW' | 'GREEN'> => {
): Promise<'RED' | 'YELLOW' | 'GREEN' | 'GREY'> => {
try {
const engine = getEngine('llamacpp') as AIEngine & {
isModelSupported?: (
Expand All @@ -608,6 +608,6 @@ export const isModelSupported = async (
return 'YELLOW' // Conservative fallback
} catch (error) {
console.error(`Error checking model support for ${modelPath}:`, error)
return 'RED' // Error state, assume not supported
return 'GREY' // Error state, assume not supported
}
}
Loading