Stale-Job-Reset, Ownership-Angleichung, robuste Dashboard-Erzeugung

- Server-Neustart setzt hängengebliebene Jobs (running/queued) zurück
  (markStaleJobs) mit Hinweis-Nachricht; /abort räumt auch verwaiste Sessions auf
- Löschen/Abbrechen/Modellwechsel ohne Owner-Beschränkung (konsistent zur
  offenen Sichtbarkeit im Ein-Nutzer-System)
- Dashboard-HTML wird nicht mehr per Tool-Aufruf übertragen, sondern in der
  finalen Antwort als ```html```-Codeblock gestreamt (GLM scheiterte
  reproduzierbar am riesigen Tool-Call); Extraktion mit klaren Fehlern bei
  fehlendem/unvollständigem Codeblock
- Reasoning-Effort pro Runde: volle Tiefe in Research-Runden, minimales Denken
  in der Dashboard-Liefer-Runde (DeepSeek: thinking aus, GLM: low) –
  Budget gehört dem HTML
- GLM-Reasoning-Default high (max verbrennt das Completion-Budget),
  DeepSeek max_tokens auf 300k
This commit is contained in:
nico committed 2026-08-28 09:17:13 +02:00
1 parent 8a2bf46b09
commit ab4f8e8570
6 files changed
+178 -36

No files matched your search

+24
View File
@@ -115,6 +115,7 @@ const stmts = {
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`
),
listMessages: db.prepare(`SELECT * FROM messages WHERE session_id = ? ORDER BY id ASC`),
listStaleSessions: db.prepare(`SELECT id FROM sessions WHERE status IN ('running', 'queued')`),
lastMessage: db.prepare(`SELECT * FROM messages WHERE session_id = ? ORDER BY id DESC LIMIT 1`),
updateMessageContent: db.prepare(`UPDATE messages SET content = ? WHERE id = ?`),
deleteMessages: db.prepare(`DELETE FROM messages WHERE session_id = ?`),
@@ -258,6 +259,29 @@ module.exports = {
stmts.deleteMessages.run(id);
stmts.deleteSession.run(id);
},
/**
* Setzt nach einem Server-Neustart alle Sessions zurück, die im alten
* Prozess noch als 'running'/'queued' festhingen (Jobs existieren im
* Speicher nicht mehr). Gibt die Anzahl zurück.
*/
markStaleJobs() {
const stale = stmts.listStaleSessions.all();
for (const s of stale) {
stmts.setSessionStatus.run('done', now(), s.id);
stmts.insertMessage.run(
s.id,
'assistant',
'⛔ Recherche wurde durch einen Server-Neustart abgebrochen.',
null,
null,
null,
null,
null,
now()
);
}
return stale.length;
},
getSessionMessages,
toApiMessages,
upsertPushSub(userName, endpoint, keys) {