159 lines
5.8 KiB
Python
159 lines
5.8 KiB
Python
# Template + Prompt preset API — CRUD endpoints for workflow templates
|
|
# and prompt presets, delegating to template_storage and prompt_storage.
|
|
|
|
from aiohttp import web
|
|
import server
|
|
|
|
from .api_utils import error_response, ok_response
|
|
|
|
from . import templates as template_storage
|
|
from . import prompts as prompt_storage
|
|
from . import model_settings
|
|
|
|
routes = server.PromptServer.instance.routes
|
|
|
|
|
|
def _resolve_model_scope(arch, family, name_param, model_hash):
|
|
"""The picker sends {hash, raw checkpoint filename as `name`, architecture}
|
|
but no catalog model_name/family. Resolve the model config (by hash, then
|
|
filename) so model- and family-scoped presets/templates match on the
|
|
catalog's real model_name + family — not the raw .safetensors filename."""
|
|
cfg = None
|
|
if model_hash:
|
|
cfg = model_settings.find_config_by_hash(model_hash)
|
|
if cfg is None and name_param:
|
|
cfg = model_settings.find_config_by_filename(name_param)
|
|
model_name = name_param
|
|
if cfg:
|
|
model_name = cfg.get("model_name") or cfg.get("display_name") or name_param
|
|
arch = arch or cfg.get("architecture")
|
|
family = family or cfg.get("family")
|
|
return arch, family, model_name, model_hash
|
|
|
|
|
|
# ── template endpoints ───────────────────────────────────────────
|
|
|
|
@routes.get("/promptchain/templates/list")
|
|
async def _api_templates_list(request):
|
|
arch, family, model_name, model_hash = _resolve_model_scope(
|
|
request.query.get("arch"), request.query.get("family"),
|
|
request.query.get("name"), request.query.get("hash"))
|
|
include_hidden = request.query.get("include_hidden") == "1"
|
|
templates = template_storage.list_templates(arch, family, model_name, model_hash, include_hidden)
|
|
category_order = template_storage.load_category_order()
|
|
return web.json_response({"templates": templates, "category_order": category_order})
|
|
|
|
|
|
@routes.post("/promptchain/templates/reset-all")
|
|
async def _api_template_reset_all(request):
|
|
count = template_storage.reset_all()
|
|
return ok_response({"removed": count})
|
|
|
|
|
|
@routes.post("/promptchain/templates/order")
|
|
async def _api_template_save_order(request):
|
|
try:
|
|
data = await request.json()
|
|
except Exception:
|
|
return error_response("invalid JSON")
|
|
ordered_ids = data.get("order", [])
|
|
if not isinstance(ordered_ids, list):
|
|
return error_response("order must be a list")
|
|
template_storage.save_order(ordered_ids)
|
|
return ok_response()
|
|
|
|
|
|
@routes.post("/promptchain/templates/category-order")
|
|
async def _api_template_save_category_order(request):
|
|
try:
|
|
data = await request.json()
|
|
except Exception:
|
|
return error_response("invalid JSON")
|
|
ordered_categories = data.get("order", [])
|
|
if not isinstance(ordered_categories, list):
|
|
return error_response("order must be a list")
|
|
template_storage.save_category_order(ordered_categories)
|
|
return ok_response()
|
|
|
|
|
|
@routes.get("/promptchain/templates/{template_id}")
|
|
async def _api_template_get(request):
|
|
template_id = request.match_info.get("template_id", "")
|
|
tpl = template_storage.load(template_id)
|
|
if not tpl:
|
|
return error_response("not found", 404)
|
|
tpl["_has_system"] = template_storage.has_system_template(template_id)
|
|
tpl["_has_user"] = template_storage.has_user_template(template_id)
|
|
return web.json_response(tpl)
|
|
|
|
|
|
@routes.post("/promptchain/templates")
|
|
async def _api_template_save(request):
|
|
try:
|
|
data = await request.json()
|
|
except Exception:
|
|
return error_response("invalid JSON")
|
|
if not data.get("name"):
|
|
return error_response("missing name")
|
|
template_id = template_storage.save(data)
|
|
return ok_response({"id": template_id})
|
|
|
|
|
|
@routes.patch("/promptchain/templates/{template_id}")
|
|
async def _api_template_update_metadata(request):
|
|
template_id = request.match_info.get("template_id", "")
|
|
try:
|
|
data = await request.json()
|
|
except Exception:
|
|
return error_response("invalid JSON")
|
|
if template_storage.update_metadata(template_id, data):
|
|
return ok_response()
|
|
return error_response("not found", 404)
|
|
|
|
|
|
@routes.post("/promptchain/templates/{template_id}/reset")
|
|
async def _api_template_reset(request):
|
|
template_id = request.match_info.get("template_id", "")
|
|
if template_storage.reset(template_id):
|
|
return ok_response()
|
|
return error_response("no user override found", 404)
|
|
|
|
|
|
@routes.delete("/promptchain/templates/{template_id}")
|
|
async def _api_template_delete(request):
|
|
template_id = request.match_info.get("template_id", "")
|
|
if template_storage.delete(template_id):
|
|
return ok_response()
|
|
return error_response("not found", 404)
|
|
|
|
|
|
# ── prompt preset endpoints ──────────────────────────────────────
|
|
|
|
@routes.get("/promptchain/prompts/list")
|
|
async def _api_prompts_list(request):
|
|
arch, family, model_name, model_hash = _resolve_model_scope(
|
|
request.query.get("arch"), request.query.get("family"),
|
|
request.query.get("name"), request.query.get("hash"))
|
|
prompts = prompt_storage.list_prompts(arch, family, model_name, model_hash)
|
|
return web.json_response({"prompts": prompts})
|
|
|
|
|
|
@routes.post("/promptchain/prompts")
|
|
async def _api_prompt_save(request):
|
|
try:
|
|
data = await request.json()
|
|
except Exception:
|
|
return error_response("invalid JSON")
|
|
if not data.get("name"):
|
|
return error_response("missing name")
|
|
prompt_id = prompt_storage.save(data)
|
|
return ok_response({"id": prompt_id})
|
|
|
|
|
|
@routes.delete("/promptchain/prompts/{prompt_id}")
|
|
async def _api_prompt_delete(request):
|
|
prompt_id = request.match_info.get("prompt_id", "")
|
|
if prompt_storage.delete(prompt_id):
|
|
return ok_response()
|
|
return error_response("not found", 404)
|