feat(diag): Memory-Anhaenge in der UI (Stufe B)

Diagnostic-Gehirn-Tab kann jetzt Bilder/Dateien an Memory-Eintraege
haengen — drag+drop ueber den File-Input im Memory-Modal.

Memory-Modal (Edit-Modus):
- Neuer Block "📎 Anhaenge" unter Pinned-Checkbox, nur sichtbar wenn
  Memory eine ID hat (Edit). Bei "Neue Memory" stattdessen Hinweis
  "Anhaenge nach Speichern hinzufuegbar".
- "⬆ Datei waehlen" oeffnet File-Picker (multiple), Upload via
  multipart/form-data POST an /memory/{id}/attachments/upload.
- Liste zeigt pro Anhang: Thumbnail (Bilder) oder 📄-Icon,
  Filename, Mime + Groesse, 🗑 Loeschen-Button.
- Bild-Thumbnails sind klickbar → openLightbox.
- Status-Zeile zeigt Upload-Progress + Erfolgsmeldung.

Memory-Liste:
- 📎N-Badge erscheint hinter dem Titel wenn N > 0 Anhaenge da sind.

Diagnostic-Server:
- Brain-Reverse-Proxy-Timeout dynamisch: 120s fuer /attachments-Routen
  (Upload), 60s sonst (vorher pauschal 30s — zu wenig fuer chat/distill).
- multipart-Body wird ueber req.pipe(proxyReq) durchgereicht (FastAPI
  liest File via UploadFile, Content-Type-Header bleibt erhalten).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-13 02:36:51 +02:00
parent da4e970a31
commit de9b7b46f9
2 changed files with 126 additions and 2 deletions
+6 -1
View File
@@ -1644,13 +1644,18 @@ const server = http.createServer((req, res) => {
// Reverse-Proxy zum aria-brain Container (intern auf 8080, nicht expose'd).
// Frontend ruft z.B. /api/brain/health → http://aria-brain:8080/health
const targetPath = req.url.replace(/^\/api\/brain/, "");
// Uploads brauchen laenger als die 30s default — Memory-Anhang-Endpoints
// koennen bis zu 20 MB tragen, plus chat/distill-Calls dauern manchmal
// mehr als eine Minute.
const isUpload = /\/attachments(\/upload)?$/.test(targetPath);
const timeout = isUpload ? 120000 : 60000;
const proxyReq = http.request({
host: "aria-brain",
port: 8080,
path: targetPath,
method: req.method,
headers: req.headers,
timeout: 30000,
timeout,
}, (proxyRes) => {
res.writeHead(proxyRes.statusCode, proxyRes.headers);
proxyRes.pipe(res);