using AxCopilot.Models; namespace AxCopilot.Services.Agent; public partial class AgentLoopService { private static (bool ShouldRun, List ParallelBatch, List SequentialBatch) CreateParallelExecutionPlan(bool parallelEnabled, List toolCalls, int maxParallelBatch) { if (!parallelEnabled || toolCalls.Count <= 1) return (false, new List(), toolCalls); var (parallelBatch, sequentialBatch) = ClassifyToolCalls(toolCalls); if (maxParallelBatch > 0 && parallelBatch.Count > maxParallelBatch) { var overflow = parallelBatch.Skip(maxParallelBatch).ToList(); parallelBatch = parallelBatch.Take(maxParallelBatch).ToList(); sequentialBatch = overflow.Concat(sequentialBatch).ToList(); } return (true, parallelBatch, sequentialBatch); } private static ( string? LastFailedToolSignature, int RepeatedFailedToolSignatureCount, int ConsecutiveErrors, bool CanRetry) ComputeFailureTransitionState( string currentToolCallSignature, string? lastFailedToolSignature, int repeatedFailedToolSignatureCount, int consecutiveErrors, int maxRetry) { if (string.Equals(lastFailedToolSignature, currentToolCallSignature, StringComparison.Ordinal)) repeatedFailedToolSignatureCount++; else { lastFailedToolSignature = currentToolCallSignature; repeatedFailedToolSignatureCount = 1; } consecutiveErrors++; var canRetry = consecutiveErrors <= maxRetry; return (lastFailedToolSignature, repeatedFailedToolSignatureCount, consecutiveErrors, canRetry); } private static bool ShouldRunPostToolVerification( string? activeTab, string? toolName, bool toolSucceeded, bool codeVerificationEnabled, bool coworkVerificationEnabled) { if (!toolSucceeded || string.IsNullOrWhiteSpace(toolName)) return false; if (string.Equals(activeTab, "Code", StringComparison.OrdinalIgnoreCase)) return codeVerificationEnabled && IsCodeVerificationTarget(toolName); return coworkVerificationEnabled && IsDocumentCreationTool(toolName); } private static (bool ShouldContinue, string? TerminalResponse, string? ToolResultMessage) EvaluateDevStepDecision(string? decision) { if (string.Equals(decision, "중단", StringComparison.Ordinal)) return (false, "사용자가 개발자 모드에서 실행을 중단했습니다.", null); if (string.Equals(decision, "건너뛰기", StringComparison.Ordinal)) return (true, null, "[SKIPPED by developer] 사용자가 이 도구 실행을 건너뛰었습니다."); return (false, null, null); } private static (bool ShouldContinue, string? TerminalResponse, string? ToolResultMessage) EvaluateScopeDecision(string? decision) { if (string.Equals(decision, "취소", StringComparison.Ordinal)) return (false, "사용자가 작업을 취소했습니다.", null); if (string.Equals(decision, "건너뛰기", StringComparison.Ordinal)) return (true, null, "[SKIPPED] 사용자가 이 작업을 건너뛰었습니다."); return (false, null, null); } }