Read A1111/Forge generation parameters: fix the SELECT and parse multi-line prompts (#165)
* get_image_prompt_info: include gi.parameters in SELECT and return value The function selects workflow_data, prompt_metadata and generation_time from generated_images but omits the parameters column, so the A1111/Forge generation-parameters string (steps, sampler, CFG, seed, LoRA list) never reaches the API even when present in the database. Add it to the SELECT and include it in the returned dict. * parse A1111/Forge parameters: multi-line prompts, structured settings _parse_comfyui_prompt took lines[0] of the parameters chunk as the whole positive prompt, truncating every multi-line prompt to its first line, and matched 'negative prompt:' only as a full line start. Split on the trailing 'Steps: ...' settings line instead, keep the full multi-line positive prompt, and extract Steps / Sampler / Schedule type / CFG scale / Seed as structured fields alongside the raw string. Together with the get_image_prompt_info SELECT fix (previous commit), the full A1111/Forge generation recipe now flows from the database to the API. * style: apply black to the A1111 parameters parser CI's black --check flagged py/api/__init__.py (slice spacing and two long lines in the settings extraction). Formatting only; the AST is unchanged. --------- Co-authored-by: kai <kai@hermes.local>
This commit is contained in:
@@ -1971,12 +1971,13 @@ class PromptDatabase:
|
||||
"""Look up prompt + image metadata for a given image path.
|
||||
|
||||
Returns a dict with prompt_id, text, category, tags, rating, notes,
|
||||
workflow_data, prompt_metadata, generation_time — or None.
|
||||
workflow_data, prompt_metadata, generation_time, parameters — or None.
|
||||
"""
|
||||
with self.model.get_connection() as conn:
|
||||
cursor = conn.execute(
|
||||
"""SELECT gi.prompt_id, p.text, p.category, p.rating, p.notes,
|
||||
gi.workflow_data, gi.prompt_metadata, gi.generation_time
|
||||
gi.workflow_data, gi.prompt_metadata, gi.generation_time,
|
||||
gi.parameters
|
||||
FROM generated_images gi
|
||||
JOIN prompts p ON gi.prompt_id = p.id
|
||||
WHERE gi.image_path = ? OR gi.file_path = ?
|
||||
@@ -2009,6 +2010,7 @@ class PromptDatabase:
|
||||
"workflow_data": workflow,
|
||||
"prompt_metadata": prompt_meta,
|
||||
"generation_time": row[7],
|
||||
"parameters": row[8] if len(row) > 8 else None,
|
||||
}
|
||||
|
||||
def get_prompt_id_for_image(self, image_path: str) -> Optional[int]:
|
||||
|
||||
+33
-8
@@ -703,18 +703,43 @@ class PromptManagerAPI(
|
||||
"negative_prompt": None,
|
||||
}
|
||||
|
||||
# Check for A1111 style parameters first (like parse-metadata.py)
|
||||
# Check for A1111/Forge style parameters first.
|
||||
# The chunk is one block: a possibly multi-line positive prompt, then a
|
||||
# "Negative prompt:" section, then a trailing "Steps: ..." settings line.
|
||||
# Taking lines[0] as the positive prompt truncates any multi-line prompt
|
||||
# to one line, so split on the settings line instead.
|
||||
if "parameters" in metadata:
|
||||
import re as _re
|
||||
|
||||
params = metadata["parameters"]
|
||||
lines = params.splitlines()
|
||||
if lines:
|
||||
result["positive_prompt"] = lines[0].strip()
|
||||
for line in lines:
|
||||
if line.lower().startswith("negative prompt:"):
|
||||
result["negative_prompt"] = line.split(":", 1)[1].strip()
|
||||
break
|
||||
body = params
|
||||
settings = ""
|
||||
_sm = _re.search(r"\nSteps:\s", body)
|
||||
if _sm:
|
||||
settings = body[_sm.start() + 1 :].strip()
|
||||
body = body[: _sm.start()]
|
||||
negative = None
|
||||
_nm = _re.search(r"(?im)^\s*negative prompt:\s*", body)
|
||||
if _nm:
|
||||
negative = body[_nm.end() :].strip()
|
||||
body = body[: _nm.start()]
|
||||
elif body.lower().lstrip().startswith("negative prompt:"):
|
||||
negative = body.lower().lstrip()[len("negative prompt:") :].strip()
|
||||
body = ""
|
||||
result["positive_prompt"] = body.strip() or None
|
||||
if negative:
|
||||
result["negative_prompt"] = negative
|
||||
# Store raw parameters too
|
||||
result["parameters"]["parameters"] = params
|
||||
if settings:
|
||||
for _f in ("Steps", "Sampler", "Schedule type", "CFG scale", "Seed"):
|
||||
_fm = _re.search(
|
||||
r"(?i)(?:^|,\s*)" + _re.escape(_f) + r":\s*([^,]+)", settings
|
||||
)
|
||||
if _fm:
|
||||
result["parameters"][_f.lower().replace(" ", "_")] = _fm.group(
|
||||
1
|
||||
).strip()
|
||||
|
||||
# If no A1111 format found, proceed with ComfyUI parsing
|
||||
if result["positive_prompt"] is None:
|
||||
|
||||
Reference in New Issue
Block a user