@a2anet/a2a-utils 0.1.0 → 0.4.0
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 +1412 -2
- package/dist/artifacts/data.d.ts +118 -0
- package/dist/artifacts/data.d.ts.map +1 -0
- package/dist/artifacts/data.js +583 -0
- package/dist/artifacts/data.js.map +1 -0
- package/dist/artifacts/index.d.ts +33 -0
- package/dist/artifacts/index.d.ts.map +1 -0
- package/dist/artifacts/index.js +131 -0
- package/dist/artifacts/index.js.map +1 -0
- package/dist/artifacts/text.d.ts +54 -0
- package/dist/artifacts/text.d.ts.map +1 -0
- package/dist/artifacts/text.js +151 -0
- package/dist/artifacts/text.js.map +1 -0
- package/dist/client/a2a-agents.d.ts +94 -0
- package/dist/client/a2a-agents.d.ts.map +1 -0
- package/dist/client/a2a-agents.js +243 -0
- package/dist/client/a2a-agents.js.map +1 -0
- package/dist/client/a2a-session.d.ts +94 -0
- package/dist/client/a2a-session.d.ts.map +1 -0
- package/dist/client/a2a-session.js +264 -0
- package/dist/client/a2a-session.js.map +1 -0
- package/dist/client/a2a-tools.d.ts +152 -0
- package/dist/client/a2a-tools.d.ts.map +1 -0
- package/dist/client/a2a-tools.js +470 -0
- package/dist/client/a2a-tools.js.map +1 -0
- package/dist/client/index.d.ts +4 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +7 -0
- package/dist/client/index.js.map +1 -0
- package/dist/files/file-store.d.ts +24 -0
- package/dist/files/file-store.d.ts.map +1 -0
- package/dist/files/file-store.js +5 -0
- package/dist/files/file-store.js.map +1 -0
- package/dist/files/index.d.ts +3 -0
- package/dist/files/index.d.ts.map +1 -0
- package/dist/files/index.js +5 -0
- package/dist/files/index.js.map +1 -0
- package/dist/files/local-file-store.d.ts +26 -0
- package/dist/files/local-file-store.d.ts.map +1 -0
- package/dist/files/local-file-store.js +99 -0
- package/dist/files/local-file-store.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/tasks/index.d.ts +2 -0
- package/dist/tasks/index.d.ts.map +1 -0
- package/dist/tasks/index.js +5 -0
- package/dist/tasks/index.js.map +1 -0
- package/dist/tasks/json-task-store.d.ts +32 -0
- package/dist/tasks/json-task-store.d.ts.map +1 -0
- package/dist/tasks/json-task-store.js +66 -0
- package/dist/tasks/json-task-store.js.map +1 -0
- package/dist/types.d.ts +65 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +23 -0
- package/dist/types.js.map +1 -0
- package/package.json +17 -4
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2025-present A2A Net <hello@a2anet.com>
|
|
2
|
+
//
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
/**
|
|
5
|
+
* Agent management for A2A applications.
|
|
6
|
+
*/
|
|
7
|
+
import * as fs from "node:fs";
|
|
8
|
+
import { DefaultAgentCardResolver } from "@a2a-js/sdk/client";
|
|
9
|
+
/**
|
|
10
|
+
* Manages A2A agent cards keyed by user-defined agent IDs.
|
|
11
|
+
*
|
|
12
|
+
* Agents are configured via a dict mapping agent_id to config, or a JSON file path.
|
|
13
|
+
*/
|
|
14
|
+
export class A2AAgents {
|
|
15
|
+
config;
|
|
16
|
+
agents = {};
|
|
17
|
+
initErrors = {};
|
|
18
|
+
initialized = false;
|
|
19
|
+
initPromise = null;
|
|
20
|
+
timeout;
|
|
21
|
+
/**
|
|
22
|
+
* Initialize the agent manager.
|
|
23
|
+
*
|
|
24
|
+
* @param agents - Agent config as:
|
|
25
|
+
* - object: {"agent-id": {"url": "https://...", "custom_headers": {"X-API-Key": "..."}}}
|
|
26
|
+
* - string: path to agents.json file with the same structure
|
|
27
|
+
* - null: empty, add agents later
|
|
28
|
+
* @param opts.timeout - HTTP timeout in seconds for fetching agent cards (default: 15s).
|
|
29
|
+
*/
|
|
30
|
+
constructor(agents = null, opts) {
|
|
31
|
+
this.timeout = opts?.timeout ?? 15.0;
|
|
32
|
+
this.config = this.loadConfig(agents);
|
|
33
|
+
}
|
|
34
|
+
/** Load and validate agent config. */
|
|
35
|
+
loadConfig(agents) {
|
|
36
|
+
if (agents === null) {
|
|
37
|
+
return {};
|
|
38
|
+
}
|
|
39
|
+
if (typeof agents === "string") {
|
|
40
|
+
const text = fs.readFileSync(agents, "utf-8");
|
|
41
|
+
return JSON.parse(text);
|
|
42
|
+
}
|
|
43
|
+
return { ...agents };
|
|
44
|
+
}
|
|
45
|
+
/** Lazily fetch all agent cards on first use (double-check locking). */
|
|
46
|
+
async ensureInitialized() {
|
|
47
|
+
if (this.initialized)
|
|
48
|
+
return;
|
|
49
|
+
// Single-flight pattern
|
|
50
|
+
if (this.initPromise === null) {
|
|
51
|
+
this.initPromise = this.doInitialize();
|
|
52
|
+
}
|
|
53
|
+
await this.initPromise;
|
|
54
|
+
}
|
|
55
|
+
async doInitialize() {
|
|
56
|
+
if (this.initialized)
|
|
57
|
+
return;
|
|
58
|
+
if (Object.keys(this.config).length === 0) {
|
|
59
|
+
console.warn("No agents configured");
|
|
60
|
+
this.initialized = true;
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const entries = Object.entries(this.config);
|
|
64
|
+
const results = await Promise.allSettled(entries.map(([agentId, cfg]) => this.fetchAgent(agentId, cfg)));
|
|
65
|
+
this.initErrors = {};
|
|
66
|
+
for (let i = 0; i < results.length; i++) {
|
|
67
|
+
const result = results[i];
|
|
68
|
+
if (result.status === "rejected") {
|
|
69
|
+
const aid = entries[i][0];
|
|
70
|
+
const url = this.config[aid]?.url ?? "unknown";
|
|
71
|
+
const reason = result.reason;
|
|
72
|
+
const errorMsg = `${reason?.constructor?.name ?? "Error"}: ${reason}`;
|
|
73
|
+
this.initErrors[aid] = errorMsg;
|
|
74
|
+
console.error(`Error loading agent '${aid}' from ${url}: ${errorMsg}`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (Object.keys(this.agents).length > 0) {
|
|
78
|
+
console.info(`Successfully initialized ${Object.keys(this.agents).length} agent(s)`);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
console.warn("No agents were successfully initialized");
|
|
82
|
+
}
|
|
83
|
+
this.initialized = true;
|
|
84
|
+
}
|
|
85
|
+
/** Fetch a single agent card and register it. */
|
|
86
|
+
async fetchAgent(agentId, config) {
|
|
87
|
+
const url = config.url;
|
|
88
|
+
const customHeaders = config.custom_headers ?? {};
|
|
89
|
+
const [baseUrl, cardPath] = this.parseAgentCardUrl(url);
|
|
90
|
+
const resolver = new DefaultAgentCardResolver({
|
|
91
|
+
fetchImpl: this.createFetchImpl(customHeaders),
|
|
92
|
+
});
|
|
93
|
+
const agentCard = await resolver.resolve(baseUrl, cardPath);
|
|
94
|
+
this.agents[agentId] = {
|
|
95
|
+
agentCard,
|
|
96
|
+
customHeaders,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
/** Create a fetch implementation that applies the configured timeout and custom headers. */
|
|
100
|
+
createFetchImpl(customHeaders) {
|
|
101
|
+
const wrappedFetch = (input, init) => {
|
|
102
|
+
const timeoutSignal = AbortSignal.timeout(this.timeout * 1000);
|
|
103
|
+
const signal = init?.signal != null
|
|
104
|
+
? AbortSignal.any([init.signal, timeoutSignal])
|
|
105
|
+
: timeoutSignal;
|
|
106
|
+
const mergedInit = {
|
|
107
|
+
...init,
|
|
108
|
+
signal,
|
|
109
|
+
headers: {
|
|
110
|
+
...init?.headers,
|
|
111
|
+
...customHeaders,
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
return fetch(input, mergedInit);
|
|
115
|
+
};
|
|
116
|
+
wrappedFetch.preconnect = fetch.preconnect;
|
|
117
|
+
return wrappedFetch;
|
|
118
|
+
}
|
|
119
|
+
/** Parse agent card URL into base_url and card_path. */
|
|
120
|
+
parseAgentCardUrl(url) {
|
|
121
|
+
const parsed = new URL(url);
|
|
122
|
+
const baseUrl = `${parsed.protocol}//${parsed.host}`;
|
|
123
|
+
const cardPath = parsed.pathname;
|
|
124
|
+
return [baseUrl, cardPath];
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Register a new agent at runtime.
|
|
128
|
+
*
|
|
129
|
+
* @param agentId - User-defined agent identifier.
|
|
130
|
+
* @param url - Agent card URL.
|
|
131
|
+
* @param customHeaders - Optional custom HTTP headers.
|
|
132
|
+
*
|
|
133
|
+
* @throws Error if agentId is already registered.
|
|
134
|
+
*/
|
|
135
|
+
async addAgent(agentId, url, customHeaders) {
|
|
136
|
+
await this.ensureInitialized();
|
|
137
|
+
if (agentId in this.agents) {
|
|
138
|
+
throw new Error(`Agent '${agentId}' is already registered`);
|
|
139
|
+
}
|
|
140
|
+
const config = {
|
|
141
|
+
url,
|
|
142
|
+
custom_headers: customHeaders ?? {},
|
|
143
|
+
};
|
|
144
|
+
await this.fetchAgent(agentId, config);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Retrieve agent by ID.
|
|
148
|
+
*
|
|
149
|
+
* @param agentId - User-defined agent identifier.
|
|
150
|
+
*
|
|
151
|
+
* @returns AgentURLAndCustomHeaders, or null if not found.
|
|
152
|
+
*/
|
|
153
|
+
async getAgent(agentId) {
|
|
154
|
+
await this.ensureInitialized();
|
|
155
|
+
return this.agents[agentId] ?? null;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Get errors from the most recent initialization attempt.
|
|
159
|
+
*
|
|
160
|
+
* @returns Object mapping agent_id to error message for agents that failed to load.
|
|
161
|
+
*/
|
|
162
|
+
get initializationErrors() {
|
|
163
|
+
return { ...this.initErrors };
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Get all registered agents.
|
|
167
|
+
*
|
|
168
|
+
* @returns Object mapping agent_id to AgentURLAndCustomHeaders.
|
|
169
|
+
*/
|
|
170
|
+
async getAgents() {
|
|
171
|
+
await this.ensureInitialized();
|
|
172
|
+
return { ...this.agents };
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Format a single agent card into a summary object.
|
|
176
|
+
*
|
|
177
|
+
* @param card - The agent card to format.
|
|
178
|
+
* @param detail - Detail level — "name", "basic", "skills", or "full".
|
|
179
|
+
*
|
|
180
|
+
* @returns Summary object for the agent.
|
|
181
|
+
*/
|
|
182
|
+
formatAgentForLlm(card, detail) {
|
|
183
|
+
if (detail === "name") {
|
|
184
|
+
return { name: card.name };
|
|
185
|
+
}
|
|
186
|
+
if (detail === "basic") {
|
|
187
|
+
return { name: card.name, description: card.description };
|
|
188
|
+
}
|
|
189
|
+
if (detail === "skills") {
|
|
190
|
+
const skillNames = card.skills ? card.skills.map((s) => s.name) : [];
|
|
191
|
+
return {
|
|
192
|
+
name: card.name,
|
|
193
|
+
description: card.description,
|
|
194
|
+
skills: skillNames,
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
// "full"
|
|
198
|
+
const skills = [];
|
|
199
|
+
if (card.skills) {
|
|
200
|
+
for (const s of card.skills) {
|
|
201
|
+
skills.push({ name: s.name, description: s.description ?? "" });
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return {
|
|
205
|
+
name: card.name,
|
|
206
|
+
description: card.description,
|
|
207
|
+
skills,
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Generate summary for a single agent.
|
|
212
|
+
*
|
|
213
|
+
* @param agentId - User-defined agent identifier.
|
|
214
|
+
* @param detail - Detail level — "name", "basic", "skills", or "full".
|
|
215
|
+
*
|
|
216
|
+
* @returns Summary object for the agent, or null if not found.
|
|
217
|
+
*/
|
|
218
|
+
async getAgentForLlm(agentId, detail = "basic") {
|
|
219
|
+
await this.ensureInitialized();
|
|
220
|
+
const agent = this.agents[agentId];
|
|
221
|
+
if (!agent) {
|
|
222
|
+
return null;
|
|
223
|
+
}
|
|
224
|
+
return this.formatAgentForLlm(agent.agentCard, detail);
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Generate summary of all agents.
|
|
228
|
+
*
|
|
229
|
+
* @param detail - Detail level — "name", "basic", "skills", or "full".
|
|
230
|
+
*
|
|
231
|
+
* @returns Object mapping agent_id to summary object, sorted by agent_id.
|
|
232
|
+
*/
|
|
233
|
+
async getAgentsForLlm(detail = "basic") {
|
|
234
|
+
await this.ensureInitialized();
|
|
235
|
+
const result = {};
|
|
236
|
+
const sortedKeys = Object.keys(this.agents).sort();
|
|
237
|
+
for (const agentId of sortedKeys) {
|
|
238
|
+
result[agentId] = this.formatAgentForLlm(this.agents[agentId].agentCard, detail);
|
|
239
|
+
}
|
|
240
|
+
return result;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
//# sourceMappingURL=a2a-agents.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"a2a-agents.js","sourceRoot":"","sources":["../../src/client/a2a-agents.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A2ASession — main interface for interacting with A2A agents.
|
|
3
|
+
*/
|
|
4
|
+
import type { Message, Task } from "@a2a-js/sdk";
|
|
5
|
+
import { type TaskStore } from "@a2a-js/sdk/server";
|
|
6
|
+
import type { FileStore } from "../files/file-store.js";
|
|
7
|
+
import type { A2AAgents } from "./a2a-agents.js";
|
|
8
|
+
/** Main interface for sending messages to A2A agents. */
|
|
9
|
+
export declare class A2ASession {
|
|
10
|
+
readonly agents: A2AAgents;
|
|
11
|
+
readonly taskStore: TaskStore;
|
|
12
|
+
readonly fileStore: FileStore | null;
|
|
13
|
+
private readonly sendMessageTimeout;
|
|
14
|
+
private readonly getTaskTimeout;
|
|
15
|
+
private readonly getTaskPollInterval;
|
|
16
|
+
constructor(agents: A2AAgents, opts?: {
|
|
17
|
+
taskStore?: TaskStore;
|
|
18
|
+
fileStore?: FileStore | null;
|
|
19
|
+
sendMessageTimeout?: number;
|
|
20
|
+
getTaskTimeout?: number;
|
|
21
|
+
getTaskPollInterval?: number;
|
|
22
|
+
});
|
|
23
|
+
/**
|
|
24
|
+
* Send a message to an A2A agent.
|
|
25
|
+
*
|
|
26
|
+
* @param agentId - Registered agent identifier.
|
|
27
|
+
* @param message - The message content to send.
|
|
28
|
+
* @param opts.contextId - Optional context ID to continue a conversation.
|
|
29
|
+
* Auto-generated when null.
|
|
30
|
+
* @param opts.taskId - Optional task ID to attach to the message.
|
|
31
|
+
* @param opts.timeout - HTTP timeout in seconds. Defaults to sendMessageTimeout
|
|
32
|
+
* from constructor.
|
|
33
|
+
*
|
|
34
|
+
* @returns Task for task responses, Message for message-only responses.
|
|
35
|
+
*
|
|
36
|
+
* @throws Error if agent is not found.
|
|
37
|
+
*/
|
|
38
|
+
sendMessage(agentId: string, message: string, opts?: {
|
|
39
|
+
contextId?: string | null;
|
|
40
|
+
taskId?: string | null;
|
|
41
|
+
timeout?: number | null;
|
|
42
|
+
}): Promise<Task | Message>;
|
|
43
|
+
/**
|
|
44
|
+
* Get the current state of a task, monitoring until terminal/actionable state.
|
|
45
|
+
*
|
|
46
|
+
* If the remote agent supports streaming, uses SSE resubscription for real-time
|
|
47
|
+
* updates. Otherwise, polls at regular intervals.
|
|
48
|
+
*
|
|
49
|
+
* On monitoring timeout, returns the current task state (which may still be
|
|
50
|
+
* non-terminal, e.g. "working"). The only errors from getTask are failed
|
|
51
|
+
* HTTP requests (agent down, network error).
|
|
52
|
+
*
|
|
53
|
+
* @param agentId - Registered agent identifier.
|
|
54
|
+
* @param taskId - Task ID from a previous sendMessage call.
|
|
55
|
+
* @param opts.timeout - Total monitoring timeout in seconds. Defaults to
|
|
56
|
+
* getTaskTimeout from constructor.
|
|
57
|
+
* @param opts.pollInterval - Interval between polls in seconds (used when streaming
|
|
58
|
+
* is not supported). Defaults to getTaskPollInterval from constructor.
|
|
59
|
+
*
|
|
60
|
+
* @returns Task with the current task state. If monitoring times out, the
|
|
61
|
+
* returned task may still be in a non-terminal state.
|
|
62
|
+
*
|
|
63
|
+
* @throws Error if agent is not found.
|
|
64
|
+
*/
|
|
65
|
+
getTask(agentId: string, taskId: string, opts?: {
|
|
66
|
+
timeout?: number | null;
|
|
67
|
+
pollInterval?: number | null;
|
|
68
|
+
}): Promise<Task>;
|
|
69
|
+
/**
|
|
70
|
+
* Save file artifacts to the file store if configured.
|
|
71
|
+
*
|
|
72
|
+
* Idempotent: skips artifacts whose files have already been saved.
|
|
73
|
+
*/
|
|
74
|
+
private saveFiles;
|
|
75
|
+
/** Monitor a task via SSE resubscription, falling back to a final fetch. */
|
|
76
|
+
private getTaskStreaming;
|
|
77
|
+
/** Monitor a task by polling at regular intervals. */
|
|
78
|
+
private getTaskPolling;
|
|
79
|
+
/** Fetch a task via A2AClient.getTask(). */
|
|
80
|
+
private fetchTask;
|
|
81
|
+
/** Narrow the SDK client to the methods this package relies on. */
|
|
82
|
+
private getSessionClient;
|
|
83
|
+
/** Create an A2AClient with optional custom headers. */
|
|
84
|
+
private createClient;
|
|
85
|
+
/**
|
|
86
|
+
* Resolve agent card and headers.
|
|
87
|
+
*
|
|
88
|
+
* @returns Tuple of [AgentCard, headers_dict].
|
|
89
|
+
*
|
|
90
|
+
* @throws Error if agent cannot be resolved.
|
|
91
|
+
*/
|
|
92
|
+
private resolveAgent;
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=a2a-session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"a2a-session.d.ts","sourceRoot":"","sources":["../../src/client/a2a-session.ts"],"names":[],"mappings":"AAIA;;GAEG;AAEH,OAAO,KAAK,EAGR,OAAO,EAEP,IAAI,EAGP,MAAM,aAAa,CAAC;AAErB,OAAO,EAAqB,KAAK,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAEvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAExD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAuBjD,yDAAyD;AACzD,qBAAa,UAAU;IACnB,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;IACrC,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAS;IAC5C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAS;gBAGzC,MAAM,EAAE,SAAS,EACjB,IAAI,CAAC,EAAE;QACH,SAAS,CAAC,EAAE,SAAS,CAAC;QACtB,SAAS,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;QAC7B,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAC5B,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,mBAAmB,CAAC,EAAE,MAAM,CAAC;KAChC;IAUL;;;;;;;;;;;;;;OAcG;IACG,WAAW,CACb,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE;QACH,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC1B,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACvB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KAC3B,GACF,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC;IAwF1B;;;;;;;;;;;;;;;;;;;;;OAqBG;IACG,OAAO,CACT,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE;QACH,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KAChC,GACF,OAAO,CAAC,IAAI,CAAC;IAkChB;;;;OAIG;YACW,SAAS;IAgBvB,4EAA4E;YAC9D,gBAAgB;IAwC9B,sDAAsD;YACxC,cAAc;IAwB5B,4CAA4C;YAC9B,SAAS;IAevB,mEAAmE;IACnE,OAAO,CAAC,gBAAgB;IAIxB,wDAAwD;IACxD,OAAO,CAAC,YAAY;IAmBpB;;;;;;OAMG;YACW,YAAY;CAS7B"}
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2025-present A2A Net <hello@a2anet.com>
|
|
2
|
+
//
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
import { A2AClient } from "@a2a-js/sdk/client";
|
|
5
|
+
import { InMemoryTaskStore } from "@a2a-js/sdk/server";
|
|
6
|
+
import { v4 as uuidv4 } from "uuid";
|
|
7
|
+
import { TERMINAL_OR_ACTIONABLE_STATES } from "../types.js";
|
|
8
|
+
function sleep(seconds) {
|
|
9
|
+
return new Promise((resolve) => setTimeout(resolve, seconds * 1000));
|
|
10
|
+
}
|
|
11
|
+
/** Main interface for sending messages to A2A agents. */
|
|
12
|
+
export class A2ASession {
|
|
13
|
+
agents;
|
|
14
|
+
taskStore;
|
|
15
|
+
fileStore;
|
|
16
|
+
sendMessageTimeout;
|
|
17
|
+
getTaskTimeout;
|
|
18
|
+
getTaskPollInterval;
|
|
19
|
+
constructor(agents, opts) {
|
|
20
|
+
this.agents = agents;
|
|
21
|
+
this.taskStore = opts?.taskStore ?? new InMemoryTaskStore();
|
|
22
|
+
this.fileStore = opts?.fileStore ?? null;
|
|
23
|
+
this.sendMessageTimeout = opts?.sendMessageTimeout ?? 60.0;
|
|
24
|
+
this.getTaskTimeout = opts?.getTaskTimeout ?? 60.0;
|
|
25
|
+
this.getTaskPollInterval = opts?.getTaskPollInterval ?? 5.0;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Send a message to an A2A agent.
|
|
29
|
+
*
|
|
30
|
+
* @param agentId - Registered agent identifier.
|
|
31
|
+
* @param message - The message content to send.
|
|
32
|
+
* @param opts.contextId - Optional context ID to continue a conversation.
|
|
33
|
+
* Auto-generated when null.
|
|
34
|
+
* @param opts.taskId - Optional task ID to attach to the message.
|
|
35
|
+
* @param opts.timeout - HTTP timeout in seconds. Defaults to sendMessageTimeout
|
|
36
|
+
* from constructor.
|
|
37
|
+
*
|
|
38
|
+
* @returns Task for task responses, Message for message-only responses.
|
|
39
|
+
*
|
|
40
|
+
* @throws Error if agent is not found.
|
|
41
|
+
*/
|
|
42
|
+
async sendMessage(agentId, message, opts) {
|
|
43
|
+
const [agentCard, headers] = await this.resolveAgent(agentId);
|
|
44
|
+
const contextId = opts?.contextId ?? uuidv4();
|
|
45
|
+
// Build A2A message
|
|
46
|
+
const a2aMessage = {
|
|
47
|
+
kind: "message",
|
|
48
|
+
messageId: uuidv4(),
|
|
49
|
+
parts: [{ kind: "text", text: message }],
|
|
50
|
+
role: "user",
|
|
51
|
+
contextId,
|
|
52
|
+
};
|
|
53
|
+
if (opts?.taskId != null) {
|
|
54
|
+
a2aMessage.taskId = opts.taskId;
|
|
55
|
+
}
|
|
56
|
+
const effectiveTimeout = opts?.timeout !== undefined && opts?.timeout !== null
|
|
57
|
+
? opts.timeout
|
|
58
|
+
: this.sendMessageTimeout;
|
|
59
|
+
const start = performance.now();
|
|
60
|
+
const client = this.createClient(agentCard, headers);
|
|
61
|
+
const response = await this.getSessionClient(client).sendMessage({
|
|
62
|
+
message: a2aMessage,
|
|
63
|
+
configuration: { blocking: false },
|
|
64
|
+
}, { signal: AbortSignal.timeout(effectiveTimeout * 1000) });
|
|
65
|
+
if ("error" in response) {
|
|
66
|
+
throw new Error(`JSON-RPC error: ${response.error.message} (code: ${response.error.code})`);
|
|
67
|
+
}
|
|
68
|
+
const result = response.result;
|
|
69
|
+
// Handle Message result
|
|
70
|
+
if (result.kind === "message") {
|
|
71
|
+
return result;
|
|
72
|
+
}
|
|
73
|
+
// Handle Task result
|
|
74
|
+
if (result.kind !== "task") {
|
|
75
|
+
throw new Error("Expected Task or Message response, got unexpected kind");
|
|
76
|
+
}
|
|
77
|
+
let task = result;
|
|
78
|
+
await this.taskStore.save(task);
|
|
79
|
+
// If task is already in a terminal/actionable state, save files and return
|
|
80
|
+
if (TERMINAL_OR_ACTIONABLE_STATES.has(task.status.state)) {
|
|
81
|
+
await this.saveFiles(task);
|
|
82
|
+
return task;
|
|
83
|
+
}
|
|
84
|
+
// Task is in a non-terminal state (e.g. working) — monitor with remaining time
|
|
85
|
+
const elapsed = (performance.now() - start) / 1000;
|
|
86
|
+
const remaining = Math.max(0, effectiveTimeout - elapsed);
|
|
87
|
+
if (remaining > 0) {
|
|
88
|
+
const supportsStreaming = agentCard.capabilities !== undefined &&
|
|
89
|
+
agentCard.capabilities !== null &&
|
|
90
|
+
agentCard.capabilities.streaming === true;
|
|
91
|
+
if (supportsStreaming) {
|
|
92
|
+
task = await this.getTaskStreaming(agentCard, headers, task.id, remaining);
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
task = await this.getTaskPolling(agentCard, headers, task.id, remaining, this.getTaskPollInterval);
|
|
96
|
+
}
|
|
97
|
+
await this.taskStore.save(task);
|
|
98
|
+
}
|
|
99
|
+
await this.saveFiles(task);
|
|
100
|
+
return task;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Get the current state of a task, monitoring until terminal/actionable state.
|
|
104
|
+
*
|
|
105
|
+
* If the remote agent supports streaming, uses SSE resubscription for real-time
|
|
106
|
+
* updates. Otherwise, polls at regular intervals.
|
|
107
|
+
*
|
|
108
|
+
* On monitoring timeout, returns the current task state (which may still be
|
|
109
|
+
* non-terminal, e.g. "working"). The only errors from getTask are failed
|
|
110
|
+
* HTTP requests (agent down, network error).
|
|
111
|
+
*
|
|
112
|
+
* @param agentId - Registered agent identifier.
|
|
113
|
+
* @param taskId - Task ID from a previous sendMessage call.
|
|
114
|
+
* @param opts.timeout - Total monitoring timeout in seconds. Defaults to
|
|
115
|
+
* getTaskTimeout from constructor.
|
|
116
|
+
* @param opts.pollInterval - Interval between polls in seconds (used when streaming
|
|
117
|
+
* is not supported). Defaults to getTaskPollInterval from constructor.
|
|
118
|
+
*
|
|
119
|
+
* @returns Task with the current task state. If monitoring times out, the
|
|
120
|
+
* returned task may still be in a non-terminal state.
|
|
121
|
+
*
|
|
122
|
+
* @throws Error if agent is not found.
|
|
123
|
+
*/
|
|
124
|
+
async getTask(agentId, taskId, opts) {
|
|
125
|
+
const [agentCard, headers] = await this.resolveAgent(agentId);
|
|
126
|
+
const effectiveTimeout = opts?.timeout !== undefined && opts?.timeout !== null
|
|
127
|
+
? opts.timeout
|
|
128
|
+
: this.getTaskTimeout;
|
|
129
|
+
const effectivePollInterval = opts?.pollInterval !== undefined && opts?.pollInterval !== null
|
|
130
|
+
? opts.pollInterval
|
|
131
|
+
: this.getTaskPollInterval;
|
|
132
|
+
const supportsStreaming = agentCard.capabilities !== undefined &&
|
|
133
|
+
agentCard.capabilities !== null &&
|
|
134
|
+
agentCard.capabilities.streaming === true;
|
|
135
|
+
let task;
|
|
136
|
+
if (supportsStreaming) {
|
|
137
|
+
task = await this.getTaskStreaming(agentCard, headers, taskId, effectiveTimeout);
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
task = await this.getTaskPolling(agentCard, headers, taskId, effectiveTimeout, effectivePollInterval);
|
|
141
|
+
}
|
|
142
|
+
await this.taskStore.save(task);
|
|
143
|
+
await this.saveFiles(task);
|
|
144
|
+
return task;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Save file artifacts to the file store if configured.
|
|
148
|
+
*
|
|
149
|
+
* Idempotent: skips artifacts whose files have already been saved.
|
|
150
|
+
*/
|
|
151
|
+
async saveFiles(task) {
|
|
152
|
+
if (this.fileStore === null || !task.artifacts) {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
for (const artifact of task.artifacts) {
|
|
156
|
+
const hasFiles = artifact.parts.some((p) => p.kind === "file");
|
|
157
|
+
if (hasFiles) {
|
|
158
|
+
const existing = await this.fileStore.get(task.id, artifact.artifactId);
|
|
159
|
+
if (existing.length === 0) {
|
|
160
|
+
await this.fileStore.save(task.id, artifact);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/** Monitor a task via SSE resubscription, falling back to a final fetch. */
|
|
166
|
+
async getTaskStreaming(agentCard, headers, taskId, timeout) {
|
|
167
|
+
const client = this.createClient(agentCard, headers);
|
|
168
|
+
const params = { id: taskId };
|
|
169
|
+
try {
|
|
170
|
+
const stream = this.getSessionClient(client).resubscribeTask(params, {
|
|
171
|
+
signal: AbortSignal.timeout(timeout * 1000),
|
|
172
|
+
});
|
|
173
|
+
for await (const event of stream) {
|
|
174
|
+
if (event.kind === "status-update") {
|
|
175
|
+
const statusEvent = event;
|
|
176
|
+
if (TERMINAL_OR_ACTIONABLE_STATES.has(statusEvent.status.state)) {
|
|
177
|
+
break;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
else if (event.kind === "task") {
|
|
181
|
+
const taskEvent = event;
|
|
182
|
+
if (TERMINAL_OR_ACTIONABLE_STATES.has(taskEvent.status.state)) {
|
|
183
|
+
break;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
catch (e) {
|
|
189
|
+
if (e instanceof DOMException && e.name === "AbortError") {
|
|
190
|
+
console.info(`Task ${taskId} still in working state after ${timeout}s`);
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
throw e;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
// Final fetch to get the complete Task with all artifacts
|
|
197
|
+
return this.fetchTask(client, taskId, timeout);
|
|
198
|
+
}
|
|
199
|
+
/** Monitor a task by polling at regular intervals. */
|
|
200
|
+
async getTaskPolling(agentCard, headers, taskId, timeout, pollInterval) {
|
|
201
|
+
const client = this.createClient(agentCard, headers);
|
|
202
|
+
const start = performance.now();
|
|
203
|
+
while (true) {
|
|
204
|
+
const task = await this.fetchTask(client, taskId, timeout);
|
|
205
|
+
if (TERMINAL_OR_ACTIONABLE_STATES.has(task.status.state)) {
|
|
206
|
+
return task;
|
|
207
|
+
}
|
|
208
|
+
const elapsed = (performance.now() - start) / 1000;
|
|
209
|
+
if (elapsed >= timeout) {
|
|
210
|
+
console.info(`Task ${taskId} still in working state after ${timeout}s`);
|
|
211
|
+
return task;
|
|
212
|
+
}
|
|
213
|
+
await sleep(pollInterval);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
/** Fetch a task via A2AClient.getTask(). */
|
|
217
|
+
async fetchTask(client, taskId, timeout) {
|
|
218
|
+
const response = await this.getSessionClient(client).getTask({ id: taskId }, timeout !== undefined ? { signal: AbortSignal.timeout(timeout * 1000) } : undefined);
|
|
219
|
+
if ("error" in response) {
|
|
220
|
+
throw new Error(`JSON-RPC error: ${response.error.message} (code: ${response.error.code})`);
|
|
221
|
+
}
|
|
222
|
+
return response.result;
|
|
223
|
+
}
|
|
224
|
+
/** Narrow the SDK client to the methods this package relies on. */
|
|
225
|
+
getSessionClient(client) {
|
|
226
|
+
return client;
|
|
227
|
+
}
|
|
228
|
+
/** Create an A2AClient with optional custom headers. */
|
|
229
|
+
createClient(agentCard, headers) {
|
|
230
|
+
if (Object.keys(headers).length > 0) {
|
|
231
|
+
const customHeaders = headers;
|
|
232
|
+
const wrappedFetch = (input, init) => {
|
|
233
|
+
const mergedInit = {
|
|
234
|
+
...init,
|
|
235
|
+
headers: {
|
|
236
|
+
...init?.headers,
|
|
237
|
+
...customHeaders,
|
|
238
|
+
},
|
|
239
|
+
};
|
|
240
|
+
return fetch(input, mergedInit);
|
|
241
|
+
};
|
|
242
|
+
wrappedFetch.preconnect = fetch.preconnect;
|
|
243
|
+
return new A2AClient(agentCard, { fetchImpl: wrappedFetch });
|
|
244
|
+
}
|
|
245
|
+
return new A2AClient(agentCard);
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Resolve agent card and headers.
|
|
249
|
+
*
|
|
250
|
+
* @returns Tuple of [AgentCard, headers_dict].
|
|
251
|
+
*
|
|
252
|
+
* @throws Error if agent cannot be resolved.
|
|
253
|
+
*/
|
|
254
|
+
async resolveAgent(agentId) {
|
|
255
|
+
const agent = await this.agents.getAgent(agentId);
|
|
256
|
+
if (agent === null) {
|
|
257
|
+
const agents = await this.agents.getAgents();
|
|
258
|
+
const available = Object.keys(agents).sort().join(", ");
|
|
259
|
+
throw new Error(`Agent '${agentId}' not found. Available agents: ${available}`);
|
|
260
|
+
}
|
|
261
|
+
return [agent.agentCard, agent.customHeaders];
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
//# sourceMappingURL=a2a-session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"a2a-session.js","sourceRoot":"","sources":["../../src/client/a2a-session.ts"],"names":[],"mappings":"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"}
|