Skip to content

Commit b93db84

Browse files
committed
Merge remote-tracking branch 'upstream/main' into feature/postgres-memory
2 parents 23faeff + 329d572 commit b93db84

File tree

2 files changed

+94
-15
lines changed

2 files changed

+94
-15
lines changed

dotnet/samples/Concepts/Agents/OpenAIAssistant_Streaming.cs

Lines changed: 55 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,24 @@ namespace Agents;
1111
/// </summary>
1212
public class OpenAIAssistant_Streaming(ITestOutputHelper output) : BaseAgentsTest(output)
1313
{
14-
private const string ParrotName = "Parrot";
15-
private const string ParrotInstructions = "Repeat the user message in the voice of a pirate and then end with a parrot sound.";
16-
1714
[Fact]
1815
public async Task UseStreamingAssistantAgentAsync()
1916
{
17+
const string AgentName = "Parrot";
18+
const string AgentInstructions = "Repeat the user message in the voice of a pirate and then end with a parrot sound.";
19+
2020
// Define the agent
2121
OpenAIAssistantAgent agent =
22-
await OpenAIAssistantAgent.CreateAsync(
23-
kernel: new(),
24-
clientProvider: this.GetClientProvider(),
25-
definition: new OpenAIAssistantDefinition(this.Model)
26-
{
27-
Instructions = ParrotInstructions,
28-
Name = ParrotName,
29-
Metadata = AssistantSampleMetadata,
30-
});
22+
await OpenAIAssistantAgent.CreateAsync(
23+
kernel: new(),
24+
clientProvider: this.GetClientProvider(),
25+
definition: new OpenAIAssistantDefinition(this.Model)
26+
{
27+
Instructions = AgentInstructions,
28+
Name = AgentName,
29+
EnableCodeInterpreter = true,
30+
Metadata = AssistantSampleMetadata,
31+
});
3132

3233
// Create a thread for the agent conversation.
3334
string threadId = await agent.CreateThreadAsync(new OpenAIThreadCreationOptions { Metadata = AssistantSampleMetadata });
@@ -44,7 +45,8 @@ await OpenAIAssistantAgent.CreateAsync(
4445
[Fact]
4546
public async Task UseStreamingAssistantAgentWithPluginAsync()
4647
{
47-
const string MenuInstructions = "Answer questions about the menu.";
48+
const string AgentName = "Host";
49+
const string AgentInstructions = "Answer questions about the menu.";
4850

4951
// Define the agent
5052
OpenAIAssistantAgent agent =
@@ -53,8 +55,8 @@ await OpenAIAssistantAgent.CreateAsync(
5355
clientProvider: this.GetClientProvider(),
5456
definition: new OpenAIAssistantDefinition(this.Model)
5557
{
56-
Instructions = MenuInstructions,
57-
Name = "Host",
58+
Instructions = AgentInstructions,
59+
Name = AgentName,
5860
Metadata = AssistantSampleMetadata,
5961
});
6062

@@ -73,6 +75,36 @@ await OpenAIAssistantAgent.CreateAsync(
7375
await DisplayChatHistoryAsync(agent, threadId);
7476
}
7577

78+
[Fact]
79+
public async Task UseStreamingAssistantWithCodeInterpreterAsync()
80+
{
81+
const string AgentName = "MathGuy";
82+
const string AgentInstructions = "Solve math problems with code.";
83+
84+
// Define the agent
85+
OpenAIAssistantAgent agent =
86+
await OpenAIAssistantAgent.CreateAsync(
87+
kernel: new(),
88+
clientProvider: this.GetClientProvider(),
89+
definition: new OpenAIAssistantDefinition(this.Model)
90+
{
91+
Instructions = AgentInstructions,
92+
Name = AgentName,
93+
EnableCodeInterpreter = true,
94+
Metadata = AssistantSampleMetadata,
95+
});
96+
97+
// Create a thread for the agent conversation.
98+
string threadId = await agent.CreateThreadAsync(new OpenAIThreadCreationOptions { Metadata = AssistantSampleMetadata });
99+
100+
// Respond to user input
101+
await InvokeAgentAsync(agent, threadId, "Is 191 a prime number?");
102+
await InvokeAgentAsync(agent, threadId, "Determine the values in the Fibonacci sequence that that are less then the value of 101");
103+
104+
// Output the entire chat history
105+
await DisplayChatHistoryAsync(agent, threadId);
106+
}
107+
76108
// Local function to invoke agent and display the conversation messages.
77109
private async Task InvokeAgentAsync(OpenAIAssistantAgent agent, string threadId, string input)
78110
{
@@ -83,13 +115,21 @@ private async Task InvokeAgentAsync(OpenAIAssistantAgent agent, string threadId,
83115
ChatHistory history = [];
84116

85117
bool isFirst = false;
118+
bool isCode = false;
86119
await foreach (StreamingChatMessageContent response in agent.InvokeStreamingAsync(threadId, messages: history))
87120
{
88121
if (string.IsNullOrEmpty(response.Content))
89122
{
90123
continue;
91124
}
92125

126+
// Differentiate between assistant and tool messages
127+
if (isCode != (response.Metadata?.ContainsKey(OpenAIAssistantAgent.CodeInterpreterMetadataKey) ?? false))
128+
{
129+
isFirst = false;
130+
isCode = !isCode;
131+
}
132+
93133
if (!isFirst)
94134
{
95135
Console.WriteLine($"\n# {response.Role} - {response.AuthorName ?? "*"}:");

dotnet/src/Agents/OpenAI/Internal/AssistantThreadActions.cs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,14 @@ public static async IAsyncEnumerable<StreamingChatMessageContent> InvokeStreamin
406406
break;
407407
}
408408
}
409+
else if (update is RunStepDetailsUpdate detailsUpdate)
410+
{
411+
StreamingChatMessageContent? toolContent = GenerateStreamingCodeInterpreterContent(agent.GetName(), detailsUpdate);
412+
if (toolContent != null)
413+
{
414+
yield return toolContent;
415+
}
416+
}
409417
else if (update is RunStepUpdate stepUpdate)
410418
{
411419
switch (stepUpdate.UpdateKind)
@@ -416,6 +424,8 @@ public static async IAsyncEnumerable<StreamingChatMessageContent> InvokeStreamin
416424
case StreamingUpdateReason.RunStepCompleted:
417425
currentStep = null;
418426
break;
427+
default:
428+
break;
419429
}
420430
}
421431
}
@@ -571,6 +581,35 @@ private static StreamingChatMessageContent GenerateStreamingMessageContent(strin
571581
return content;
572582
}
573583

584+
private static StreamingChatMessageContent? GenerateStreamingCodeInterpreterContent(string? assistantName, RunStepDetailsUpdate update)
585+
{
586+
StreamingChatMessageContent content =
587+
new(AuthorRole.Assistant, content: null)
588+
{
589+
AuthorName = assistantName,
590+
};
591+
592+
// Process text content
593+
if (update.CodeInterpreterInput != null)
594+
{
595+
content.Items.Add(new StreamingTextContent(update.CodeInterpreterInput));
596+
content.Metadata = new Dictionary<string, object?> { { OpenAIAssistantAgent.CodeInterpreterMetadataKey, true } };
597+
}
598+
599+
if ((update.CodeInterpreterOutputs?.Count ?? 0) > 0)
600+
{
601+
foreach (var output in update.CodeInterpreterOutputs!)
602+
{
603+
if (output.ImageFileId != null)
604+
{
605+
content.Items.Add(new StreamingFileReferenceContent(output.ImageFileId));
606+
}
607+
}
608+
}
609+
610+
return content.Items.Count > 0 ? content : null;
611+
}
612+
574613
private static AnnotationContent GenerateAnnotationContent(TextAnnotation annotation)
575614
{
576615
string? fileId = null;

0 commit comments

Comments
 (0)