fix: flatten TaskPushNotificationConfig to match v1 spec - #418
fix: flatten TaskPushNotificationConfig to match v1 spec#418darrelmiller wants to merge 6 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.
- 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:
|
- Remove CreateTaskPushNotificationConfigRequest wrapper; Create RPC now
takes TaskPushNotificationConfig directly as params (matching proto)
- Rename ListTaskPushNotificationConfig{Request,Response} to plural
ListTaskPushNotificationConfigs{Request,Response} (matching proto)
- Rename A2AMethods constant to ListTaskPushNotificationConfigs
Closes #416
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Document all breaking changes: flattened model, removed wrapper, property rename, pluralized list types, handler interface changes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…onfig - Change REST create endpoint to bind TaskPushNotificationConfig directly (previously used PushNotificationConfig which has no Tenant field) - Clear task_id in embedded SendMessageConfiguration push config per spec: 'Task id should be empty when sending this configuration in a SendMessage request' Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
| } | ||
|
|
||
| // Create payload for the task | ||
| var payload = new SendMessageRequest() |
There was a problem hiding this comment.
this is the embedded SendMessageConfiguration.task_push_notification_config path, not the standalone CreateTaskPushNotificationConfig path.
| payload.Configuration.TaskPushNotificationConfig = new TaskPushNotificationConfig | ||
| { | ||
| Id = Guid.NewGuid().ToString(), | ||
| TaskId = taskId, |
There was a problem hiding this comment.
For the standalone create API, the config is being added to an already-known task, so taskId identifies the parent task for that operation. But in SendMessage, the push config is attached while the message is being sent, and the server should associate it with the task created or selected by that SendMessage request.
There was a problem hiding this comment.
TaskId = taskId says which task this config belongs to. In the embedded SendMessage path, that should come from the SendMessage task context, so I think this should be omitted.
| { | ||
| AcceptedOutputModes = ["mode1"], | ||
| PushNotificationConfig = new PushNotificationConfig { Url = "http://push" }, | ||
| TaskPushNotificationConfig = new TaskPushNotificationConfig { Id = "cfg-1", TaskId = "t-1", Url = "http://push" }, |
There was a problem hiding this comment.
This test is for SendMessageAsync, so it is exercising the embedded SendMessageConfiguration.taskPushNotificationConfig shape.
Because the spec says the embedded SendMessage config should not carry taskId, I think this fixture should avoid both identifiers here:
no TaskId, because the task association comes from the SendMessage task context
no Id, unless SendMessage explicitly supports client-assigned push-config ids
| // REST handler: Create push notification config | ||
| internal static Task<IResult> CreatePushNotificationConfigRestAsync( | ||
| IA2ARequestHandler requestHandler, ILogger logger, string taskId, PushNotificationConfig config, CancellationToken cancellationToken) | ||
| IA2ARequestHandler requestHandler, ILogger logger, string taskId, TaskPushNotificationConfig config, CancellationToken cancellationToken) |
There was a problem hiding this comment.
One REST behavior to clarify: this endpoint now binds the body as TaskPushNotificationConfig, which includes Tenant, then forwards the config after only overriding TaskId from the route.
That means a non-tenant REST call to /tasks/{id}/pushNotificationConfigs can still pass tenant in the body to the handler. But MapHttpA2A currently documents tenant REST variants as unsupported and says request Tenant fields are always null for REST calls.
Could we make this consistent one way or the other?
If tenant REST is out of scope, reject or clear config.Tenant on the non-tenant REST route and add a test for that behavior.
If body tenant is intentionally supported on the non-tenant route, update the REST limitation docs and add a route/body test so this is explicit.
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