update
This commit is contained in:
@@ -1500,48 +1500,69 @@ async def check_element(element: dict, provider: str = DEFAULT_PROVIDER) -> list
|
||||
return None
|
||||
|
||||
|
||||
async def _element_rewrite(template: str, element: dict, provider: str, **extra) -> tuple[str, dict | None]:
|
||||
"""Gemeinsames Muster: Element + Template → (Antwort, neue Felder|None)."""
|
||||
def _element_json(element: dict) -> str:
|
||||
return json.dumps(
|
||||
{k: element[k] for k in ("title", "description", "examples", "hints")},
|
||||
ensure_ascii=False, indent=1,
|
||||
)
|
||||
|
||||
|
||||
def _validate_change(c, element: dict) -> dict | None:
|
||||
"""Validiert einen Änderungs-Vorschlag aus KI-Output gegen das Element."""
|
||||
if not isinstance(c, dict):
|
||||
return None
|
||||
text = str(c.get("text", "")).strip()
|
||||
action = c.get("action")
|
||||
target = c.get("target")
|
||||
index = c.get("index")
|
||||
content = str(c.get("content", "")).strip()
|
||||
if not text or action not in ("entfernen", "anpassen", "hinzufuegen"):
|
||||
return None
|
||||
if target not in ("title", "description", "examples", "hints"):
|
||||
return None
|
||||
if action in ("anpassen", "hinzufuegen") and not content:
|
||||
return None
|
||||
if action == "entfernen" and target not in ("examples", "hints"):
|
||||
return None
|
||||
# Index nur für anpassen/entfernen in Listen-Feldern; muss existieren
|
||||
if target in ("examples", "hints") and action in ("anpassen", "entfernen"):
|
||||
if not isinstance(index, int) or not (0 <= index < len(element[target])):
|
||||
return None
|
||||
else:
|
||||
index = None
|
||||
if target == "examples" and action in ("anpassen", "hinzufuegen"):
|
||||
content = _fence(content)
|
||||
return {"text": text, "action": action, "target": target, "index": index, "content": content}
|
||||
|
||||
|
||||
async def chat_with_element(element: dict, messages: list[dict], provider: str = DEFAULT_PROVIDER) -> tuple[str, list[dict]]:
|
||||
"""Chat zum Element. Gibt (Antwort, Änderungs-Vorschläge) zurück — ändert nichts direkt."""
|
||||
fehler = "Entschuldigung, das hat nicht geklappt. Bitte versuche es erneut."
|
||||
try:
|
||||
element_json = json.dumps(
|
||||
{k: element[k] for k in ("title", "description", "examples", "hints")},
|
||||
ensure_ascii=False, indent=1,
|
||||
transcript = "\n".join(
|
||||
f"{'Nutzer' if m.get('role') == 'user' else 'Assistent'}: {m.get('content', '')}"
|
||||
for m in messages
|
||||
)
|
||||
prompt = _prompt(template, topic=element["topic"], element_json=element_json, **extra)
|
||||
prompt = _prompt("Element-Chat", topic=element["topic"], element_json=_element_json(element), transcript=transcript)
|
||||
returncode, stdout, _ = await run_agent(
|
||||
f"element-{template.lower()}-" + str(uuid.uuid4()), prompt, 240,
|
||||
provider=provider, role="fast", capabilities="none",
|
||||
"element-chat-" + str(uuid.uuid4()), prompt, 240, provider=provider, role="fast", capabilities="none"
|
||||
)
|
||||
if returncode != 0:
|
||||
return fehler, None
|
||||
return fehler, []
|
||||
data = _parse_json_text(stdout)
|
||||
if not isinstance(data, dict):
|
||||
return fehler, None
|
||||
fields = _element_fields(data.get("element"))
|
||||
reply = str(data.get("reply", "")).strip() or ("Erledigt." if fields else fehler)
|
||||
return reply, fields
|
||||
return fehler, []
|
||||
changes = [v for c in data.get("changes", []) if (v := _validate_change(c, element))]
|
||||
reply = str(data.get("reply", "")).strip() or ("Vorschläge erstellt." if changes else fehler)
|
||||
return reply, changes
|
||||
except Exception:
|
||||
return fehler, None
|
||||
|
||||
|
||||
async def chat_with_element(element: dict, messages: list[dict], provider: str = DEFAULT_PROVIDER) -> tuple[str, dict | None]:
|
||||
"""Passt ein Element per Chat an. Gibt (Antwort, neue Felder|None) zurück."""
|
||||
transcript = "\n".join(
|
||||
f"{'Nutzer' if m.get('role') == 'user' else 'Assistent'}: {m.get('content', '')}"
|
||||
for m in messages
|
||||
)
|
||||
return await _element_rewrite("Element-Chat", element, provider, transcript=transcript)
|
||||
return fehler, []
|
||||
|
||||
|
||||
async def style_element(element: dict, provider: str = DEFAULT_PROVIDER) -> list[dict] | None:
|
||||
"""Prüft ein Element auf die Stil-Regeln und schlägt Änderungen vor. None bei Fehler."""
|
||||
try:
|
||||
element_json = json.dumps(
|
||||
{k: element[k] for k in ("title", "description", "examples", "hints")},
|
||||
ensure_ascii=False, indent=1,
|
||||
)
|
||||
prompt = _prompt("Element-Stil", topic=element["topic"], element_json=element_json)
|
||||
prompt = _prompt("Element-Stil", topic=element["topic"], element_json=_element_json(element))
|
||||
returncode, stdout, _ = await run_agent(
|
||||
"element-stil-" + str(uuid.uuid4()), prompt, 240, provider=provider, role="fast", capabilities="none"
|
||||
)
|
||||
@@ -1550,32 +1571,28 @@ async def style_element(element: dict, provider: str = DEFAULT_PROVIDER) -> list
|
||||
data = _parse_json_text(stdout)
|
||||
if not isinstance(data, dict):
|
||||
return None
|
||||
changes = []
|
||||
for c in data.get("changes", []):
|
||||
if not isinstance(c, dict):
|
||||
continue
|
||||
text = str(c.get("text", "")).strip()
|
||||
action = c.get("action")
|
||||
target = c.get("target")
|
||||
index = c.get("index")
|
||||
content = str(c.get("content", "")).strip()
|
||||
if not text or action not in ("entfernen", "anpassen", "hinzufuegen"):
|
||||
continue
|
||||
if target not in ("title", "description", "examples", "hints"):
|
||||
continue
|
||||
if action in ("anpassen", "hinzufuegen") and not content:
|
||||
continue
|
||||
if action == "entfernen" and target not in ("examples", "hints"):
|
||||
continue
|
||||
# Index nur für anpassen/entfernen in Listen-Feldern; muss existieren
|
||||
if target in ("examples", "hints") and action in ("anpassen", "entfernen"):
|
||||
if not isinstance(index, int) or not (0 <= index < len(element[target])):
|
||||
continue
|
||||
else:
|
||||
index = None
|
||||
if target == "examples" and action in ("anpassen", "hinzufuegen"):
|
||||
content = _fence(content)
|
||||
changes.append({"text": text, "action": action, "target": target, "index": index, "content": content})
|
||||
return changes
|
||||
return [v for c in data.get("changes", []) if (v := _validate_change(c, element))]
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
|
||||
async def refine_suggestion(element: dict, suggestion: dict, instruction: str, provider: str = DEFAULT_PROVIDER) -> dict | None:
|
||||
"""Überarbeitet einen einzelnen Vorschlag nach Nutzer-Anweisung. None bei Fehler."""
|
||||
try:
|
||||
prompt = _prompt(
|
||||
"Element-Refine",
|
||||
topic=element["topic"], element_json=_element_json(element),
|
||||
suggestion_json=json.dumps(suggestion, ensure_ascii=False, indent=1),
|
||||
instruction=instruction,
|
||||
)
|
||||
returncode, stdout, _ = await run_agent(
|
||||
"element-refine-" + str(uuid.uuid4()), prompt, 240, provider=provider, role="fast", capabilities="none"
|
||||
)
|
||||
if returncode != 0:
|
||||
return None
|
||||
data = _parse_json_text(stdout)
|
||||
if not isinstance(data, dict):
|
||||
return None
|
||||
return _validate_change(data.get("change"), element)
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
Reference in New Issue
Block a user