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

+14 -2
View File
@@ -52,7 +52,19 @@ public static class ChatEndpoint
var userId = req.HttpContext.GetUserId();
var maxIterations = config.GetValue<int>("MaxIterations", 100);
var ctx = await chatService.PrepareContext(sessionId, userId, maxIterations);
// Bei Choice-Response: planMode vom vorherigen Chain übernehmen
var effectivePlanMode = body.PlanMode;
if (isChoiceResponse && !effectivePlanMode)
{
var prevChainId = await chatService.FindChainWithToolCall(sessionId, body.ChoiceToolCallId);
if (prevChainId != null)
{
var prevChain = await db.GetChain(prevChainId);
if (prevChain != null) effectivePlanMode = prevChain.PlanMode;
}
}
var ctx = await chatService.PrepareContext(sessionId, userId, maxIterations, planMode: effectivePlanMode);
if (ctx == null)
{
res.StatusCode = 400;
@@ -132,7 +144,7 @@ public static class ChatEndpoint
try
{
await anthropic.StreamChat(res, ctx.ModelId, ctx.SystemPrompt, messages, ctx.ChainId, ctx.Workspace, sessionId, agentId: ctx.AgentId, useMemory: ctx.UseMemory, webSearchVersion: ctx.WebSearchVersion, maxIterations: ctx.MaxIterations, toolChoice: effectiveToolChoice, review: ctx.Review, finalizer: ctx.Finalizer, allowUserChoice: ctx.Agent?.AllowUserChoice ?? true, cancellationToken: linkedCts.Token);
await anthropic.StreamChat(res, ctx.ModelId, ctx.SystemPrompt, messages, ctx.ChainId, ctx.Workspace, sessionId, agentId: ctx.AgentId, useMemory: ctx.UseMemory, webSearchVersion: ctx.WebSearchVersion, maxIterations: ctx.MaxIterations, toolChoice: effectiveToolChoice, review: ctx.Review, finalizer: ctx.Finalizer, allowUserChoice: ctx.Agent?.AllowUserChoice ?? true, planMode: ctx.PlanMode, cancellationToken: linkedCts.Token);
}
finally
{