summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortanaka takashi <isazaka@gmail.com>2026-08-11 05:54:22 +0900
committertanaka takashi <isazaka@gmail.com>2026-08-11 05:54:22 +0900
commit7aa4ff5d8403e4c1480faafce0af8d3549276c9f (patch)
tree6fe55142e9e8ede756ca5253031473ec4ab7515b
parent35719799e62a18850efc52d380fb53bf3baa8022 (diff)
Fix PlanAsync fallback and BeginTask TaskGraph conflict
Two runtime bugs discovered during MCP integration testing: 1. PlannerService.BuildTaskGraph fallback: If the LLM-generated plan contains invalid tasks (bad estimates, cycles, etc.), graph.AddTask throws PlannerValidationException. Previously this propagated up and caused "No tasks were executed." or "Planning failed" errors. Fix: wrap BuildTaskGraph in try/catch, fall back to single-task graph. Also handle graph.Count == 0 after filtering. 2. TaskGraphToolHandler.BeginTask conflict: PlanAsync stores the planned TaskGraph in session.TaskGraphs[taskId] before RunAsync calls BeginTaskAsync. BeginTask then tried TryAdd which failed because the key already existed, throwing "TaskGraph for '...' already exists in session". Fix: use TryAdd without throwing on conflict — if PlanAsync already created the graph, keep it; otherwise add a new empty one. Test results: Core 61/61, Planner 10/10, Windows 41/41 (elevated). MCP integration: agent_run/agent_status verified via HTTP transport. ACL boundary: C:\Windows\System32 access correctly denied by sandbox. ToolUseGuard: "Required external effect was not completed" fires correctly when LLM does not produce verifiable external effect.
-rw-r--r--src/Agent.Core/Runtime/PlannerService.cs25
-rw-r--r--src/Agent.Core/Tools/TaskGraphToolHandler.cs8
2 files changed, 26 insertions, 7 deletions
diff --git a/src/Agent.Core/Runtime/PlannerService.cs b/src/Agent.Core/Runtime/PlannerService.cs
index 7a450d0..110e476 100644
--- a/src/Agent.Core/Runtime/PlannerService.cs
+++ b/src/Agent.Core/Runtime/PlannerService.cs
@@ -55,7 +55,15 @@ public sealed class PlannerService(IOllamaClient ollama, AgentRuntimeSettings se
if (plan is null || plan.Tasks.Count == 0)
return CreateFallbackGraph(request);
- TaskGraph graph = BuildTaskGraph(plan, request);
+ TaskGraph graph;
+ try
+ {
+ graph = BuildTaskGraph(plan, request);
+ }
+ catch
+ {
+ return CreateFallbackGraph(request);
+ }
session.TaskGraphs[taskId] = graph;
return graph;
}
@@ -116,10 +124,21 @@ public sealed class PlannerService(IOllamaClient ollama, AgentRuntimeSettings se
}
string description = string.IsNullOrWhiteSpace(pt.Description) ? originalRequest : pt.Description;
- PlannerTask task = graph.AddTask(description, budgetClass, estimate, dependencies, pt.RequiresExternalEffect);
- idMap.Add(task.Id);
+ try
+ {
+ PlannerTask task = graph.AddTask(description, budgetClass, estimate, dependencies, pt.RequiresExternalEffect);
+ idMap.Add(task.Id);
+ }
+ catch (PlannerValidationException)
+ {
+ // If a task fails validation (e.g., bad estimate, cycle), fall back to single-task graph.
+ return CreateFallbackGraph(originalRequest);
+ }
}
+ // If all tasks were filtered out, fall back.
+ if (graph.Count == 0) return CreateFallbackGraph(originalRequest);
+
return graph;
}
diff --git a/src/Agent.Core/Tools/TaskGraphToolHandler.cs b/src/Agent.Core/Tools/TaskGraphToolHandler.cs
index edc1cc5..10094d3 100644
--- a/src/Agent.Core/Tools/TaskGraphToolHandler.cs
+++ b/src/Agent.Core/Tools/TaskGraphToolHandler.cs
@@ -21,13 +21,13 @@ public sealed class TaskGraphToolHandler(int maxTasks = 32, SessionStore? sessio
TaskGraph graph = new(maxTasks);
if (sessions is not null && sessions.TryGet(sessionId, out AgentSession? session) && session is not null)
{
- if (!session.TaskGraphs.TryAdd(taskId, graph))
- throw new InvalidOperationException($"TaskGraph for '{taskId}' already exists in session '{sessionId}'.");
+ // PlanAsync may have already created a TaskGraph for this taskId.
+ // If so, keep the planned graph; otherwise add a new empty one.
+ session.TaskGraphs.TryAdd(taskId, graph);
}
else
{
- if (!_fallbackGraphs.TryAdd(taskId, graph))
- throw new InvalidOperationException($"TaskGraph for '{taskId}' already exists.");
+ _fallbackGraphs.TryAdd(taskId, graph);
}
}