Skip to content
Open
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
18 changes: 17 additions & 1 deletion provider/a2aprovider/a2a.go
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,22 @@ func yieldTask(yield func(*agent.ResponseUpdate, error) bool, task *a2a.Task) bo
timestamp = *task.Status.Timestamp
}
var contents []message.Content
messageID := ""
if task.Status.Message != nil {
messageID = task.Status.Message.ID
// Mirror the streaming TaskStatusUpdateEvent path: surface the status
// message text for states where it carries the agent's response (an
// input-required follow-up question or a terminal summary), rather than
// dropping it when the task has no artifacts.
if task.Status.State == a2a.TaskStateInputRequired || task.Status.State.Terminal() {
var err error
contents, err = partsToContents(task.Status.Message.Parts, contents)
if err != nil {
yield(nil, err)
return false
}
}
}
for _, artifact := range task.Artifacts {
var err error
contents, err = partsToContents(artifact.Parts, contents)
Expand All @@ -273,7 +289,7 @@ func yieldTask(yield func(*agent.ResponseUpdate, error) bool, task *a2a.Task) bo
}
}

update := newResponseUpdate(task, task.Metadata, string(task.ID), "", message.RoleAssistant, contents, timestamp)
update := newResponseUpdate(task, task.Metadata, string(task.ID), messageID, message.RoleAssistant, contents, timestamp)
update.ContinuationToken = continuationToken
return yield(update, nil)
}
Expand Down
35 changes: 35 additions & 0 deletions provider/a2aprovider/a2a_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -921,6 +921,41 @@ func TestRunWithAgentTaskResponse(t *testing.T) {
}
}

// TestRunWithInputRequiredTaskMessage verifies that a non-streaming Task response
// in an InputRequired state surfaces the text carried in Status.Message (when the
// task has no artifacts), matching the streaming TaskStatusUpdateEvent path.
func TestRunWithInputRequiredTaskMessage(t *testing.T) {
const question = "What color should the background be?"
transport := &mockA2ATransport{
responseToReturn: &a2a.Task{
ID: a2a.TaskID("task-1"),
ContextID: "context-1",
Status: a2a.TaskStatus{
State: a2a.TaskStateInputRequired,
Message: &a2a.Message{
ID: "msg-1",
Role: a2a.MessageRoleAgent,
Parts: a2a.ContentParts{a2a.NewTextPart(question)},
},
},
},
}
a := newTestAgent(transport, agent.Config{})

session, err := a.CreateSession(t.Context())
if err != nil {
t.Fatal(err)
}

result, err := a.RunText(t.Context(), "make the background transparent", agent.WithSession(session)).Collect()
if err != nil {
t.Fatalf("error = %v, want nil", err)
}
if got := result.String(); got != question {
t.Errorf("response text = %q, want %q", got, question)
}
}

// TestRunWithVariousTaskStates tests continuation token behavior for different task states
func TestRunWithVariousTaskStates(t *testing.T) {
tests := []struct {
Expand Down
Loading