using System.Text.Json; namespace Agent.Core.Tools; public sealed class InternalToolDispatcher(IToolPolicyEngine policy, IInternalToolBackend backend) { public Task BeginTaskAsync(Guid taskId, Guid sessionId, CancellationToken cancellationToken) => backend.BeginTaskAsync(taskId, sessionId, cancellationToken); public Task EndTaskAsync(Guid taskId, bool success, CancellationToken cancellationToken) => backend.EndTaskAsync(taskId, success, cancellationToken); public async Task DispatchAsync(Guid taskId, string toolName, JsonElement arguments, CancellationToken cancellationToken) { InternalToolValidator.Validate(toolName, arguments); ToolPolicyDecision decision = policy.Evaluate(toolName, arguments); if (!decision.Allowed) return new(false, decision.Reason, false, $"policy:{toolName}:{decision.Reason}", RetryAllowed: false, ErrorCode: "policy.tool_denied", ErrorCategory: "policy", Resolution: "Review the enabled Internal Tool policy."); return await backend.ExecuteAsync(taskId, toolName, arguments, cancellationToken).ConfigureAwait(false); } } public sealed class FakeInternalToolBackend : IInternalToolBackend { private readonly List<(string Name, JsonElement Arguments)> _calls = []; public IReadOnlyList<(string Name, JsonElement Arguments)> Calls => _calls; public Task ExecuteAsync(Guid taskId, string toolName, JsonElement arguments, CancellationToken cancellationToken) { _calls.Add((toolName, arguments.Clone())); bool effect = toolName is "file_edit" or "process_run" or "dir"; return Task.FromResult(new ToolExecutionResult(true, "fake-ok", effect)); } }