Как написать урок
Урок это список шагов, и каждый описан как то, что должно быть на холсте после него. Приложение читает холст, чтобы понять, где человек, поэтому урок не хранит своего состояния: удалите ноду, и урок вернётся к её шагу. Как уроки выглядят для человека: Как устроены уроки. Эта страница о встроенном уроке в коде; человек делает свой урок в приложении, и такой урок переносится файлом урока: Формат файла урока.
Где что лежит
| Что | Где |
|---|---|
| Шаги | src/shared/lessons/lessons.ts (и src/shared/lessons/sets/ для групп уроков, например семейств моделей для картинок или видео). |
| Тексты | src/shared/lessons/texts.en.ts, texts.ru.ts (и sets/*.texts.*.ts), под теми же id урока и шага. |
| Почему это значение | src/shared/lessons/reasons.en.ts, reasons.ru.ts: по одному предложению на правило. |
| Какой файл | src/shared/lessons/files.ts (виды файлов моделей, FILES), fileTables.ts (таблицы поздних наборов и пары одного семейства). |
| Правила, которые соблюдает каждый урок | src/shared/lessons/schema.ts (lessonProblems). |
| Проверка холста | src/shared/lessons/engine.ts, fit.ts (есть ли в этом ComfyUI то, что нужно уроку), flow.ts. |
| Файлы уроков | src/shared/lessons/share/ (format.ts читает и проверяет файл, mine.ts «Мои уроки», authoring.ts редактор, tryLesson.ts проба с пустого холста). |
| Панель | src/renderer/components/lessons/LessonPanel.tsx, MyLessons.tsx, LessonEditor.tsx. |
| Страница вики | docs/wiki/lessons/<Name>.md и .ru.md с комментарием <!-- lesson: <id> -->. |
Шаг
{ id: 'model', roles: [node('checkpoint', 'CheckpointLoaderSimple')], fields: [field('checkpoint', 'ckpt_name', chosen)] }read: true: шаг, который только объясняет; человек читает его и идёт дальше. Знание кладите сюда, а шаги с действием держите короткими. Шаг для чтения ничего не просит; шаг, который ничего не просит, должен быть шагом для чтения.roles: ноды, которые должны быть на холсте, у каждой имя роли и классы, которые подходят.links:link(from, output, to, input, via?);viaперечисляет ноды, которые могут стоять посередине (загрузчик LoRA).fields:field(role, name, test). Проверки (FieldTestвsrc/shared/lessons/engine.ts):chosen,equals,between(сprefer, значение, которое ставит «Сделать за меня»;framesдля 4n + 1 у Wan),text(наименьшая длина и настоящие слова, метки, которые он должен содержать, латиница, без «без шляпы»),weighted(вес в промпте в диапазоне),file(файл модели нужного вида),sameFamily(LoRA или ControlNet семейства чекпойнта),sizeиaspect(размер, на котором учили модель),less,sameиdiffers(по сравнению с другим полем) иhas-trigger(слова-триггеры выбранной LoRA).why: id предложения вreasons.*.ts. «Осталось сделать» показывает его, когда значение неверное, чтобы человек понял, зачем шагу это значение, а не только что оно неверно.
Пишите собственные имена классов и портов ComfyUI. Урок, чьих классов или входов нет в ComfyUI человека, пишет «Этот урок пока не подходит к вашему ComfyUI» и называет причины, а не даёт неверных указаний.
Какой файл модели
Шаг, который спрашивал только «выбрано ли что-нибудь», засчитывал первый файл списка, каким бы он ни был. Поэтому поле, куда выбирают файл модели, называет нужный вид:
FILESвfiles.ts: вид с семействами, к которым файл может (или не может) относиться, метками, которые его имя должно содержать (high,i2v,umt5) и не должно, папкой внутриmodelsи примером имени. Файл судят по семейству из его метаданных, иначе по имени; файл, о семействе которого ничего не известно, проверяют только по меткам.- Набор может дать свои виды таблицей слов (
FileRow:has,any,not):VIDEO_FILE_KINDSвsets/video.tsиSET_FILE_KINDSвfileTables.ts.withFileTableставит каждую строку в её урок. FAMILY_PAIRSвfileTables.tsдержит LoRA или ControlNet в семействе чекпойнта, с которым они работают;withFamilyPairsставит правило на место.- О неверном файле говорится словами человека: у каждого вида есть предложение
lessons.fileKind.<вид>в каталоге.
Тексты
Для каждого урока: title, result (одна строка: что получится у человека) и для каждого id шага короткий title и
body (небольшой markdown: абзацы, список, code). Пишите {role}, чтобы назвать ноду урока: приложение подставит
имя ноды так, как его показывает библиотека этого ComfyUI. Простые слова, сначала действие, меню называется так, как
его называет меню. Слово из словаря подчёркивается точками там, где встречается впервые, поэтому объяснять его на месте
не нужно.
Порядок
LESSONSэто порядок, в котором человек их встречает, по группам (LESSON_PATH).LESSON_AFTERговорит, на графе какого урока стоит урок (показывается в списке, но не навязывается).- Уроки для взрослых (
ADULT_LESSONS) закрыты переключателем «Настройки ▸ Приватность ▸ Содержимое для взрослых (18+)» и видны одной закрытой строкой.
Тесты
tests/unit/lessonSchema.test.tsпрогоняетlessonProblemsпо каждому уроку: id, шаги, роли до использования, предложение для каждогоwhy, виды файлов, которые знает приложение.tests/unit/lessons.test.tsиlessons.<набор>.test.tsпроходят каждый урок с пустого холста до конца, делая то, что он говорит, проверяют, что каждый объясняющий шаг показан один раз и что место в уроке читается по графу (удалённая нода возвращает назад).tests/unit/lessonFit.test.tsпроверяет, когда урок подходит к ComfyUI, а когда нет;lessonImageFiles.test.tsиlessonModel.test.tsпроверяют виды файлов.tests/unit/lessonFiles.*.test.tsчитают, проверяют, хранят, экспортируют и импортируют файлы уроков.tests/unit/wiki.test.tsпроверяет, что у каждого id урока есть страница вики с пометкой<!-- lesson: <id> -->на обоих языках.tests/e2e/lessons.test.tsпроходит урок в окне.