Respecting AIP response payloads in HTTP #1247
Replies: 4 comments 1 reply
-
|
the AIP issue seems to be only about marking the field with google.api.resource_reference, right? the name field is on the message already. btw: i think the redundancy comes from the reuse of PushNotificationConfig in the send message config, although i'm not sure why in SendMessage we are not expected to send the resource name and in SetTaskPushNotificationConfig we are. |
Beta Was this translation helpful? Give feedback.
-
|
@darrelmiller on AIP I notice that running the linter on the current a2a.proto
Summary Table
|
Beta Was this translation helpful? Give feedback.
-
|
If we keep the rules below we need to fix the proto file as reported by the linting tool.
1. URI Naming (AIP-140)Rename // Before
string url = 2;
string authorization_url = 1;
string token_url = 2;
string refresh_url = 3;
// After
string uri = 2;
string authorization_uri = 1;
string token_uri = 2;
string refresh_uri = 3;Affected locations:
2. Field Behavior Annotations (AIP-203)Add // Before
string context_id = 2;
// After
string context_id = 2 [(google.api.field_behavior) = OPTIONAL];Key fields needing annotations:
3. Reserved Words (AIP-140)Rename fields using reserved words: // Before
bool final = 4;
string protected = 1;
// After
bool is_final = 4; // or 'last', 'completed'
string protected_header = 1; // or rename based on contextAffected locations:
4. Timestamp Naming (AIP-142)Rename timestamp fields to end with // Before
google.protobuf.Timestamp timestamp = 3;
// After
google.protobuf.Timestamp update_time = 3;Affected location:
5. State Field Output-Only (AIP-216)Mark state fields as OUTPUT_ONLY: // Before
TaskState state = 1 [(google.api.field_behavior) = REQUIRED];
// After
TaskState state = 1 [(google.api.field_behavior) = OUTPUT_ONLY];Affected locations:
6. File Layout (AIP-191)Move the message Task {
enum State {
STATE_UNSPECIFIED = 0;
STATE_SUBMITTED = 1;
// ...
}
State state = 1;
// ...
}7. Base64 Fields (AIP-140)Fields mentioning base64 should use // This is intentional per JWS RFC 7515 - consider adding a linter exception
string protected = 1; // base64url-encoded, but JWS spec mandates string
string signature = 2; // base64url-encoded, but JWS spec mandates string8. Abbreviations (AIP-140)Use // Before
message SendMessageConfiguration { ... }
SendMessageConfiguration configuration = 2;
// After
message SendMessageConfig { ... }
SendMessageConfig config = 2;9. Resource References (AIP-131, AIP-132, AIP-135)Add resource reference annotations: import "google/api/resource.proto";
message Task {
option (google.api.resource) = {
type: "a2a.googleapis.com/Task"
pattern: "tasks/{task}"
};
// ...
}
message GetTaskRequest {
string name = 1 [
(google.api.field_behavior) = REQUIRED,
(google.api.resource_reference) = {
type: "a2a.googleapis.com/Task"
}
];
}10. Method Signature for GetExtendedAgentCard (AIP-131)Add method signature and name field: rpc GetExtendedAgentCard(GetExtendedAgentCardRequest) returns (AgentCard) {
option (google.api.http) = {
get: "/v1/{name=extendedAgentCards/*}"
};
option (google.api.method_signature) = "name";
}
message GetExtendedAgentCardRequest {
string name = 1 [(google.api.field_behavior) = REQUIRED];
}11. ListTasks Parent Field (AIP-132)Add parent field for list operations: message ListTasksRequest {
string parent = 1 [(google.api.field_behavior) = REQUIRED];
// ... existing fields
} |
Beta Was this translation helpful? Give feedback.
-
|
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
To facilitate keeping the gRPC and HTTP protocol binding in sync, and enable middleware to automatically translate between the protocol bindings, without using SDKs, the current path for A2A is to use AIP conventions.
In most cases, the conformance to AIP guidelines is fairly transparent as it uses common HTTP conventions. However, there are some conventions that are a bit unusual.
AIP has some very specific guidance around what it means by a "Resource" and how those resources should be named. https://google.aip.dev/122
One that is causing some challenges at this point is:
This is most obvious in the
GetTaskPushNotificationConfigmethodrpc SetTaskPushNotificationConfig(SetTaskPushNotificationConfigRequest) returns (TaskPushNotificationConfig) { option (google.api.http) = { post: "/v1/{parent=tasks/*/pushNotificationConfigs}" body: "config" }; option (google.api.method_signature) = "parent,config"; }This method returns TaskPushNotificationConfig which looks like
and finally PushNotificationConfig looks like this
This extra layering of TaskPushNotificationConfig containing a PushNotificationConfig is a bit redundant. I mistakenly assumed this was a gRPC specific issue and described the abstract operation as returning PushNotificationConfig. However, this is not a gRPC issue, it is a AIP convention that requires "Resources" to contain a name field. This means that both the HTTP and gRPC binding require the name field if they are to be AIP compliant.
It is not clear to me whether this particular convention would actually affect the mechanical translation, but the path of willful violations is paved with regret. It is also worth noting that the community derivative of AIP, confusingly called AEP renames the
namefield topathbut also requires it. https://aep.dev/122/It is my opinion that we should aspire to keep these AIP specific conventions out of the abstract protocol definition. However, what this means is that we need to recognize that the documented HTTP binding, is going to be an AIP HTTP binding, and needs to layer AIP conventions onto the abstract protocol.
This opens the door for a future community effort to create an AEP HTTP binding that conforms to its conventions.
I am assuming this means that we will need to create a "resource" message type to contain a "Task" and I have no idea what to do with GetExtendedAgentCard.
Beta Was this translation helpful? Give feedback.
All reactions