KI-Agent: Änderungen erscheinen in Live-Vorschau und PDF

- Dateien des Agenten werden sofort committet (die Vorschau liest in anderer Sitzung; vorher KeyError/unverändert)
- Beispielprotokoll der PDF-Vorschau gehört zum Arbeitsstand: neues Tool set_sample, run_prompt_test setzt das LLM-Ergebnis als Beispiel; im Vorschlag und bei der Freigabe übernommen
- Vorschau wechselt bei PDF-relevanten Änderungen automatisch auf die PDF-Ansicht
- Regressionstests inkl. echter SSE-/Freigabe-Strecke

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
RubenRWU
2026-10-15 16:46:32 +02:00
parent 9c352be05b
commit 40b3f687f7
6 changed files with 174 additions and 13 deletions

View File

@@ -29,6 +29,7 @@ class Workspace:
cfg, files = store.content(db, tenant, "draft")
self.base_cfg, self.base_files = deepcopy(cfg), dict(files)
self.cfg, self.files = deepcopy(cfg), dict(files) # files: {pfad: sha}
self.base_sample = self.sample = tenant.preview_sample # Beispielprotokoll der PDF-Vorschau (None = Standard)
# ── Lesen ──
def list_files(self) -> list[dict]:
@@ -60,6 +61,7 @@ class Workspace:
if path.endswith(".py"):
compile(content, path, "exec") # Syntaxfehler früh melden
self.files[path] = store.put_blob(self.db, content.encode("utf-8"), path)
self.db.commit() # Blob sofort sichtbar machen: die Live-Vorschau liest in einer ANDEREN Sitzung, während der Agent noch läuft
def edit(self, path: str, old: str, new: str) -> None:
cur = self.read(path) if path != "tenant.json" else json.dumps(self.cfg, indent=2, ensure_ascii=False)
@@ -90,7 +92,24 @@ class Workspace:
# ── Ergebnis ──
def changed(self) -> bool:
return self.cfg != self.base_cfg or self.files != self.base_files
return self.cfg != self.base_cfg or self.files != self.base_files or self.sample != self.base_sample
def snapshot(self) -> tuple[dict, dict, str | None]:
return deepcopy(self.cfg), dict(self.files), self.sample
def changed_paths(self, prev: tuple[dict, dict, str | None]) -> list[str]:
"""Was hat sich seit `prev` geändert? (für die Vorschau: PDF-relevante Änderungen → PDF-Ansicht)"""
cfg0, files0, sample0 = prev
out = [p for p in set(self.files) | set(files0) if self.files.get(p) != files0.get(p)]
for k in set(self.cfg) | set(cfg0):
if self.cfg.get(k) != cfg0.get(k):
if isinstance(self.cfg.get(k), dict) or isinstance(cfg0.get(k), dict):
out += [f"{k}.{kk}" for kk in set(self.cfg.get(k) or {}) | set(cfg0.get(k) or {}) if (self.cfg.get(k) or {}).get(kk) != (cfg0.get(k) or {}).get(kk)]
else:
out.append(k)
if self.sample != sample0:
out.append("preview_sample")
return sorted(out)
def proposal(self, summary: str) -> dict | None:
if not self.changed():
@@ -102,5 +121,7 @@ class Workspace:
items.append({"path": "tenant.json", "kind": "geändert"})
items += [{"path": p, "kind": "neu" if p not in self.base_files else "geändert"} for p in files]
items += [{"path": p, "kind": "gelöscht"} for p in deleted]
if self.sample != self.base_sample:
items.append({"path": "Vorschau-Beispielprotokoll", "kind": "geändert"})
return {"summary": summary, "config": self.cfg if self.cfg != self.base_cfg else None,
"files": files, "deleted": deleted, "items": items}
"files": files, "deleted": deleted, "items": items, "sample": self.sample if self.sample != self.base_sample else None}