@assistant-ui/react-a2a 0.2.21 → 0.2.23
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/dist/A2AClient.d.ts +8 -5
- package/dist/A2AClient.d.ts.map +1 -1
- package/dist/A2AClient.js +85 -24
- package/dist/A2AClient.js.map +1 -1
- package/dist/A2AThreadRuntimeCore.d.ts +15 -4
- package/dist/A2AThreadRuntimeCore.d.ts.map +1 -1
- package/dist/A2AThreadRuntimeCore.js +162 -45
- package/dist/A2AThreadRuntimeCore.js.map +1 -1
- package/dist/a2aExtras.d.ts +0 -1
- package/dist/a2aExtras.d.ts.map +1 -1
- package/dist/conversions.d.ts +6 -4
- package/dist/conversions.d.ts.map +1 -1
- package/dist/conversions.js +32 -3
- package/dist/conversions.js.map +1 -1
- package/dist/hooks.d.ts +0 -1
- package/dist/hooks.d.ts.map +1 -1
- package/dist/types.d.ts +27 -14
- package/dist/types.d.ts.map +1 -1
- package/dist/useA2ARuntime.d.ts +0 -1
- package/dist/useA2ARuntime.d.ts.map +1 -1
- package/dist/useA2ARuntime.js +30 -18
- package/dist/useA2ARuntime.js.map +1 -1
- package/package.json +11 -6
- package/src/A2AClient.test.ts +321 -4
- package/src/A2AClient.ts +158 -49
- package/src/A2AThreadRuntimeCore.test.ts +458 -0
- package/src/A2AThreadRuntimeCore.ts +215 -57
- package/src/conversions.test.ts +109 -2
- package/src/conversions.ts +46 -4
- package/src/useA2ARuntime.test.tsx +142 -0
- package/src/useA2ARuntime.ts +55 -36
package/dist/A2AClient.d.ts
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import { A2AAgentCard, A2AErrorInfo, A2AListTaskPushNotificationConfigsResponse, A2AListTasksRequest, A2AListTasksResponse, A2AMessage, A2ASendMessageConfiguration, A2AStreamEvent, A2ATask, A2ATaskPushNotificationConfig } from "./types.js";
|
|
2
|
-
|
|
3
2
|
//#region src/A2AClient.d.ts
|
|
4
3
|
type A2AClientOptions = {
|
|
5
|
-
baseUrl: string;
|
|
6
|
-
|
|
4
|
+
baseUrl: string;
|
|
5
|
+
/** Optional path prefix for all API endpoints (e.g. "/v1"). Does not affect agent card discovery. */
|
|
6
|
+
basePath?: string | undefined;
|
|
7
|
+
/** Optional tenant ID for multi-tenant servers. */
|
|
7
8
|
tenant?: string | undefined;
|
|
8
|
-
headers?: Record<string, string> | (() => Record<string, string> | Promise<Record<string, string>>) | undefined;
|
|
9
|
-
|
|
9
|
+
headers?: Record<string, string> | (() => Record<string, string> | Promise<Record<string, string>>) | undefined;
|
|
10
|
+
/** A2A extension URIs to negotiate. Sent as A2A-Extensions header. */
|
|
11
|
+
extensions?: string[] | undefined;
|
|
12
|
+
/** Extra fetch options applied to every request. */
|
|
10
13
|
fetchOptions?: Omit<RequestInit, "headers" | "body" | "method" | "signal"> | undefined;
|
|
11
14
|
};
|
|
12
15
|
declare class A2AError extends Error {
|
package/dist/A2AClient.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"A2AClient.d.ts","names":[],"sources":["../src/A2AClient.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"A2AClient.d.ts","names":[],"sources":["../src/A2AClient.ts"],"mappings":";;KAkBY;EACV;;EAEA;;EAEA;EACA,UACI,gCACO,yBAAyB,QAAQ;;EAG5C;;EAEA,eACI,KAAK;;cAIE,iBAAiB;EAC5B;EACA;EACA;EAEY,YAAA,MAAM;;cAmOP;UACH;UACA;UACA;UACA;UACA;UAIA;EAII,YAAA,SAAS;UAkBb;UAIM;UAqBA;UAyBA;EAuBR,aAAa,SAAS,cAAc,QAAQ;EAe5C,qBAAqB,SAAS,cAAc,QAAQ;EAUpD,YACJ,SAAS,YACT,gBAAgB,6BAChB,WAAW,yBACX,SAAS,cACR,QAAQ,UAAU;EAmBd,cACL,SAAS,YACT,gBAAgB,6BAChB,WAAW,yBACX,SAAS,cACR,eAAe;EA6BZ,QACJ,gBACA,wBACA,SAAS,cACR,QAAQ;EAaL,UACJ,UAAU,qBACV,SAAS,cACR,QAAQ;EAoBL,WACJ,gBACA,WAAW,yBACX,SAAS,cACR,QAAQ;EAYJ,gBACL,gBACA,SAAS,cACR,eAAe;EAqBZ,iCACJ,QAAQ,+BACR,SAAS,cACR,QAAQ;EAaL,8BACJ,gBACA,kBACA,SAAS,cACR,QAAQ;EAOL,gCACJ,gBACA;IAAY;IAAmB;KAC/B,SAAS,cACR,QAAQ;EAYL,iCACJ,gBACA,kBACA,SAAS,cACR;UAmBY"}
|
package/dist/A2AClient.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import "./types.js";
|
|
2
|
+
import { SSEEventDecoder } from "assistant-stream/utils";
|
|
3
|
+
import { isRecord } from "@assistant-ui/core/internal";
|
|
2
4
|
//#region src/A2AClient.ts
|
|
3
5
|
var A2AError = class extends Error {
|
|
4
6
|
code;
|
|
@@ -75,6 +77,60 @@ function discriminateStreamResponse(data) {
|
|
|
75
77
|
};
|
|
76
78
|
return null;
|
|
77
79
|
}
|
|
80
|
+
const TASK_STATES = new Set(Object.keys({
|
|
81
|
+
unspecified: true,
|
|
82
|
+
submitted: true,
|
|
83
|
+
working: true,
|
|
84
|
+
completed: true,
|
|
85
|
+
failed: true,
|
|
86
|
+
canceled: true,
|
|
87
|
+
input_required: true,
|
|
88
|
+
rejected: true,
|
|
89
|
+
auth_required: true
|
|
90
|
+
}));
|
|
91
|
+
const isTaskState = (value) => typeof value === "string" && TASK_STATES.has(value);
|
|
92
|
+
const isTask = (value) => isRecord(value) && typeof value.id === "string" && value.id.length > 0 && isRecord(value.status) && isTaskState(value.status.state);
|
|
93
|
+
const isMessage = (value) => isRecord(value) && typeof value.messageId === "string" && value.messageId.length > 0 && typeof value.role === "string" && value.role.length > 0 && Array.isArray(value.parts) && value.parts.every(isRecord);
|
|
94
|
+
const isStringArray = (value) => Array.isArray(value) && value.every((item) => typeof item === "string");
|
|
95
|
+
const invalidAgentCard = () => {
|
|
96
|
+
throw new Error("Invalid A2A agent card response: expected a valid agent card payload.");
|
|
97
|
+
};
|
|
98
|
+
const parseCardString = (value) => value == null ? "" : typeof value === "string" ? value : invalidAgentCard();
|
|
99
|
+
const parseCardStringArray = (value) => value == null ? [] : isStringArray(value) ? value : invalidAgentCard();
|
|
100
|
+
const parseCardRecordArray = (value) => value == null ? [] : Array.isArray(value) && value.every(isRecord) ? value : invalidAgentCard();
|
|
101
|
+
const parseCardRecord = (value) => value == null ? {} : isRecord(value) ? value : invalidAgentCard();
|
|
102
|
+
const parseAgentCardResponse = (value) => {
|
|
103
|
+
if (!isRecord(value) || typeof value.name !== "string" || value.name.length === 0) return invalidAgentCard();
|
|
104
|
+
return {
|
|
105
|
+
...value,
|
|
106
|
+
name: value.name,
|
|
107
|
+
description: parseCardString(value.description),
|
|
108
|
+
version: parseCardString(value.version),
|
|
109
|
+
supportedInterfaces: parseCardRecordArray(value.supportedInterfaces).map((entry) => ({
|
|
110
|
+
...entry,
|
|
111
|
+
url: parseCardString(entry.url),
|
|
112
|
+
protocolBinding: parseCardString(entry.protocolBinding),
|
|
113
|
+
protocolVersion: parseCardString(entry.protocolVersion)
|
|
114
|
+
})),
|
|
115
|
+
capabilities: parseCardRecord(value.capabilities),
|
|
116
|
+
defaultInputModes: parseCardStringArray(value.defaultInputModes),
|
|
117
|
+
defaultOutputModes: parseCardStringArray(value.defaultOutputModes),
|
|
118
|
+
skills: parseCardRecordArray(value.skills).map((entry) => ({
|
|
119
|
+
...entry,
|
|
120
|
+
id: parseCardString(entry.id),
|
|
121
|
+
name: parseCardString(entry.name),
|
|
122
|
+
description: parseCardString(entry.description),
|
|
123
|
+
tags: parseCardStringArray(entry.tags)
|
|
124
|
+
}))
|
|
125
|
+
};
|
|
126
|
+
};
|
|
127
|
+
const parseSendMessageResponse = (value) => {
|
|
128
|
+
if (isRecord(value)) {
|
|
129
|
+
const candidate = value.task ?? value.message ?? value;
|
|
130
|
+
if (isTask(candidate) || isMessage(candidate)) return candidate;
|
|
131
|
+
}
|
|
132
|
+
throw new Error("Invalid A2A message:send response: expected a valid task or message payload.");
|
|
133
|
+
};
|
|
78
134
|
function signalInit(signal) {
|
|
79
135
|
return signal ? { signal } : {};
|
|
80
136
|
}
|
|
@@ -150,10 +206,12 @@ var A2AClient = class {
|
|
|
150
206
|
...signalInit(signal)
|
|
151
207
|
});
|
|
152
208
|
if (!response.ok) await this.throwResponseError(response);
|
|
153
|
-
|
|
209
|
+
const json = await response.json();
|
|
210
|
+
return parseAgentCardResponse(normalizeKeys(json));
|
|
154
211
|
}
|
|
155
212
|
async getExtendedAgentCard(signal) {
|
|
156
|
-
|
|
213
|
+
const result = await this.fetchJSON(`${this.getBasePath()}/extendedAgentCard`, signalInit(signal));
|
|
214
|
+
return parseAgentCardResponse(result);
|
|
157
215
|
}
|
|
158
216
|
async sendMessage(message, configuration, metadata, signal) {
|
|
159
217
|
const body = { message: toWireMessage(message) };
|
|
@@ -164,9 +222,7 @@ var A2AClient = class {
|
|
|
164
222
|
body: JSON.stringify(body),
|
|
165
223
|
...signalInit(signal)
|
|
166
224
|
});
|
|
167
|
-
|
|
168
|
-
if ("message" in result && result.message) return result.message;
|
|
169
|
-
return result;
|
|
225
|
+
return parseSendMessageResponse(result);
|
|
170
226
|
}
|
|
171
227
|
async *streamMessage(message, configuration, metadata, signal) {
|
|
172
228
|
const headers = await this.getHeaders(true);
|
|
@@ -251,32 +307,37 @@ var A2AClient = class {
|
|
|
251
307
|
if (!response.ok) await this.throwResponseError(response);
|
|
252
308
|
}
|
|
253
309
|
async *parseSSE(response) {
|
|
310
|
+
const contentType = response.headers.get("Content-Type");
|
|
311
|
+
if (contentType?.split(";", 1)[0]?.trim().toLowerCase() !== "text/event-stream") {
|
|
312
|
+
const received = contentType ? `"${contentType}"` : "no Content-Type header";
|
|
313
|
+
throw new Error(`Expected A2A stream response Content-Type "text/event-stream", received ${received}`);
|
|
314
|
+
}
|
|
254
315
|
const reader = response.body?.getReader();
|
|
255
316
|
if (!reader) throw new Error("No response body");
|
|
256
317
|
const decoder = new TextDecoder();
|
|
257
|
-
|
|
318
|
+
const sseDecoder = new SSEEventDecoder();
|
|
319
|
+
const readEvent = (event) => {
|
|
320
|
+
try {
|
|
321
|
+
let parsed = JSON.parse(event.data);
|
|
322
|
+
if (parsed && typeof parsed === "object" && "jsonrpc" in parsed && "result" in parsed) parsed = parsed.result;
|
|
323
|
+
return discriminateStreamResponse(normalizeKeys(parsed));
|
|
324
|
+
} catch {
|
|
325
|
+
return null;
|
|
326
|
+
}
|
|
327
|
+
};
|
|
258
328
|
try {
|
|
259
329
|
while (true) {
|
|
260
330
|
const { done, value } = await reader.read();
|
|
261
|
-
if (done)
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
const eventText = buffer.slice(0, eventEnd);
|
|
266
|
-
buffer = buffer.slice(eventEnd + 2);
|
|
267
|
-
const dataLines = [];
|
|
268
|
-
for (const line of eventText.split("\n")) {
|
|
269
|
-
const trimmed = line.replace(/\r$/, "");
|
|
270
|
-
if (trimmed.startsWith("data:")) dataLines.push(trimmed.slice(5).trim());
|
|
331
|
+
if (done) {
|
|
332
|
+
for (const event of sseDecoder.push(decoder.decode())) {
|
|
333
|
+
const parsed = readEvent(event);
|
|
334
|
+
if (parsed) yield parsed;
|
|
271
335
|
}
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
if (event) yield event;
|
|
278
|
-
} catch {}
|
|
279
|
-
eventEnd = buffer.indexOf("\n\n");
|
|
336
|
+
break;
|
|
337
|
+
}
|
|
338
|
+
for (const event of sseDecoder.push(decoder.decode(value, { stream: true }))) {
|
|
339
|
+
const parsed = readEvent(event);
|
|
340
|
+
if (parsed) yield parsed;
|
|
280
341
|
}
|
|
281
342
|
}
|
|
282
343
|
} finally {
|
package/dist/A2AClient.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"A2AClient.js","names":[],"sources":["../src/A2AClient.ts"],"sourcesContent":["import type {\n A2AAgentCard,\n A2AErrorInfo,\n A2AListTaskPushNotificationConfigsResponse,\n A2AListTasksRequest,\n A2AListTasksResponse,\n A2AMessage,\n A2ARole,\n A2ASendMessageConfiguration,\n A2AStreamEvent,\n A2ATask,\n A2ATaskPushNotificationConfig,\n A2ATaskState,\n} from \"./types\";\nimport { A2A_PROTOCOL_VERSION } from \"./types\";\n\nexport type A2AClientOptions = {\n baseUrl: string;\n /** Optional path prefix for all API endpoints (e.g. \"/v1\"). Does not affect agent card discovery. */\n basePath?: string | undefined;\n /** Optional tenant ID for multi-tenant servers. */\n tenant?: string | undefined;\n headers?:\n | Record<string, string>\n | (() => Record<string, string> | Promise<Record<string, string>>)\n | undefined;\n /** A2A extension URIs to negotiate. Sent as A2A-Extensions header. */\n extensions?: string[] | undefined;\n /** Extra fetch options applied to every request. */\n fetchOptions?:\n | Omit<RequestInit, \"headers\" | \"body\" | \"method\" | \"signal\">\n | undefined;\n};\n\nexport class A2AError extends Error {\n code: number;\n status: string;\n details: unknown[] | undefined;\n\n constructor(info: A2AErrorInfo) {\n super(info.message);\n this.name = \"A2AError\";\n this.code = info.code;\n this.status = info.status;\n this.details = info.details;\n }\n}\n\n// Incoming key normalization: snake_case → camelCase, plus ProtoJSON enum normalization.\nfunction toCamelCase(key: string): string {\n return key.replace(/_([a-z])/g, (_, c: string) => c.toUpperCase());\n}\n\n// Fields whose values are opaque user data (google.protobuf.Struct / Value).\n// Keys inside these objects must NOT be camelCased or have enum normalization applied.\nconst OPAQUE_FIELDS = new Set([\n \"metadata\",\n \"data\",\n \"params\",\n \"forwardedProps\",\n \"scopes\",\n]);\n\nfunction normalizeKeys(obj: unknown, opaque = false): unknown {\n if (Array.isArray(obj)) return obj.map((v) => normalizeKeys(v, opaque));\n if (obj !== null && typeof obj === \"object\") {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj as Record<string, unknown>)) {\n // Inside opaque fields: preserve keys and values as-is (only recurse arrays/objects structurally)\n if (opaque) {\n result[key] =\n typeof value === \"object\" && value !== null\n ? normalizeKeys(value, true)\n : value;\n continue;\n }\n\n const camelKey = toCamelCase(key);\n const isOpaqueChild = OPAQUE_FIELDS.has(camelKey);\n\n if (\n camelKey === \"state\" &&\n typeof value === \"string\" &&\n value.startsWith(\"TASK_STATE_\")\n ) {\n result[camelKey] = value.slice(11).toLowerCase();\n } else if (\n camelKey === \"role\" &&\n typeof value === \"string\" &&\n value.startsWith(\"ROLE_\")\n ) {\n result[camelKey] = value.slice(5).toLowerCase();\n } else if (camelKey === \"content\" && Array.isArray(value)) {\n // v0.3 servers used \"content\" for message/artifact parts; normalize to \"parts\" for backward compat\n result.parts = normalizeKeys(value, false);\n } else if (camelKey !== \"parts\" || !(\"parts\" in result)) {\n // dedup: \"content\" was already mapped to parts above; don't overwrite\n result[camelKey] = isOpaqueChild ? value : normalizeKeys(value, false);\n }\n }\n return result;\n }\n return obj;\n}\n\n// Outgoing enum conversion (v1.0 ProtoJSON format)\nfunction toWireRole(role: A2ARole): string {\n if (role === \"user\") return \"ROLE_USER\";\n if (role === \"agent\") return \"ROLE_AGENT\";\n return \"ROLE_UNSPECIFIED\";\n}\n\nfunction toWireTaskState(state: A2ATaskState): string {\n return `TASK_STATE_${state.toUpperCase()}`;\n}\n\nfunction toWireMessage(msg: A2AMessage): unknown {\n return { ...msg, role: toWireRole(msg.role) };\n}\n\nfunction discriminateStreamResponse(\n data: Record<string, unknown>,\n): A2AStreamEvent | null {\n if (\"task\" in data && data.task) {\n return { type: \"task\", task: data.task as A2ATask };\n }\n if (\"message\" in data && data.message) {\n return { type: \"message\", message: data.message as A2AMessage };\n }\n if (\"statusUpdate\" in data && data.statusUpdate) {\n return {\n type: \"statusUpdate\",\n event: data.statusUpdate as A2AStreamEvent extends {\n type: \"statusUpdate\";\n event: infer E;\n }\n ? E\n : never,\n };\n }\n if (\"artifactUpdate\" in data && data.artifactUpdate) {\n return {\n type: \"artifactUpdate\",\n event: data.artifactUpdate as A2AStreamEvent extends {\n type: \"artifactUpdate\";\n event: infer E;\n }\n ? E\n : never,\n };\n }\n return null;\n}\n\nfunction signalInit(signal?: AbortSignal): RequestInit {\n return signal ? { signal } : {};\n}\n\nexport class A2AClient {\n private baseUrl: string;\n private basePath: string;\n private tenant: string | undefined;\n private extensionUris: string[] | undefined;\n private fetchOptions: Omit<\n RequestInit,\n \"headers\" | \"body\" | \"method\" | \"signal\"\n >;\n private headersFn:\n | Record<string, string>\n | (() => Record<string, string> | Promise<Record<string, string>>);\n\n constructor(options: A2AClientOptions) {\n this.baseUrl = options.baseUrl.replace(/\\/$/, \"\");\n this.basePath = options.basePath\n ? `/${options.basePath.replace(/^\\/|\\/$/g, \"\")}`\n : \"\";\n this.tenant = options.tenant;\n this.extensionUris = options.extensions;\n const {\n headers: _h,\n body: _b,\n method: _m,\n signal: _s,\n ...safeFetchOptions\n } = (options.fetchOptions ?? {}) as RequestInit;\n this.fetchOptions = safeFetchOptions;\n this.headersFn = options.headers ?? {};\n }\n\n private getBasePath(): string {\n return `${this.basePath}${this.tenant ? `/${encodeURIComponent(this.tenant)}` : \"\"}`;\n }\n\n private async getHeaders(\n includeContentType = true,\n ): Promise<Record<string, string>> {\n const custom =\n typeof this.headersFn === \"function\"\n ? await this.headersFn()\n : this.headersFn;\n const headers: Record<string, string> = {\n Accept: \"application/a2a+json, application/json\",\n \"A2A-Version\": A2A_PROTOCOL_VERSION,\n ...custom,\n };\n if (includeContentType) {\n headers[\"Content-Type\"] = \"application/a2a+json\";\n }\n if (this.extensionUris?.length) {\n headers[\"A2A-Extensions\"] = this.extensionUris.join(\", \");\n }\n return headers;\n }\n\n private async throwResponseError(response: Response): Promise<never> {\n let errorBody: unknown;\n try {\n errorBody = await response.json();\n } catch {\n // no parseable body\n }\n\n if (errorBody && typeof errorBody === \"object\" && \"error\" in errorBody) {\n const err = (errorBody as Record<string, any>).error;\n throw new A2AError({\n code: err.code ?? response.status,\n status: err.status ?? response.statusText,\n message: err.message ?? `A2A request failed: ${response.status}`,\n details: err.details,\n });\n }\n\n throw new A2AError({\n code: response.status,\n status: response.statusText,\n message: `A2A request failed: ${response.status} ${response.statusText}`,\n });\n }\n\n private async fetchJSON<T>(\n path: string,\n options: RequestInit = {},\n ): Promise<T> {\n const isGet = !options.method || options.method.toUpperCase() === \"GET\";\n const headers = await this.getHeaders(!isGet);\n const response = await fetch(`${this.baseUrl}${path}`, {\n ...this.fetchOptions,\n ...options,\n headers: {\n ...headers,\n ...(options.headers as Record<string, string>),\n },\n });\n if (!response.ok) {\n await this.throwResponseError(response);\n }\n const json = await response.json();\n return normalizeKeys(json) as T;\n }\n\n // --- Agent Card ---\n\n async getAgentCard(signal?: AbortSignal): Promise<A2AAgentCard> {\n const headers = await this.getHeaders(false); // GET: no Content-Type\n const url = `${this.baseUrl}/.well-known/agent-card.json`;\n const response = await fetch(url, {\n ...this.fetchOptions,\n headers,\n ...signalInit(signal),\n });\n if (!response.ok) {\n await this.throwResponseError(response);\n }\n const json = await response.json();\n return normalizeKeys(json) as A2AAgentCard;\n }\n\n async getExtendedAgentCard(signal?: AbortSignal): Promise<A2AAgentCard> {\n return this.fetchJSON<A2AAgentCard>(\n `${this.getBasePath()}/extendedAgentCard`,\n signalInit(signal),\n );\n }\n\n // --- Message ---\n\n async sendMessage(\n message: A2AMessage,\n configuration?: A2ASendMessageConfiguration,\n metadata?: Record<string, unknown>,\n signal?: AbortSignal,\n ): Promise<A2ATask | A2AMessage> {\n const body: Record<string, unknown> = {\n message: toWireMessage(message),\n };\n if (configuration) body.configuration = configuration;\n if (metadata) body.metadata = metadata;\n\n const result = await this.fetchJSON<Record<string, unknown>>(\n `${this.getBasePath()}/message:send`,\n {\n method: \"POST\",\n body: JSON.stringify(body),\n ...signalInit(signal),\n },\n );\n\n // Unwrap SendMessageResponse: {task: Task} | {message: Message}\n if (\"task\" in result && result.task) return result.task as A2ATask;\n if (\"message\" in result && result.message)\n return result.message as A2AMessage;\n return result as unknown as A2ATask | A2AMessage;\n }\n\n async *streamMessage(\n message: A2AMessage,\n configuration?: A2ASendMessageConfiguration,\n metadata?: Record<string, unknown>,\n signal?: AbortSignal,\n ): AsyncGenerator<A2AStreamEvent> {\n const headers = await this.getHeaders(true);\n headers.Accept = \"text/event-stream\";\n\n const body: Record<string, unknown> = {\n message: toWireMessage(message),\n };\n if (configuration) body.configuration = configuration;\n if (metadata) body.metadata = metadata;\n\n const response = await fetch(\n `${this.baseUrl}${this.getBasePath()}/message:stream`,\n {\n ...this.fetchOptions,\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n ...signalInit(signal),\n },\n );\n if (!response.ok) {\n await this.throwResponseError(response);\n }\n\n yield* this.parseSSE(response);\n }\n\n // --- Tasks ---\n\n async getTask(\n taskId: string,\n historyLength?: number,\n signal?: AbortSignal,\n ): Promise<A2ATask> {\n const params = new URLSearchParams();\n if (historyLength !== undefined) {\n // Proto field name for HTTP transcoding query params\n params.set(\"history_length\", String(historyLength));\n }\n const qs = params.toString();\n return this.fetchJSON<A2ATask>(\n `${this.getBasePath()}/tasks/${encodeURIComponent(taskId)}${qs ? `?${qs}` : \"\"}`,\n signalInit(signal),\n );\n }\n\n async listTasks(\n request?: A2AListTasksRequest,\n signal?: AbortSignal,\n ): Promise<A2AListTasksResponse> {\n const params = new URLSearchParams();\n if (request?.contextId) params.set(\"context_id\", request.contextId);\n if (request?.status) params.set(\"status\", toWireTaskState(request.status));\n if (request?.pageSize !== undefined)\n params.set(\"page_size\", String(request.pageSize));\n if (request?.pageToken) params.set(\"page_token\", request.pageToken);\n if (request?.historyLength !== undefined)\n params.set(\"history_length\", String(request.historyLength));\n if (request?.statusTimestampAfter)\n params.set(\"status_timestamp_after\", request.statusTimestampAfter);\n if (request?.includeArtifacts !== undefined)\n params.set(\"include_artifacts\", String(request.includeArtifacts));\n const qs = params.toString();\n return this.fetchJSON<A2AListTasksResponse>(\n `${this.getBasePath()}/tasks${qs ? `?${qs}` : \"\"}`,\n signalInit(signal),\n );\n }\n\n async cancelTask(\n taskId: string,\n metadata?: Record<string, unknown>,\n signal?: AbortSignal,\n ): Promise<A2ATask> {\n const body = metadata ? { metadata } : {};\n return this.fetchJSON<A2ATask>(\n `${this.getBasePath()}/tasks/${encodeURIComponent(taskId)}:cancel`,\n {\n method: \"POST\",\n body: JSON.stringify(body),\n ...signalInit(signal),\n },\n );\n }\n\n async *subscribeToTask(\n taskId: string,\n signal?: AbortSignal,\n ): AsyncGenerator<A2AStreamEvent> {\n const headers = await this.getHeaders(false); // GET: no Content-Type\n headers.Accept = \"text/event-stream\";\n\n const response = await fetch(\n `${this.baseUrl}${this.getBasePath()}/tasks/${encodeURIComponent(taskId)}:subscribe`,\n {\n ...this.fetchOptions,\n headers,\n ...signalInit(signal),\n },\n );\n if (!response.ok) {\n await this.throwResponseError(response);\n }\n\n yield* this.parseSSE(response);\n }\n\n // --- Push Notification Configs ---\n\n async createTaskPushNotificationConfig(\n config: A2ATaskPushNotificationConfig,\n signal?: AbortSignal,\n ): Promise<A2ATaskPushNotificationConfig> {\n const taskId = config.taskId;\n if (!taskId) throw new Error(\"taskId is required\");\n return this.fetchJSON<A2ATaskPushNotificationConfig>(\n `${this.getBasePath()}/tasks/${encodeURIComponent(taskId)}/pushNotificationConfigs`,\n {\n method: \"POST\",\n body: JSON.stringify(config),\n ...signalInit(signal),\n },\n );\n }\n\n async getTaskPushNotificationConfig(\n taskId: string,\n configId: string,\n signal?: AbortSignal,\n ): Promise<A2ATaskPushNotificationConfig> {\n return this.fetchJSON<A2ATaskPushNotificationConfig>(\n `${this.getBasePath()}/tasks/${encodeURIComponent(taskId)}/pushNotificationConfigs/${encodeURIComponent(configId)}`,\n signalInit(signal),\n );\n }\n\n async listTaskPushNotificationConfigs(\n taskId: string,\n options?: { pageSize?: number; pageToken?: string },\n signal?: AbortSignal,\n ): Promise<A2AListTaskPushNotificationConfigsResponse> {\n const params = new URLSearchParams();\n if (options?.pageSize !== undefined)\n params.set(\"page_size\", String(options.pageSize));\n if (options?.pageToken) params.set(\"page_token\", options.pageToken);\n const qs = params.toString();\n return this.fetchJSON<A2AListTaskPushNotificationConfigsResponse>(\n `${this.getBasePath()}/tasks/${encodeURIComponent(taskId)}/pushNotificationConfigs${qs ? `?${qs}` : \"\"}`,\n signalInit(signal),\n );\n }\n\n async deleteTaskPushNotificationConfig(\n taskId: string,\n configId: string,\n signal?: AbortSignal,\n ): Promise<void> {\n const isGet = false;\n const headers = await this.getHeaders(!isGet);\n const response = await fetch(\n `${this.baseUrl}${this.getBasePath()}/tasks/${encodeURIComponent(taskId)}/pushNotificationConfigs/${encodeURIComponent(configId)}`,\n {\n ...this.fetchOptions,\n method: \"DELETE\",\n headers,\n ...signalInit(signal),\n },\n );\n if (!response.ok) {\n await this.throwResponseError(response);\n }\n }\n\n // --- SSE Parsing ---\n\n private async *parseSSE(response: Response): AsyncGenerator<A2AStreamEvent> {\n const reader = response.body?.getReader();\n if (!reader) throw new Error(\"No response body\");\n\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n\n let eventEnd: number = buffer.indexOf(\"\\n\\n\");\n while (eventEnd !== -1) {\n const eventText = buffer.slice(0, eventEnd);\n buffer = buffer.slice(eventEnd + 2);\n\n const dataLines: string[] = [];\n\n for (const line of eventText.split(\"\\n\")) {\n const trimmed = line.replace(/\\r$/, \"\");\n if (trimmed.startsWith(\"data:\")) {\n dataLines.push(trimmed.slice(5).trim());\n }\n // event:, id:, retry: lines are parsed but not used —\n // we discriminate event type from the JSON payload.\n }\n\n if (dataLines.length === 0) continue;\n\n try {\n let parsed = JSON.parse(dataLines.join(\"\\n\"));\n\n // Unwrap JSON-RPC envelope if present\n if (\n parsed &&\n typeof parsed === \"object\" &&\n \"jsonrpc\" in parsed &&\n \"result\" in parsed\n ) {\n parsed = parsed.result;\n }\n\n const normalized = normalizeKeys(parsed) as Record<string, unknown>;\n const event = discriminateStreamResponse(normalized);\n if (event) yield event;\n } catch {\n // Skip malformed events\n }\n eventEnd = buffer.indexOf(\"\\n\\n\");\n }\n }\n } finally {\n reader.releaseLock();\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"A2AClient.js","names":[],"sources":["../src/A2AClient.ts"],"sourcesContent":["import { SSEEventDecoder, type SSEEvent } from \"assistant-stream/utils\";\nimport { isRecord } from \"@assistant-ui/core/internal\";\nimport type {\n A2AAgentCard,\n A2AErrorInfo,\n A2AListTaskPushNotificationConfigsResponse,\n A2AListTasksRequest,\n A2AListTasksResponse,\n A2AMessage,\n A2ARole,\n A2ASendMessageConfiguration,\n A2AStreamEvent,\n A2ATask,\n A2ATaskPushNotificationConfig,\n A2ATaskState,\n} from \"./types\";\nimport { A2A_PROTOCOL_VERSION } from \"./types\";\n\nexport type A2AClientOptions = {\n baseUrl: string;\n /** Optional path prefix for all API endpoints (e.g. \"/v1\"). Does not affect agent card discovery. */\n basePath?: string | undefined;\n /** Optional tenant ID for multi-tenant servers. */\n tenant?: string | undefined;\n headers?:\n | Record<string, string>\n | (() => Record<string, string> | Promise<Record<string, string>>)\n | undefined;\n /** A2A extension URIs to negotiate. Sent as A2A-Extensions header. */\n extensions?: string[] | undefined;\n /** Extra fetch options applied to every request. */\n fetchOptions?:\n | Omit<RequestInit, \"headers\" | \"body\" | \"method\" | \"signal\">\n | undefined;\n};\n\nexport class A2AError extends Error {\n code: number;\n status: string;\n details: unknown[] | undefined;\n\n constructor(info: A2AErrorInfo) {\n super(info.message);\n this.name = \"A2AError\";\n this.code = info.code;\n this.status = info.status;\n this.details = info.details;\n }\n}\n\n// Incoming key normalization: snake_case → camelCase, plus ProtoJSON enum normalization.\nfunction toCamelCase(key: string): string {\n return key.replace(/_([a-z])/g, (_, c: string) => c.toUpperCase());\n}\n\n// Fields whose values are opaque user data (google.protobuf.Struct / Value).\n// Keys inside these objects must NOT be camelCased or have enum normalization applied.\nconst OPAQUE_FIELDS = new Set([\n \"metadata\",\n \"data\",\n \"params\",\n \"forwardedProps\",\n \"scopes\",\n]);\n\nfunction normalizeKeys(obj: unknown, opaque = false): unknown {\n if (Array.isArray(obj)) return obj.map((v) => normalizeKeys(v, opaque));\n if (obj !== null && typeof obj === \"object\") {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj as Record<string, unknown>)) {\n // Inside opaque fields: preserve keys and values as-is (only recurse arrays/objects structurally)\n if (opaque) {\n result[key] =\n typeof value === \"object\" && value !== null\n ? normalizeKeys(value, true)\n : value;\n continue;\n }\n\n const camelKey = toCamelCase(key);\n const isOpaqueChild = OPAQUE_FIELDS.has(camelKey);\n\n if (\n camelKey === \"state\" &&\n typeof value === \"string\" &&\n value.startsWith(\"TASK_STATE_\")\n ) {\n result[camelKey] = value.slice(11).toLowerCase();\n } else if (\n camelKey === \"role\" &&\n typeof value === \"string\" &&\n value.startsWith(\"ROLE_\")\n ) {\n result[camelKey] = value.slice(5).toLowerCase();\n } else if (camelKey === \"content\" && Array.isArray(value)) {\n // v0.3 servers used \"content\" for message/artifact parts; normalize to \"parts\" for backward compat\n result.parts = normalizeKeys(value, false);\n } else if (camelKey !== \"parts\" || !(\"parts\" in result)) {\n // dedup: \"content\" was already mapped to parts above; don't overwrite\n result[camelKey] = isOpaqueChild ? value : normalizeKeys(value, false);\n }\n }\n return result;\n }\n return obj;\n}\n\n// Outgoing enum conversion (v1.0 ProtoJSON format)\nfunction toWireRole(role: A2ARole): string {\n if (role === \"user\") return \"ROLE_USER\";\n if (role === \"agent\") return \"ROLE_AGENT\";\n return \"ROLE_UNSPECIFIED\";\n}\n\nfunction toWireTaskState(state: A2ATaskState): string {\n return `TASK_STATE_${state.toUpperCase()}`;\n}\n\nfunction toWireMessage(msg: A2AMessage): unknown {\n return { ...msg, role: toWireRole(msg.role) };\n}\n\nfunction discriminateStreamResponse(\n data: Record<string, unknown>,\n): A2AStreamEvent | null {\n if (\"task\" in data && data.task) {\n return { type: \"task\", task: data.task as A2ATask };\n }\n if (\"message\" in data && data.message) {\n return { type: \"message\", message: data.message as A2AMessage };\n }\n if (\"statusUpdate\" in data && data.statusUpdate) {\n return {\n type: \"statusUpdate\",\n event: data.statusUpdate as A2AStreamEvent extends {\n type: \"statusUpdate\";\n event: infer E;\n }\n ? E\n : never,\n };\n }\n if (\"artifactUpdate\" in data && data.artifactUpdate) {\n return {\n type: \"artifactUpdate\",\n event: data.artifactUpdate as A2AStreamEvent extends {\n type: \"artifactUpdate\";\n event: infer E;\n }\n ? E\n : never,\n };\n }\n return null;\n}\n\nconst TASK_STATES: ReadonlySet<string> = new Set(\n Object.keys({\n unspecified: true,\n submitted: true,\n working: true,\n completed: true,\n failed: true,\n canceled: true,\n input_required: true,\n rejected: true,\n auth_required: true,\n } satisfies Record<A2ATaskState, true>),\n);\n\nconst isTaskState = (value: unknown): value is A2ATaskState =>\n typeof value === \"string\" && TASK_STATES.has(value);\n\nconst isTask = (value: unknown): value is A2ATask =>\n isRecord(value) &&\n typeof value.id === \"string\" &&\n value.id.length > 0 &&\n isRecord(value.status) &&\n isTaskState(value.status.state);\n\nconst isMessage = (value: unknown): value is A2AMessage =>\n isRecord(value) &&\n typeof value.messageId === \"string\" &&\n value.messageId.length > 0 &&\n typeof value.role === \"string\" &&\n value.role.length > 0 &&\n Array.isArray(value.parts) &&\n value.parts.every(isRecord);\n\nconst isStringArray = (value: unknown): value is string[] =>\n Array.isArray(value) && value.every((item) => typeof item === \"string\");\n\nconst invalidAgentCard = (): never => {\n throw new Error(\n \"Invalid A2A agent card response: expected a valid agent card payload.\",\n );\n};\n\nconst parseCardString = (value: unknown): string =>\n value == null ? \"\" : typeof value === \"string\" ? value : invalidAgentCard();\n\nconst parseCardStringArray = (value: unknown): string[] =>\n value == null ? [] : isStringArray(value) ? value : invalidAgentCard();\n\nconst parseCardRecordArray = (value: unknown): Record<string, unknown>[] =>\n value == null\n ? []\n : Array.isArray(value) && value.every(isRecord)\n ? (value as Record<string, unknown>[])\n : invalidAgentCard();\n\nconst parseCardRecord = (value: unknown): Record<string, unknown> =>\n value == null ? {} : isRecord(value) ? value : invalidAgentCard();\n\n// Proto3 JSON parsing treats omitted and null fields as defaults, so a valid\n// card may arrive without its empty lists, strings, or capabilities. Fill\n// those per the proto3 JSON mapping rules; a payload without a name or with a\n// present field of the wrong type rejects.\nconst parseAgentCardResponse = (value: unknown): A2AAgentCard => {\n if (\n !isRecord(value) ||\n typeof value.name !== \"string\" ||\n value.name.length === 0\n ) {\n return invalidAgentCard();\n }\n\n return {\n ...value,\n name: value.name,\n description: parseCardString(value.description),\n version: parseCardString(value.version),\n supportedInterfaces: parseCardRecordArray(value.supportedInterfaces).map(\n (entry) => ({\n ...entry,\n url: parseCardString(entry.url),\n protocolBinding: parseCardString(entry.protocolBinding),\n protocolVersion: parseCardString(entry.protocolVersion),\n }),\n ),\n capabilities: parseCardRecord(value.capabilities),\n defaultInputModes: parseCardStringArray(value.defaultInputModes),\n defaultOutputModes: parseCardStringArray(value.defaultOutputModes),\n skills: parseCardRecordArray(value.skills).map((entry) => ({\n ...entry,\n id: parseCardString(entry.id),\n name: parseCardString(entry.name),\n description: parseCardString(entry.description),\n tags: parseCardStringArray(entry.tags),\n })),\n } as A2AAgentCard;\n};\n\nconst parseSendMessageResponse = (value: unknown): A2ATask | A2AMessage => {\n if (isRecord(value)) {\n const candidate = value.task ?? value.message ?? value;\n if (isTask(candidate) || isMessage(candidate)) return candidate;\n }\n\n throw new Error(\n \"Invalid A2A message:send response: expected a valid task or message payload.\",\n );\n};\n\nfunction signalInit(signal?: AbortSignal): RequestInit {\n return signal ? { signal } : {};\n}\n\nexport class A2AClient {\n private baseUrl: string;\n private basePath: string;\n private tenant: string | undefined;\n private extensionUris: string[] | undefined;\n private fetchOptions: Omit<\n RequestInit,\n \"headers\" | \"body\" | \"method\" | \"signal\"\n >;\n private headersFn:\n | Record<string, string>\n | (() => Record<string, string> | Promise<Record<string, string>>);\n\n constructor(options: A2AClientOptions) {\n this.baseUrl = options.baseUrl.replace(/\\/$/, \"\");\n this.basePath = options.basePath\n ? `/${options.basePath.replace(/^\\/|\\/$/g, \"\")}`\n : \"\";\n this.tenant = options.tenant;\n this.extensionUris = options.extensions;\n const {\n headers: _h,\n body: _b,\n method: _m,\n signal: _s,\n ...safeFetchOptions\n } = (options.fetchOptions ?? {}) as RequestInit;\n this.fetchOptions = safeFetchOptions;\n this.headersFn = options.headers ?? {};\n }\n\n private getBasePath(): string {\n return `${this.basePath}${this.tenant ? `/${encodeURIComponent(this.tenant)}` : \"\"}`;\n }\n\n private async getHeaders(\n includeContentType = true,\n ): Promise<Record<string, string>> {\n const custom =\n typeof this.headersFn === \"function\"\n ? await this.headersFn()\n : this.headersFn;\n const headers: Record<string, string> = {\n Accept: \"application/a2a+json, application/json\",\n \"A2A-Version\": A2A_PROTOCOL_VERSION,\n ...custom,\n };\n if (includeContentType) {\n headers[\"Content-Type\"] = \"application/a2a+json\";\n }\n if (this.extensionUris?.length) {\n headers[\"A2A-Extensions\"] = this.extensionUris.join(\", \");\n }\n return headers;\n }\n\n private async throwResponseError(response: Response): Promise<never> {\n let errorBody: unknown;\n try {\n errorBody = await response.json();\n } catch {\n // no parseable body\n }\n\n if (errorBody && typeof errorBody === \"object\" && \"error\" in errorBody) {\n const err = (errorBody as Record<string, any>).error;\n throw new A2AError({\n code: err.code ?? response.status,\n status: err.status ?? response.statusText,\n message: err.message ?? `A2A request failed: ${response.status}`,\n details: err.details,\n });\n }\n\n throw new A2AError({\n code: response.status,\n status: response.statusText,\n message: `A2A request failed: ${response.status} ${response.statusText}`,\n });\n }\n\n private async fetchJSON<T>(\n path: string,\n options: RequestInit = {},\n ): Promise<T> {\n const isGet = !options.method || options.method.toUpperCase() === \"GET\";\n const headers = await this.getHeaders(!isGet);\n const response = await fetch(`${this.baseUrl}${path}`, {\n ...this.fetchOptions,\n ...options,\n headers: {\n ...headers,\n ...(options.headers as Record<string, string>),\n },\n });\n if (!response.ok) {\n await this.throwResponseError(response);\n }\n const json = await response.json();\n return normalizeKeys(json) as T;\n }\n\n // --- Agent Card ---\n\n async getAgentCard(signal?: AbortSignal): Promise<A2AAgentCard> {\n const headers = await this.getHeaders(false); // GET: no Content-Type\n const url = `${this.baseUrl}/.well-known/agent-card.json`;\n const response = await fetch(url, {\n ...this.fetchOptions,\n headers,\n ...signalInit(signal),\n });\n if (!response.ok) {\n await this.throwResponseError(response);\n }\n const json = await response.json();\n return parseAgentCardResponse(normalizeKeys(json));\n }\n\n async getExtendedAgentCard(signal?: AbortSignal): Promise<A2AAgentCard> {\n const result = await this.fetchJSON<unknown>(\n `${this.getBasePath()}/extendedAgentCard`,\n signalInit(signal),\n );\n return parseAgentCardResponse(result);\n }\n\n // --- Message ---\n\n async sendMessage(\n message: A2AMessage,\n configuration?: A2ASendMessageConfiguration,\n metadata?: Record<string, unknown>,\n signal?: AbortSignal,\n ): Promise<A2ATask | A2AMessage> {\n const body: Record<string, unknown> = {\n message: toWireMessage(message),\n };\n if (configuration) body.configuration = configuration;\n if (metadata) body.metadata = metadata;\n\n const result = await this.fetchJSON<unknown>(\n `${this.getBasePath()}/message:send`,\n {\n method: \"POST\",\n body: JSON.stringify(body),\n ...signalInit(signal),\n },\n );\n\n return parseSendMessageResponse(result);\n }\n\n async *streamMessage(\n message: A2AMessage,\n configuration?: A2ASendMessageConfiguration,\n metadata?: Record<string, unknown>,\n signal?: AbortSignal,\n ): AsyncGenerator<A2AStreamEvent> {\n const headers = await this.getHeaders(true);\n headers.Accept = \"text/event-stream\";\n\n const body: Record<string, unknown> = {\n message: toWireMessage(message),\n };\n if (configuration) body.configuration = configuration;\n if (metadata) body.metadata = metadata;\n\n const response = await fetch(\n `${this.baseUrl}${this.getBasePath()}/message:stream`,\n {\n ...this.fetchOptions,\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n ...signalInit(signal),\n },\n );\n if (!response.ok) {\n await this.throwResponseError(response);\n }\n\n yield* this.parseSSE(response);\n }\n\n // --- Tasks ---\n\n async getTask(\n taskId: string,\n historyLength?: number,\n signal?: AbortSignal,\n ): Promise<A2ATask> {\n const params = new URLSearchParams();\n if (historyLength !== undefined) {\n // Proto field name for HTTP transcoding query params\n params.set(\"history_length\", String(historyLength));\n }\n const qs = params.toString();\n return this.fetchJSON<A2ATask>(\n `${this.getBasePath()}/tasks/${encodeURIComponent(taskId)}${qs ? `?${qs}` : \"\"}`,\n signalInit(signal),\n );\n }\n\n async listTasks(\n request?: A2AListTasksRequest,\n signal?: AbortSignal,\n ): Promise<A2AListTasksResponse> {\n const params = new URLSearchParams();\n if (request?.contextId) params.set(\"context_id\", request.contextId);\n if (request?.status) params.set(\"status\", toWireTaskState(request.status));\n if (request?.pageSize !== undefined)\n params.set(\"page_size\", String(request.pageSize));\n if (request?.pageToken) params.set(\"page_token\", request.pageToken);\n if (request?.historyLength !== undefined)\n params.set(\"history_length\", String(request.historyLength));\n if (request?.statusTimestampAfter)\n params.set(\"status_timestamp_after\", request.statusTimestampAfter);\n if (request?.includeArtifacts !== undefined)\n params.set(\"include_artifacts\", String(request.includeArtifacts));\n const qs = params.toString();\n return this.fetchJSON<A2AListTasksResponse>(\n `${this.getBasePath()}/tasks${qs ? `?${qs}` : \"\"}`,\n signalInit(signal),\n );\n }\n\n async cancelTask(\n taskId: string,\n metadata?: Record<string, unknown>,\n signal?: AbortSignal,\n ): Promise<A2ATask> {\n const body = metadata ? { metadata } : {};\n return this.fetchJSON<A2ATask>(\n `${this.getBasePath()}/tasks/${encodeURIComponent(taskId)}:cancel`,\n {\n method: \"POST\",\n body: JSON.stringify(body),\n ...signalInit(signal),\n },\n );\n }\n\n async *subscribeToTask(\n taskId: string,\n signal?: AbortSignal,\n ): AsyncGenerator<A2AStreamEvent> {\n const headers = await this.getHeaders(false); // GET: no Content-Type\n headers.Accept = \"text/event-stream\";\n\n const response = await fetch(\n `${this.baseUrl}${this.getBasePath()}/tasks/${encodeURIComponent(taskId)}:subscribe`,\n {\n ...this.fetchOptions,\n headers,\n ...signalInit(signal),\n },\n );\n if (!response.ok) {\n await this.throwResponseError(response);\n }\n\n yield* this.parseSSE(response);\n }\n\n // --- Push Notification Configs ---\n\n async createTaskPushNotificationConfig(\n config: A2ATaskPushNotificationConfig,\n signal?: AbortSignal,\n ): Promise<A2ATaskPushNotificationConfig> {\n const taskId = config.taskId;\n if (!taskId) throw new Error(\"taskId is required\");\n return this.fetchJSON<A2ATaskPushNotificationConfig>(\n `${this.getBasePath()}/tasks/${encodeURIComponent(taskId)}/pushNotificationConfigs`,\n {\n method: \"POST\",\n body: JSON.stringify(config),\n ...signalInit(signal),\n },\n );\n }\n\n async getTaskPushNotificationConfig(\n taskId: string,\n configId: string,\n signal?: AbortSignal,\n ): Promise<A2ATaskPushNotificationConfig> {\n return this.fetchJSON<A2ATaskPushNotificationConfig>(\n `${this.getBasePath()}/tasks/${encodeURIComponent(taskId)}/pushNotificationConfigs/${encodeURIComponent(configId)}`,\n signalInit(signal),\n );\n }\n\n async listTaskPushNotificationConfigs(\n taskId: string,\n options?: { pageSize?: number; pageToken?: string },\n signal?: AbortSignal,\n ): Promise<A2AListTaskPushNotificationConfigsResponse> {\n const params = new URLSearchParams();\n if (options?.pageSize !== undefined)\n params.set(\"page_size\", String(options.pageSize));\n if (options?.pageToken) params.set(\"page_token\", options.pageToken);\n const qs = params.toString();\n return this.fetchJSON<A2AListTaskPushNotificationConfigsResponse>(\n `${this.getBasePath()}/tasks/${encodeURIComponent(taskId)}/pushNotificationConfigs${qs ? `?${qs}` : \"\"}`,\n signalInit(signal),\n );\n }\n\n async deleteTaskPushNotificationConfig(\n taskId: string,\n configId: string,\n signal?: AbortSignal,\n ): Promise<void> {\n const isGet = false;\n const headers = await this.getHeaders(!isGet);\n const response = await fetch(\n `${this.baseUrl}${this.getBasePath()}/tasks/${encodeURIComponent(taskId)}/pushNotificationConfigs/${encodeURIComponent(configId)}`,\n {\n ...this.fetchOptions,\n method: \"DELETE\",\n headers,\n ...signalInit(signal),\n },\n );\n if (!response.ok) {\n await this.throwResponseError(response);\n }\n }\n\n // --- SSE Parsing ---\n\n private async *parseSSE(response: Response): AsyncGenerator<A2AStreamEvent> {\n const contentType = response.headers.get(\"Content-Type\");\n const mediaType = contentType?.split(\";\", 1)[0]?.trim().toLowerCase();\n if (mediaType !== \"text/event-stream\") {\n const received = contentType\n ? `\"${contentType}\"`\n : \"no Content-Type header\";\n throw new Error(\n `Expected A2A stream response Content-Type \"text/event-stream\", received ${received}`,\n );\n }\n\n const reader = response.body?.getReader();\n if (!reader) throw new Error(\"No response body\");\n\n const decoder = new TextDecoder();\n const sseDecoder = new SSEEventDecoder();\n\n const readEvent = (event: SSEEvent): A2AStreamEvent | null => {\n try {\n let parsed = JSON.parse(event.data);\n\n if (\n parsed &&\n typeof parsed === \"object\" &&\n \"jsonrpc\" in parsed &&\n \"result\" in parsed\n ) {\n parsed = parsed.result;\n }\n\n const normalized = normalizeKeys(parsed) as Record<string, unknown>;\n return discriminateStreamResponse(normalized);\n } catch {\n return null;\n }\n };\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) {\n for (const event of sseDecoder.push(decoder.decode())) {\n const parsed = readEvent(event);\n if (parsed) yield parsed;\n }\n break;\n }\n\n for (const event of sseDecoder.push(\n decoder.decode(value, { stream: true }),\n )) {\n const parsed = readEvent(event);\n if (parsed) yield parsed;\n }\n }\n } finally {\n reader.releaseLock();\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { A2AAgentCard, A2AArtifact, A2ASendMessageConfiguration, A2ATask } from "./types.js";
|
|
2
2
|
import { A2AClient } from "./A2AClient.js";
|
|
3
|
-
import { AppendMessage, AssistantRuntime, ThreadHistoryAdapter, ThreadMessage } from "@assistant-ui/core";
|
|
4
|
-
|
|
3
|
+
import { AppendMessage, AssistantRuntime, ExportedMessageRepository, ThreadHistoryAdapter, ThreadMessage } from "@assistant-ui/core";
|
|
5
4
|
//#region src/A2AThreadRuntimeCore.d.ts
|
|
6
5
|
type A2AThreadRuntimeCoreOptions = {
|
|
7
6
|
client: A2AClient;
|
|
@@ -23,7 +22,8 @@ declare class A2AThreadRuntimeCore {
|
|
|
23
22
|
private history;
|
|
24
23
|
private readonly notifyUpdate;
|
|
25
24
|
private runtime;
|
|
26
|
-
private
|
|
25
|
+
private readonly repository;
|
|
26
|
+
private exportedRepository;
|
|
27
27
|
private isRunningFlag;
|
|
28
28
|
private abortController;
|
|
29
29
|
private pendingError;
|
|
@@ -40,6 +40,15 @@ declare class A2AThreadRuntimeCore {
|
|
|
40
40
|
detachRuntime(): void;
|
|
41
41
|
getRuntime(): AssistantRuntime | undefined;
|
|
42
42
|
getMessages(): readonly ThreadMessage[];
|
|
43
|
+
getMessageRepository(): ExportedMessageRepository;
|
|
44
|
+
private tryGetMessage;
|
|
45
|
+
private tryGetMessages;
|
|
46
|
+
private hasMessage;
|
|
47
|
+
private addOrUpdateMessage;
|
|
48
|
+
private switchToBranch;
|
|
49
|
+
private resetRepositoryHead;
|
|
50
|
+
private clearRepository;
|
|
51
|
+
private updateMessage;
|
|
43
52
|
getTask(): A2ATask | undefined;
|
|
44
53
|
getArtifacts(): readonly A2AArtifact[];
|
|
45
54
|
getAgentCard(): A2AAgentCard | undefined;
|
|
@@ -52,7 +61,10 @@ declare class A2AThreadRuntimeCore {
|
|
|
52
61
|
runConfig?: Record<string, unknown>;
|
|
53
62
|
}): Promise<void>;
|
|
54
63
|
cancel(): Promise<void>;
|
|
64
|
+
private appendLinearChain;
|
|
65
|
+
private finalizeExternalApply;
|
|
55
66
|
applyExternalMessages(messages: readonly ThreadMessage[]): void;
|
|
67
|
+
private applyExternalMessageRepository;
|
|
56
68
|
private startRun;
|
|
57
69
|
private runStreaming;
|
|
58
70
|
private runSync;
|
|
@@ -68,7 +80,6 @@ declare class A2AThreadRuntimeCore {
|
|
|
68
80
|
private getAssistantStatus;
|
|
69
81
|
private setRunning;
|
|
70
82
|
private finishRun;
|
|
71
|
-
private resetHead;
|
|
72
83
|
private recordHistoryEntry;
|
|
73
84
|
private markPendingAssistantHistory;
|
|
74
85
|
private persistAssistantHistory;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"A2AThreadRuntimeCore.d.ts","names":[],"sources":["../src/A2AThreadRuntimeCore.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"A2AThreadRuntimeCore.d.ts","names":[],"sources":["../src/A2AThreadRuntimeCore.ts"],"mappings":";;;;KAgCY;EACV,QAAQ;EACR;EACA,gBAAgB;EAChB,YAAY,OAAO;EACnB;EACA,uBAAuB,UAAU;EACjC,UAAU;EACV;;cAQW;UACH;UACA;UACA;UACA;UACA;UACA;UACA;mBACS;UAET;mBACS;UACT;UACA;UACA;UACA;UAGA;UACA;UACA;mBAGS;mBACA;UACT;UACA;EAEI,YAAA,SAAS;EAWrB,cAAc,SAAS,KAAK;EAU5B,cAAc,SAAS;EAIvB;EASA,cAAc;EAId,wBAAwB;EAIxB,wBAAwB;UAKhB;UAQA;UAUA;UAIA;UAQA;UAKA;UAKA;UAKA;EAYR,WAAW;EAIX,yBAAyB;EAIzB,gBAAgB;EAIhB;MAII;EAIJ,mBAAmB;EA+Bb,OAAO,SAAS,gBAAgB;EAuBhC,KAAK,SAAS,gBAAgB;EAI9B,OACJ,yBACA;IAAW,YAAY;MACtB;EAaG,UAAU;UAiBR;UAgBA;EAWR,sBAAsB,mBAAmB;UAiCjC;UA6DM;UAwEA;UA4BA;UA4BN;UAiBA;UA6BA;UAqCA;UAQA;UAuBA;UAmCA;UAsBA;UAUA;UAaA;UAQA;UAKA;UASA;UAIA;UAQA;UAeA"}
|