using System; using System.Collections.Generic; using System.Globalization; using System.Runtime.InteropServices; using System.Text.Json; using System.Threading; using System.Threading.Tasks; namespace AxCopilot.Services.Agent; public class DateTimeTool : IAgentTool { public string Name => "datetime_tool"; public string Description => "Date/time utility tool. Actions: 'now' — get current date/time in various formats; 'parse' — parse a date string into standard format; 'diff' — calculate difference between two dates; 'add' — add/subtract days/hours/minutes to a date; 'epoch' — convert between Unix epoch and datetime; 'format' — format a date into specified pattern."; public ToolParameterSchema Parameters { get { ToolParameterSchema toolParameterSchema = new ToolParameterSchema(); Dictionary dictionary = new Dictionary(); ToolProperty obj = new ToolProperty { Type = "string", Description = "Action to perform" }; int num = 6; List list = new List(num); CollectionsMarshal.SetCount(list, num); Span span = CollectionsMarshal.AsSpan(list); span[0] = "now"; span[1] = "parse"; span[2] = "diff"; span[3] = "add"; span[4] = "epoch"; span[5] = "format"; obj.Enum = list; dictionary["action"] = obj; dictionary["date"] = new ToolProperty { Type = "string", Description = "Date string (for parse/diff/add/format/epoch). For epoch: Unix timestamp in seconds." }; dictionary["date2"] = new ToolProperty { Type = "string", Description = "Second date string (for diff action)" }; dictionary["amount"] = new ToolProperty { Type = "string", Description = "Amount to add (for add action). E.g. '7' for 7 days" }; ToolProperty obj2 = new ToolProperty { Type = "string", Description = "Unit for add action" }; num = 6; List list2 = new List(num); CollectionsMarshal.SetCount(list2, num); Span span2 = CollectionsMarshal.AsSpan(list2); span2[0] = "days"; span2[1] = "hours"; span2[2] = "minutes"; span2[3] = "seconds"; span2[4] = "months"; span2[5] = "years"; obj2.Enum = list2; dictionary["unit"] = obj2; dictionary["pattern"] = new ToolProperty { Type = "string", Description = "Format pattern (for format action). E.g. 'yyyy-MM-dd HH:mm:ss', 'ddd MMM d yyyy'" }; toolParameterSchema.Properties = dictionary; num = 1; List list3 = new List(num); CollectionsMarshal.SetCount(list3, num); CollectionsMarshal.AsSpan(list3)[0] = "action"; toolParameterSchema.Required = list3; return toolParameterSchema; } } public Task ExecuteAsync(JsonElement args, AgentContext context, CancellationToken ct = default(CancellationToken)) { string text = args.GetProperty("action").GetString() ?? ""; try { if (1 == 0) { } ToolResult result = text switch { "now" => Now(), "parse" => Parse(args), "diff" => Diff(args), "add" => Add(args), "epoch" => Epoch(args), "format" => FormatDate(args), _ => ToolResult.Fail("Unknown action: " + text), }; if (1 == 0) { } return Task.FromResult(result); } catch (Exception ex) { return Task.FromResult(ToolResult.Fail("DateTime 오류: " + ex.Message)); } } private static ToolResult Now() { DateTime now = DateTime.Now; DateTime utcNow = DateTime.UtcNow; long value = new DateTimeOffset(utcNow).ToUnixTimeSeconds(); return ToolResult.Ok($"Local: {now:yyyy-MM-dd HH:mm:ss (ddd)} ({TimeZoneInfo.Local.DisplayName})\nUTC: {utcNow:yyyy-MM-dd HH:mm:ss}\nISO: {now:O}\nEpoch: {value}\nWeek: {CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(now, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday)}"); } private static ToolResult Parse(JsonElement args) { JsonElement value; string text = (args.TryGetProperty("date", out value) ? (value.GetString() ?? "") : ""); if (string.IsNullOrEmpty(text)) { return ToolResult.Fail("'date' parameter is required"); } if (!DateTime.TryParse(text, CultureInfo.InvariantCulture, DateTimeStyles.None, out var result) && !DateTime.TryParse(text, CultureInfo.CurrentCulture, DateTimeStyles.None, out result)) { return ToolResult.Fail("Cannot parse date: '" + text + "'"); } return ToolResult.Ok($"Parsed: {result:yyyy-MM-dd HH:mm:ss}\nDay: {result:dddd}\nISO: {result:O}\nEpoch: {new DateTimeOffset(result).ToUnixTimeSeconds()}"); } private static ToolResult Diff(JsonElement args) { JsonElement value; string text = (args.TryGetProperty("date", out value) ? (value.GetString() ?? "") : ""); JsonElement value2; string text2 = (args.TryGetProperty("date2", out value2) ? (value2.GetString() ?? "") : ""); if (string.IsNullOrEmpty(text) || string.IsNullOrEmpty(text2)) { return ToolResult.Fail("'date' and 'date2' parameters are required"); } if (!DateTime.TryParse(text, out var result)) { return ToolResult.Fail("Cannot parse date: '" + text + "'"); } if (!DateTime.TryParse(text2, out var result2)) { return ToolResult.Fail("Cannot parse date: '" + text2 + "'"); } TimeSpan timeSpan = result2 - result; return ToolResult.Ok($"From: {result:yyyy-MM-dd HH:mm:ss}\nTo: {result2:yyyy-MM-dd HH:mm:ss}\n\nDifference:\n {Math.Abs(timeSpan.TotalDays):F1} days\n {Math.Abs(timeSpan.TotalHours):F1} hours\n {Math.Abs(timeSpan.TotalMinutes):F0} minutes\n {Math.Abs(timeSpan.TotalSeconds):F0} seconds\n ({((timeSpan.TotalDays >= 0.0) ? "forward" : "backward")})"); } private static ToolResult Add(JsonElement args) { JsonElement value; string text = (args.TryGetProperty("date", out value) ? (value.GetString() ?? "") : ""); JsonElement value2; string text2 = (args.TryGetProperty("amount", out value2) ? (value2.GetString() ?? "0") : "0"); JsonElement value3; string text3 = (args.TryGetProperty("unit", out value3) ? (value3.GetString() ?? "days") : "days"); if (string.IsNullOrEmpty(text)) { return ToolResult.Fail("'date' parameter is required"); } if (!DateTime.TryParse(text, out var result)) { return ToolResult.Fail("Cannot parse date: '" + text + "'"); } if (!double.TryParse(text2, out var result2)) { return ToolResult.Fail("Invalid amount: '" + text2 + "'"); } if (1 == 0) { } DateTime dateTime = text3 switch { "days" => result.AddDays(result2), "hours" => result.AddHours(result2), "minutes" => result.AddMinutes(result2), "seconds" => result.AddSeconds(result2), "months" => result.AddMonths((int)result2), "years" => result.AddYears((int)result2), _ => result.AddDays(result2), }; if (1 == 0) { } DateTime value4 = dateTime; return ToolResult.Ok($"Original: {result:yyyy-MM-dd HH:mm:ss}\nAdded: {result2} {text3}\nResult: {value4:yyyy-MM-dd HH:mm:ss} ({value4:dddd})"); } private static ToolResult Epoch(JsonElement args) { JsonElement value; string text = (args.TryGetProperty("date", out value) ? (value.GetString() ?? "") : ""); if (string.IsNullOrEmpty(text)) { return ToolResult.Fail("'date' parameter is required"); } if (long.TryParse(text, out var result)) { DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeSeconds(result); return ToolResult.Ok($"Epoch: {result}\nUTC: {dateTimeOffset.UtcDateTime:yyyy-MM-dd HH:mm:ss}\nLocal: {dateTimeOffset.LocalDateTime:yyyy-MM-dd HH:mm:ss}"); } if (DateTime.TryParse(text, out var result2)) { long value2 = new DateTimeOffset(result2).ToUnixTimeSeconds(); return ToolResult.Ok($"Date: {result2:yyyy-MM-dd HH:mm:ss}\nEpoch: {value2}"); } return ToolResult.Fail("Cannot parse: '" + text + "'"); } private static ToolResult FormatDate(JsonElement args) { JsonElement value; string text = (args.TryGetProperty("date", out value) ? (value.GetString() ?? "") : ""); JsonElement value2; string text2 = (args.TryGetProperty("pattern", out value2) ? (value2.GetString() ?? "yyyy-MM-dd") : "yyyy-MM-dd"); if (string.IsNullOrEmpty(text)) { return ToolResult.Fail("'date' parameter is required"); } if (!DateTime.TryParse(text, out var result)) { return ToolResult.Fail("Cannot parse date: '" + text + "'"); } return ToolResult.Ok(result.ToString(text2, CultureInfo.InvariantCulture)); } }