fix: flatten TaskPushNotificationConfig to match v1 spec - #418
fix: flatten TaskPushNotificationConfig to match v1 spec#418darrelmiller wants to merge 2 commits into
Conversation
Resolves #416. The v1 spec defines TaskPushNotificationConfig as a flat structure with url, token, and authentication fields directly on the type. The SDK previously had a nested two-class structure with PushNotificationConfig inside TaskPushNotificationConfig. Changes: - Move url, token, authentication onto TaskPushNotificationConfig directly - Simplify CreateTaskPushNotificationConfigRequest to wrap TaskPushNotificationConfig - Update SendMessageConfiguration to use TaskPushNotificationConfig - Retain PushNotificationConfig for HTTP+JSON REST endpoint compatibility - Add V0_3Compat converters for bidirectional mapping - Update all tests Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Code Review
This pull request flattens the TaskPushNotificationConfig structure in v1.0, moving properties like Url, Token, and Authentication directly into the class instead of nesting them, and updates the client, server processors, compatibility converters, and tests accordingly. The review feedback identifies several issues: an uninitialized TaskId in A2ACli.cs that should be replaced with the taskId parameter, a lack of validation for TaskId in A2AHttpJsonClient.cs which could lead to malformed URLs, and potential NullReferenceExceptions in V03TypeConverter.cs when accessing auth.Schemes.Count without null-safety checks.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| Id = Guid.NewGuid().ToString(), | ||
| TaskId = payload.Message.TaskId ?? string.Empty, |
There was a problem hiding this comment.
Fixed now uses the taskId parameter from the method signature instead of payload.Message.TaskId.
| public async Task<TaskPushNotificationConfig> CreateTaskPushNotificationConfigAsync( | ||
| CreateTaskPushNotificationConfigRequest request, CancellationToken cancellationToken = default) | ||
| { | ||
| return await PostJsonAsync<PushNotificationConfig, TaskPushNotificationConfig>( | ||
| $"/tasks/{Uri.EscapeDataString(request.TaskId)}/pushNotificationConfigs", | ||
| return await PostJsonAsync<TaskPushNotificationConfig, TaskPushNotificationConfig>( | ||
| $"/tasks/{Uri.EscapeDataString(request.Config.TaskId ?? string.Empty)}/pushNotificationConfigs", | ||
| request.Config, "CreateTaskPushNotificationConfig", cancellationToken).ConfigureAwait(false); | ||
| } |
There was a problem hiding this comment.
If request.Config.TaskId is null or empty, the constructed URL will be malformed (e.g., /tasks//pushNotificationConfigs), leading to a generic HTTP error. Adding validation prevents invalid requests from being sent.
public async Task<TaskPushNotificationConfig> CreateTaskPushNotificationConfigAsync(
CreateTaskPushNotificationConfigRequest request, CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(request);
if (string.IsNullOrEmpty(request.Config?.TaskId))
{
throw new ArgumentException("TaskId must be specified in the configuration.", nameof(request));
}
return await PostJsonAsync<TaskPushNotificationConfig, TaskPushNotificationConfig>(
$"/tasks/{Uri.EscapeDataString(request.Config.TaskId)}/pushNotificationConfigs",
request.Config, "CreateTaskPushNotificationConfig", cancellationToken).ConfigureAwait(false);
}There was a problem hiding this comment.
Fixed added ArgumentException.ThrowIfNullOrEmpty(request.Config.TaskId) validation before constructing the URL.
| Token = config.Token, | ||
| }; | ||
|
|
||
| if (config.Authentication is { } auth && auth.Schemes.Count > 0) |
There was a problem hiding this comment.
Fixed switched to null-safe pattern matching: if (config.Authentication is { Schemes: { Count: > 0 } schemes })
| Token = config.PushNotificationConfig.Token, | ||
| }; | ||
|
|
||
| if (config.PushNotificationConfig.Authentication is { } auth && auth.Schemes.Count > 0) |
There was a problem hiding this comment.
Fixed same null-safe pattern matching applied to all three conversion methods.
- Use taskId parameter instead of uninitialized payload.Message.TaskId in A2ACli - Add TaskId validation in A2AHttpJsonClient to prevent malformed URLs - Use null-safe pattern matching for auth.Schemes in V03TypeConverter Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Verified this independently against current Spec conformance checks outChecked the flattened model field by field against message TaskPushNotificationConfig {
string tenant = 1;
string id = 2;
string task_id = 3;
string url = 4 [(google.api.field_behavior) = REQUIRED];
string token = 5;
AuthenticationInfo authentication = 6;
}The new shape matches exactly, and relaxing Both The three points from the automated review all read as resolved on the current head:
|
Summary
Flattens TaskPushNotificationConfig to match the v1 A2A specification.
Fixes #416
Problem
The SDK used a nested two-class structure (TaskPushNotificationConfig wrapping PushNotificationConfig) that didn't match the v1 spec's flat model where url, token, and authentication are direct properties of TaskPushNotificationConfig.
Solution
Testing