Skip to content

Commit 22cbbb7

Browse files
authored
Fix Assistants IChatClient handling of unrelated tool calls in history (#6891)
The implementation is assuming that any tool results in the incoming message history mean a thread ID is required, which would be necessary if those tool results were for an active run. But that's not the case if the history just contains historical function calls/responses, as is the case in agent scenarios where the message history from one agent is passed to another. The fix is to just stop throwing based on this incorrect assumption.
1 parent 8e32d98 commit 22cbbb7

File tree

2 files changed

+6
-8
lines changed

2 files changed

+6
-8
lines changed

src/Libraries/Microsoft.Extensions.AI.OpenAI/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
## NOT YET RELEASED
44

5+
- Fixed issue with IChatClient for Assistants API where a chat history including unrelated function calls would cause an exception.
6+
57
## 9.9.1-preview.1.25474.6
68

79
- Updated to depend on OpenAI 2.5.0.

src/Libraries/Microsoft.Extensions.AI.OpenAI/OpenAIAssistantsChatClient.cs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -80,14 +80,10 @@ public async IAsyncEnumerable<ChatResponseUpdate> GetStreamingResponseAsync(
8080

8181
// Get the thread ID.
8282
string? threadId = options?.ConversationId ?? _defaultThreadId;
83-
if (threadId is null && toolResults is not null)
84-
{
85-
Throw.ArgumentException(nameof(messages), "No thread ID was provided, but chat messages includes tool results.");
86-
}
8783

8884
// Get any active run ID for this thread. This is necessary in case a thread has been left with an
89-
// active run, in which all attempts other than submitting tools will fail. We thus need to cancel
90-
// any active run on the thread.
85+
// active run, in which case all attempts other than submitting tools will fail. We thus need to cancel
86+
// any active run on the thread if we're not submitting tool results to it.
9187
ThreadRun? threadRun = null;
9288
if (threadId is not null)
9389
{
@@ -111,7 +107,7 @@ public async IAsyncEnumerable<ChatResponseUpdate> GetStreamingResponseAsync(
111107
ConvertFunctionResultsToToolOutput(toolResults, out List<ToolOutput>? toolOutputs) is { } toolRunId &&
112108
toolRunId == threadRun.Id)
113109
{
114-
// There's an active run and we have tool results to submit, so submit the results and continue streaming.
110+
// There's an active run and, critically, we have tool results to submit for that exact run, so submit the results and continue streaming.
115111
// This is going to ignore any additional messages in the run options, as we are only submitting tool outputs,
116112
// but there doesn't appear to be a way to submit additional messages, and having such additional messages is rare.
117113
updates = _client.SubmitToolOutputsToRunStreamingAsync(threadRun.ThreadId, threadRun.Id, toolOutputs, cancellationToken);
@@ -487,7 +483,7 @@ void AppendSystemInstructions(string? toAppend)
487483
messageContents.Add(MessageContent.FromImageUri(image.Uri));
488484
break;
489485

490-
case FunctionResultContent result:
486+
case FunctionResultContent result when chatMessage.Role == ChatRole.Tool:
491487
(functionResults ??= []).Add(result);
492488
break;
493489
}

0 commit comments

Comments
 (0)