Skip to content

.Net: Bug: AgentActor.InvokeAsync returns empty since response is not assigned. #12626

@hanhsia

Description

@hanhsia

Describe the bug
AgentActor.InvokeAsync returns empty which cause agent returns empty.

Expected behavior
AgentActor.InvokeAsync should return the response of InvokeAsync or InvokeStreamingAsync

Platform

  • Language: [e.g. C#, Python] C#
  • Source: [e.g. NuGet package version 0.1.0, pip package version 0.1.0, main branch of repository]
  • AI model: [e.g. OpenAI:GPT-4o-mini(2024-07-18)]
  • IDE: [e.g. Visual Studio, VS Code]
  • OS: [e.g. Windows, Mac]

Additional context
the latest change #12455 raised the issue that response isn't assigned any value:
current code:
protected async ValueTask InvokeAsync(IList input, CancellationToken cancellationToken)
{
this.Context.Cancellation.ThrowIfCancellationRequested();

 **_ChatMessageContent? response = null;_**

 AgentInvokeOptions options = this.GetInvokeOptions(HandleMessage);
 if (this.Context.StreamingResponseCallback == null)
 {
     // No need to utilize streaming if no callback is provided
     **_await this.InvokeAsync(input, options, cancellationToken).ConfigureAwait(false);_**
 }
 else
 {
     **_await this.InvokeStreamingAsync(input, options, cancellationToken).ConfigureAwait(false);_**
 }

 **_return response ?? new ChatMessageContent(AuthorRole.Assistant, string.Empty);_**

 async Task HandleMessage(ChatMessageContent message)
 {
     response = message; // Keep track of most recent response for both invocation modes

     if (this.Context.ResponseCallback is not null && !this.ResponseCallbackFilter(message))
     {
         await this.Context.ResponseCallback.Invoke(message).ConfigureAwait(false);
     }
 }

}

expected code:
protected async ValueTask InvokeAsync(IList input, CancellationToken cancellationToken)
{
this.Context.Cancellation.ThrowIfCancellationRequested();

    ChatMessageContent? response = null;

    AgentInvokeOptions options = this.GetInvokeOptions(HandleMessage);
    if (this.Context.StreamingResponseCallback == null)
    {
        // Handle non-streaming: directly await last response and capture it
        var lastResponseItem = await this.Agent.InvokeAsync(input, this.Thread, options, cancellationToken)
            .LastOrDefaultAsync(cancellationToken).ConfigureAwait(false);
        this.Thread ??= lastResponseItem?.Thread;
        response = lastResponseItem?.Message;
    }
    else
    {
         //not sure how to handle it correctly.
        _await this.InvokeStreamingAsync(input, options, cancellationToken).ConfigureAwait(false);_
    }

    return response ?? new ChatMessageContent(AuthorRole.Assistant, string.Empty);

    async Task HandleMessage(ChatMessageContent message)
    {
        response = message; // Keep track of most recent response for both invocation modes

        if (this.Context.ResponseCallback is not null && !this.ResponseCallbackFilter(message))
        {
            await this.Context.ResponseCallback.Invoke(message).ConfigureAwait(false);
        }
    }
}

Sub-issues

Metadata

Metadata

Assignees

Labels

.NETIssue or Pull requests regarding .NET codeagentsbugSomething isn't workingmulti-agentIssues for multi-agent orchestrationpythonPull requests for the Python Semantic Kernel

Type

Projects

Status

Sprint: Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions