From 8f8e82e00e5d0e9347feef10111faac788ad7d88 Mon Sep 17 00:00:00 2001 From: tanaka takashi Date: Tue, 11 Aug 2026 22:36:21 +0900 Subject: Require task-specific tool evidence --- src/Agent.Planner/TaskGraph.cs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'src/Agent.Planner/TaskGraph.cs') diff --git a/src/Agent.Planner/TaskGraph.cs b/src/Agent.Planner/TaskGraph.cs index 729f646..a4cdc5f 100644 --- a/src/Agent.Planner/TaskGraph.cs +++ b/src/Agent.Planner/TaskGraph.cs @@ -19,7 +19,7 @@ public sealed class TaskGraph(int maxTasks = 32) IEnumerable? dependencies = null, bool requiresExternalEffect = false, Guid? id = null, - IEnumerable? requiredEffectTools = null) + IEnumerable? requiredTools = null) { if (string.IsNullOrWhiteSpace(description)) throw new PlannerValidationException("Task description is required."); if (_tasks.Count >= MaxTasks) throw new PlannerValidationException($"Task limit of {MaxTasks} exceeded."); @@ -27,13 +27,12 @@ public sealed class TaskGraph(int maxTasks = 32) Guid taskId = id ?? Guid.NewGuid(); if (_tasks.ContainsKey(taskId)) throw new PlannerValidationException($"Task '{taskId}' already exists."); HashSet dependencySet = dependencies?.ToHashSet() ?? []; - HashSet effectTools = requiredEffectTools?.ToHashSet(StringComparer.Ordinal) ?? []; - if (requiresExternalEffect && effectTools.Count == 0) throw new PlannerValidationException("An external-effect Task must name at least one required effect tool."); - if (!requiresExternalEffect && effectTools.Count != 0) throw new PlannerValidationException("A non-effect Task cannot require an effect tool."); + HashSet tools = requiredTools?.ToHashSet(StringComparer.Ordinal) ?? []; + if (requiresExternalEffect && tools.Count == 0) throw new PlannerValidationException("An external-effect Task must name at least one required tool."); EnsureDependenciesExist(dependencySet); if (dependencySet.Contains(taskId)) throw new PlannerValidationException("A task cannot depend on itself."); - _tasks.Add(taskId, new MutableTask(taskId, description, dependencySet, budgetClass, estimate, requiresExternalEffect, effectTools)); + _tasks.Add(taskId, new MutableTask(taskId, description, dependencySet, budgetClass, estimate, requiresExternalEffect, tools)); _insertionOrder.Add(taskId); try { @@ -167,7 +166,7 @@ public sealed class TaskGraph(int maxTasks = 32) if (task.State == PlannerTaskState.Completed) throw new PlannerValidationException("Completed tasks are immutable."); } - private sealed class MutableTask(Guid id, string description, HashSet dependencies, TokenBudgetClass budgetClass, TokenEstimate estimate, bool requiresExternalEffect, HashSet requiredEffectTools) + private sealed class MutableTask(Guid id, string description, HashSet dependencies, TokenBudgetClass budgetClass, TokenEstimate estimate, bool requiresExternalEffect, HashSet requiredTools) { public Guid Id { get; } = id; public string Description { get; } = description; @@ -178,7 +177,7 @@ public sealed class TaskGraph(int maxTasks = 32) public long ActualInputTokens { get; set; } public long ActualOutputTokens { get; set; } public bool RequiresExternalEffect { get; } = requiresExternalEffect; - public HashSet RequiredEffectTools { get; } = requiredEffectTools; - public PlannerTask Snapshot() => new(Id, Description, Dependencies.ToHashSet(), State, BudgetClass, Estimate, ActualInputTokens, ActualOutputTokens, RequiresExternalEffect, RequiredEffectTools.ToHashSet(StringComparer.Ordinal)); + public HashSet RequiredTools { get; } = requiredTools; + public PlannerTask Snapshot() => new(Id, Description, Dependencies.ToHashSet(), State, BudgetClass, Estimate, ActualInputTokens, ActualOutputTokens, RequiresExternalEffect, RequiredTools.ToHashSet(StringComparer.Ordinal)); } } -- cgit v1.2.3