mirror of
https://github.com/davidkaya/aryx.git
synced 2026-08-26 12:53:59 +02:00
feat: emit tool-call file previews
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -19,6 +19,7 @@ internal sealed class CopilotApprovalCoordinator
|
||||
private const string MemoryPermissionKind = "memory";
|
||||
private const string CustomToolPermissionKind = "custom-tool";
|
||||
private const string HookPermissionKind = "hook";
|
||||
private const string ToolCallingActivityType = "tool-calling";
|
||||
|
||||
private readonly ConcurrentDictionary<string, PendingApprovalRequest> _pendingApprovals = new(StringComparer.Ordinal);
|
||||
private readonly ConcurrentDictionary<string, ConcurrentDictionary<string, byte>> _requestApprovedTools = new(StringComparer.Ordinal);
|
||||
@@ -54,11 +55,40 @@ internal sealed class CopilotApprovalCoordinator
|
||||
IReadOnlyDictionary<string, string> toolNamesByCallId,
|
||||
Func<ApprovalRequestedEventDto, Task> onApproval,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
return await RequestApprovalAsync(
|
||||
command,
|
||||
agent,
|
||||
request,
|
||||
invocation,
|
||||
toolNamesByCallId,
|
||||
onActivity: null,
|
||||
onApproval,
|
||||
cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task<PermissionRequestResult> RequestApprovalAsync(
|
||||
RunTurnCommandDto command,
|
||||
PatternAgentDefinitionDto agent,
|
||||
PermissionRequest request,
|
||||
PermissionInvocation invocation,
|
||||
IReadOnlyDictionary<string, string> toolNamesByCallId,
|
||||
Func<AgentActivityEventDto, Task>? onActivity,
|
||||
Func<ApprovalRequestedEventDto, Task> onApproval,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
string? toolName = ResolveApprovalToolName(request, toolNamesByCallId);
|
||||
string? autoApprovedToolName = ResolveAutoApprovedToolName(request);
|
||||
string? mcpServerApprovalKey = ResolveMcpServerApprovalKey(request);
|
||||
string? approvalCacheKey = ResolveApprovalCacheKey(toolName, autoApprovedToolName);
|
||||
|
||||
AgentActivityEventDto? fileChangeActivity = BuildToolCallFileChangeActivity(command, agent, request, toolName);
|
||||
if (fileChangeActivity is not null && onActivity is not null)
|
||||
{
|
||||
await onActivity(fileChangeActivity).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (IsToolApprovedForRequest(command.RequestId, approvalCacheKey)
|
||||
|| !RequiresToolCallApproval(command.Pattern.ApprovalPolicy, agent.Id, toolName, autoApprovedToolName, mcpServerApprovalKey))
|
||||
{
|
||||
@@ -154,6 +184,46 @@ internal sealed class CopilotApprovalCoordinator
|
||||
};
|
||||
}
|
||||
|
||||
internal static AgentActivityEventDto? BuildToolCallFileChangeActivity(
|
||||
RunTurnCommandDto command,
|
||||
PatternAgentDefinitionDto agent,
|
||||
PermissionRequest request,
|
||||
string? toolName)
|
||||
{
|
||||
if (request is not PermissionRequestWrite write)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
string? filePath = NormalizeOptionalString(write.FileName);
|
||||
if (filePath is null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
string agentName = string.IsNullOrWhiteSpace(agent.Name) ? agent.Id : agent.Name;
|
||||
return new AgentActivityEventDto
|
||||
{
|
||||
Type = "agent-activity",
|
||||
RequestId = command.RequestId,
|
||||
SessionId = command.SessionId,
|
||||
ActivityType = ToolCallingActivityType,
|
||||
AgentId = NormalizeOptionalString(agent.Id),
|
||||
AgentName = NormalizeOptionalString(agentName),
|
||||
ToolName = NormalizeOptionalString(toolName),
|
||||
ToolCallId = NormalizeOptionalString(write.ToolCallId),
|
||||
FileChanges =
|
||||
[
|
||||
new ToolCallFileChangeDto
|
||||
{
|
||||
Path = filePath,
|
||||
Diff = NormalizeOptionalPreviewText(write.Diff),
|
||||
NewFileContents = NormalizeOptionalPreviewText(write.NewFileContents),
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
internal static PermissionDetailDto BuildPermissionDetail(PermissionRequest request)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(request);
|
||||
@@ -495,6 +565,11 @@ internal sealed class CopilotApprovalCoordinator
|
||||
return string.IsNullOrWhiteSpace(value) ? null : value.Trim();
|
||||
}
|
||||
|
||||
private static string? NormalizeOptionalPreviewText(string? value)
|
||||
{
|
||||
return string.IsNullOrWhiteSpace(value) ? null : value;
|
||||
}
|
||||
|
||||
private static IReadOnlyList<string>? NormalizeOptionalStringList(IEnumerable<string?> values)
|
||||
{
|
||||
List<string> normalized = values
|
||||
|
||||
@@ -50,6 +50,7 @@ public sealed class CopilotWorkflowRunner : ITurnWorkflowRunner
|
||||
request,
|
||||
invocation,
|
||||
state.ToolNamesByCallId,
|
||||
activity => EmitActivityAsync(command, state, activity, onEvent),
|
||||
onApproval,
|
||||
runCancellation.Token),
|
||||
(agent, request, invocation) => _userInputCoordinator.RequestUserInputAsync(
|
||||
|
||||
@@ -74,6 +74,7 @@ internal static class WorkflowRequestInfoInterpreter
|
||||
AgentId = activeAgent.AgentId,
|
||||
AgentName = activeAgent.AgentName,
|
||||
ToolName = tool.ToolName,
|
||||
ToolCallId = tool.ToolCallId,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user