@alis-build/a2a 1.0.519 → 1.0.520
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -9
- package/package.json +1 -1
- package/transport/jsonrpc/client.ts +37 -41
- package/transport/jsonrpc/index.ts +2 -1
- package/transport/jsonrpc/wire/agent-card.ts +91 -0
- package/transport/jsonrpc/wire/common.ts +212 -0
- package/transport/jsonrpc/wire/index.ts +52 -0
- package/transport/jsonrpc/wire/json.ts +5 -0
- package/transport/jsonrpc/wire/wire.test.ts +70 -0
- package/tsconfig.json +11 -0
- package/vitest.config.ts +7 -0
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@ TypeScript types and a **JSON-RPC 2.0** client for the **Agent-to-Agent (A2A)**
|
|
|
5
5
|
## Requirements
|
|
6
6
|
|
|
7
7
|
- **Runtime**: `fetch`, `TextDecoderStream`, and `AbortSignal` (e.g. **Node.js 18+** or modern browsers).
|
|
8
|
-
- **Types**:
|
|
8
|
+
- **Types**: JSON-RPC request/response shapes are defined in `transport/jsonrpc/wire` for the **A2A JSON-RPC wire format** (what a conforming server expects on the wire). They differ from protobuf `*.AsObject` / grpc-web JSON field names and nesting. The generated files under `lf/a2a/v1/` remain available for gRPC/protobuf workflows.
|
|
9
9
|
|
|
10
10
|
## Installation
|
|
11
11
|
|
|
@@ -31,11 +31,18 @@ const client = new A2AClient({
|
|
|
31
31
|
extraHeaders: { "X-Custom-Header": "value" }, // optional
|
|
32
32
|
});
|
|
33
33
|
|
|
34
|
-
// Unary — one JSON-RPC response
|
|
34
|
+
// Unary — one JSON-RPC response (wire-format fields: `parts`, `acceptedOutputModes`, `returnImmediately`, …)
|
|
35
35
|
const response = await client.sendMessage({
|
|
36
36
|
tenant: "",
|
|
37
|
-
message: {
|
|
38
|
-
|
|
37
|
+
message: {
|
|
38
|
+
messageId: "00000000-0000-7000-0000-000000000001",
|
|
39
|
+
role: "ROLE_USER",
|
|
40
|
+
parts: [{ text: "Hello" }],
|
|
41
|
+
},
|
|
42
|
+
configuration: {
|
|
43
|
+
acceptedOutputModes: ["text/plain"],
|
|
44
|
+
returnImmediately: true,
|
|
45
|
+
},
|
|
39
46
|
});
|
|
40
47
|
|
|
41
48
|
// Streaming — SSE frames, each parsed as JSON-RPC
|
|
@@ -43,8 +50,15 @@ const controller = new AbortController();
|
|
|
43
50
|
for await (const event of client.sendStreamingMessage(
|
|
44
51
|
{
|
|
45
52
|
tenant: "",
|
|
46
|
-
message: {
|
|
47
|
-
|
|
53
|
+
message: {
|
|
54
|
+
messageId: "00000000-0000-7000-0000-000000000002",
|
|
55
|
+
role: "ROLE_USER",
|
|
56
|
+
parts: [{ text: "Hello" }],
|
|
57
|
+
},
|
|
58
|
+
configuration: {
|
|
59
|
+
acceptedOutputModes: ["text/plain"],
|
|
60
|
+
returnImmediately: false,
|
|
61
|
+
},
|
|
48
62
|
},
|
|
49
63
|
controller.signal,
|
|
50
64
|
)) {
|
|
@@ -69,7 +83,7 @@ for await (const event of client.sendStreamingMessage(
|
|
|
69
83
|
| `sendStreamingMessage` | `SendStreamingMessage` | Streaming (async iterator) |
|
|
70
84
|
| `subscribeToTask` | `SubscribeToTask` | Streaming (async iterator) |
|
|
71
85
|
|
|
72
|
-
Push-notification
|
|
86
|
+
Push-notification methods use the same JSON-RPC names as the protobuf RPCs, but **request bodies** follow the JSON-RPC wire shape (e.g. `createTaskPushNotificationConfig` expects `{ taskId, config }`, not a flat protobuf `AsObject`).
|
|
73
87
|
|
|
74
88
|
## Transport (`transport/jsonrpc`)
|
|
75
89
|
|
|
@@ -126,17 +140,27 @@ import type {
|
|
|
126
140
|
JsonRpcError,
|
|
127
141
|
JsonRpcRequest,
|
|
128
142
|
JsonRpcResponse,
|
|
143
|
+
SendMessageRequest,
|
|
144
|
+
StreamResponse,
|
|
145
|
+
Task,
|
|
129
146
|
} from "./transport/jsonrpc";
|
|
130
147
|
```
|
|
131
148
|
|
|
132
|
-
Protobuf
|
|
149
|
+
### Protobuf vs JSON-RPC types
|
|
150
|
+
|
|
151
|
+
| Use case | Types |
|
|
152
|
+
| -------- | ----- |
|
|
153
|
+
| **JSON-RPC client** (`A2AClient`) | Import wire types from `./transport/jsonrpc` (e.g. `SendMessageRequest`, `Task`, `StreamResponse`). These match the **A2A JSON-RPC** payloads your server accepts. |
|
|
154
|
+
| **gRPC / binary protobuf** | Generated messages under `lf/a2a/v1/a2a_pb` (`*.AsObject`, `Message`, etc.). |
|
|
155
|
+
|
|
156
|
+
Do not pass protobuf `AsObject` trees to `A2AClient` methods: field names differ (`parts` vs `partsList`, `acceptedOutputModes` vs `acceptedOutputModesList`, nested push `config`, flattened `Part` JSON, etc.).
|
|
133
157
|
|
|
134
158
|
## Project layout
|
|
135
159
|
|
|
136
160
|
| Path | Purpose |
|
|
137
161
|
| -------------------- | ------------------------------------------ |
|
|
138
162
|
| `lf/a2a/v1/` | Generated protobuf JS/TS (A2A API) |
|
|
139
|
-
| `transport/jsonrpc/` | JSON-RPC client, SSE parser, errors, types |
|
|
163
|
+
| `transport/jsonrpc/` | JSON-RPC client, SSE parser, errors, **wire types** (`wire/`) |
|
|
140
164
|
|
|
141
165
|
## Dependencies
|
|
142
166
|
|
package/package.json
CHANGED
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
import { A2AClientConfig, JsonRpcRequest, JsonRpcResponse } from "./types";
|
|
2
|
-
import {
|
|
2
|
+
import type {
|
|
3
3
|
AgentCard,
|
|
4
4
|
CancelTaskRequest,
|
|
5
|
-
|
|
5
|
+
CreateTaskPushConfigRequest,
|
|
6
|
+
DeleteTaskPushConfigRequest,
|
|
6
7
|
GetExtendedAgentCardRequest,
|
|
7
|
-
|
|
8
|
+
GetTaskPushConfigRequest,
|
|
8
9
|
GetTaskRequest,
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
ListTaskPushConfigRequest,
|
|
11
|
+
ListTaskPushConfigResponse,
|
|
11
12
|
ListTasksRequest,
|
|
12
13
|
ListTasksResponse,
|
|
13
14
|
SendMessageRequest,
|
|
14
15
|
StreamResponse,
|
|
15
16
|
SubscribeToTaskRequest,
|
|
16
17
|
Task,
|
|
17
|
-
|
|
18
|
-
} from "
|
|
18
|
+
TaskPushConfig,
|
|
19
|
+
} from "./wire";
|
|
19
20
|
import { createProtocolError, JsonRpcTransportError } from "./errors";
|
|
20
21
|
import { readSseStream } from "./sse";
|
|
21
22
|
|
|
@@ -72,38 +73,36 @@ export class A2AClient {
|
|
|
72
73
|
* Sends a message and waits for a single complete response.
|
|
73
74
|
* Use sendStreamingMessage() if the agent streams partial updates.
|
|
74
75
|
*/
|
|
75
|
-
async sendMessage(
|
|
76
|
-
|
|
77
|
-
): Promise<StreamResponse.AsObject> {
|
|
78
|
-
return this.request<StreamResponse.AsObject>(Methods.sendMessage, params);
|
|
76
|
+
async sendMessage(params: SendMessageRequest): Promise<StreamResponse> {
|
|
77
|
+
return this.request<StreamResponse>(Methods.sendMessage, params);
|
|
79
78
|
}
|
|
80
79
|
|
|
81
80
|
/**
|
|
82
81
|
* Retrieves a task by ID.
|
|
83
82
|
*/
|
|
84
|
-
async getTask(params: GetTaskRequest
|
|
85
|
-
return this.request<Task
|
|
83
|
+
async getTask(params: GetTaskRequest): Promise<Task> {
|
|
84
|
+
return this.request<Task>(Methods.getTask, params);
|
|
86
85
|
}
|
|
87
86
|
|
|
88
87
|
/**
|
|
89
88
|
* Cancels a task by ID.
|
|
90
89
|
*/
|
|
91
|
-
async cancelTask(params: CancelTaskRequest
|
|
92
|
-
return this.request<Task
|
|
90
|
+
async cancelTask(params: CancelTaskRequest): Promise<Task> {
|
|
91
|
+
return this.request<Task>(Methods.cancelTask, params);
|
|
93
92
|
}
|
|
94
93
|
|
|
95
94
|
/** Lists tasks, with optional filtering and pagination. */
|
|
96
95
|
async listTasks(
|
|
97
|
-
params: Partial<ListTasksRequest
|
|
98
|
-
): Promise<ListTasksResponse
|
|
99
|
-
return this.request<ListTasksResponse
|
|
96
|
+
params: Partial<ListTasksRequest> = {},
|
|
97
|
+
): Promise<ListTasksResponse> {
|
|
98
|
+
return this.request<ListTasksResponse>(Methods.listTasks, params);
|
|
100
99
|
}
|
|
101
100
|
|
|
102
101
|
/** Retrieves a push notification config by task ID and config ID. */
|
|
103
102
|
async getTaskPushNotificationConfig(
|
|
104
|
-
params:
|
|
105
|
-
): Promise<
|
|
106
|
-
return this.request<
|
|
103
|
+
params: GetTaskPushConfigRequest,
|
|
104
|
+
): Promise<TaskPushConfig> {
|
|
105
|
+
return this.request<TaskPushConfig>(
|
|
107
106
|
Methods.getTaskPushNotificationConfig,
|
|
108
107
|
params,
|
|
109
108
|
);
|
|
@@ -111,12 +110,12 @@ export class A2AClient {
|
|
|
111
110
|
|
|
112
111
|
/**
|
|
113
112
|
* Creates a push notification config for a task.
|
|
114
|
-
*
|
|
113
|
+
* Request body: `taskId`, nested `config`, optional `tenant`.
|
|
115
114
|
*/
|
|
116
115
|
async createTaskPushNotificationConfig(
|
|
117
|
-
params:
|
|
118
|
-
): Promise<
|
|
119
|
-
return this.request<
|
|
116
|
+
params: CreateTaskPushConfigRequest,
|
|
117
|
+
): Promise<TaskPushConfig> {
|
|
118
|
+
return this.request<TaskPushConfig>(
|
|
120
119
|
Methods.createTaskPushNotificationConfig,
|
|
121
120
|
params,
|
|
122
121
|
);
|
|
@@ -124,9 +123,9 @@ export class A2AClient {
|
|
|
124
123
|
|
|
125
124
|
/** Lists push notification configs for a task. */
|
|
126
125
|
async listTaskPushNotificationConfigs(
|
|
127
|
-
params:
|
|
128
|
-
): Promise<
|
|
129
|
-
return this.request<
|
|
126
|
+
params: ListTaskPushConfigRequest,
|
|
127
|
+
): Promise<ListTaskPushConfigResponse> {
|
|
128
|
+
return this.request<ListTaskPushConfigResponse>(
|
|
130
129
|
Methods.listTaskPushNotificationConfigs,
|
|
131
130
|
params,
|
|
132
131
|
);
|
|
@@ -134,19 +133,16 @@ export class A2AClient {
|
|
|
134
133
|
|
|
135
134
|
/** Deletes a push notification config. Returns void — server sends an empty result. */
|
|
136
135
|
async deleteTaskPushNotificationConfig(
|
|
137
|
-
params:
|
|
136
|
+
params: DeleteTaskPushConfigRequest,
|
|
138
137
|
): Promise<void> {
|
|
139
138
|
await this.request<void>(Methods.deleteTaskPushNotificationConfig, params);
|
|
140
139
|
}
|
|
141
140
|
|
|
142
141
|
/** Retrieves the extended agent card. */
|
|
143
142
|
async getExtendedAgentCard(
|
|
144
|
-
params: Partial<GetExtendedAgentCardRequest
|
|
145
|
-
): Promise<AgentCard
|
|
146
|
-
return this.request<AgentCard
|
|
147
|
-
Methods.getExtendedAgentCard,
|
|
148
|
-
params,
|
|
149
|
-
);
|
|
143
|
+
params: Partial<GetExtendedAgentCardRequest> = {},
|
|
144
|
+
): Promise<AgentCard> {
|
|
145
|
+
return this.request<AgentCard>(Methods.getExtendedAgentCard, params);
|
|
150
146
|
}
|
|
151
147
|
|
|
152
148
|
/**
|
|
@@ -164,10 +160,10 @@ export class A2AClient {
|
|
|
164
160
|
* @throws {JsonRpcProtocolError} On a JSON-RPC error frame (terminal).
|
|
165
161
|
*/
|
|
166
162
|
async *sendStreamingMessage(
|
|
167
|
-
params: SendMessageRequest
|
|
163
|
+
params: SendMessageRequest,
|
|
168
164
|
signal?: AbortSignal,
|
|
169
|
-
): AsyncGenerator<StreamResponse
|
|
170
|
-
yield* this.stream<StreamResponse
|
|
165
|
+
): AsyncGenerator<StreamResponse> {
|
|
166
|
+
yield* this.stream<StreamResponse>(
|
|
171
167
|
Methods.sendStreamingMessage,
|
|
172
168
|
params,
|
|
173
169
|
signal,
|
|
@@ -181,10 +177,10 @@ export class A2AClient {
|
|
|
181
177
|
* @throws {JsonRpcProtocolError} On a JSON-RPC error frame (terminal).
|
|
182
178
|
*/
|
|
183
179
|
async *subscribeToTask(
|
|
184
|
-
params: SubscribeToTaskRequest
|
|
180
|
+
params: SubscribeToTaskRequest,
|
|
185
181
|
signal?: AbortSignal,
|
|
186
|
-
): AsyncGenerator<StreamResponse
|
|
187
|
-
yield* this.stream<StreamResponse
|
|
182
|
+
): AsyncGenerator<StreamResponse> {
|
|
183
|
+
yield* this.stream<StreamResponse>(
|
|
188
184
|
Methods.subscribeToTask,
|
|
189
185
|
params,
|
|
190
186
|
signal,
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import type { JsonObject } from "./json";
|
|
2
|
+
|
|
3
|
+
/** Parameters for the `GetExtendedAgentCard` JSON-RPC method. */
|
|
4
|
+
export interface GetExtendedAgentCardRequest {
|
|
5
|
+
tenant?: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/** Declared optional capabilities of an agent. */
|
|
9
|
+
export interface AgentCapabilities {
|
|
10
|
+
extensions?: AgentExtension[];
|
|
11
|
+
pushNotifications?: boolean;
|
|
12
|
+
streaming?: boolean;
|
|
13
|
+
extendedAgentCard?: boolean;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** Declaration of a protocol extension. */
|
|
17
|
+
export interface AgentExtension {
|
|
18
|
+
description?: string;
|
|
19
|
+
params?: JsonObject;
|
|
20
|
+
required?: boolean;
|
|
21
|
+
uri?: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** Transport protocol binding at an interface URL (open string; e.g. `JSONRPC`, `GRPC`). */
|
|
25
|
+
export type TransportProtocol = string;
|
|
26
|
+
|
|
27
|
+
/** Protocol version string (e.g. `1.0`). */
|
|
28
|
+
export type ProtocolVersion = string;
|
|
29
|
+
|
|
30
|
+
/** A supported URL and protocol binding for the agent. */
|
|
31
|
+
export interface AgentInterface {
|
|
32
|
+
url: string;
|
|
33
|
+
protocolBinding: TransportProtocol;
|
|
34
|
+
tenant?: string;
|
|
35
|
+
protocolVersion: ProtocolVersion;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** Service provider metadata (`organization` in JSON). */
|
|
39
|
+
export interface AgentProvider {
|
|
40
|
+
organization: string;
|
|
41
|
+
url: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** A skill exposed by the agent. */
|
|
45
|
+
export interface AgentSkill {
|
|
46
|
+
description: string;
|
|
47
|
+
examples?: string[];
|
|
48
|
+
id: string;
|
|
49
|
+
inputModes?: string[];
|
|
50
|
+
name: string;
|
|
51
|
+
outputModes?: string[];
|
|
52
|
+
securityRequirements?: SecurityRequirementsOptions;
|
|
53
|
+
tags: string[];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** JWS signature block for an agent card. */
|
|
57
|
+
export interface AgentCardSignature {
|
|
58
|
+
header?: JsonObject;
|
|
59
|
+
protected: string;
|
|
60
|
+
signature: string;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Security requirements list: each item has a `schemes` map from scheme name to required scopes.
|
|
65
|
+
*/
|
|
66
|
+
export type SecurityRequirementsOptions = Array<{
|
|
67
|
+
schemes: Record<string, string[]>;
|
|
68
|
+
}>;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Named security scheme definitions (OpenAPI-style); keys are scheme names.
|
|
72
|
+
*/
|
|
73
|
+
export type NamedSecuritySchemes = Record<string, unknown>;
|
|
74
|
+
|
|
75
|
+
/** Self-describing agent manifest. */
|
|
76
|
+
export interface AgentCard {
|
|
77
|
+
supportedInterfaces: AgentInterface[];
|
|
78
|
+
capabilities: AgentCapabilities;
|
|
79
|
+
defaultInputModes: string[];
|
|
80
|
+
defaultOutputModes: string[];
|
|
81
|
+
description: string;
|
|
82
|
+
documentationUrl?: string;
|
|
83
|
+
iconUrl?: string;
|
|
84
|
+
name: string;
|
|
85
|
+
provider?: AgentProvider;
|
|
86
|
+
securityRequirements?: SecurityRequirementsOptions;
|
|
87
|
+
securitySchemes?: NamedSecuritySchemes;
|
|
88
|
+
signatures?: AgentCardSignature[];
|
|
89
|
+
skills: AgentSkill[];
|
|
90
|
+
version: string;
|
|
91
|
+
}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import type { JsonObject } from "./json";
|
|
2
|
+
|
|
3
|
+
/** JSON string values for a message `role` in the A2A wire format. */
|
|
4
|
+
export type MessageRoleJson =
|
|
5
|
+
| "ROLE_UNSPECIFIED"
|
|
6
|
+
| "ROLE_AGENT"
|
|
7
|
+
| "ROLE_USER"
|
|
8
|
+
| "";
|
|
9
|
+
|
|
10
|
+
/** JSON string values for task `state` in the A2A wire format. */
|
|
11
|
+
export type TaskStateJson =
|
|
12
|
+
| "TASK_STATE_UNSPECIFIED"
|
|
13
|
+
| "TASK_STATE_SUBMITTED"
|
|
14
|
+
| "TASK_STATE_WORKING"
|
|
15
|
+
| "TASK_STATE_COMPLETED"
|
|
16
|
+
| "TASK_STATE_FAILED"
|
|
17
|
+
| "TASK_STATE_CANCELED"
|
|
18
|
+
| "TASK_STATE_INPUT_REQUIRED"
|
|
19
|
+
| "TASK_STATE_REJECTED"
|
|
20
|
+
| "TASK_STATE_AUTH_REQUIRED"
|
|
21
|
+
| "";
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* A content part as JSON: a single flattened variant using `text`, `raw` (base64),
|
|
25
|
+
* `data`, or `url` (A2A JSON-RPC wire format).
|
|
26
|
+
*/
|
|
27
|
+
export interface Part {
|
|
28
|
+
text?: string;
|
|
29
|
+
/** Base64-encoded bytes when sent as a JSON string. */
|
|
30
|
+
raw?: string;
|
|
31
|
+
data?: unknown;
|
|
32
|
+
url?: string;
|
|
33
|
+
filename?: string;
|
|
34
|
+
mediaType?: string;
|
|
35
|
+
metadata?: JsonObject;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface Message {
|
|
39
|
+
messageId: string;
|
|
40
|
+
contextId?: string;
|
|
41
|
+
extensions?: string[];
|
|
42
|
+
metadata?: JsonObject;
|
|
43
|
+
parts: Part[];
|
|
44
|
+
referenceTaskIds?: string[];
|
|
45
|
+
role: MessageRoleJson;
|
|
46
|
+
taskId?: string;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface TaskStatus {
|
|
50
|
+
message?: Message;
|
|
51
|
+
state: TaskStateJson;
|
|
52
|
+
/** RFC3339 timestamp string. */
|
|
53
|
+
timestamp?: string;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface Artifact {
|
|
57
|
+
artifactId: string;
|
|
58
|
+
description?: string;
|
|
59
|
+
extensions?: string[];
|
|
60
|
+
metadata?: JsonObject;
|
|
61
|
+
name?: string;
|
|
62
|
+
parts: Part[];
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export interface Task {
|
|
66
|
+
id: string;
|
|
67
|
+
artifacts?: Artifact[];
|
|
68
|
+
contextId: string;
|
|
69
|
+
history?: Message[];
|
|
70
|
+
metadata?: JsonObject;
|
|
71
|
+
status: TaskStatus;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface TaskStatusUpdateEvent {
|
|
75
|
+
contextId: string;
|
|
76
|
+
status: TaskStatus;
|
|
77
|
+
taskId: string;
|
|
78
|
+
metadata?: JsonObject;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export interface TaskArtifactUpdateEvent {
|
|
82
|
+
append?: boolean;
|
|
83
|
+
artifact: Artifact;
|
|
84
|
+
contextId: string;
|
|
85
|
+
lastChunk?: boolean;
|
|
86
|
+
taskId: string;
|
|
87
|
+
metadata?: JsonObject;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Unary `SendMessage` and streaming frames use the same result wrapper.
|
|
92
|
+
* At most one payload field should be set.
|
|
93
|
+
*/
|
|
94
|
+
export interface StreamResponse {
|
|
95
|
+
message?: Message;
|
|
96
|
+
task?: Task;
|
|
97
|
+
statusUpdate?: TaskStatusUpdateEvent;
|
|
98
|
+
artifactUpdate?: TaskArtifactUpdateEvent;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/** Authentication details for a push notification endpoint. */
|
|
102
|
+
export interface PushAuthInfo {
|
|
103
|
+
credentials?: string;
|
|
104
|
+
scheme: string;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/** Push notification callback configuration. */
|
|
108
|
+
export interface PushConfig {
|
|
109
|
+
id?: string;
|
|
110
|
+
authentication?: PushAuthInfo;
|
|
111
|
+
token?: string;
|
|
112
|
+
url: string;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** Options for `SendMessage` / `SendStreamingMessage` (`configuration` in JSON). */
|
|
116
|
+
export interface SendMessageConfig {
|
|
117
|
+
acceptedOutputModes?: string[];
|
|
118
|
+
returnImmediately?: boolean;
|
|
119
|
+
historyLength?: number;
|
|
120
|
+
pushNotificationConfig?: PushConfig;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/** Parameters for the `SendMessage` JSON-RPC method. */
|
|
124
|
+
export interface SendMessageRequest {
|
|
125
|
+
tenant?: string;
|
|
126
|
+
configuration?: SendMessageConfig;
|
|
127
|
+
message: Message;
|
|
128
|
+
metadata?: JsonObject;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/** Parameters for the `GetTask` JSON-RPC method. */
|
|
132
|
+
export interface GetTaskRequest {
|
|
133
|
+
tenant?: string;
|
|
134
|
+
id: string;
|
|
135
|
+
historyLength?: number;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/** Parameters for the `ListTasks` JSON-RPC method. */
|
|
139
|
+
export interface ListTasksRequest {
|
|
140
|
+
tenant?: string;
|
|
141
|
+
contextId?: string;
|
|
142
|
+
status?: TaskStateJson;
|
|
143
|
+
pageSize?: number;
|
|
144
|
+
pageToken?: string;
|
|
145
|
+
historyLength?: number;
|
|
146
|
+
/** RFC3339 timestamp string */
|
|
147
|
+
statusTimestampAfter?: string;
|
|
148
|
+
includeArtifacts?: boolean;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/** Result of the `ListTasks` JSON-RPC method. */
|
|
152
|
+
export interface ListTasksResponse {
|
|
153
|
+
tasks: Task[];
|
|
154
|
+
totalSize: number;
|
|
155
|
+
pageSize: number;
|
|
156
|
+
nextPageToken: string;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/** Parameters for the `CancelTask` JSON-RPC method. */
|
|
160
|
+
export interface CancelTaskRequest {
|
|
161
|
+
tenant?: string;
|
|
162
|
+
id: string;
|
|
163
|
+
metadata?: JsonObject;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/** Parameters for the `SubscribeToTask` JSON-RPC method. */
|
|
167
|
+
export interface SubscribeToTaskRequest {
|
|
168
|
+
tenant?: string;
|
|
169
|
+
id: string;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/** Push configuration associated with a task. */
|
|
173
|
+
export interface TaskPushConfig {
|
|
174
|
+
tenant?: string;
|
|
175
|
+
config: PushConfig;
|
|
176
|
+
taskId: string;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/** Parameters for `GetTaskPushNotificationConfig`. */
|
|
180
|
+
export interface GetTaskPushConfigRequest {
|
|
181
|
+
tenant?: string;
|
|
182
|
+
taskId: string;
|
|
183
|
+
id: string;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/** Parameters for `ListTaskPushNotificationConfigs`. */
|
|
187
|
+
export interface ListTaskPushConfigRequest {
|
|
188
|
+
tenant?: string;
|
|
189
|
+
taskId: string;
|
|
190
|
+
pageSize?: number;
|
|
191
|
+
pageToken?: string;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/** Result of `ListTaskPushNotificationConfigs`. */
|
|
195
|
+
export interface ListTaskPushConfigResponse {
|
|
196
|
+
configs: TaskPushConfig[];
|
|
197
|
+
nextPageToken?: string;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/** Parameters for `CreateTaskPushNotificationConfig`. */
|
|
201
|
+
export interface CreateTaskPushConfigRequest {
|
|
202
|
+
tenant?: string;
|
|
203
|
+
config: PushConfig;
|
|
204
|
+
taskId: string;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/** Parameters for `DeleteTaskPushNotificationConfig`. */
|
|
208
|
+
export interface DeleteTaskPushConfigRequest {
|
|
209
|
+
tenant?: string;
|
|
210
|
+
taskId: string;
|
|
211
|
+
id: string;
|
|
212
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A2A JSON-RPC wire types.
|
|
3
|
+
*
|
|
4
|
+
* Request `params` include: `SendMessageRequest`, `GetTaskRequest`, `ListTasksRequest`,
|
|
5
|
+
* `CancelTaskRequest`, `SubscribeToTaskRequest`, push config requests, `GetExtendedAgentCardRequest`.
|
|
6
|
+
*
|
|
7
|
+
* Response `result` shapes include: `StreamResponse`, `Task`, `ListTasksResponse`,
|
|
8
|
+
* `ListTaskPushConfigResponse`, `TaskPushConfig`, `AgentCard`, etc.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export type { JsonObject } from "./json";
|
|
12
|
+
export type {
|
|
13
|
+
Artifact,
|
|
14
|
+
CancelTaskRequest,
|
|
15
|
+
CreateTaskPushConfigRequest,
|
|
16
|
+
DeleteTaskPushConfigRequest,
|
|
17
|
+
GetTaskPushConfigRequest,
|
|
18
|
+
GetTaskRequest,
|
|
19
|
+
ListTaskPushConfigRequest,
|
|
20
|
+
ListTaskPushConfigResponse,
|
|
21
|
+
ListTasksRequest,
|
|
22
|
+
ListTasksResponse,
|
|
23
|
+
Message,
|
|
24
|
+
MessageRoleJson,
|
|
25
|
+
Part,
|
|
26
|
+
PushAuthInfo,
|
|
27
|
+
PushConfig,
|
|
28
|
+
SendMessageConfig,
|
|
29
|
+
SendMessageRequest,
|
|
30
|
+
StreamResponse,
|
|
31
|
+
SubscribeToTaskRequest,
|
|
32
|
+
Task,
|
|
33
|
+
TaskArtifactUpdateEvent,
|
|
34
|
+
TaskPushConfig,
|
|
35
|
+
TaskStateJson,
|
|
36
|
+
TaskStatus,
|
|
37
|
+
TaskStatusUpdateEvent,
|
|
38
|
+
} from "./common";
|
|
39
|
+
export type {
|
|
40
|
+
AgentCapabilities,
|
|
41
|
+
AgentCard,
|
|
42
|
+
AgentCardSignature,
|
|
43
|
+
AgentExtension,
|
|
44
|
+
AgentInterface,
|
|
45
|
+
AgentProvider,
|
|
46
|
+
AgentSkill,
|
|
47
|
+
GetExtendedAgentCardRequest,
|
|
48
|
+
NamedSecuritySchemes,
|
|
49
|
+
ProtocolVersion,
|
|
50
|
+
SecurityRequirementsOptions,
|
|
51
|
+
TransportProtocol,
|
|
52
|
+
} from "./agent-card";
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import type { CreateTaskPushConfigRequest, Part, SendMessageRequest } from "./index";
|
|
3
|
+
|
|
4
|
+
/** Golden part payloads for the JSON-RPC wire format (flattened `text` / `raw` / `data` / `url`). */
|
|
5
|
+
const PARTS_JSON = [
|
|
6
|
+
`{"text":"hello, world"}`,
|
|
7
|
+
`{"data":{"foo":"bar"}}`,
|
|
8
|
+
`{"filename":"foo","url":"https://cats.com/1.png"}`,
|
|
9
|
+
`{"filename":"foo","mediaType":"image/png","raw":"//4="}`,
|
|
10
|
+
`{"metadata":{"foo":"bar"},"text":"42"}`,
|
|
11
|
+
];
|
|
12
|
+
|
|
13
|
+
describe("JSON-RPC wire types", () => {
|
|
14
|
+
it("round-trips Part JSON (flattened content fields)", () => {
|
|
15
|
+
const parsed: Part[] = PARTS_JSON.map((s) => JSON.parse(s) as Part);
|
|
16
|
+
expect(parsed).toHaveLength(5);
|
|
17
|
+
expect(parsed[0].text).toBe("hello, world");
|
|
18
|
+
expect(parsed[1].data).toEqual({ foo: "bar" });
|
|
19
|
+
expect(parsed[2].url).toBe("https://cats.com/1.png");
|
|
20
|
+
expect(parsed[3].raw).toBe("//4=");
|
|
21
|
+
for (let i = 0; i < PARTS_JSON.length; i++) {
|
|
22
|
+
expect(JSON.stringify(parsed[i])).toBe(PARTS_JSON[i]);
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it("SendMessageRequest uses wire field names (not protobuf AsObject)", () => {
|
|
27
|
+
const req: SendMessageRequest = {
|
|
28
|
+
tenant: "",
|
|
29
|
+
configuration: {
|
|
30
|
+
acceptedOutputModes: ["text/plain"],
|
|
31
|
+
returnImmediately: true,
|
|
32
|
+
historyLength: 3,
|
|
33
|
+
},
|
|
34
|
+
message: {
|
|
35
|
+
messageId: "m1",
|
|
36
|
+
role: "ROLE_USER",
|
|
37
|
+
parts: [{ text: "hi" }],
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
const json = JSON.stringify(req);
|
|
41
|
+
const o = JSON.parse(json) as Record<string, unknown>;
|
|
42
|
+
expect(o.configuration).toBeDefined();
|
|
43
|
+
const cfg = o.configuration as Record<string, unknown>;
|
|
44
|
+
expect(cfg.acceptedOutputModes).toEqual(["text/plain"]);
|
|
45
|
+
expect(cfg.returnImmediately).toBe(true);
|
|
46
|
+
expect(cfg.historyLength).toBe(3);
|
|
47
|
+
expect("acceptedOutputModesList" in cfg).toBe(false);
|
|
48
|
+
expect("blocking" in cfg).toBe(false);
|
|
49
|
+
const msg = o.message as Record<string, unknown>;
|
|
50
|
+
expect(msg.parts).toEqual([{ text: "hi" }]);
|
|
51
|
+
expect("partsList" in msg).toBe(false);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it("CreateTaskPushConfigRequest uses nested config (not flat TaskPushNotificationConfig)", () => {
|
|
55
|
+
const req: CreateTaskPushConfigRequest = {
|
|
56
|
+
tenant: "t1",
|
|
57
|
+
taskId: "task-1",
|
|
58
|
+
config: {
|
|
59
|
+
id: "cfg-1",
|
|
60
|
+
url: "https://example.com/push",
|
|
61
|
+
token: "tok",
|
|
62
|
+
authentication: { scheme: "Bearer", credentials: "x" },
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
const o = JSON.parse(JSON.stringify(req)) as Record<string, unknown>;
|
|
66
|
+
expect(o.taskId).toBe("task-1");
|
|
67
|
+
expect(o.config).toBeDefined();
|
|
68
|
+
expect((o.config as { url: string }).url).toBe("https://example.com/push");
|
|
69
|
+
});
|
|
70
|
+
});
|
package/tsconfig.json
ADDED