diff --git a/aria-data/config/BOOTSTRAP.md b/aria-data/config/BOOTSTRAP.md index cbda2a6..f314e5b 100644 --- a/aria-data/config/BOOTSTRAP.md +++ b/aria-data/config/BOOTSTRAP.md @@ -114,6 +114,14 @@ OHNE diesen Marker erscheint die Datei NICHT in der App / Diagnostic. Mehrere Dateien: mehrere `[FILE: ...]`-Marker am Ende, jeder in eigener Zeile. +**WICHTIG — Datei MUSS existieren bevor du den Marker setzt.** +Marker fuer nicht-existente Pfade werden silent gefiltert + Stefan +bekommt einen Hinweis dass du eine Datei versprochen aber nicht +erstellt hast. Wenn du z.B. eine MIDI-Datei nicht generieren kannst, +sag das offen statt nur den Marker zu setzen. Verifiziere zur Not +mit `Bash` + `ls -la /shared/uploads/aria_.` dass die +Datei wirklich da ist. + ### Beispiel — kompletter Workflow User: "Schreib mir ein Lasagne-Rezept als md-Datei" diff --git a/bridge/aria_bridge.py b/bridge/aria_bridge.py index 36b4e41..611faee 100644 --- a/bridge/aria_bridge.py +++ b/bridge/aria_bridge.py @@ -894,9 +894,11 @@ class ARIABridge: # enthalten, Endung beliebig). Mehrfach im Text moeglich. _FILE_MARKER_RE = re.compile(r"\[FILE:\s*(/shared/uploads/[^\]]+?)\s*\]", re.IGNORECASE) - def _extract_file_markers(self, text: str) -> tuple[str, list[dict]]: - """Sucht [FILE: /shared/uploads/...]-Marker, gibt (cleaned_text, file_list) zurueck.""" + def _extract_file_markers(self, text: str) -> tuple[str, list[dict], list[str]]: + """Sucht [FILE: /shared/uploads/...]-Marker. + Returns (cleaned_text, valid_files, missing_paths).""" files: list[dict] = [] + missing: list[str] = [] for m in self._FILE_MARKER_RE.finditer(text): path = m.group(1).strip() if not path.startswith("/shared/uploads/"): @@ -904,6 +906,7 @@ class ARIABridge: continue if not os.path.isfile(path): logger.warning("[core] FILE-Marker zeigt auf nicht existente Datei: %s", path) + missing.append(path) continue name = os.path.basename(path) mime, _ = mimetypes.guess_type(path) @@ -917,7 +920,7 @@ class ARIABridge: cleaned = self._FILE_MARKER_RE.sub("", text).strip() # Zwei aufeinanderfolgende Leerzeilen → eine cleaned = re.sub(r"\n{3,}", "\n\n", cleaned) - return cleaned, files + return cleaned, files, missing async def _broadcast_aria_file(self, file_info: dict) -> None: """ARIA hat eine Datei fuer den User erstellt — App+Diagnostic informieren.""" @@ -950,9 +953,17 @@ class ARIABridge: # ARIA legt damit Dateien fuer den User bereit (Bilder, PDFs, etc.). # Der Marker wird aus dem Antworttext entfernt (TTS soll ihn nicht # vorlesen) und parallel als file_from_aria-Event geschickt. - text, aria_files = self._extract_file_markers(text) + text, aria_files, missing_files = self._extract_file_markers(text) for f in aria_files: await self._broadcast_aria_file(f) + # Bei fehlenden Files: User informieren (sonst sieht er nur stille + # Verluste — ARIA hat den Marker hingeschrieben aber das File nicht + # tatsaechlich angelegt). + if missing_files: + missing_list = "\n".join(f" • {os.path.basename(p)}" for p in missing_files) + text = (text + "\n\n[Hinweis] Folgende Dateien hat ARIA zwar erwaehnt " + f"aber nicht erstellt:\n{missing_list}\n" + "Bitte ARIA bitten, sie wirklich zu schreiben.").strip() metadata = payload.get("metadata", {}) is_critical = metadata.get("critical", False)