fix(profiles): KeyError bei JSON-Beispielen in Prompt-Templates
Bug: 9 von 17 Profilen (phone-call, brainstorm, one-on-one, postmortem,
schichtuebergabe, pflegedoku, visite, biografie) zeigen in ihren Prompts
JSON-Schema-Beispiele wie {"owner", "task"}. Python's str.format() liest
diese geschweiften Klammern als Platzhalter und wirft KeyError →
HTTP 500 vom Mac-Worker → Job FAILED bei summarize/protocol.
Fix:
- Neuer render(template, **vars) Helper in ollama_client: ersetzt nur
explizit benannte Platzhalter, lässt alles andere literal stehen.
- summarize/make_protocol nutzen diesen Helper statt .format()
- profiles.validate_all() warnt beim Worker-Start, wenn ein erwarteter
Platzhalter fehlt — Defekte werden früh sichtbar
- Mac-Worker-Middleware fängt unhandled exceptions und liefert JSON-Body
mit Type+Message+Traceback-Tail (statt generic "Internal Server Error")
- LXC MacClient liest diesen Error-Body und packt ihn in die HTTPStatusError-
Message → landet im Job-error-Feld + Diagnose-Panel mit echter Wurzel-Info
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -28,13 +28,30 @@ class MacClient:
|
||||
return None
|
||||
return {"X-Job-Id": str(job_id)}
|
||||
|
||||
@staticmethod
|
||||
def _raise_for_status(r: httpx.Response, url: str) -> None:
|
||||
"""Wie raise_for_status, aber zieht den 'error'-Feld aus JSON-Body in die Exception."""
|
||||
if r.status_code < 400:
|
||||
return
|
||||
detail = ""
|
||||
try:
|
||||
j = r.json()
|
||||
detail = j.get("error") or j.get("detail") or ""
|
||||
except Exception: # noqa: BLE001
|
||||
detail = (r.text or "").strip()[:300]
|
||||
raise httpx.HTTPStatusError(
|
||||
f"HTTP {r.status_code} {url} — {detail}" if detail else f"HTTP {r.status_code} {url}",
|
||||
request=r.request,
|
||||
response=r,
|
||||
)
|
||||
|
||||
async def _post_json_retry(self, url: str, payload: dict, job_id: int | None) -> dict:
|
||||
"""JSON-POST mit einmaligem Retry bei transienten Verbindungsabbrüchen."""
|
||||
for attempt in (0, 1):
|
||||
try:
|
||||
async with httpx.AsyncClient(timeout=self.timeout) as c:
|
||||
r = await c.post(url, json=payload, headers=self._hdrs(job_id))
|
||||
r.raise_for_status()
|
||||
self._raise_for_status(r, url)
|
||||
return r.json()
|
||||
except _RETRY_EXCEPTIONS as e:
|
||||
if attempt == 0:
|
||||
@@ -48,7 +65,7 @@ class MacClient:
|
||||
try:
|
||||
async with httpx.AsyncClient(timeout=self.timeout) as c:
|
||||
r = await c.post(url, json=payload, headers=self._hdrs(job_id))
|
||||
r.raise_for_status()
|
||||
self._raise_for_status(r, url)
|
||||
return r.content
|
||||
except _RETRY_EXCEPTIONS as e:
|
||||
if attempt == 0:
|
||||
|
||||
Reference in New Issue
Block a user