using Agent.Core.Tasks; using Microsoft.Extensions.Hosting; using Agent.Core.Runtime; namespace Agent.Mcp; public sealed class QueuedTaskWorker(TaskRegistry registry, AgentRuntime runtime) : BackgroundService { protected override async Task ExecuteAsync(CancellationToken stoppingToken) { await foreach (Guid taskId in registry.ReadQueuedAsync(stoppingToken).ConfigureAwait(false)) { if (!registry.Transition(taskId, AgentTaskState.Planning, "planning")) continue; using var linked = CancellationTokenSource.CreateLinkedTokenSource(stoppingToken, registry.GetCancellationToken(taskId)); try { // ExecuteAsync handles Planning → Running transition internally. await runtime.ExecuteAsync(taskId, linked.Token).ConfigureAwait(false); } catch (OperationCanceledException) when (linked.IsCancellationRequested) { registry.Cancel(taskId); } } } }