124 lines
4.1 KiB
C#
124 lines
4.1 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Runtime.InteropServices;
|
|
using System.Text.Encodings.Web;
|
|
using System.Text.Json;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace AxCopilot.Services.Agent;
|
|
|
|
public class SuggestActionsTool : IAgentTool
|
|
{
|
|
public string Name => "suggest_actions";
|
|
|
|
public string Description => "Suggest 2-5 follow-up actions after completing a task. Returns structured JSON that the UI renders as clickable action chips. Each action has a label (display text), command (slash command or natural language prompt), optional icon (Segoe MDL2 Assets code), and priority (high/medium/low).";
|
|
|
|
public ToolParameterSchema Parameters
|
|
{
|
|
get
|
|
{
|
|
ToolParameterSchema obj = new ToolParameterSchema
|
|
{
|
|
Properties = new Dictionary<string, ToolProperty>
|
|
{
|
|
["actions"] = new ToolProperty
|
|
{
|
|
Type = "array",
|
|
Description = "List of action objects. Each object: {\"label\": \"표시 텍스트\", \"command\": \"/slash 또는 자연어\", \"icon\": \"\\uE8A5\" (optional), \"priority\": \"high|medium|low\"}",
|
|
Items = new ToolProperty
|
|
{
|
|
Type = "object",
|
|
Description = "Action object with label, command, icon, priority"
|
|
}
|
|
},
|
|
["context"] = new ToolProperty
|
|
{
|
|
Type = "string",
|
|
Description = "Current task context summary (optional)"
|
|
}
|
|
}
|
|
};
|
|
int num = 1;
|
|
List<string> list = new List<string>(num);
|
|
CollectionsMarshal.SetCount(list, num);
|
|
CollectionsMarshal.AsSpan(list)[0] = "actions";
|
|
obj.Required = list;
|
|
return obj;
|
|
}
|
|
}
|
|
|
|
public Task<ToolResult> ExecuteAsync(JsonElement args, AgentContext context, CancellationToken ct = default(CancellationToken))
|
|
{
|
|
try
|
|
{
|
|
if (!args.TryGetProperty("actions", out var value) || value.ValueKind != JsonValueKind.Array)
|
|
{
|
|
return Task.FromResult(ToolResult.Fail("actions 배열이 필요합니다."));
|
|
}
|
|
List<Dictionary<string, string>> list = new List<Dictionary<string, string>>();
|
|
foreach (JsonElement item in value.EnumerateArray())
|
|
{
|
|
JsonElement value3;
|
|
string value2 = (item.TryGetProperty("label", out value3) ? (value3.GetString() ?? "") : "");
|
|
JsonElement value5;
|
|
string value4 = (item.TryGetProperty("command", out value5) ? (value5.GetString() ?? "") : "");
|
|
JsonElement value7;
|
|
string value6 = (item.TryGetProperty("icon", out value7) ? (value7.GetString() ?? "") : "");
|
|
JsonElement value9;
|
|
string value8 = (item.TryGetProperty("priority", out value9) ? (value9.GetString() ?? "medium") : "medium");
|
|
if (string.IsNullOrWhiteSpace(value2))
|
|
{
|
|
return Task.FromResult(ToolResult.Fail("각 action에는 label이 필요합니다."));
|
|
}
|
|
if (string.IsNullOrWhiteSpace(value4))
|
|
{
|
|
return Task.FromResult(ToolResult.Fail("각 action에는 command가 필요합니다."));
|
|
}
|
|
string[] source = new string[3] { "high", "medium", "low" };
|
|
if (!source.Contains(value8))
|
|
{
|
|
value8 = "medium";
|
|
}
|
|
Dictionary<string, string> dictionary = new Dictionary<string, string>
|
|
{
|
|
["label"] = value2,
|
|
["command"] = value4,
|
|
["priority"] = value8
|
|
};
|
|
if (!string.IsNullOrEmpty(value6))
|
|
{
|
|
dictionary["icon"] = value6;
|
|
}
|
|
list.Add(dictionary);
|
|
}
|
|
if (list.Count < 1 || list.Count > 5)
|
|
{
|
|
return Task.FromResult(ToolResult.Fail("actions는 1~5개 사이여야 합니다."));
|
|
}
|
|
JsonElement value11;
|
|
string value10 = (args.TryGetProperty("context", out value11) ? (value11.GetString() ?? "") : "");
|
|
Dictionary<string, object> dictionary2 = new Dictionary<string, object>
|
|
{
|
|
["type"] = "suggest_actions",
|
|
["actions"] = list
|
|
};
|
|
if (!string.IsNullOrEmpty(value10))
|
|
{
|
|
dictionary2["context"] = value10;
|
|
}
|
|
string output = JsonSerializer.Serialize(dictionary2, new JsonSerializerOptions
|
|
{
|
|
WriteIndented = true,
|
|
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
|
|
});
|
|
return Task.FromResult(ToolResult.Ok(output));
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return Task.FromResult(ToolResult.Fail("액션 제안 오류: " + ex.Message));
|
|
}
|
|
}
|
|
}
|