dist-mcp / helpers / imageModelMeta.js
dist-mcp / helpers / imageModelMeta.js
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.resolveImageModelInfoFromModelUsed = resolveImageModelInfoFromModelUsed;
exports.formatImageModelForToolDisplay = formatImageModelForToolDisplay;
const node_path_1 = __importDefault(require("node:path"));
const modelOverlays_js_1 = require("../services/modelOverlays.js");
const customConfigsLoader_js_1 = require("../services/customConfigsLoader.js");
const core_bundle_mjs_1 = require("../core-bundle.mjs");
function normalizeModelFilenameForLookup(value) {
return node_path_1.default.basename(value).trim().toLowerCase();
}
function resolveModelFamilyFromModelBasename(modelBasename) {
const normalized = normalizeModelFilenameForLookup(modelBasename);
if (!normalized)
return "unknown";
// 1) Primary: overlay param files (z-image/qwen-image/flux/ltx)
for (const family of ["z-image", "qwen-image", "flux", "ltx"]) {
for (const mode of ["txt2img", "img2img", "edit", "txt2vid", "img2vid"]) {
const m = (0, modelOverlays_js_1.getModelFilename)(family, mode);
if (typeof m !== "string")
continue;
if (normalizeModelFilenameForLookup(m) === normalized)
return family;
}
}
// 2) Secondary: capabilities.ts (older / inactive models)
for (const family of ["z-image", "qwen-image", "flux", "ltx"]) {
const key = core_bundle_mjs_1.MODEL_PRESET_TO_CAPABILITY_KEY?.[family];
if (typeof key !== "string")
continue;
const cap = core_bundle_mjs_1.IMAGE_MODEL_CAPABILITY_MAP?.[key];
const filenames = cap?.modelFilenames;
if (!Array.isArray(filenames))
continue;
for (const f of filenames) {
if (typeof f !== "string")
continue;
if (normalizeModelFilenameForLookup(f) === normalized)
return family;
}
}
// 3) Tertiary: custom_configs.json presets that explicitly set `model`.
// Only treat these as "custom" when the model file is otherwise unknown.
const customLabels = (0, customConfigsLoader_js_1.getCustomPresetLabelsUsingModelFilename)(normalized);
if (customLabels.length > 0)
return "custom";
return "unknown";
}
function modeToUserMode(mode) {
switch (mode) {
case "txt2img": return "text2image";
case "img2img": return "image2image";
case "txt2vid": return "text2video";
case "img2vid": return "image2video";
case "edit": return "edit";
}
}
function userModeToMode(mode) {
switch (mode) {
case "text2image": return "txt2img";
case "image2image": return "img2img";
case "text2video": return "txt2vid";
case "image2video": return "img2vid";
case "edit": return "edit";
}
}
function getDefaultModelForMode(mode) {
const raw = mode === "txt2img"
? core_bundle_mjs_1.defaultParams?.model
: mode === "img2img"
? core_bundle_mjs_1.defaultParamsImg2Img?.model
: mode === "txt2vid"
? core_bundle_mjs_1.defaultParamsText2Video?.model
: mode === "img2vid"
? core_bundle_mjs_1.defaultParamsImage2Video?.model
: core_bundle_mjs_1.defaultParamsEdit?.model;
return typeof raw === "string" ? raw : "";
}
function computeEffectiveModelFilename(modelId, mode) {
const base = getDefaultModelForMode(mode);
const baseBase = normalizeModelFilenameForLookup(base);
const overlay = (0, customConfigsLoader_js_1.getEffectiveOverlay)(modelId, mode);
const overlayModel = overlay.params?.model;
const chosen = typeof overlayModel === "string" && overlayModel.trim()
? overlayModel
: base;
const chosenBase = normalizeModelFilenameForLookup(chosen);
return {
modelBasename: chosenBase || baseBase,
overlaySource: overlay.source,
presetName: overlay.presetName,
};
}
function scorePresetForDisplay(p) {
// Prefer the thing the user can actually pass as `model=`.
// If a custom config overrides "auto", that should win.
const isAuto = p.modelId === "auto";
const isCustomConfig = p.overlaySource === "custom";
const isOverlay = p.overlaySource === "modelOverlay";
// Higher is better.
return (isCustomConfig ? 100 : isOverlay ? 50 : 0) + (isAuto ? 10 : 0);
}
function pickDisplayPreset(presets) {
if (!presets.length)
return undefined;
return [...presets].sort((a, b) => scorePresetForDisplay(b) - scorePresetForDisplay(a))[0];
}
/**
* Resolve a Draw Things backend model filename (.ckpt) to the set of presets
* (mode + modelId) that would result in this model file being used.
*
* IMPORTANT: Display-only. Do not use for input validation.
*/
function resolveImageModelInfoFromModelUsed(modelFilenameOrPath, opts) {
if (typeof modelFilenameOrPath !== "string")
return null;
const base = node_path_1.default.basename(modelFilenameOrPath).trim();
if (!base)
return null;
const normalized = normalizeModelFilenameForLookup(base);
const modes = opts?.mode
? [userModeToMode(opts.mode)]
: ["txt2img", "img2img", "edit", "txt2vid", "img2vid"];
const presets = [];
for (const mode of modes) {
for (const modelId of modelOverlays_js_1.MODEL_IDS) {
const eff = computeEffectiveModelFilename(modelId, mode);
if (!eff.modelBasename)
continue;
if (eff.modelBasename !== normalized)
continue;
// Skip "default" fallback matches for any modelId other than "auto":
// those modelIds have no overlay for this mode and silently fall through
// to the mode default — not a meaningful/intentional preset match.
if (eff.overlaySource === "default" && modelId !== "auto")
continue;
const userMode = modeToUserMode(mode);
const preset = `${userMode}.${modelId}`;
presets.push({
mode: userMode,
modelId,
preset,
overlaySource: eff.overlaySource,
...(eff.presetName ? { customConfig: eff.presetName } : {}),
});
}
}
const customConfigLabels = (0, customConfigsLoader_js_1.getCustomPresetLabelsUsingModelFilename)(base);
const chosen = pickDisplayPreset(presets);
const modelFamily = resolveModelFamilyFromModelBasename(base);
const display = modelFamily && modelFamily !== "unknown" ? `${modelFamily} (${base})` : base;
return {
modelUsedBasename: base,
display,
...(chosen ? { chosen_model_id: chosen.modelId } : {}),
...(modelFamily ? { model_family: modelFamily } : {}),
presets,
...(customConfigLabels.length ? { custom_config_labels: customConfigLabels } : {}),
};
}
function formatImageModelForToolDisplay(modelFilenameOrPath) {
const info = resolveImageModelInfoFromModelUsed(modelFilenameOrPath);
return info?.display ?? "";
}
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.resolveImageModelInfoFromModelUsed = resolveImageModelInfoFromModelUsed;
exports.formatImageModelForToolDisplay = formatImageModelForToolDisplay;
const node_path_1 = __importDefault(require("node:path"));
const modelOverlays_js_1 = require("../services/modelOverlays.js");
const customConfigsLoader_js_1 = require("../services/customConfigsLoader.js");
const core_bundle_mjs_1 = require("../core-bundle.mjs");
function normalizeModelFilenameForLookup(value) {
return node_path_1.default.basename(value).trim().toLowerCase();
}
function resolveModelFamilyFromModelBasename(modelBasename) {
const normalized = normalizeModelFilenameForLookup(modelBasename);
if (!normalized)
return "unknown";
// 1) Primary: overlay param files (z-image/qwen-image/flux/ltx)
for (const family of ["z-image", "qwen-image", "flux", "ltx"]) {
for (const mode of ["txt2img", "img2img", "edit", "txt2vid", "img2vid"]) {
const m = (0, modelOverlays_js_1.getModelFilename)(family, mode);
if (typeof m !== "string")
continue;
if (normalizeModelFilenameForLookup(m) === normalized)
return family;
}
}
// 2) Secondary: capabilities.ts (older / inactive models)
for (const family of ["z-image", "qwen-image", "flux", "ltx"]) {
const key = core_bundle_mjs_1.MODEL_PRESET_TO_CAPABILITY_KEY?.[family];
if (typeof key !== "string")
continue;
const cap = core_bundle_mjs_1.IMAGE_MODEL_CAPABILITY_MAP?.[key];
const filenames = cap?.modelFilenames;
if (!Array.isArray(filenames))
continue;
for (const f of filenames) {
if (typeof f !== "string")
continue;
if (normalizeModelFilenameForLookup(f) === normalized)
return family;
}
}
// 3) Tertiary: custom_configs.json presets that explicitly set `model`.
// Only treat these as "custom" when the model file is otherwise unknown.
const customLabels = (0, customConfigsLoader_js_1.getCustomPresetLabelsUsingModelFilename)(normalized);
if (customLabels.length > 0)
return "custom";
return "unknown";
}
function modeToUserMode(mode) {
switch (mode) {
case "txt2img": return "text2image";
case "img2img": return "image2image";
case "txt2vid": return "text2video";
case "img2vid": return "image2video";
case "edit": return "edit";
}
}
function userModeToMode(mode) {
switch (mode) {
case "text2image": return "txt2img";
case "image2image": return "img2img";
case "text2video": return "txt2vid";
case "image2video": return "img2vid";
case "edit": return "edit";
}
}
function getDefaultModelForMode(mode) {
const raw = mode === "txt2img"
? core_bundle_mjs_1.defaultParams?.model
: mode === "img2img"
? core_bundle_mjs_1.defaultParamsImg2Img?.model
: mode === "txt2vid"
? core_bundle_mjs_1.defaultParamsText2Video?.model
: mode === "img2vid"
? core_bundle_mjs_1.defaultParamsImage2Video?.model
: core_bundle_mjs_1.defaultParamsEdit?.model;
return typeof raw === "string" ? raw : "";
}
function computeEffectiveModelFilename(modelId, mode) {
const base = getDefaultModelForMode(mode);
const baseBase = normalizeModelFilenameForLookup(base);
const overlay = (0, customConfigsLoader_js_1.getEffectiveOverlay)(modelId, mode);
const overlayModel = overlay.params?.model;
const chosen = typeof overlayModel === "string" && overlayModel.trim()
? overlayModel
: base;
const chosenBase = normalizeModelFilenameForLookup(chosen);
return {
modelBasename: chosenBase || baseBase,
overlaySource: overlay.source,
presetName: overlay.presetName,
};
}
function scorePresetForDisplay(p) {
// Prefer the thing the user can actually pass as `model=`.
// If a custom config overrides "auto", that should win.
const isAuto = p.modelId === "auto";
const isCustomConfig = p.overlaySource === "custom";
const isOverlay = p.overlaySource === "modelOverlay";
// Higher is better.
return (isCustomConfig ? 100 : isOverlay ? 50 : 0) + (isAuto ? 10 : 0);
}
function pickDisplayPreset(presets) {
if (!presets.length)
return undefined;
return [...presets].sort((a, b) => scorePresetForDisplay(b) - scorePresetForDisplay(a))[0];
}
/**
* Resolve a Draw Things backend model filename (.ckpt) to the set of presets
* (mode + modelId) that would result in this model file being used.
*
* IMPORTANT: Display-only. Do not use for input validation.
*/
function resolveImageModelInfoFromModelUsed(modelFilenameOrPath, opts) {
if (typeof modelFilenameOrPath !== "string")
return null;
const base = node_path_1.default.basename(modelFilenameOrPath).trim();
if (!base)
return null;
const normalized = normalizeModelFilenameForLookup(base);
const modes = opts?.mode
? [userModeToMode(opts.mode)]
: ["txt2img", "img2img", "edit", "txt2vid", "img2vid"];
const presets = [];
for (const mode of modes) {
for (const modelId of modelOverlays_js_1.MODEL_IDS) {
const eff = computeEffectiveModelFilename(modelId, mode);
if (!eff.modelBasename)
continue;
if (eff.modelBasename !== normalized)
continue;
// Skip "default" fallback matches for any modelId other than "auto":
// those modelIds have no overlay for this mode and silently fall through
// to the mode default — not a meaningful/intentional preset match.
if (eff.overlaySource === "default" && modelId !== "auto")
continue;
const userMode = modeToUserMode(mode);
const preset = `${userMode}.${modelId}`;
presets.push({
mode: userMode,
modelId,
preset,
overlaySource: eff.overlaySource,
...(eff.presetName ? { customConfig: eff.presetName } : {}),
});
}
}
const customConfigLabels = (0, customConfigsLoader_js_1.getCustomPresetLabelsUsingModelFilename)(base);
const chosen = pickDisplayPreset(presets);
const modelFamily = resolveModelFamilyFromModelBasename(base);
const display = modelFamily && modelFamily !== "unknown" ? `${modelFamily} (${base})` : base;
return {
modelUsedBasename: base,
display,
...(chosen ? { chosen_model_id: chosen.modelId } : {}),
...(modelFamily ? { model_family: modelFamily } : {}),
presets,
...(customConfigLabels.length ? { custom_config_labels: customConfigLabels } : {}),
};
}
function formatImageModelForToolDisplay(modelFilenameOrPath) {
const info = resolveImageModelInfoFromModelUsed(modelFilenameOrPath);
return info?.display ?? "";
}