feat: Payload-Preview im Chat-Menü + Reminder von hinten gezählt

- Neuer Endpoint GET /api/sessions/{id}/payload-preview
  Gibt den exakten Anthropic-API-Payload als JSON zurück (read-only)
- Chat-Menü: 'Payload anzeigen' öffnet Modal mit formatiertem JSON
- Reminder-Logik umgebaut: halbes Intervall (15) vor Ende,
  dann volle Intervalle (30) rückwärts statt von vorne gezählt
- CSS: Payload-Modal Styling, kleine Variable-Fixes
This commit is contained in:
Meleki committed 2026-03-15 10:46:51 +01:00
1 parent 229e6d9e53
commit 49ef6bedc6
7 files changed
+154 -21

No files matched your search

+31 -18
View File
@@ -549,9 +549,10 @@ Für welche Plattform soll die App entwickelt werden? Web, Mobile oder Desktop?
history.RemoveRange(0, removeCount);
}
// Reminder einfügen: alle ~30 user/assistant-Paare ein Reminder-Paar einfügen
// Reminder einfügen: von hinten gezählt – halbes Intervall vor Ende, dann volle Intervalle
var reminder = SystemPromptBuilder.BuildReminder(promptBlocks);
if (!string.IsNullOrWhiteSpace(reminder) && ReminderInterval > 0 && history.Count > ReminderInterval)
int halfInterval = ReminderInterval / 2;
if (!string.IsNullOrWhiteSpace(reminder) && ReminderInterval > 0 && history.Count > halfInterval)
{
var reminderUser = new Dictionary<string, object>
{
@@ -564,17 +565,29 @@ Für welche Plattform soll die App entwickelt werden? Web, Mobile oder Desktop?
["content"] = new List<object> { new { type = "text", text = "Verstanden." } }
};
// Alle 30 Messages ein Reminder-Paar einfügen (von hinten nach vorne, damit Indizes stimmen)
var insertPositions = new List<int>();
int messageCount = 0;
for (int i = 0; i < history.Count; i++)
// Zielpositionen von hinten berechnen:
// Erste Position: history.Count - halfInterval (z.B. 15 vom Ende)
// Weitere Positionen: jeweils - ReminderInterval (z.B. 30er-Schritte rückwärts)
var targetPositions = new List<int>();
int pos = history.Count - halfInterval;
while (pos > 0)
{
messageCount++;
if (messageCount > 0 && messageCount % ReminderInterval == 0)
targetPositions.Add(pos);
pos -= ReminderInterval;
}
// Für jede Zielposition die nächste valide Einfügestelle finden
var insertPositions = new List<int>();
foreach (int target in targetPositions)
{
// Suche ab target rückwärts nach einer assistant-Message,
// deren Folge-Message kein tool_result ist
for (int i = Math.Min(target, history.Count - 1); i >= 1; i--)
{
// Position nach dem aktuellen Element – aber nur einfügen wenn es eine
// assistant-Message ist (damit user/assistant-Alternierung nicht bricht)
// UND die nächste Message kein tool_result ist (sonst bricht tool_use/tool_result-Paar)
if (!(history[i] is Dictionary<string, object> d &&
d.TryGetValue("role", out var r) && r.ToString() == "assistant"))
continue;
bool nextIsToolResult = false;
if (i + 1 < history.Count && history[i + 1] is Dictionary<string, object> nextDict &&
nextDict.TryGetValue("role", out var nextRole) && nextRole.ToString() == "user" &&
@@ -587,20 +600,20 @@ Für welche Plattform soll die App entwickelt werden? Web, Mobile oder Desktop?
});
}
if (!nextIsToolResult && history[i] is Dictionary<string, object> d &&
d.TryGetValue("role", out var r) && r.ToString() == "assistant")
if (!nextIsToolResult)
{
insertPositions.Add(i + 1);
break;
}
}
}
// Von hinten nach vorne einfügen, damit Indizes nicht verschoben werden
for (int j = insertPositions.Count - 1; j >= 0; j--)
// Deduplizieren und von hinten nach vorne einfügen, damit Indizes nicht verschoben werden
insertPositions = insertPositions.Distinct().OrderByDescending(x => x).ToList();
foreach (int insertPos in insertPositions)
{
var pos = insertPositions[j];
history.Insert(pos, reminderAssistant);
history.Insert(pos, reminderUser);
history.Insert(insertPos, reminderAssistant);
history.Insert(insertPos, reminderUser);
}
}