using System.Text.Json; namespace AxCopilot.Services.Agent; /// /// 환경변수 읽기·쓰기 도구. /// 현재 프로세스 범위에서만 동작하며 시스템 환경변수는 변경하지 않습니다. /// public class EnvTool : IAgentTool { public string Name => "env_tool"; public string Description => "Read or set environment variables (process scope only). Actions: " + "'get' — read an environment variable value; " + "'set' — set an environment variable (process scope, not permanent); " + "'list' — list all environment variables; " + "'expand' — expand %VAR% references in a string."; public ToolParameterSchema Parameters => new() { Properties = new() { ["action"] = new() { Type = "string", Description = "Action to perform", Enum = ["get", "set", "list", "expand"], }, ["name"] = new() { Type = "string", Description = "Variable name (for get/set)", }, ["value"] = new() { Type = "string", Description = "Variable value (for set) or string to expand (for expand)", }, ["filter"] = new() { Type = "string", Description = "Filter pattern for list action (case-insensitive substring match)", }, }, Required = ["action"], }; public Task ExecuteAsync(JsonElement args, AgentContext context, CancellationToken ct = default) { var action = args.GetProperty("action").GetString() ?? ""; try { return Task.FromResult(action switch { "get" => Get(args), "set" => Set(args), "list" => ListVars(args), "expand" => Expand(args), _ => ToolResult.Fail($"Unknown action: {action}"), }); } catch (Exception ex) { return Task.FromResult(ToolResult.Fail($"환경변수 오류: {ex.Message}")); } } private static ToolResult Get(JsonElement args) { if (!args.TryGetProperty("name", out var n)) return ToolResult.Fail("'name' parameter is required for get action"); var name = n.GetString() ?? ""; var value = Environment.GetEnvironmentVariable(name); return value != null ? ToolResult.Ok($"{name}={value}") : ToolResult.Ok($"{name} is not set"); } private static ToolResult Set(JsonElement args) { if (!args.TryGetProperty("name", out var n)) return ToolResult.Fail("'name' parameter is required for set action"); if (!args.TryGetProperty("value", out var v)) return ToolResult.Fail("'value' parameter is required for set action"); var name = n.GetString() ?? ""; var value = v.GetString() ?? ""; Environment.SetEnvironmentVariable(name, value, EnvironmentVariableTarget.Process); return ToolResult.Ok($"✓ Set {name}={value} (process scope)"); } private static ToolResult ListVars(JsonElement args) { var filter = args.TryGetProperty("filter", out var f) ? f.GetString() ?? "" : ""; var vars = Environment.GetEnvironmentVariables(); var entries = new List(); foreach (System.Collections.DictionaryEntry entry in vars) { var key = entry.Key?.ToString() ?? ""; var val = entry.Value?.ToString() ?? ""; if (!string.IsNullOrEmpty(filter) && !key.Contains(filter, StringComparison.OrdinalIgnoreCase) && !val.Contains(filter, StringComparison.OrdinalIgnoreCase)) continue; // 긴 값은 자르기 if (val.Length > 120) val = val[..120] + "..."; entries.Add($"{key}={val}"); } entries.Sort(StringComparer.OrdinalIgnoreCase); var result = $"Environment variables ({entries.Count}):\n" + string.Join("\n", entries); if (result.Length > 8000) result = result[..8000] + "\n... (truncated)"; return ToolResult.Ok(result); } private static ToolResult Expand(JsonElement args) { if (!args.TryGetProperty("value", out var v)) return ToolResult.Fail("'value' parameter is required for expand action"); var input = v.GetString() ?? ""; var expanded = Environment.ExpandEnvironmentVariables(input); return ToolResult.Ok(expanded); } }