@assistant-ui/react-a2a 0.2.28 → 0.2.30
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.map +1 -1
- package/dist/A2AClient.js +82 -7
- package/dist/A2AClient.js.map +1 -1
- package/dist/A2AThreadRuntimeCore.d.ts.map +1 -1
- package/dist/A2AThreadRuntimeCore.js +19 -3
- package/dist/A2AThreadRuntimeCore.js.map +1 -1
- package/dist/conversions.js +2 -2
- package/dist/conversions.js.map +1 -1
- package/package.json +5 -5
- package/src/A2AClient.test.ts +233 -9
- package/src/A2AClient.ts +167 -8
- package/src/A2AThreadRuntimeCore.test.ts +135 -10
- package/src/A2AThreadRuntimeCore.ts +34 -4
- package/src/conversions.test.ts +16 -0
- package/src/conversions.ts +2 -2
- package/src/useA2ARuntime.test.tsx +20 -6
package/dist/A2AClient.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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;;
|
|
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;;cAqXP;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;EAcL,UACJ,UAAU,qBACV,SAAS,cACR,QAAQ;EAqBL,WACJ,gBACA,WAAW,yBACX,SAAS,cACR,QAAQ;EAaJ,gBACL,gBACA,SAAS,cACR,eAAe;EAqBZ,iCACJ,QAAQ,+BACR,SAAS,cACR,QAAQ;EAiBL,8BACJ,gBACA,kBACA,SAAS,cACR,QAAQ;EAWL,gCACJ,gBACA;IAAY;IAAmB;KAC/B,SAAS,cACR,QAAQ;EAaL,iCACJ,gBACA,kBACA,SAAS,cACR;UAmBY"}
|
package/dist/A2AClient.js
CHANGED
|
@@ -89,8 +89,14 @@ const TASK_STATES = new Set(Object.keys({
|
|
|
89
89
|
auth_required: true
|
|
90
90
|
}));
|
|
91
91
|
const isTaskState = (value) => typeof value === "string" && TASK_STATES.has(value);
|
|
92
|
+
const ROLES = new Set(Object.keys({
|
|
93
|
+
unspecified: true,
|
|
94
|
+
user: true,
|
|
95
|
+
agent: true
|
|
96
|
+
}));
|
|
97
|
+
const isRole = (value) => typeof value === "string" && ROLES.has(value);
|
|
92
98
|
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 &&
|
|
99
|
+
const isMessage = (value) => isRecord(value) && typeof value.messageId === "string" && value.messageId.length > 0 && isRole(value.role) && Array.isArray(value.parts) && value.parts.every(isRecord);
|
|
94
100
|
const isStringArray = (value) => Array.isArray(value) && value.every((item) => typeof item === "string");
|
|
95
101
|
const invalidAgentCard = () => {
|
|
96
102
|
throw new Error("Invalid A2A agent card response: expected a valid agent card payload.");
|
|
@@ -131,6 +137,68 @@ const parseSendMessageResponse = (value) => {
|
|
|
131
137
|
}
|
|
132
138
|
throw new Error("Invalid A2A message:send response: expected a valid task or message payload.");
|
|
133
139
|
};
|
|
140
|
+
const parseTaskResponse = (value, operation) => {
|
|
141
|
+
if (isTask(value)) return value;
|
|
142
|
+
throw new Error(`Invalid A2A ${operation} response: expected a valid task payload.`);
|
|
143
|
+
};
|
|
144
|
+
const isNonNegativeInteger = (value) => typeof value === "number" && Number.isInteger(value) && value >= 0;
|
|
145
|
+
const invalidListTasksResponse = () => {
|
|
146
|
+
throw new Error("Invalid A2A tasks:list response: expected a valid task list payload.");
|
|
147
|
+
};
|
|
148
|
+
const parseListTasksResponse = (value) => {
|
|
149
|
+
if (!isRecord(value)) return invalidListTasksResponse();
|
|
150
|
+
const tasks = value.tasks ?? [];
|
|
151
|
+
if (!Array.isArray(tasks) || !tasks.every(isTask)) return invalidListTasksResponse();
|
|
152
|
+
const { nextPageToken, pageSize, totalSize } = value;
|
|
153
|
+
if (nextPageToken != null && typeof nextPageToken !== "string" || pageSize != null && !isNonNegativeInteger(pageSize) || totalSize != null && !isNonNegativeInteger(totalSize)) return invalidListTasksResponse();
|
|
154
|
+
return {
|
|
155
|
+
...value,
|
|
156
|
+
tasks,
|
|
157
|
+
nextPageToken: nextPageToken ?? "",
|
|
158
|
+
pageSize: pageSize ?? 0,
|
|
159
|
+
totalSize: totalSize ?? 0
|
|
160
|
+
};
|
|
161
|
+
};
|
|
162
|
+
const invalidPushNotificationConfigResponse = (operation) => () => {
|
|
163
|
+
throw new Error(`Invalid A2A ${operation} response: expected a valid push notification config payload.`);
|
|
164
|
+
};
|
|
165
|
+
const invalidListPushNotificationConfigsResponse = () => {
|
|
166
|
+
throw new Error("Invalid A2A pushNotificationConfigs:list response: expected a valid push notification config list payload.");
|
|
167
|
+
};
|
|
168
|
+
const parseOptionalString = (value, invalid) => value == null ? void 0 : typeof value === "string" ? value : invalid();
|
|
169
|
+
const parseTaskPushNotificationConfigResponse = (value, invalid) => {
|
|
170
|
+
if (!isRecord(value) || typeof value.url !== "string" || value.url.length === 0) return invalid();
|
|
171
|
+
const { tenant, id, taskId, url, token, authentication, ...extra } = value;
|
|
172
|
+
let normalizedAuthentication;
|
|
173
|
+
if (authentication != null) {
|
|
174
|
+
if (!isRecord(authentication)) return invalid();
|
|
175
|
+
const { scheme, credentials, ...authenticationExtra } = authentication;
|
|
176
|
+
normalizedAuthentication = {
|
|
177
|
+
...authenticationExtra,
|
|
178
|
+
scheme: parseOptionalString(scheme, invalid) ?? "",
|
|
179
|
+
...credentials == null ? {} : { credentials: parseOptionalString(credentials, invalid) }
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
return {
|
|
183
|
+
...extra,
|
|
184
|
+
...tenant == null ? {} : { tenant: parseOptionalString(tenant, invalid) },
|
|
185
|
+
...id == null ? {} : { id: parseOptionalString(id, invalid) },
|
|
186
|
+
...taskId == null ? {} : { taskId: parseOptionalString(taskId, invalid) },
|
|
187
|
+
url,
|
|
188
|
+
...token == null ? {} : { token: parseOptionalString(token, invalid) },
|
|
189
|
+
...normalizedAuthentication === void 0 ? {} : { authentication: normalizedAuthentication }
|
|
190
|
+
};
|
|
191
|
+
};
|
|
192
|
+
const parseListTaskPushNotificationConfigsResponse = (value) => {
|
|
193
|
+
if (!isRecord(value)) return invalidListPushNotificationConfigsResponse();
|
|
194
|
+
const { configs: rawConfigs, nextPageToken, ...extra } = value;
|
|
195
|
+
if (rawConfigs != null && !Array.isArray(rawConfigs)) return invalidListPushNotificationConfigsResponse();
|
|
196
|
+
return {
|
|
197
|
+
...extra,
|
|
198
|
+
configs: (rawConfigs ?? []).map((config) => parseTaskPushNotificationConfigResponse(config, invalidListPushNotificationConfigsResponse)),
|
|
199
|
+
...nextPageToken == null ? {} : { nextPageToken: parseOptionalString(nextPageToken, invalidListPushNotificationConfigsResponse) }
|
|
200
|
+
};
|
|
201
|
+
};
|
|
134
202
|
function signalInit(signal) {
|
|
135
203
|
return signal ? { signal } : {};
|
|
136
204
|
}
|
|
@@ -244,7 +312,8 @@ var A2AClient = class {
|
|
|
244
312
|
const params = new URLSearchParams();
|
|
245
313
|
if (historyLength !== void 0) params.set("history_length", String(historyLength));
|
|
246
314
|
const qs = params.toString();
|
|
247
|
-
|
|
315
|
+
const result = await this.fetchJSON(`${this.getBasePath()}/tasks/${encodeURIComponent(taskId)}${qs ? `?${qs}` : ""}`, signalInit(signal));
|
|
316
|
+
return parseTaskResponse(result, "tasks:get");
|
|
248
317
|
}
|
|
249
318
|
async listTasks(request, signal) {
|
|
250
319
|
const params = new URLSearchParams();
|
|
@@ -256,15 +325,17 @@ var A2AClient = class {
|
|
|
256
325
|
if (request?.statusTimestampAfter) params.set("status_timestamp_after", request.statusTimestampAfter);
|
|
257
326
|
if (request?.includeArtifacts !== void 0) params.set("include_artifacts", String(request.includeArtifacts));
|
|
258
327
|
const qs = params.toString();
|
|
259
|
-
|
|
328
|
+
const result = await this.fetchJSON(`${this.getBasePath()}/tasks${qs ? `?${qs}` : ""}`, signalInit(signal));
|
|
329
|
+
return parseListTasksResponse(result);
|
|
260
330
|
}
|
|
261
331
|
async cancelTask(taskId, metadata, signal) {
|
|
262
332
|
const body = metadata ? { metadata } : {};
|
|
263
|
-
|
|
333
|
+
const result = await this.fetchJSON(`${this.getBasePath()}/tasks/${encodeURIComponent(taskId)}:cancel`, {
|
|
264
334
|
method: "POST",
|
|
265
335
|
body: JSON.stringify(body),
|
|
266
336
|
...signalInit(signal)
|
|
267
337
|
});
|
|
338
|
+
return parseTaskResponse(result, "tasks:cancel");
|
|
268
339
|
}
|
|
269
340
|
async *subscribeToTask(taskId, signal) {
|
|
270
341
|
const headers = await this.getHeaders(false);
|
|
@@ -280,21 +351,24 @@ var A2AClient = class {
|
|
|
280
351
|
async createTaskPushNotificationConfig(config, signal) {
|
|
281
352
|
const taskId = config.taskId;
|
|
282
353
|
if (!taskId) throw new Error("taskId is required");
|
|
283
|
-
|
|
354
|
+
const result = await this.fetchJSON(`${this.getBasePath()}/tasks/${encodeURIComponent(taskId)}/pushNotificationConfigs`, {
|
|
284
355
|
method: "POST",
|
|
285
356
|
body: JSON.stringify(config),
|
|
286
357
|
...signalInit(signal)
|
|
287
358
|
});
|
|
359
|
+
return parseTaskPushNotificationConfigResponse(result, invalidPushNotificationConfigResponse("pushNotificationConfigs:create"));
|
|
288
360
|
}
|
|
289
361
|
async getTaskPushNotificationConfig(taskId, configId, signal) {
|
|
290
|
-
|
|
362
|
+
const result = await this.fetchJSON(`${this.getBasePath()}/tasks/${encodeURIComponent(taskId)}/pushNotificationConfigs/${encodeURIComponent(configId)}`, signalInit(signal));
|
|
363
|
+
return parseTaskPushNotificationConfigResponse(result, invalidPushNotificationConfigResponse("pushNotificationConfigs:get"));
|
|
291
364
|
}
|
|
292
365
|
async listTaskPushNotificationConfigs(taskId, options, signal) {
|
|
293
366
|
const params = new URLSearchParams();
|
|
294
367
|
if (options?.pageSize !== void 0) params.set("page_size", String(options.pageSize));
|
|
295
368
|
if (options?.pageToken) params.set("page_token", options.pageToken);
|
|
296
369
|
const qs = params.toString();
|
|
297
|
-
|
|
370
|
+
const result = await this.fetchJSON(`${this.getBasePath()}/tasks/${encodeURIComponent(taskId)}/pushNotificationConfigs${qs ? `?${qs}` : ""}`, signalInit(signal));
|
|
371
|
+
return parseListTaskPushNotificationConfigsResponse(result);
|
|
298
372
|
}
|
|
299
373
|
async deleteTaskPushNotificationConfig(taskId, configId, signal) {
|
|
300
374
|
const headers = await this.getHeaders(true);
|
|
@@ -310,6 +384,7 @@ var A2AClient = class {
|
|
|
310
384
|
const contentType = response.headers.get("Content-Type");
|
|
311
385
|
if (contentType?.split(";", 1)[0]?.trim().toLowerCase() !== "text/event-stream") {
|
|
312
386
|
const received = contentType ? `"${contentType}"` : "no Content-Type header";
|
|
387
|
+
response.body?.cancel().catch(() => void 0);
|
|
313
388
|
throw new Error(`Expected A2A stream response Content-Type "text/event-stream", received ${received}`);
|
|
314
389
|
}
|
|
315
390
|
const reader = response.body?.getReader();
|
package/dist/A2AClient.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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 let shouldCancel = true;\n try {\n while (true) {\n let result: ReadableStreamReadResult<Uint8Array>;\n try {\n result = await reader.read();\n } catch (error) {\n shouldCancel = false;\n throw error;\n }\n\n const { done, value } = result;\n if (done) {\n shouldCancel = false;\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 try {\n if (shouldCancel) await reader.cancel().catch(() => undefined);\n } finally {\n reader.releaseLock();\n }\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 ROLES: ReadonlySet<string> = new Set(\n Object.keys({\n unspecified: true,\n user: true,\n agent: true,\n } satisfies Record<A2ARole, true>),\n);\n\nconst isRole = (value: unknown): value is A2ARole =>\n typeof value === \"string\" && ROLES.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 isRole(value.role) &&\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\nconst parseTaskResponse = (\n value: unknown,\n operation: \"tasks:get\" | \"tasks:cancel\",\n): A2ATask => {\n if (isTask(value)) return value;\n\n throw new Error(\n `Invalid A2A ${operation} response: expected a valid task payload.`,\n );\n};\n\nconst isNonNegativeInteger = (value: unknown): value is number =>\n typeof value === \"number\" && Number.isInteger(value) && value >= 0;\n\nconst invalidListTasksResponse = (): never => {\n throw new Error(\n \"Invalid A2A tasks:list response: expected a valid task list payload.\",\n );\n};\n\nconst parseListTasksResponse = (value: unknown): A2AListTasksResponse => {\n if (!isRecord(value)) return invalidListTasksResponse();\n\n const tasks = value.tasks ?? [];\n if (!Array.isArray(tasks) || !tasks.every(isTask)) {\n return invalidListTasksResponse();\n }\n\n const { nextPageToken, pageSize, totalSize } = value;\n if (\n (nextPageToken != null && typeof nextPageToken !== \"string\") ||\n (pageSize != null && !isNonNegativeInteger(pageSize)) ||\n (totalSize != null && !isNonNegativeInteger(totalSize))\n ) {\n return invalidListTasksResponse();\n }\n\n return {\n ...value,\n tasks,\n nextPageToken: nextPageToken ?? \"\",\n pageSize: pageSize ?? 0,\n totalSize: totalSize ?? 0,\n };\n};\n\nconst invalidPushNotificationConfigResponse =\n (\n operation: \"pushNotificationConfigs:create\" | \"pushNotificationConfigs:get\",\n ) =>\n (): never => {\n throw new Error(\n `Invalid A2A ${operation} response: expected a valid push notification config payload.`,\n );\n };\n\nconst invalidListPushNotificationConfigsResponse = (): never => {\n throw new Error(\n \"Invalid A2A pushNotificationConfigs:list response: expected a valid push notification config list payload.\",\n );\n};\n\nconst parseOptionalString = (\n value: unknown,\n invalid: () => never,\n): string | undefined =>\n value == null ? undefined : typeof value === \"string\" ? value : invalid();\n\nconst parseTaskPushNotificationConfigResponse = (\n value: unknown,\n invalid: () => never,\n): A2ATaskPushNotificationConfig => {\n if (\n !isRecord(value) ||\n typeof value.url !== \"string\" ||\n value.url.length === 0\n ) {\n return invalid();\n }\n\n const { tenant, id, taskId, url, token, authentication, ...extra } = value;\n let normalizedAuthentication: A2ATaskPushNotificationConfig[\"authentication\"];\n if (authentication != null) {\n if (!isRecord(authentication)) return invalid();\n const { scheme, credentials, ...authenticationExtra } = authentication;\n normalizedAuthentication = {\n ...authenticationExtra,\n scheme: parseOptionalString(scheme, invalid) ?? \"\",\n ...(credentials == null\n ? {}\n : { credentials: parseOptionalString(credentials, invalid) }),\n };\n }\n\n return {\n ...extra,\n ...(tenant == null ? {} : { tenant: parseOptionalString(tenant, invalid) }),\n ...(id == null ? {} : { id: parseOptionalString(id, invalid) }),\n ...(taskId == null ? {} : { taskId: parseOptionalString(taskId, invalid) }),\n url,\n ...(token == null ? {} : { token: parseOptionalString(token, invalid) }),\n ...(normalizedAuthentication === undefined\n ? {}\n : { authentication: normalizedAuthentication }),\n };\n};\n\nconst parseListTaskPushNotificationConfigsResponse = (\n value: unknown,\n): A2AListTaskPushNotificationConfigsResponse => {\n if (!isRecord(value)) return invalidListPushNotificationConfigsResponse();\n\n const { configs: rawConfigs, nextPageToken, ...extra } = value;\n if (rawConfigs != null && !Array.isArray(rawConfigs)) {\n return invalidListPushNotificationConfigsResponse();\n }\n\n return {\n ...extra,\n configs: (rawConfigs ?? []).map((config) =>\n parseTaskPushNotificationConfigResponse(\n config,\n invalidListPushNotificationConfigsResponse,\n ),\n ),\n ...(nextPageToken == null\n ? {}\n : {\n nextPageToken: parseOptionalString(\n nextPageToken,\n invalidListPushNotificationConfigsResponse,\n ),\n }),\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 const result = await this.fetchJSON<unknown>(\n `${this.getBasePath()}/tasks/${encodeURIComponent(taskId)}${qs ? `?${qs}` : \"\"}`,\n signalInit(signal),\n );\n return parseTaskResponse(result, \"tasks:get\");\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 const result = await this.fetchJSON<unknown>(\n `${this.getBasePath()}/tasks${qs ? `?${qs}` : \"\"}`,\n signalInit(signal),\n );\n return parseListTasksResponse(result);\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 const result = await this.fetchJSON<unknown>(\n `${this.getBasePath()}/tasks/${encodeURIComponent(taskId)}:cancel`,\n {\n method: \"POST\",\n body: JSON.stringify(body),\n ...signalInit(signal),\n },\n );\n return parseTaskResponse(result, \"tasks:cancel\");\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 const result = await this.fetchJSON<unknown>(\n `${this.getBasePath()}/tasks/${encodeURIComponent(taskId)}/pushNotificationConfigs`,\n {\n method: \"POST\",\n body: JSON.stringify(config),\n ...signalInit(signal),\n },\n );\n return parseTaskPushNotificationConfigResponse(\n result,\n invalidPushNotificationConfigResponse(\"pushNotificationConfigs:create\"),\n );\n }\n\n async getTaskPushNotificationConfig(\n taskId: string,\n configId: string,\n signal?: AbortSignal,\n ): Promise<A2ATaskPushNotificationConfig> {\n const result = await this.fetchJSON<unknown>(\n `${this.getBasePath()}/tasks/${encodeURIComponent(taskId)}/pushNotificationConfigs/${encodeURIComponent(configId)}`,\n signalInit(signal),\n );\n return parseTaskPushNotificationConfigResponse(\n result,\n invalidPushNotificationConfigResponse(\"pushNotificationConfigs:get\"),\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 const result = await this.fetchJSON<unknown>(\n `${this.getBasePath()}/tasks/${encodeURIComponent(taskId)}/pushNotificationConfigs${qs ? `?${qs}` : \"\"}`,\n signalInit(signal),\n );\n return parseListTaskPushNotificationConfigsResponse(result);\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 void response.body?.cancel().catch(() => undefined);\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 let shouldCancel = true;\n try {\n while (true) {\n let result: ReadableStreamReadResult<Uint8Array>;\n try {\n result = await reader.read();\n } catch (error) {\n shouldCancel = false;\n throw error;\n }\n\n const { done, value } = result;\n if (done) {\n shouldCancel = false;\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 try {\n if (shouldCancel) await reader.cancel().catch(() => undefined);\n } finally {\n reader.releaseLock();\n }\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
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;;
|
|
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;;cA6CW;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;EAiCb,OAAO,SAAS,gBAAgB;EAuBhC,KAAK,SAAS,gBAAgB;EAI9B,OACJ,yBACA;IAAW,YAAY;MACtB;EAaG,UAAU;UAiBR;UAgBA;EAWR,sBAAsB,mBAAmB;UAiCjC;UA6DM;UAwEA;UAkCA;UA4BN;UAiBA;UA6BA;UA0CA;UAQA;UAuCA;UAmCA;UAsBA;UAUA;UAaA;UAQA;UAKA;UAQA;UAIA;UAQA;UAeA"}
|
|
@@ -21,6 +21,12 @@ const invokeRuntimeCallback = (name, callback, ...args) => {
|
|
|
21
21
|
reportCallbackError(name, error);
|
|
22
22
|
}
|
|
23
23
|
};
|
|
24
|
+
function normalizeArtifact(artifact) {
|
|
25
|
+
return {
|
|
26
|
+
...artifact,
|
|
27
|
+
parts: Array.isArray(artifact.parts) ? artifact.parts : []
|
|
28
|
+
};
|
|
29
|
+
}
|
|
24
30
|
var A2AThreadRuntimeCore = class {
|
|
25
31
|
client;
|
|
26
32
|
contextId;
|
|
@@ -326,11 +332,14 @@ var A2AThreadRuntimeCore = class {
|
|
|
326
332
|
}
|
|
327
333
|
async runStreaming(a2aMessage, assistantId, abortController) {
|
|
328
334
|
const stream = this.client.streamMessage(a2aMessage, this.configuration, void 0, abortController.signal);
|
|
335
|
+
let receivedEvent = false;
|
|
329
336
|
for await (const event of stream) {
|
|
330
337
|
if (abortController.signal.aborted) break;
|
|
338
|
+
receivedEvent = true;
|
|
331
339
|
this.handleStreamEvent(assistantId, event);
|
|
332
340
|
}
|
|
333
341
|
if (!abortController.signal.aborted) {
|
|
342
|
+
if (!receivedEvent) throw new Error("A2A message stream ended without any events.");
|
|
334
343
|
if (this.getAssistantStatus(assistantId)?.type === "running") this.updateAssistantStatus(assistantId, {
|
|
335
344
|
type: "complete",
|
|
336
345
|
reason: "stop"
|
|
@@ -383,7 +392,8 @@ var A2AThreadRuntimeCore = class {
|
|
|
383
392
|
this.notifyUpdate();
|
|
384
393
|
}
|
|
385
394
|
handleArtifactUpdate(event) {
|
|
386
|
-
const {
|
|
395
|
+
const { append, lastChunk } = event;
|
|
396
|
+
const artifact = normalizeArtifact(event.artifact);
|
|
387
397
|
const existingIdx = this.currentArtifacts.findIndex((a) => a.artifactId === artifact.artifactId);
|
|
388
398
|
let updated;
|
|
389
399
|
if (existingIdx >= 0 && append) {
|
|
@@ -418,9 +428,15 @@ var A2AThreadRuntimeCore = class {
|
|
|
418
428
|
this.notifyUpdate();
|
|
419
429
|
}
|
|
420
430
|
handleTaskSnapshot(assistantId, task) {
|
|
421
|
-
|
|
431
|
+
const artifacts = task.artifacts === void 0 ? void 0 : Array.isArray(task.artifacts) ? task.artifacts.map(normalizeArtifact) : [];
|
|
432
|
+
const history = task.history === void 0 ? void 0 : Array.isArray(task.history) ? task.history : [];
|
|
433
|
+
this.currentTask = {
|
|
434
|
+
...task,
|
|
435
|
+
...artifacts === void 0 ? {} : { artifacts },
|
|
436
|
+
...history === void 0 ? {} : { history }
|
|
437
|
+
};
|
|
422
438
|
if (task.contextId) this.contextId = task.contextId;
|
|
423
|
-
if (
|
|
439
|
+
if (artifacts) this.currentArtifacts = artifacts;
|
|
424
440
|
if (task.status.message) {
|
|
425
441
|
const content = a2aMessageToContent(task.status.message);
|
|
426
442
|
this.updateAssistantContent(assistantId, content);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"A2AThreadRuntimeCore.js","names":[],"sources":["../src/A2AThreadRuntimeCore.ts"],"sourcesContent":["\"use client\";\n\nimport { generateId, fromThreadMessageLike } from \"@assistant-ui/core\";\nimport type {\n AppendMessage,\n AssistantRuntime,\n ExportedMessageRepository,\n MessageStatus,\n ThreadAssistantMessage,\n ThreadHistoryAdapter,\n ThreadMessage,\n} from \"@assistant-ui/core\";\nimport { MessageRepository } from \"@assistant-ui/core/internal\";\nimport type { A2AClient } from \"./A2AClient\";\nimport type {\n A2AArtifact,\n A2AAgentCard,\n A2AMessage,\n A2APart,\n A2ASendMessageConfiguration,\n A2AStreamEvent,\n A2ATask,\n A2ATaskArtifactUpdateEvent,\n A2ATaskStatusUpdateEvent,\n} from \"./types\";\nimport {\n a2aMessageToContent,\n contentPartsToA2AParts,\n isTerminalTaskState,\n taskStateToMessageStatus,\n} from \"./conversions\";\n\nexport type A2AThreadRuntimeCoreOptions = {\n client: A2AClient;\n contextId?: string | undefined;\n configuration?: A2ASendMessageConfiguration | undefined;\n onError?: ((error: Error) => void) | undefined;\n onCancel?: (() => void) | undefined;\n onArtifactComplete?: ((artifact: A2AArtifact) => void) | undefined;\n history?: ThreadHistoryAdapter | undefined;\n notifyUpdate: () => void;\n};\n\nconst FALLBACK_USER_STATUS = {\n type: \"complete\",\n reason: \"unknown\",\n} as const;\n\ntype A2ARuntimeCallbackName = \"onError\" | \"onCancel\" | \"onArtifactComplete\";\n\nconst reportCallbackError = (name: A2ARuntimeCallbackName, error: unknown) => {\n console.error(`[react-a2a] ${name} callback threw an error`, error);\n};\n\nconst invokeRuntimeCallback = <TArgs extends unknown[]>(\n name: A2ARuntimeCallbackName,\n callback: ((...args: TArgs) => void) | undefined,\n ...args: TArgs\n) => {\n if (!callback) return;\n\n try {\n const result = callback(...args) as unknown;\n if (\n result !== null &&\n (typeof result === \"object\" || typeof result === \"function\") &&\n \"then\" in result &&\n typeof result.then === \"function\"\n ) {\n void Promise.resolve(result).catch((error) => {\n reportCallbackError(name, error);\n });\n }\n } catch (error) {\n reportCallbackError(name, error);\n }\n};\n\nexport class A2AThreadRuntimeCore {\n private client: A2AClient;\n private contextId: string | undefined;\n private configuration: A2ASendMessageConfiguration | undefined;\n private onError: ((error: Error) => void) | undefined;\n private onCancel: (() => void) | undefined;\n private onArtifactComplete: ((artifact: A2AArtifact) => void) | undefined;\n private history: ThreadHistoryAdapter | undefined;\n private readonly notifyUpdate: () => void;\n\n private runtime: AssistantRuntime | undefined;\n private readonly repository = new MessageRepository();\n private exportedRepository: ExportedMessageRepository | undefined;\n private isRunningFlag = false;\n private abortController: AbortController | null = null;\n private pendingError: Error | null = null;\n\n // A2A-specific state\n private currentTask: A2ATask | undefined;\n private currentArtifacts: A2AArtifact[] = [];\n private agentCardValue: A2AAgentCard | undefined;\n\n // History tracking\n private readonly assistantHistoryParents = new Map<string, string | null>();\n private readonly recordedHistoryIds = new Set<string>();\n private _isLoading = false;\n private _loadPromise: Promise<void> | undefined;\n\n constructor(options: A2AThreadRuntimeCoreOptions) {\n this.client = options.client;\n this.contextId = options.contextId;\n this.configuration = options.configuration;\n this.onError = options.onError;\n this.onCancel = options.onCancel;\n this.onArtifactComplete = options.onArtifactComplete;\n this.history = options.history;\n this.notifyUpdate = options.notifyUpdate;\n }\n\n updateOptions(options: Omit<A2AThreadRuntimeCoreOptions, \"notifyUpdate\">) {\n this.client = options.client;\n this.contextId = options.contextId;\n this.configuration = options.configuration;\n this.onError = options.onError;\n this.onCancel = options.onCancel;\n this.onArtifactComplete = options.onArtifactComplete;\n this.history = options.history;\n }\n\n attachRuntime(runtime: AssistantRuntime) {\n this.runtime = runtime;\n }\n\n detachRuntime() {\n this.runtime = undefined;\n // Abort in-flight requests on unmount\n if (this.abortController) {\n this.abortController.abort();\n this.abortController = null;\n }\n }\n\n getRuntime(): AssistantRuntime | undefined {\n return this.runtime;\n }\n\n getMessages(): readonly ThreadMessage[] {\n return this.repository.getMessages();\n }\n\n getMessageRepository(): ExportedMessageRepository {\n this.exportedRepository ??= this.repository.export();\n return this.exportedRepository;\n }\n\n private tryGetMessage(messageId: string) {\n try {\n return this.repository.getMessage(messageId);\n } catch {\n return undefined;\n }\n }\n\n private tryGetMessages(\n messageId: string,\n ): readonly ThreadMessage[] | undefined {\n try {\n return this.repository.getMessages(messageId);\n } catch {\n return undefined;\n }\n }\n\n private hasMessage(messageId: string): boolean {\n return this.tryGetMessage(messageId) !== undefined;\n }\n\n private addOrUpdateMessage(\n parentId: string | null,\n message: ThreadMessage,\n ): void {\n this.repository.addOrUpdateMessage(parentId, message);\n this.exportedRepository = undefined;\n }\n\n private switchToBranch(messageId: string): void {\n this.repository.switchToBranch(messageId);\n this.exportedRepository = undefined;\n }\n\n private resetRepositoryHead(messageId: string | null): void {\n this.repository.resetHead(messageId);\n this.exportedRepository = undefined;\n }\n\n private clearRepository(): void {\n this.repository.clear();\n this.exportedRepository = undefined;\n }\n\n private updateMessage(\n messageId: string,\n updater: (message: ThreadMessage) => ThreadMessage,\n ): boolean {\n const item = this.tryGetMessage(messageId);\n if (!item) return false;\n const message = updater(item.message);\n if (message === item.message) return false;\n this.addOrUpdateMessage(item.parentId, message);\n return true;\n }\n\n getTask(): A2ATask | undefined {\n return this.currentTask;\n }\n\n getArtifacts(): readonly A2AArtifact[] {\n return this.currentArtifacts;\n }\n\n getAgentCard(): A2AAgentCard | undefined {\n return this.agentCardValue;\n }\n\n isRunning(): boolean {\n return this.isRunningFlag;\n }\n\n get isLoading(): boolean {\n return this._isLoading;\n }\n\n __internal_load(): Promise<void> {\n if (this._loadPromise) return this._loadPromise;\n\n this._isLoading = true;\n\n const historyPromise = this.history?.load() ?? Promise.resolve(null);\n const agentCardPromise = this.client.getAgentCard().catch(() => undefined);\n\n this._loadPromise = Promise.all([historyPromise, agentCardPromise])\n .then(([repo, agentCard]) => {\n if (agentCard) {\n this.agentCardValue = agentCard;\n }\n if (repo) {\n this.applyExternalMessageRepository(repo);\n }\n })\n .catch((error) => {\n invokeRuntimeCallback(\n \"onError\",\n this.onError,\n error instanceof Error ? error : new Error(String(error)),\n );\n })\n .finally(() => {\n this._isLoading = false;\n this.notifyUpdate();\n });\n\n this.notifyUpdate();\n return this._loadPromise;\n }\n\n async append(message: AppendMessage): Promise<void> {\n const startRun = message.startRun ?? message.role === \"user\";\n\n const threadMessage = fromThreadMessageLike(\n message as any,\n generateId(),\n FALLBACK_USER_STATUS,\n );\n const parentId =\n message.parentId === null\n ? null\n : message.parentId && this.hasMessage(message.parentId)\n ? message.parentId\n : this.repository.headId;\n this.addOrUpdateMessage(parentId, threadMessage);\n this.switchToBranch(threadMessage.id);\n this.notifyUpdate();\n this.recordHistoryEntry(parentId, threadMessage);\n\n if (!startRun) return;\n await this.startRun(threadMessage);\n }\n\n async edit(message: AppendMessage): Promise<void> {\n await this.append(message);\n }\n\n async reload(\n parentId: string | null,\n _config: { runConfig?: Record<string, unknown> } = {},\n ): Promise<void> {\n const messages =\n parentId === null\n ? []\n : (this.tryGetMessages(parentId) ?? this.getMessages());\n for (let i = messages.length - 1; i >= 0; i--) {\n if (messages[i]!.role === \"user\") {\n await this.startRun(messages[i]!);\n return;\n }\n }\n }\n\n async cancel(): Promise<void> {\n if (!this.abortController) return;\n\n // Abort locally first so the stream stops immediately\n this.abortController.abort();\n\n // Then try to cancel the task on the server\n if (this.currentTask?.id) {\n try {\n const updated = await this.client.cancelTask(this.currentTask.id);\n this.currentTask = updated;\n } catch {\n // Server cancel failed; local abort already handled\n }\n }\n }\n\n private appendLinearChain(messages: readonly ThreadMessage[]): string | null {\n let parentId: string | null = null;\n let lastId: string | null = null;\n const seen = new Set<string>();\n\n for (const message of messages) {\n if (seen.has(message.id)) continue;\n seen.add(message.id);\n this.addOrUpdateMessage(parentId, message);\n parentId = message.id;\n lastId = message.id;\n }\n\n return lastId;\n }\n\n private finalizeExternalApply(): void {\n this.assistantHistoryParents.clear();\n this.recordedHistoryIds.clear();\n for (const { message } of this.getMessageRepository().messages) {\n this.recordedHistoryIds.add(message.id);\n }\n this.currentTask = undefined;\n this.currentArtifacts = [];\n this.notifyUpdate();\n }\n\n applyExternalMessages(messages: readonly ThreadMessage[]): void {\n if (messages.length === 0) {\n this.clearRepository();\n } else {\n let expectedParentId: string | null = null;\n let lastAppliedId: string | null = null;\n let hardReplace = false;\n const seen = new Set<string>();\n\n for (const message of messages) {\n if (seen.has(message.id)) continue;\n seen.add(message.id);\n const existing = this.tryGetMessage(message.id);\n if (existing && existing.parentId !== expectedParentId) {\n hardReplace = true;\n break;\n }\n this.addOrUpdateMessage(expectedParentId, message);\n expectedParentId = message.id;\n lastAppliedId = message.id;\n }\n\n if (hardReplace) {\n this.clearRepository();\n lastAppliedId = this.appendLinearChain(messages);\n }\n\n this.resetRepositoryHead(lastAppliedId);\n }\n\n this.finalizeExternalApply();\n }\n\n private applyExternalMessageRepository(\n loaded: ExportedMessageRepository,\n ): void {\n const headId = loaded.headId ?? loaded.messages.at(-1)?.message.id ?? null;\n const ids = new Set<string>();\n let degenerate = false;\n for (const { message } of loaded.messages) {\n if (ids.has(message.id)) {\n degenerate = true;\n break;\n }\n ids.add(message.id);\n }\n if (headId !== null && !ids.has(headId)) degenerate = true;\n\n if (!degenerate) {\n this.clearRepository();\n let pending = [...loaded.messages];\n const importedIds = new Set<string>();\n\n while (pending.length > 0) {\n const unresolved: typeof pending = [];\n let progressed = false;\n for (const item of pending) {\n if (item.parentId !== null && !importedIds.has(item.parentId)) {\n unresolved.push(item);\n continue;\n }\n this.addOrUpdateMessage(item.parentId, item.message);\n importedIds.add(item.message.id);\n progressed = true;\n }\n if (!progressed) {\n degenerate = true;\n break;\n }\n pending = unresolved;\n }\n }\n\n if (degenerate) {\n this.clearRepository();\n let previousId: string | null = null;\n for (const { message } of loaded.messages) {\n const existing = this.tryGetMessage(message.id);\n this.addOrUpdateMessage(\n existing ? existing.parentId : previousId,\n message,\n );\n previousId = message.id;\n }\n this.resetRepositoryHead(previousId);\n } else {\n this.resetRepositoryHead(headId);\n }\n\n this.finalizeExternalApply();\n }\n\n // --- Run logic ---\n\n private async startRun(userThreadMessage: ThreadMessage): Promise<void> {\n // Cancel any in-progress run before starting a new one\n if (this.abortController) {\n this.abortController.abort();\n this.abortController = null;\n }\n\n const a2aMessage = this.threadMessageToA2AMessage(userThreadMessage);\n\n // Clear task if previous task reached terminal state\n if (\n this.currentTask &&\n isTerminalTaskState(this.currentTask.status.state)\n ) {\n this.currentTask = undefined;\n }\n\n this.currentArtifacts = [];\n\n const assistantParentId = userThreadMessage.id;\n const assistantId = this.insertAssistantPlaceholder(assistantParentId);\n this.markPendingAssistantHistory(assistantId, assistantParentId);\n\n const abortController = new AbortController();\n this.abortController = abortController;\n\n abortController.signal.addEventListener(\n \"abort\",\n () => {\n this.updateAssistantStatus(assistantId, {\n type: \"incomplete\",\n reason: \"cancelled\",\n });\n this.finishRun(abortController);\n invokeRuntimeCallback(\"onCancel\", this.onCancel);\n },\n { once: true },\n );\n\n this.setRunning(true);\n\n // Check if agent supports streaming; fall back to sync sendMessage if not\n const supportsStreaming =\n this.agentCardValue?.capabilities?.streaming !== false;\n\n try {\n if (supportsStreaming) {\n await this.runStreaming(a2aMessage, assistantId, abortController);\n } else {\n await this.runSync(a2aMessage, assistantId, abortController);\n }\n } catch (error) {\n if (!abortController.signal.aborted) {\n const err = error instanceof Error ? error : new Error(String(error));\n this.updateAssistantStatus(assistantId, {\n type: \"incomplete\",\n reason: \"error\",\n });\n invokeRuntimeCallback(\"onError\", this.onError, err);\n this.pendingError = this.pendingError ?? err;\n }\n } finally {\n this.finishRun(abortController);\n }\n\n if (this.pendingError) {\n const err = this.pendingError;\n this.pendingError = null;\n throw err;\n }\n }\n\n private async runStreaming(\n a2aMessage: A2AMessage,\n assistantId: string,\n abortController: AbortController,\n ): Promise<void> {\n const stream = this.client.streamMessage(\n a2aMessage,\n this.configuration,\n undefined, // metadata\n abortController.signal,\n );\n\n for await (const event of stream) {\n if (abortController.signal.aborted) break;\n this.handleStreamEvent(assistantId, event);\n }\n\n if (!abortController.signal.aborted) {\n const lastStatus = this.getAssistantStatus(assistantId);\n if (lastStatus?.type === \"running\") {\n this.updateAssistantStatus(assistantId, {\n type: \"complete\",\n reason: \"stop\",\n });\n }\n }\n }\n\n private async runSync(\n a2aMessage: A2AMessage,\n assistantId: string,\n abortController: AbortController,\n ): Promise<void> {\n const result = await this.client.sendMessage(\n a2aMessage,\n this.configuration,\n undefined, // metadata\n abortController.signal,\n );\n\n if (abortController.signal.aborted) return;\n\n // Result is either A2ATask or A2AMessage\n if (\"id\" in result && \"status\" in result) {\n // It's a Task\n this.handleTaskSnapshot(assistantId, result as A2ATask);\n } else if (\"messageId\" in result && \"parts\" in result) {\n // It's a Message\n this.handleMessage(assistantId, result as A2AMessage);\n this.updateAssistantStatus(assistantId, {\n type: \"complete\",\n reason: \"stop\",\n });\n }\n }\n\n private handleStreamEvent(assistantId: string, event: A2AStreamEvent) {\n switch (event.type) {\n case \"statusUpdate\":\n this.handleStatusUpdate(assistantId, event.event);\n break;\n case \"artifactUpdate\":\n this.handleArtifactUpdate(event.event);\n break;\n case \"message\":\n this.handleMessage(assistantId, event.message);\n break;\n case \"task\":\n this.handleTaskSnapshot(assistantId, event.task);\n break;\n }\n }\n\n private handleStatusUpdate(\n assistantId: string,\n event: A2ATaskStatusUpdateEvent,\n ) {\n if (!this.currentTask) {\n this.currentTask = {\n id: event.taskId,\n contextId: event.contextId,\n status: event.status,\n };\n } else {\n this.currentTask = { ...this.currentTask, status: event.status };\n }\n\n if (event.contextId) {\n this.contextId = event.contextId;\n }\n\n if (event.status.message) {\n const content = a2aMessageToContent(event.status.message);\n this.updateAssistantContent(assistantId, content);\n }\n\n const status = taskStateToMessageStatus(event.status.state);\n this.updateAssistantStatus(assistantId, status);\n\n this.notifyUpdate();\n }\n\n private handleArtifactUpdate(event: A2ATaskArtifactUpdateEvent) {\n const { artifact, append, lastChunk } = event;\n const existingIdx = this.currentArtifacts.findIndex(\n (a) => a.artifactId === artifact.artifactId,\n );\n\n let updated: A2AArtifact;\n if (existingIdx >= 0 && append) {\n const existing = this.currentArtifacts[existingIdx]!;\n updated = {\n ...existing,\n parts: [...existing.parts, ...artifact.parts],\n };\n this.currentArtifacts = [\n ...this.currentArtifacts.slice(0, existingIdx),\n updated,\n ...this.currentArtifacts.slice(existingIdx + 1),\n ];\n } else if (existingIdx >= 0) {\n updated = artifact;\n this.currentArtifacts = [\n ...this.currentArtifacts.slice(0, existingIdx),\n updated,\n ...this.currentArtifacts.slice(existingIdx + 1),\n ];\n } else {\n updated = artifact;\n this.currentArtifacts = [...this.currentArtifacts, updated];\n }\n\n if (lastChunk) {\n invokeRuntimeCallback(\n \"onArtifactComplete\",\n this.onArtifactComplete,\n updated,\n );\n }\n\n this.notifyUpdate();\n }\n\n private handleMessage(assistantId: string, message: A2AMessage) {\n if (message.role !== \"agent\") return;\n\n const content = a2aMessageToContent(message);\n this.updateAssistantContent(assistantId, content);\n this.notifyUpdate();\n }\n\n private handleTaskSnapshot(assistantId: string, task: A2ATask) {\n this.currentTask = task;\n\n if (task.contextId) {\n this.contextId = task.contextId;\n }\n if (task.artifacts) {\n this.currentArtifacts = task.artifacts;\n }\n\n if (task.status.message) {\n const content = a2aMessageToContent(task.status.message);\n this.updateAssistantContent(assistantId, content);\n }\n\n const status = taskStateToMessageStatus(task.status.state);\n this.updateAssistantStatus(assistantId, status);\n\n this.notifyUpdate();\n }\n\n // --- Message helpers ---\n\n private threadMessageToA2AMessage(message: ThreadMessage): A2AMessage {\n const parts: A2APart[] = [];\n\n if (message.role === \"user\") {\n parts.push(...contentPartsToA2AParts(message.content));\n for (const attachment of message.attachments ?? []) {\n parts.push(\n ...contentPartsToA2AParts(\n attachment.content ?? [],\n attachment.contentType,\n ),\n );\n }\n }\n\n const a2aMsg: A2AMessage = {\n messageId: message.id,\n role: \"user\",\n parts,\n };\n\n if (this.contextId) {\n a2aMsg.contextId = this.contextId;\n }\n // Only attach taskId if current task is NOT in terminal state\n if (\n this.currentTask?.id &&\n !isTerminalTaskState(this.currentTask.status.state)\n ) {\n a2aMsg.taskId = this.currentTask.id;\n }\n\n return a2aMsg;\n }\n\n private insertAssistantPlaceholder(parentId: string): string {\n const id = generateId();\n const assistant: ThreadAssistantMessage = {\n id,\n role: \"assistant\",\n createdAt: new Date(),\n status: { type: \"running\" },\n content: [],\n metadata: {\n unstable_state: null,\n unstable_annotations: [],\n unstable_data: [],\n steps: [],\n custom: {},\n },\n };\n this.addOrUpdateMessage(parentId, assistant);\n this.switchToBranch(id);\n this.notifyUpdate();\n return id;\n }\n\n private updateAssistantContent(\n messageId: string,\n content: ThreadAssistantMessage[\"content\"],\n ) {\n this.updateMessage(messageId, (message) => {\n if (message.role !== \"assistant\") return message;\n return { ...message, content };\n });\n }\n\n private updateAssistantStatus(messageId: string, status: MessageStatus) {\n const touched = this.updateMessage(messageId, (message) => {\n if (message.role !== \"assistant\") return message;\n return { ...message, status };\n });\n if (touched) {\n this.notifyUpdate();\n if (status.type === \"complete\" || status.type === \"incomplete\") {\n this.persistAssistantHistory(messageId);\n }\n }\n }\n\n private getAssistantStatus(messageId: string): MessageStatus | undefined {\n const msg = this.tryGetMessage(messageId)?.message;\n if (msg?.role !== \"assistant\") return undefined;\n return msg.status;\n }\n\n // --- Lifecycle helpers ---\n\n private setRunning(running: boolean) {\n this.isRunningFlag = running;\n this.notifyUpdate();\n }\n\n private finishRun(controller: AbortController | null) {\n if (this.abortController !== controller) return;\n this.abortController = null;\n this.setRunning(false);\n }\n\n // --- History persistence ---\n\n private recordHistoryEntry(parentId: string | null, message: ThreadMessage) {\n this.appendHistoryItem(parentId, message);\n }\n\n private markPendingAssistantHistory(\n messageId: string,\n parentId: string | null,\n ) {\n if (!this.history) return;\n this.assistantHistoryParents.set(messageId, parentId);\n }\n\n private persistAssistantHistory(messageId: string) {\n if (!this.history) return;\n const parentId = this.assistantHistoryParents.get(messageId);\n if (parentId === undefined) return;\n const message = this.tryGetMessage(messageId)?.message;\n if (!message || message.role !== \"assistant\") return;\n if (\n message.status?.type !== \"complete\" &&\n message.status?.type !== \"incomplete\"\n )\n return;\n this.assistantHistoryParents.delete(messageId);\n this.appendHistoryItem(parentId, message);\n }\n\n private appendHistoryItem(parentId: string | null, message: ThreadMessage) {\n if (!this.history || this.recordedHistoryIds.has(message.id)) return;\n this.recordedHistoryIds.add(message.id);\n void this.history.append({ parentId, message }).catch(() => {\n this.recordedHistoryIds.delete(message.id);\n });\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"A2AThreadRuntimeCore.js","names":[],"sources":["../src/A2AThreadRuntimeCore.ts"],"sourcesContent":["\"use client\";\n\nimport { generateId, fromThreadMessageLike } from \"@assistant-ui/core\";\nimport type {\n AppendMessage,\n AssistantRuntime,\n ExportedMessageRepository,\n MessageStatus,\n ThreadAssistantMessage,\n ThreadHistoryAdapter,\n ThreadMessage,\n} from \"@assistant-ui/core\";\nimport { MessageRepository } from \"@assistant-ui/core/internal\";\nimport type { A2AClient } from \"./A2AClient\";\nimport type {\n A2AArtifact,\n A2AAgentCard,\n A2AMessage,\n A2APart,\n A2ASendMessageConfiguration,\n A2AStreamEvent,\n A2ATask,\n A2ATaskArtifactUpdateEvent,\n A2ATaskStatusUpdateEvent,\n} from \"./types\";\nimport {\n a2aMessageToContent,\n contentPartsToA2AParts,\n isTerminalTaskState,\n taskStateToMessageStatus,\n} from \"./conversions\";\n\nexport type A2AThreadRuntimeCoreOptions = {\n client: A2AClient;\n contextId?: string | undefined;\n configuration?: A2ASendMessageConfiguration | undefined;\n onError?: ((error: Error) => void) | undefined;\n onCancel?: (() => void) | undefined;\n onArtifactComplete?: ((artifact: A2AArtifact) => void) | undefined;\n history?: ThreadHistoryAdapter | undefined;\n notifyUpdate: () => void;\n};\n\nconst FALLBACK_USER_STATUS = {\n type: \"complete\",\n reason: \"unknown\",\n} as const;\n\ntype A2ARuntimeCallbackName = \"onError\" | \"onCancel\" | \"onArtifactComplete\";\n\nconst reportCallbackError = (name: A2ARuntimeCallbackName, error: unknown) => {\n console.error(`[react-a2a] ${name} callback threw an error`, error);\n};\n\nconst invokeRuntimeCallback = <TArgs extends unknown[]>(\n name: A2ARuntimeCallbackName,\n callback: ((...args: TArgs) => void) | undefined,\n ...args: TArgs\n) => {\n if (!callback) return;\n\n try {\n const result = callback(...args) as unknown;\n if (\n result !== null &&\n (typeof result === \"object\" || typeof result === \"function\") &&\n \"then\" in result &&\n typeof result.then === \"function\"\n ) {\n void Promise.resolve(result).catch((error) => {\n reportCallbackError(name, error);\n });\n }\n } catch (error) {\n reportCallbackError(name, error);\n }\n};\n\nfunction normalizeArtifact(artifact: A2AArtifact): A2AArtifact {\n return {\n ...artifact,\n parts: Array.isArray(artifact.parts) ? artifact.parts : [],\n };\n}\n\nexport class A2AThreadRuntimeCore {\n private client: A2AClient;\n private contextId: string | undefined;\n private configuration: A2ASendMessageConfiguration | undefined;\n private onError: ((error: Error) => void) | undefined;\n private onCancel: (() => void) | undefined;\n private onArtifactComplete: ((artifact: A2AArtifact) => void) | undefined;\n private history: ThreadHistoryAdapter | undefined;\n private readonly notifyUpdate: () => void;\n\n private runtime: AssistantRuntime | undefined;\n private readonly repository = new MessageRepository();\n private exportedRepository: ExportedMessageRepository | undefined;\n private isRunningFlag = false;\n private abortController: AbortController | null = null;\n private pendingError: Error | null = null;\n\n // A2A-specific state\n private currentTask: A2ATask | undefined;\n private currentArtifacts: A2AArtifact[] = [];\n private agentCardValue: A2AAgentCard | undefined;\n\n // History tracking\n private readonly assistantHistoryParents = new Map<string, string | null>();\n private readonly recordedHistoryIds = new Set<string>();\n private _isLoading = false;\n private _loadPromise: Promise<void> | undefined;\n\n constructor(options: A2AThreadRuntimeCoreOptions) {\n this.client = options.client;\n this.contextId = options.contextId;\n this.configuration = options.configuration;\n this.onError = options.onError;\n this.onCancel = options.onCancel;\n this.onArtifactComplete = options.onArtifactComplete;\n this.history = options.history;\n this.notifyUpdate = options.notifyUpdate;\n }\n\n updateOptions(options: Omit<A2AThreadRuntimeCoreOptions, \"notifyUpdate\">) {\n this.client = options.client;\n this.contextId = options.contextId;\n this.configuration = options.configuration;\n this.onError = options.onError;\n this.onCancel = options.onCancel;\n this.onArtifactComplete = options.onArtifactComplete;\n this.history = options.history;\n }\n\n attachRuntime(runtime: AssistantRuntime) {\n this.runtime = runtime;\n }\n\n detachRuntime() {\n this.runtime = undefined;\n // Abort in-flight requests on unmount\n if (this.abortController) {\n this.abortController.abort();\n this.abortController = null;\n }\n }\n\n getRuntime(): AssistantRuntime | undefined {\n return this.runtime;\n }\n\n getMessages(): readonly ThreadMessage[] {\n return this.repository.getMessages();\n }\n\n getMessageRepository(): ExportedMessageRepository {\n this.exportedRepository ??= this.repository.export();\n return this.exportedRepository;\n }\n\n private tryGetMessage(messageId: string) {\n try {\n return this.repository.getMessage(messageId);\n } catch {\n return undefined;\n }\n }\n\n private tryGetMessages(\n messageId: string,\n ): readonly ThreadMessage[] | undefined {\n try {\n return this.repository.getMessages(messageId);\n } catch {\n return undefined;\n }\n }\n\n private hasMessage(messageId: string): boolean {\n return this.tryGetMessage(messageId) !== undefined;\n }\n\n private addOrUpdateMessage(\n parentId: string | null,\n message: ThreadMessage,\n ): void {\n this.repository.addOrUpdateMessage(parentId, message);\n this.exportedRepository = undefined;\n }\n\n private switchToBranch(messageId: string): void {\n this.repository.switchToBranch(messageId);\n this.exportedRepository = undefined;\n }\n\n private resetRepositoryHead(messageId: string | null): void {\n this.repository.resetHead(messageId);\n this.exportedRepository = undefined;\n }\n\n private clearRepository(): void {\n this.repository.clear();\n this.exportedRepository = undefined;\n }\n\n private updateMessage(\n messageId: string,\n updater: (message: ThreadMessage) => ThreadMessage,\n ): boolean {\n const item = this.tryGetMessage(messageId);\n if (!item) return false;\n const message = updater(item.message);\n if (message === item.message) return false;\n this.addOrUpdateMessage(item.parentId, message);\n return true;\n }\n\n getTask(): A2ATask | undefined {\n return this.currentTask;\n }\n\n getArtifacts(): readonly A2AArtifact[] {\n return this.currentArtifacts;\n }\n\n getAgentCard(): A2AAgentCard | undefined {\n return this.agentCardValue;\n }\n\n isRunning(): boolean {\n return this.isRunningFlag;\n }\n\n get isLoading(): boolean {\n return this._isLoading;\n }\n\n __internal_load(): Promise<void> {\n if (this._loadPromise) return this._loadPromise;\n\n this._isLoading = true;\n\n const historyPromise = this.history?.load() ?? Promise.resolve(null);\n const agentCardPromise = this.client.getAgentCard().catch(() => undefined);\n\n this._loadPromise = Promise.all([historyPromise, agentCardPromise])\n .then(([repo, agentCard]) => {\n if (agentCard) {\n this.agentCardValue = agentCard;\n }\n if (repo) {\n this.applyExternalMessageRepository(repo);\n }\n })\n .catch((error) => {\n invokeRuntimeCallback(\n \"onError\",\n this.onError,\n error instanceof Error ? error : new Error(String(error)),\n );\n })\n .finally(() => {\n this._isLoading = false;\n this.notifyUpdate();\n });\n\n this.notifyUpdate();\n return this._loadPromise;\n }\n\n async append(message: AppendMessage): Promise<void> {\n const startRun = message.startRun ?? message.role === \"user\";\n\n const threadMessage = fromThreadMessageLike(\n message as any,\n generateId(),\n FALLBACK_USER_STATUS,\n );\n const parentId =\n message.parentId === null\n ? null\n : message.parentId && this.hasMessage(message.parentId)\n ? message.parentId\n : this.repository.headId;\n this.addOrUpdateMessage(parentId, threadMessage);\n this.switchToBranch(threadMessage.id);\n this.notifyUpdate();\n this.recordHistoryEntry(parentId, threadMessage);\n\n if (!startRun) return;\n await this.startRun(threadMessage);\n }\n\n async edit(message: AppendMessage): Promise<void> {\n await this.append(message);\n }\n\n async reload(\n parentId: string | null,\n _config: { runConfig?: Record<string, unknown> } = {},\n ): Promise<void> {\n const messages =\n parentId === null\n ? []\n : (this.tryGetMessages(parentId) ?? this.getMessages());\n for (let i = messages.length - 1; i >= 0; i--) {\n if (messages[i]!.role === \"user\") {\n await this.startRun(messages[i]!);\n return;\n }\n }\n }\n\n async cancel(): Promise<void> {\n if (!this.abortController) return;\n\n // Abort locally first so the stream stops immediately\n this.abortController.abort();\n\n // Then try to cancel the task on the server\n if (this.currentTask?.id) {\n try {\n const updated = await this.client.cancelTask(this.currentTask.id);\n this.currentTask = updated;\n } catch {\n // Server cancel failed; local abort already handled\n }\n }\n }\n\n private appendLinearChain(messages: readonly ThreadMessage[]): string | null {\n let parentId: string | null = null;\n let lastId: string | null = null;\n const seen = new Set<string>();\n\n for (const message of messages) {\n if (seen.has(message.id)) continue;\n seen.add(message.id);\n this.addOrUpdateMessage(parentId, message);\n parentId = message.id;\n lastId = message.id;\n }\n\n return lastId;\n }\n\n private finalizeExternalApply(): void {\n this.assistantHistoryParents.clear();\n this.recordedHistoryIds.clear();\n for (const { message } of this.getMessageRepository().messages) {\n this.recordedHistoryIds.add(message.id);\n }\n this.currentTask = undefined;\n this.currentArtifacts = [];\n this.notifyUpdate();\n }\n\n applyExternalMessages(messages: readonly ThreadMessage[]): void {\n if (messages.length === 0) {\n this.clearRepository();\n } else {\n let expectedParentId: string | null = null;\n let lastAppliedId: string | null = null;\n let hardReplace = false;\n const seen = new Set<string>();\n\n for (const message of messages) {\n if (seen.has(message.id)) continue;\n seen.add(message.id);\n const existing = this.tryGetMessage(message.id);\n if (existing && existing.parentId !== expectedParentId) {\n hardReplace = true;\n break;\n }\n this.addOrUpdateMessage(expectedParentId, message);\n expectedParentId = message.id;\n lastAppliedId = message.id;\n }\n\n if (hardReplace) {\n this.clearRepository();\n lastAppliedId = this.appendLinearChain(messages);\n }\n\n this.resetRepositoryHead(lastAppliedId);\n }\n\n this.finalizeExternalApply();\n }\n\n private applyExternalMessageRepository(\n loaded: ExportedMessageRepository,\n ): void {\n const headId = loaded.headId ?? loaded.messages.at(-1)?.message.id ?? null;\n const ids = new Set<string>();\n let degenerate = false;\n for (const { message } of loaded.messages) {\n if (ids.has(message.id)) {\n degenerate = true;\n break;\n }\n ids.add(message.id);\n }\n if (headId !== null && !ids.has(headId)) degenerate = true;\n\n if (!degenerate) {\n this.clearRepository();\n let pending = [...loaded.messages];\n const importedIds = new Set<string>();\n\n while (pending.length > 0) {\n const unresolved: typeof pending = [];\n let progressed = false;\n for (const item of pending) {\n if (item.parentId !== null && !importedIds.has(item.parentId)) {\n unresolved.push(item);\n continue;\n }\n this.addOrUpdateMessage(item.parentId, item.message);\n importedIds.add(item.message.id);\n progressed = true;\n }\n if (!progressed) {\n degenerate = true;\n break;\n }\n pending = unresolved;\n }\n }\n\n if (degenerate) {\n this.clearRepository();\n let previousId: string | null = null;\n for (const { message } of loaded.messages) {\n const existing = this.tryGetMessage(message.id);\n this.addOrUpdateMessage(\n existing ? existing.parentId : previousId,\n message,\n );\n previousId = message.id;\n }\n this.resetRepositoryHead(previousId);\n } else {\n this.resetRepositoryHead(headId);\n }\n\n this.finalizeExternalApply();\n }\n\n // --- Run logic ---\n\n private async startRun(userThreadMessage: ThreadMessage): Promise<void> {\n // Cancel any in-progress run before starting a new one\n if (this.abortController) {\n this.abortController.abort();\n this.abortController = null;\n }\n\n const a2aMessage = this.threadMessageToA2AMessage(userThreadMessage);\n\n // Clear task if previous task reached terminal state\n if (\n this.currentTask &&\n isTerminalTaskState(this.currentTask.status.state)\n ) {\n this.currentTask = undefined;\n }\n\n this.currentArtifacts = [];\n\n const assistantParentId = userThreadMessage.id;\n const assistantId = this.insertAssistantPlaceholder(assistantParentId);\n this.markPendingAssistantHistory(assistantId, assistantParentId);\n\n const abortController = new AbortController();\n this.abortController = abortController;\n\n abortController.signal.addEventListener(\n \"abort\",\n () => {\n this.updateAssistantStatus(assistantId, {\n type: \"incomplete\",\n reason: \"cancelled\",\n });\n this.finishRun(abortController);\n invokeRuntimeCallback(\"onCancel\", this.onCancel);\n },\n { once: true },\n );\n\n this.setRunning(true);\n\n // Check if agent supports streaming; fall back to sync sendMessage if not\n const supportsStreaming =\n this.agentCardValue?.capabilities?.streaming !== false;\n\n try {\n if (supportsStreaming) {\n await this.runStreaming(a2aMessage, assistantId, abortController);\n } else {\n await this.runSync(a2aMessage, assistantId, abortController);\n }\n } catch (error) {\n if (!abortController.signal.aborted) {\n const err = error instanceof Error ? error : new Error(String(error));\n this.updateAssistantStatus(assistantId, {\n type: \"incomplete\",\n reason: \"error\",\n });\n invokeRuntimeCallback(\"onError\", this.onError, err);\n this.pendingError = this.pendingError ?? err;\n }\n } finally {\n this.finishRun(abortController);\n }\n\n if (this.pendingError) {\n const err = this.pendingError;\n this.pendingError = null;\n throw err;\n }\n }\n\n private async runStreaming(\n a2aMessage: A2AMessage,\n assistantId: string,\n abortController: AbortController,\n ): Promise<void> {\n const stream = this.client.streamMessage(\n a2aMessage,\n this.configuration,\n undefined, // metadata\n abortController.signal,\n );\n\n let receivedEvent = false;\n for await (const event of stream) {\n if (abortController.signal.aborted) break;\n receivedEvent = true;\n this.handleStreamEvent(assistantId, event);\n }\n\n if (!abortController.signal.aborted) {\n if (!receivedEvent) {\n throw new Error(\"A2A message stream ended without any events.\");\n }\n\n const lastStatus = this.getAssistantStatus(assistantId);\n if (lastStatus?.type === \"running\") {\n this.updateAssistantStatus(assistantId, {\n type: \"complete\",\n reason: \"stop\",\n });\n }\n }\n }\n\n private async runSync(\n a2aMessage: A2AMessage,\n assistantId: string,\n abortController: AbortController,\n ): Promise<void> {\n const result = await this.client.sendMessage(\n a2aMessage,\n this.configuration,\n undefined, // metadata\n abortController.signal,\n );\n\n if (abortController.signal.aborted) return;\n\n // Result is either A2ATask or A2AMessage\n if (\"id\" in result && \"status\" in result) {\n // It's a Task\n this.handleTaskSnapshot(assistantId, result as A2ATask);\n } else if (\"messageId\" in result && \"parts\" in result) {\n // It's a Message\n this.handleMessage(assistantId, result as A2AMessage);\n this.updateAssistantStatus(assistantId, {\n type: \"complete\",\n reason: \"stop\",\n });\n }\n }\n\n private handleStreamEvent(assistantId: string, event: A2AStreamEvent) {\n switch (event.type) {\n case \"statusUpdate\":\n this.handleStatusUpdate(assistantId, event.event);\n break;\n case \"artifactUpdate\":\n this.handleArtifactUpdate(event.event);\n break;\n case \"message\":\n this.handleMessage(assistantId, event.message);\n break;\n case \"task\":\n this.handleTaskSnapshot(assistantId, event.task);\n break;\n }\n }\n\n private handleStatusUpdate(\n assistantId: string,\n event: A2ATaskStatusUpdateEvent,\n ) {\n if (!this.currentTask) {\n this.currentTask = {\n id: event.taskId,\n contextId: event.contextId,\n status: event.status,\n };\n } else {\n this.currentTask = { ...this.currentTask, status: event.status };\n }\n\n if (event.contextId) {\n this.contextId = event.contextId;\n }\n\n if (event.status.message) {\n const content = a2aMessageToContent(event.status.message);\n this.updateAssistantContent(assistantId, content);\n }\n\n const status = taskStateToMessageStatus(event.status.state);\n this.updateAssistantStatus(assistantId, status);\n\n this.notifyUpdate();\n }\n\n private handleArtifactUpdate(event: A2ATaskArtifactUpdateEvent) {\n const { append, lastChunk } = event;\n const artifact = normalizeArtifact(event.artifact);\n const existingIdx = this.currentArtifacts.findIndex(\n (a) => a.artifactId === artifact.artifactId,\n );\n\n let updated: A2AArtifact;\n if (existingIdx >= 0 && append) {\n const existing = this.currentArtifacts[existingIdx]!;\n updated = {\n ...existing,\n parts: [...existing.parts, ...artifact.parts],\n };\n this.currentArtifacts = [\n ...this.currentArtifacts.slice(0, existingIdx),\n updated,\n ...this.currentArtifacts.slice(existingIdx + 1),\n ];\n } else if (existingIdx >= 0) {\n updated = artifact;\n this.currentArtifacts = [\n ...this.currentArtifacts.slice(0, existingIdx),\n updated,\n ...this.currentArtifacts.slice(existingIdx + 1),\n ];\n } else {\n updated = artifact;\n this.currentArtifacts = [...this.currentArtifacts, updated];\n }\n\n if (lastChunk) {\n invokeRuntimeCallback(\n \"onArtifactComplete\",\n this.onArtifactComplete,\n updated,\n );\n }\n\n this.notifyUpdate();\n }\n\n private handleMessage(assistantId: string, message: A2AMessage) {\n if (message.role !== \"agent\") return;\n\n const content = a2aMessageToContent(message);\n this.updateAssistantContent(assistantId, content);\n this.notifyUpdate();\n }\n\n private handleTaskSnapshot(assistantId: string, task: A2ATask) {\n const artifacts =\n task.artifacts === undefined\n ? undefined\n : Array.isArray(task.artifacts)\n ? task.artifacts.map(normalizeArtifact)\n : [];\n const history =\n task.history === undefined\n ? undefined\n : Array.isArray(task.history)\n ? task.history\n : [];\n this.currentTask = {\n ...task,\n ...(artifacts === undefined ? {} : { artifacts }),\n ...(history === undefined ? {} : { history }),\n };\n\n if (task.contextId) {\n this.contextId = task.contextId;\n }\n if (artifacts) {\n this.currentArtifacts = artifacts;\n }\n\n if (task.status.message) {\n const content = a2aMessageToContent(task.status.message);\n this.updateAssistantContent(assistantId, content);\n }\n\n const status = taskStateToMessageStatus(task.status.state);\n this.updateAssistantStatus(assistantId, status);\n\n this.notifyUpdate();\n }\n\n // --- Message helpers ---\n\n private threadMessageToA2AMessage(message: ThreadMessage): A2AMessage {\n const parts: A2APart[] = [];\n\n if (message.role === \"user\") {\n parts.push(...contentPartsToA2AParts(message.content));\n for (const attachment of message.attachments ?? []) {\n parts.push(\n ...contentPartsToA2AParts(\n attachment.content ?? [],\n attachment.contentType,\n ),\n );\n }\n }\n\n const a2aMsg: A2AMessage = {\n messageId: message.id,\n role: \"user\",\n parts,\n };\n\n if (this.contextId) {\n a2aMsg.contextId = this.contextId;\n }\n // Only attach taskId if current task is NOT in terminal state\n if (\n this.currentTask?.id &&\n !isTerminalTaskState(this.currentTask.status.state)\n ) {\n a2aMsg.taskId = this.currentTask.id;\n }\n\n return a2aMsg;\n }\n\n private insertAssistantPlaceholder(parentId: string): string {\n const id = generateId();\n const assistant: ThreadAssistantMessage = {\n id,\n role: \"assistant\",\n createdAt: new Date(),\n status: { type: \"running\" },\n content: [],\n metadata: {\n unstable_state: null,\n unstable_annotations: [],\n unstable_data: [],\n steps: [],\n custom: {},\n },\n };\n this.addOrUpdateMessage(parentId, assistant);\n this.switchToBranch(id);\n this.notifyUpdate();\n return id;\n }\n\n private updateAssistantContent(\n messageId: string,\n content: ThreadAssistantMessage[\"content\"],\n ) {\n this.updateMessage(messageId, (message) => {\n if (message.role !== \"assistant\") return message;\n return { ...message, content };\n });\n }\n\n private updateAssistantStatus(messageId: string, status: MessageStatus) {\n const touched = this.updateMessage(messageId, (message) => {\n if (message.role !== \"assistant\") return message;\n return { ...message, status };\n });\n if (touched) {\n this.notifyUpdate();\n if (status.type === \"complete\" || status.type === \"incomplete\") {\n this.persistAssistantHistory(messageId);\n }\n }\n }\n\n private getAssistantStatus(messageId: string): MessageStatus | undefined {\n const msg = this.tryGetMessage(messageId)?.message;\n if (msg?.role !== \"assistant\") return undefined;\n return msg.status;\n }\n\n // --- Lifecycle helpers ---\n\n private setRunning(running: boolean) {\n this.isRunningFlag = running;\n this.notifyUpdate();\n }\n\n private finishRun(controller: AbortController | null) {\n if (this.abortController !== controller) return;\n this.abortController = null;\n this.setRunning(false);\n }\n\n // --- History persistence ---\n\n private recordHistoryEntry(parentId: string | null, message: ThreadMessage) {\n this.appendHistoryItem(parentId, message);\n }\n\n private markPendingAssistantHistory(\n messageId: string,\n parentId: string | null,\n ) {\n if (!this.history) return;\n this.assistantHistoryParents.set(messageId, parentId);\n }\n\n private persistAssistantHistory(messageId: string) {\n if (!this.history) return;\n const parentId = this.assistantHistoryParents.get(messageId);\n if (parentId === undefined) return;\n const message = this.tryGetMessage(messageId)?.message;\n if (!message || message.role !== \"assistant\") return;\n if (\n message.status?.type !== \"complete\" &&\n message.status?.type !== \"incomplete\"\n )\n return;\n this.assistantHistoryParents.delete(messageId);\n this.appendHistoryItem(parentId, message);\n }\n\n private appendHistoryItem(parentId: string | null, message: ThreadMessage) {\n if (!this.history || this.recordedHistoryIds.has(message.id)) return;\n this.recordedHistoryIds.add(message.id);\n void this.history.append({ parentId, message }).catch(() => {\n this.recordedHistoryIds.delete(message.id);\n });\n }\n}\n"],"mappings":"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"}
|
package/dist/conversions.js
CHANGED
|
@@ -46,7 +46,7 @@ function a2aPartToContent(part) {
|
|
|
46
46
|
};
|
|
47
47
|
}
|
|
48
48
|
function a2aPartsToContent(parts) {
|
|
49
|
-
return parts.map(a2aPartToContent);
|
|
49
|
+
return (Array.isArray(parts) ? parts : []).map(a2aPartToContent);
|
|
50
50
|
}
|
|
51
51
|
const TERMINAL_STATES = /* @__PURE__ */ new Set([
|
|
52
52
|
"completed",
|
|
@@ -143,7 +143,7 @@ function contentPartsToA2AParts(content, fallbackMimeType) {
|
|
|
143
143
|
}).filter((p) => p !== null);
|
|
144
144
|
}
|
|
145
145
|
function a2aMessageToContent(message) {
|
|
146
|
-
return a2aPartsToContent(message
|
|
146
|
+
return a2aPartsToContent(message?.parts ?? []);
|
|
147
147
|
}
|
|
148
148
|
//#endregion
|
|
149
149
|
export { a2aMessageToContent, a2aPartToContent, a2aPartsToContent, contentPartsToA2AParts, isInterruptedTaskState, isTerminalTaskState, taskStateToMessageStatus };
|