diff --git a/Services/AnthropicService.cs b/Services/AnthropicService.cs
index f2f8308..a847de9 100644
--- a/Services/AnthropicService.cs
+++ b/Services/AnthropicService.cs
@@ -60,6 +60,7 @@ public class AnthropicService
int iterations = 0;
int reviewRound = 0;
string lastStopReason = "";
+ int promptTrimRetries = 0;
var chain = new ChainRecord
{
@@ -106,6 +107,23 @@ public class AnthropicService
{
var errBody = await httpResp.Content.ReadAsStringAsync(workCt);
var errMsg = $"API {(int)httpResp.StatusCode}: {errBody}";
+
+ // Auto-Retry bei "prompt too long" / "exceed context limit": History kürzen und erneut versuchen
+ if ((int)httpResp.StatusCode == 400 &&
+ (errBody.Contains("prompt is too long") || errBody.Contains("exceed context limit")) &&
+ messages.Count > 4 && promptTrimRetries < 5)
+ {
+ promptTrimRetries++;
+ int trimCount = Math.Max(2, messages.Count / 5); // 20% der Messages entfernen
+ trimCount = TrimMessagesCleanly(messages, trimCount);
+ if (trimCount > 0)
+ {
+ await TryWriteSse(response, "info", new { message = $"History zu lang – {trimCount} ältere Messages entfernt, Retry ({promptTrimRetries}/5)..." }, sseCt);
+ iterations--; // Iteration nicht zählen, war ja kein echter Versuch
+ continue; // → nächste while-Iteration mit kürzerer History
+ }
+ }
+
await _db.SaveMessage(new MessageRecord
{
ChainId = chainId, Iteration = iterations,
@@ -120,6 +138,7 @@ public class AnthropicService
var (stopReason, assistantContent, executedTools, streamErrorInfo) = await ProcessStream(response, httpResp, usage, workspace, agentId, workCt, sseCt);
lastStopReason = stopReason;
+ promptTrimRetries = 0; // Erfolgreicher API-Call → Retry-Counter resetten
messages.Add(new { role = "assistant", content = assistantContent });
@@ -726,6 +745,20 @@ public class AnthropicService
if (!httpResp.IsSuccessStatusCode)
{
+ // Auto-Retry bei "prompt too long" in Sub-Agents
+ if ((int)httpResp.StatusCode == 400 &&
+ (respBody.Contains("prompt is too long") || respBody.Contains("exceed context limit")) &&
+ messages.Count > 4)
+ {
+ int trimCount = Math.Max(2, messages.Count / 5);
+ trimCount = TrimMessagesCleanly(messages, trimCount);
+ if (trimCount > 0)
+ {
+ await TryWriteSse(response, "info", new { message = $"{tag}: History zu lang – {trimCount} Messages entfernt, Retry..." }, sseCt);
+ iterations--;
+ continue;
+ }
+ }
return ($"{tag}-Agent API Fehler: {(int)httpResp.StatusCode}: {respBody}", iterations);
}
@@ -931,6 +964,20 @@ public class AnthropicService
if (!httpResp.IsSuccessStatusCode)
{
+ // Auto-Retry bei "prompt too long" in Non-Streaming
+ if ((int)httpResp.StatusCode == 400 &&
+ (respBody.Contains("prompt is too long") || respBody.Contains("exceed context limit")) &&
+ messages.Count > 4)
+ {
+ int trimCount = Math.Max(2, messages.Count / 5);
+ trimCount = TrimMessagesCleanly(messages, trimCount);
+ if (trimCount > 0)
+ {
+ iterations--;
+ continue;
+ }
+ }
+
var errMsg = $"API {(int)httpResp.StatusCode}: {respBody}";
await _db.SaveMessage(new MessageRecord
{
@@ -1485,6 +1532,50 @@ public class AnthropicService
payload["tool_choice"] = new { type = effectiveChoice };
}
+ ///
+ /// Entfernt Messages vom Anfang der Liste, ohne tool_use/tool_result-Paare zu trennen.
+ /// Gibt die tatsächliche Anzahl entfernter Messages zurück.
+ ///
+ private static int TrimMessagesCleanly(List