Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1542,7 +1542,7 @@ private static bool CurrentActivityIsInvokeAgent
ref List<ApprovalResultWithRequestMessage>? targetList = ref approvalResponse.Approved ? ref approvedFunctionCalls : ref rejectedFunctionCalls;

ChatMessage? requestMessage = null;
_ = allApprovalRequestsMessages?.TryGetValue(approvalResponse.FunctionCall.CallId, out requestMessage);
_ = allApprovalRequestsMessages?.TryGetValue(approvalResponse.Id, out requestMessage);

(targetList ??= []).Add(new() { Response = approvalResponse, RequestMessage = requestMessage });
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1156,6 +1156,55 @@ public async Task FunctionCallsWithInvocationRequiredFalseAreNotReplacedWithAppr
Assert.Equal(0, functionInvokedCount);
}

[Fact]
public async Task ApprovalResponsePreservesOriginalRequestMessageMetadata()
{
var options = new ChatOptions
{
Tools =
[
new ApprovalRequiredAIFunction(AIFunctionFactory.Create(() => "Result 1", "Func1")),
]
};

const string OriginalMessageId = "original-message-id";

// Create input with approval request containing a known MessageId on the containing message
List<ChatMessage> input =
[
new ChatMessage(ChatRole.User, "hello"),
new ChatMessage(ChatRole.Assistant,
[
new FunctionApprovalRequestContent("approval-request-id", new FunctionCallContent("function-call-id", "Func1"))
]) { MessageId = OriginalMessageId }, // This MessageId should be preserved
new ChatMessage(ChatRole.User,
[
new FunctionApprovalResponseContent("approval-request-id", true, new FunctionCallContent("function-call-id", "Func1"))
]),
];

List<ChatMessage> downstreamClientOutput =
[
new ChatMessage(ChatRole.Assistant, "world"),
];

// The reconstructed function call message should preserve the original MessageId
List<ChatMessage> expectedOutput =
[
new ChatMessage(ChatRole.Assistant, [new FunctionCallContent("function-call-id", "Func1")]) { MessageId = OriginalMessageId },
new ChatMessage(ChatRole.Tool, [new FunctionResultContent("function-call-id", result: "Result 1")]),
new ChatMessage(ChatRole.Assistant, "world"),
];

var actualOutput = await InvokeAndAssertAsync(options, input, downstreamClientOutput, expectedOutput);

// Verify that the reconstructed function call message has the original MessageId, not a synthetic one
Assert.Equal(OriginalMessageId, actualOutput[0].MessageId);

actualOutput = await InvokeAndAssertStreamingAsync(options, input, downstreamClientOutput, expectedOutput);
Assert.Equal(OriginalMessageId, actualOutput[0].MessageId);
}

private static Task<List<ChatMessage>> InvokeAndAssertAsync(
ChatOptions? options,
List<ChatMessage> input,
Expand Down
Loading