mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
Merge branch 'main' into feat/durable_task
This commit is contained in:
@@ -127,6 +127,7 @@ public sealed class A2AAgent : AIAgent
|
||||
{
|
||||
AgentId = this.Id,
|
||||
ResponseId = message.MessageId,
|
||||
FinishReason = ChatFinishReason.Stop,
|
||||
RawRepresentation = message,
|
||||
Messages = [message.ToChatMessage()],
|
||||
AdditionalProperties = message.Metadata?.ToAdditionalProperties(),
|
||||
@@ -141,6 +142,7 @@ public sealed class A2AAgent : AIAgent
|
||||
{
|
||||
AgentId = this.Id,
|
||||
ResponseId = agentTask.Id,
|
||||
FinishReason = MapTaskStateToFinishReason(agentTask.Status.State),
|
||||
RawRepresentation = agentTask,
|
||||
Messages = agentTask.ToChatMessages() ?? [],
|
||||
ContinuationToken = CreateContinuationToken(agentTask.Id, agentTask.Status.State),
|
||||
@@ -328,6 +330,7 @@ public sealed class A2AAgent : AIAgent
|
||||
{
|
||||
AgentId = this.Id,
|
||||
ResponseId = message.MessageId,
|
||||
FinishReason = ChatFinishReason.Stop,
|
||||
RawRepresentation = message,
|
||||
Role = ChatRole.Assistant,
|
||||
MessageId = message.MessageId,
|
||||
@@ -342,6 +345,7 @@ public sealed class A2AAgent : AIAgent
|
||||
{
|
||||
AgentId = this.Id,
|
||||
ResponseId = task.Id,
|
||||
FinishReason = MapTaskStateToFinishReason(task.Status.State),
|
||||
RawRepresentation = task,
|
||||
Role = ChatRole.Assistant,
|
||||
Contents = task.ToAIContents(),
|
||||
@@ -365,7 +369,16 @@ public sealed class A2AAgent : AIAgent
|
||||
responseUpdate.Contents = artifactUpdateEvent.Artifact.ToAIContents();
|
||||
responseUpdate.RawRepresentation = artifactUpdateEvent;
|
||||
}
|
||||
else if (taskUpdateEvent is TaskStatusUpdateEvent statusUpdateEvent)
|
||||
{
|
||||
responseUpdate.FinishReason = MapTaskStateToFinishReason(statusUpdateEvent.Status.State);
|
||||
}
|
||||
|
||||
return responseUpdate;
|
||||
}
|
||||
|
||||
private static ChatFinishReason? MapTaskStateToFinishReason(TaskState state)
|
||||
{
|
||||
return state == TaskState.Completed ? ChatFinishReason.Stop : null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,6 +61,7 @@ public class AgentResponse
|
||||
|
||||
this.AdditionalProperties = response.AdditionalProperties;
|
||||
this.CreatedAt = response.CreatedAt;
|
||||
this.FinishReason = response.FinishReason;
|
||||
this.Messages = response.Messages;
|
||||
this.RawRepresentation = response;
|
||||
this.ResponseId = response.ResponseId;
|
||||
@@ -84,6 +85,7 @@ public class AgentResponse
|
||||
|
||||
this.AdditionalProperties = response.AdditionalProperties;
|
||||
this.CreatedAt = response.CreatedAt;
|
||||
this.FinishReason = response.FinishReason;
|
||||
this.Messages = response.Messages;
|
||||
this.RawRepresentation = response;
|
||||
this.ResponseId = response.ResponseId;
|
||||
@@ -190,6 +192,21 @@ public class AgentResponse
|
||||
/// </remarks>
|
||||
public DateTimeOffset? CreatedAt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the reason for the agent response finishing.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="ChatFinishReason"/> value indicating why the response finished (e.g., stop, length, content filter, tool calls),
|
||||
/// or <see langword="null"/> if the finish reason is not available.
|
||||
/// </value>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This property is particularly useful for detecting non-normal completions, such as content filtering
|
||||
/// or token limit truncation, which may require special handling by the caller.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public ChatFinishReason? FinishReason { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the resource usage information for generating this response.
|
||||
/// </summary>
|
||||
@@ -276,6 +293,7 @@ public class AgentResponse
|
||||
RawRepresentation = message.RawRepresentation,
|
||||
Role = message.Role,
|
||||
|
||||
FinishReason = this.FinishReason,
|
||||
AgentId = this.AgentId,
|
||||
ResponseId = this.ResponseId,
|
||||
MessageId = message.MessageId,
|
||||
|
||||
@@ -38,6 +38,7 @@ public static class AgentResponseExtensions
|
||||
{
|
||||
AdditionalProperties = response.AdditionalProperties,
|
||||
CreatedAt = response.CreatedAt,
|
||||
FinishReason = response.FinishReason,
|
||||
Messages = response.Messages,
|
||||
RawRepresentation = response,
|
||||
ResponseId = response.ResponseId,
|
||||
@@ -71,6 +72,7 @@ public static class AgentResponseExtensions
|
||||
AuthorName = responseUpdate.AuthorName,
|
||||
Contents = responseUpdate.Contents,
|
||||
CreatedAt = responseUpdate.CreatedAt,
|
||||
FinishReason = responseUpdate.FinishReason,
|
||||
MessageId = responseUpdate.MessageId,
|
||||
RawRepresentation = responseUpdate,
|
||||
ResponseId = responseUpdate.ResponseId,
|
||||
|
||||
@@ -70,6 +70,7 @@ public class AgentResponseUpdate
|
||||
this.AuthorName = chatResponseUpdate.AuthorName;
|
||||
this.Contents = chatResponseUpdate.Contents;
|
||||
this.CreatedAt = chatResponseUpdate.CreatedAt;
|
||||
this.FinishReason = chatResponseUpdate.FinishReason;
|
||||
this.MessageId = chatResponseUpdate.MessageId;
|
||||
this.RawRepresentation = chatResponseUpdate;
|
||||
this.ResponseId = chatResponseUpdate.ResponseId;
|
||||
@@ -153,6 +154,15 @@ public class AgentResponseUpdate
|
||||
/// </remarks>
|
||||
public ResponseContinuationToken? ContinuationToken { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the reason for the agent response finishing.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="ChatFinishReason"/> value indicating why the response finished (e.g., stop, length, content filter, tool calls),
|
||||
/// or <see langword="null"/> if the finish reason is not available or not yet determined (mid-stream).
|
||||
/// </value>
|
||||
public ChatFinishReason? FinishReason { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string ToString() => this.Text;
|
||||
|
||||
|
||||
+1
-3
@@ -72,9 +72,7 @@ internal static class AIAgentChatCompletionsProcessor
|
||||
|
||||
await foreach (var agentResponseUpdate in agent.RunStreamingAsync(chatMessages, options: options, cancellationToken: cancellationToken).WithCancellation(cancellationToken))
|
||||
{
|
||||
var finishReason = (agentResponseUpdate.RawRepresentation is ChatResponseUpdate { FinishReason: not null } chatResponseUpdate)
|
||||
? chatResponseUpdate.FinishReason.ToString()
|
||||
: "stop";
|
||||
var finishReason = agentResponseUpdate.FinishReason?.ToString() ?? "stop";
|
||||
|
||||
var choiceChunks = new List<ChatCompletionChoiceChunk>();
|
||||
CompletionUsage? usageDetails = null;
|
||||
|
||||
+1
-3
@@ -34,9 +34,7 @@ internal static class AgentResponseExtensions
|
||||
var chatCompletionChoices = new List<ChatCompletionChoice>();
|
||||
var index = 0;
|
||||
|
||||
var finishReason = (agentResponse.RawRepresentation is ChatResponse { FinishReason: not null } chatResponse)
|
||||
? chatResponse.FinishReason.ToString()
|
||||
: "stop"; // "stop" is a natural stop point; returning this by-default
|
||||
var finishReason = agentResponse.FinishReason?.ToString() ?? ChatFinishReason.Stop.Value; // "stop" is a natural stop point; returning this by-default
|
||||
|
||||
foreach (var message in agentResponse.Messages)
|
||||
{
|
||||
|
||||
@@ -124,6 +124,7 @@ internal sealed class MessageMerger
|
||||
List<ChatMessage> messages = [];
|
||||
Dictionary<string, AgentResponse> responses = [];
|
||||
HashSet<string> agentIds = [];
|
||||
HashSet<ChatFinishReason> finishReasons = [];
|
||||
|
||||
foreach (string responseId in this._mergeStates.Keys)
|
||||
{
|
||||
@@ -156,6 +157,11 @@ internal sealed class MessageMerger
|
||||
createdTimes.Add(response.CreatedAt.Value);
|
||||
}
|
||||
|
||||
if (response.FinishReason.HasValue)
|
||||
{
|
||||
finishReasons.Add(response.FinishReason.Value);
|
||||
}
|
||||
|
||||
usage = MergeUsage(usage, response.Usage);
|
||||
additionalProperties = MergeProperties(additionalProperties, response.AdditionalProperties);
|
||||
}
|
||||
@@ -182,6 +188,7 @@ internal sealed class MessageMerger
|
||||
AgentId = primaryAgentId
|
||||
?? primaryAgentName
|
||||
?? (agentIds.Count == 1 ? agentIds.First() : null),
|
||||
FinishReason = finishReasons.Count == 1 ? finishReasons.First() : null,
|
||||
CreatedAt = DateTimeOffset.UtcNow,
|
||||
Usage = usage,
|
||||
AdditionalProperties = additionalProperties
|
||||
@@ -207,6 +214,7 @@ internal sealed class MessageMerger
|
||||
AgentId = incoming.AgentId ?? current.AgentId,
|
||||
AdditionalProperties = MergeProperties(current.AdditionalProperties, incoming.AdditionalProperties),
|
||||
CreatedAt = incoming.CreatedAt ?? current.CreatedAt,
|
||||
FinishReason = incoming.FinishReason ?? current.FinishReason,
|
||||
Messages = current.Messages.Concat(incoming.Messages).ToList(),
|
||||
ResponseId = current.ResponseId,
|
||||
RawRepresentation = rawRepresentation,
|
||||
|
||||
Reference in New Issue
Block a user