feat: Plan-Modus – Toggle im Chat zum Umschalten zwischen Plan/Ausführung

- Toggle-Button (🗺️) im Chat-Input-Bereich neben Explorer
- Plan-Modus wird per ChatRequest.planMode an Backend gesendet
- Backend: Write-Tools gefiltert (nur read_file, list_files, glob, grep,
  todo_write, memory_*, ask_user_choice bleiben), System-Prompt-Block
  ergänzt der Änderungen verbietet, tool_choice nie 'any' erzwungen
- ChainRecord.PlanMode: pro Chain gespeichert (informativ für History)
- Chain-Meta-Badge '📋 Plan-Modus' bei Plan-Chains
- Choice-Response erbt planMode vom vorherigen Chain
- CSS: .plan-mode-active Styling (Primary-Color Highlight)
- Placeholder wechselt zu 'Plannen...' wenn aktiv
- Plan-Modus wird bei Session-Wechsel zurückgesetzt
This commit is contained in:
Meleki committed 2026-03-07 12:07:39 +01:00
1 parent 1c11ffa3cd
commit 6d95f9aec2
13 files changed
+123 -13

No files matched your search

+28
View File
@@ -17,6 +17,34 @@ public class ToolService
{
public const string AskUserChoiceToolName = "ask_user_choice";
/// <summary>
/// Read-only Tools die im Plan-Modus verfügbar bleiben.
/// Write-Tools (write_file, edit_file, delete_file, execute) werden entfernt.
/// </summary>
private static readonly HashSet<string> ReadOnlyToolNames = new HashSet<string>
{
"read_file", "list_files", "glob", "grep", "todo_write",
"memory_read", "memory_write", "memory_list",
AskUserChoiceToolName
};
public object[] FilterReadOnlyTools(object[] tools)
{
var filtered = new List<object>();
foreach (var tool in tools)
{
var json = JsonSerializer.Serialize(tool);
var el = JsonSerializer.Deserialize<JsonElement>(json);
if (el.TryGetProperty("name", out var nameProp))
{
var name = nameProp.GetString() ?? "";
if (ReadOnlyToolNames.Contains(name))
filtered.Add(tool);
}
}
return filtered.ToArray();
}
public object[] GetToolDefinitions(bool includeFileTools = false, bool includeMemory = false, bool includeUserChoice = true)
{
var allTools = new List<object>();