using System.Data; using System.Text.Json; namespace AxCopilot.Services.Agent; /// 수학 수식을 계산하는 도구. public class MathTool : IAgentTool { public string Name => "math_eval"; public string Description => "Evaluate a mathematical expression and return the result. " + "Supports: +, -, *, /, %, parentheses, and common math operations. " + "Use for calculations, unit conversions, and numeric analysis."; public ToolParameterSchema Parameters => new() { Properties = new() { ["expression"] = new() { Type = "string", Description = "Mathematical expression to evaluate (e.g. '(100 * 1.08) / 3')", }, ["precision"] = new() { Type = "integer", Description = "Decimal places for rounding (default: 6)", }, }, Required = ["expression"], }; public Task ExecuteAsync(JsonElement args, AgentContext context, CancellationToken ct = default) { var expression = args.GetProperty("expression").GetString() ?? ""; var precision = args.TryGetProperty("precision", out var p) ? p.GetInt32() : 6; if (string.IsNullOrWhiteSpace(expression)) return Task.FromResult(ToolResult.Fail("수식이 비어 있습니다.")); try { // DataTable.Compute를 사용한 안전한 수식 평가 var sanitized = expression .Replace("^", " ") // XOR 방지 — ** 패턴은 아래에서 처리 .Replace("Math.", "") .Replace("System.", ""); // 기본 보안 검사: 알파벳 함수 호출 차단 if (System.Text.RegularExpressions.Regex.IsMatch(sanitized, @"[a-zA-Z]{3,}")) return Task.FromResult(ToolResult.Fail("함수 호출은 지원하지 않습니다. 기본 사칙연산만 가능합니다.")); var dt = new DataTable(); var result = dt.Compute(sanitized, null); var value = Convert.ToDouble(result); var rounded = Math.Round(value, precision); return Task.FromResult(ToolResult.Ok( $"Expression: {expression}\nResult: {rounded}")); } catch (Exception ex) { return Task.FromResult(ToolResult.Fail($"수식 평가 오류: {ex.Message}")); } } }