fix: enrich tool activity arguments on dedup

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
David Kaya
2026-04-08 12:14:03 +02:00
co-authored by Copilot
parent 0e2f9b8ae5
commit b9e73831e8
6 changed files with 178 additions and 35 deletions
@@ -319,7 +319,8 @@ public class AgentWorkflowTurnRunner : ITurnWorkflowRunner
command,
requestInfo,
state.ActiveAgent,
state.ToolNamesByCallId);
state.ToolNamesByCallId,
state.ToolCallHasArgumentsById);
if (activity is null)
{
@@ -23,6 +23,8 @@ internal class TurnExecutionState
public ConcurrentDictionary<string, string> ToolNamesByCallId { get; } = new(StringComparer.Ordinal);
public ConcurrentDictionary<string, bool> ToolCallHasArgumentsById { get; } = new(StringComparer.Ordinal);
public AgentIdentity? ActiveAgent { get; private set; }
public List<ChatMessageDto> CompletedMessages { get; private set; } = [];
@@ -93,7 +95,7 @@ internal class TurnExecutionState
case ProviderToolExecutionStartEvent toolExecutionStart:
string toolCallId = toolExecutionStart.ToolCallId;
string toolName = toolExecutionStart.ToolName;
ToolNamesByCallId[toolCallId] = toolName;
TrackToolCall(toolCallId, toolName, toolExecutionStart.ToolArguments);
ActiveAgent = agent;
AgentActivityEventDto? toolActivity = CreateToolCallingActivity(
agent, toolName, toolCallId, toolExecutionStart.ToolArguments);
@@ -269,6 +271,15 @@ internal class TurnExecutionState
_lastObservedMessageId = messageId;
}
private void TrackToolCall(
string toolCallId,
string toolName,
IReadOnlyDictionary<string, object?>? toolArguments)
{
ToolNamesByCallId[toolCallId] = toolName;
ToolCallHasArgumentsById[toolCallId] = toolArguments is { Count: > 0 };
}
private void QueueMessageReclassifiedIfNeeded(string? messageId)
{
if (string.IsNullOrWhiteSpace(messageId))
@@ -20,7 +20,8 @@ internal static class WorkflowRequestInfoInterpreter
RunTurnCommandDto command,
RequestInfoEvent requestInfo,
AgentIdentity? activeAgent,
ConcurrentDictionary<string, string> toolNamesByCallId)
ConcurrentDictionary<string, string> toolNamesByCallId,
ConcurrentDictionary<string, bool> toolCallHasArgumentsById)
{
RequestInterpretation interpretation = InterpretRequest(command.Workflow, requestInfo);
return interpretation switch
@@ -28,7 +29,7 @@ internal static class WorkflowRequestInfoInterpreter
HandoffRequestInterpretation handoff =>
CreateHandoffActivity(command, handoff.TargetAgent, activeAgent),
ToolRequestInterpretation tool when activeAgent.HasValue =>
CreateToolCallingActivity(command, activeAgent.Value, tool, toolNamesByCallId),
CreateToolCallingActivity(command, activeAgent.Value, tool, toolNamesByCallId, toolCallHasArgumentsById),
_ => null,
};
}
@@ -63,14 +64,21 @@ internal static class WorkflowRequestInfoInterpreter
RunTurnCommandDto command,
AgentIdentity activeAgent,
ToolRequestInterpretation tool,
ConcurrentDictionary<string, string> toolNamesByCallId)
ConcurrentDictionary<string, string> toolNamesByCallId,
ConcurrentDictionary<string, bool> toolCallHasArgumentsById)
{
bool hasToolArguments = tool.ToolArguments is { Count: > 0 };
if (tool.ToolCallId is not null && toolNamesByCallId.ContainsKey(tool.ToolCallId))
{
return null;
bool trackedHasArguments = toolCallHasArgumentsById.TryGetValue(tool.ToolCallId, out bool hasTrackedArguments)
&& hasTrackedArguments;
if (trackedHasArguments || !hasToolArguments)
{
return null;
}
}
TrackToolCallId(toolNamesByCallId, tool.ToolCallId, tool.ToolName);
TrackToolCallId(toolNamesByCallId, toolCallHasArgumentsById, tool.ToolCallId, tool.ToolName, hasToolArguments);
return new AgentActivityEventDto
{
@@ -88,12 +96,15 @@ internal static class WorkflowRequestInfoInterpreter
private static void TrackToolCallId(
ConcurrentDictionary<string, string> toolNamesByCallId,
ConcurrentDictionary<string, bool> toolCallHasArgumentsById,
string? toolCallId,
string toolName)
string toolName,
bool hasToolArguments)
{
if (toolCallId is not null)
{
toolNamesByCallId[toolCallId] = toolName;
toolCallHasArgumentsById[toolCallId] = hasToolArguments;
}
}