Remote-Keep-Alive gegen 180s-Timeout + System-Prompt via Datei

Task 1 – Remote-Befehle laufen nicht mehr in einen starren 180s-Timeout:
- RemoteConnectionManager.ExecuteCommand nutzt jetzt einen INAKTIVITÄTS-
  Timeout (Watchdog auf LastProgressAt) statt hartem Wall-Clock-Limit; ein
  Befehl darf beliebig lange laufen, solange der Client Progress-Frames sendet.
- RemoteEndpoint: neuer "progress"-Case setzt die Frist zurück.
- InternalEndpoint (MCP-Pfad remote_execute): hartes CancellationTokenSource(180s)
  entfernt → nutzt konfigurierbares ExecuteTimeout-Setting + RequestAborted.
- remote.ps1 / remote.sh: senden während laufender Befehle alle 15s ein
  {"type":"progress"}-Keep-Alive; async stdout/stderr-Lesen gegen Pipe-Deadlocks.
- ToolService: Tool-Beschreibungen erklären den Inaktivitäts-Timeout.

Task 2 – System-Prompt über --system-prompt-file statt CLI-Argument:
- ClaudeCliService schreibt den vollen System-Prompt in eine Temp-Datei und
  übergibt --system-prompt-file, um das Windows-Kommandozeilen-Längenlimit zu
  umgehen. Cleanup im finally. Agent-Verhalten unverändert (MEMORY.md bleibt inline).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
MelekiandClaude Opus 4.8 committed 2026-07-21 09:21:55 +02:00
1 parent 9db9bd4cc7
commit ace5036f00
7 files changed
+118 -26

No files matched your search

+7 -3
View File
@@ -42,7 +42,7 @@ public static class InternalEndpoint
app.MapPost("/api/internal/memory-list", HandleMemoryList);
}
private static async Task<IResult> HandleRemoteExecute(HttpContext ctx, RemoteConnectionManager mgr)
private static async Task<IResult> HandleRemoteExecute(HttpContext ctx, RemoteConnectionManager mgr, ServerSettingsService settings)
{
try
{
@@ -71,8 +71,12 @@ public static class InternalEndpoint
if (conn == null)
return Results.NotFound(new { error = "Keine Remote-Verbindung für diese Session" });
using var cts = new CancellationTokenSource(System.TimeSpan.FromSeconds(180));
var result = await mgr.ExecuteCommand(conn.Id, command, 180, cts.Token);
// Kein hartes Wall-Clock-Limit mehr: ExecuteCommand nutzt einen INAKTIVITÄTS-Timeout
// (Client sendet Progress-Keep-Alives). Als Frist die konfigurierbare ExecuteTimeout-
// Einstellung verwenden; abgebrochen wird nur bei echtem Client-Stillstand oder wenn
// der Request selbst abbricht (RequestAborted).
var inactivityTimeout = settings.GetInt("ExecuteTimeout", 180);
var result = await mgr.ExecuteCommand(conn.Id, command, inactivityTimeout, ctx.RequestAborted);
return Results.Ok(new
{
+7
View File
@@ -138,6 +138,13 @@ public static class RemoteEndpoint
mgr.HandleResult(conn.Id, cmdResult);
break;
case "progress":
// Keep-Alive während eines laufenden Befehls: Inaktivitäts-Timeout in
// ExecuteCommand zurücksetzen (LastActivityAt oben deckt zusätzlich den
// WebSocket-Dead-Timeout ab). So laufen lange Befehle nicht in den Timeout.
mgr.HandleProgress(conn.Id);
break;
case "ping":
var pong = Encoding.UTF8.GetBytes("{\"type\":\"pong\"}");
await ws.SendAsync(pong, WebSocketMessageType.Text, true, ct);