Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
33 changes: 33 additions & 0 deletions apps/website/src/config/models.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { describe, expect, it } from 'vitest'

import generatedModels from './generated-models.json'
import { MODEL_DIRECTORIES, isModelDirectory } from './models'

describe('isModelDirectory', () => {
it('accepts every declared directory', () => {
for (const directory of MODEL_DIRECTORIES) {
expect(isModelDirectory(directory)).toBe(true)
}
})

it.for([
{ label: 'an undeclared directory', value: 'not_a_real_directory' },
{ label: 'an empty string', value: '' },
{ label: 'a near-miss', value: 'diffusion_model' },
{ label: 'an inherited Object property', value: 'toString' }
])('rejects $label', ({ value }) => {
expect(isModelDirectory(value)).toBe(false)
})
})

describe('generated model data', () => {
it('only uses directories declared in MODEL_DIRECTORIES', () => {
const undeclared = [
...new Set(generatedModels.map((model) => model.directory))
]
.filter((directory) => !isModelDirectory(directory))
.sort()

expect(undeclared).toEqual([])
})
Comment thread
coderabbitai[bot] marked this conversation as resolved.
})
55 changes: 40 additions & 15 deletions apps/website/src/config/models.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,45 @@
import generatedModels from './generated-models.json'
import { modelMetadata } from './model-metadata'

type ModelDirectory =
| 'diffusion_models'
| 'checkpoints'
| 'loras'
| 'controlnet'
| 'clip_vision'
| 'model_patches'
| 'vae'
| 'text_encoders'
| 'audio_encoders'
| 'latent_upscale_models'
| 'upscale_models'
| 'style_models'
| 'partner_nodes'
export const MODEL_DIRECTORIES = [
'diffusion_models',
'checkpoints',
'loras',
'controlnet',
'clip_vision',
'model_patches',
'vae',
'text_encoders',
'audio_encoders',
'latent_upscale_models',
'upscale_models',
'style_models',
'partner_nodes',
'background_removal',
'detection',
'frame_interpolation',
'geometry_estimation',
'optical_flow'
] as const

export type ModelDirectory = (typeof MODEL_DIRECTORIES)[number]

const MODEL_DIRECTORY_SET: ReadonlySet<string> = new Set(MODEL_DIRECTORIES)

export function isModelDirectory(value: string): value is ModelDirectory {
return MODEL_DIRECTORY_SET.has(value)
}

function toModelDirectory(value: string, slug: string): ModelDirectory {
if (!isModelDirectory(value)) {
throw new Error(
`Unknown model directory ${JSON.stringify(value)} for model "${slug}". ` +
`Add it to MODEL_DIRECTORIES in src/config/models.ts and give it a ` +
`label and description on the supported-models pages.`
)
}
return value
}

interface Model {
readonly slug: string
Expand Down Expand Up @@ -48,7 +73,7 @@ export const models: readonly Model[] = (
...(m.canonicalSlug ? { canonicalSlug: m.canonicalSlug } : {}),
name: m.name,
displayName: m.displayName,
directory: m.directory as ModelDirectory,
directory: toModelDirectory(m.directory, m.slug),
huggingFaceUrl: m.huggingFaceUrl,
...(m.docsUrl ? { docsUrl: m.docsUrl } : {}),
...(m.thumbnailUrl ? { thumbnailUrl: m.thumbnailUrl } : {}),
Expand Down
12 changes: 9 additions & 3 deletions apps/website/src/pages/p/supported-models/[slug].astro
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import type { GetStaticPaths } from 'astro'
import BaseLayout from '../../../layouts/BaseLayout.astro'
import ModelHeroSection from '../../../components/models/ModelHeroSection.vue'
import type { ModelDirectory } from '../../../config/models'
import { models, getModelBySlug } from '../../../config/models'
import { t } from '../../../i18n/translations'
import type { JsonLdNode } from '../../../utils/jsonLd'
Expand All @@ -27,7 +28,7 @@ if (model.canonicalSlug) {

const { displayName } = model

const dirDescriptions: Record<string, string> = {
const dirDescriptions: Record<ModelDirectory, string> = {
diffusion_models: 'a diffusion model that generates images or video from text and image prompts',
checkpoints: 'an all-in-one checkpoint model that bundles a diffusion model, text encoder, and VAE',
loras: 'a LoRA (Low-Rank Adaptation) that fine-tunes an existing model for a specific style or subject',
Expand All @@ -40,10 +41,15 @@ const dirDescriptions: Record<string, string> = {
latent_upscale_models: 'a latent upscale model that refines latents at higher resolution before decoding',
style_models: 'a style model that transfers artistic style onto generated images',
model_patches: 'a model patch that modifies or extends the behavior of an existing base model',
partner_nodes: 'a cloud API model accessible through ComfyUI partner nodes without local hardware requirements'
partner_nodes: 'a cloud API model accessible through ComfyUI partner nodes without local hardware requirements',
background_removal: 'a background removal model that separates subjects from their background',
detection: 'a detection model that locates objects, faces, or regions within an image',
frame_interpolation: 'a frame interpolation model that generates intermediate frames to smooth or slow down video',
geometry_estimation: 'a geometry estimation model that infers depth, normals, or 3D structure from images',
optical_flow: 'an optical flow model that estimates per-pixel motion between video frames'
}

const dirDesc = dirDescriptions[model.directory] ?? 'an AI model'
const dirDesc = dirDescriptions[model.directory]
const whatIsDescription = `${displayName} is ${dirDesc}. You can run it locally in ComfyUI with full control over every parameter, or access it through Comfy Cloud. ComfyUI's node-based workflow editor lets you connect ${displayName} with ControlNets, LoRAs, upscalers, and custom nodes to build any pipeline you need. There are ${model.workflowCount} community workflow templates using ${displayName} on Comfy Workflows, ready to load and customize.`

const pageTitle = `${displayName} in ComfyUI`
Expand Down
12 changes: 9 additions & 3 deletions apps/website/src/pages/p/supported-models/index.astro
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
import BaseLayout from '../../../layouts/BaseLayout.astro'
import type { ModelDirectory } from '../../../config/models'
import { models } from '../../../config/models'
import { t } from '../../../i18n/translations'
import {
Expand All @@ -25,7 +26,7 @@ const modelList = itemListNode(
})),
)

const dirLabel: Record<string, string> = {
const dirLabel: Record<ModelDirectory, string> = {
diffusion_models: 'Diffusion',
checkpoints: 'Checkpoint',
loras: 'LoRA',
Expand All @@ -38,7 +39,12 @@ const dirLabel: Record<string, string> = {
latent_upscale_models: 'Latent Upscale',
upscale_models: 'Upscale',
style_models: 'Style',
partner_nodes: 'Partner Node'
partner_nodes: 'Partner Node',
background_removal: 'Background Removal',
detection: 'Detection',
frame_interpolation: 'Frame Interpolation',
geometry_estimation: 'Geometry Estimation',
optical_flow: 'Optical Flow'
}
---

Expand Down Expand Up @@ -80,7 +86,7 @@ const dirLabel: Record<string, string> = {
{model.displayName}
</span>
<span class="shrink-0 rounded-full bg-white/10 px-2 py-0.5 text-xs font-medium text-primary-comfy-canvas/70">
{dirLabel[model.directory] ?? model.directory}
{dirLabel[model.directory]}
</span>
</div>
<p class="mt-auto text-xs text-primary-comfy-canvas/50">
Expand Down
Loading