@assistant-ui/react-a2a 0.2.20 → 0.2.21

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.js CHANGED
@@ -15,7 +15,7 @@ var A2AError = class extends Error {
15
15
  function toCamelCase(key) {
16
16
  return key.replace(/_([a-z])/g, (_, c) => c.toUpperCase());
17
17
  }
18
- const OPAQUE_FIELDS = new Set([
18
+ const OPAQUE_FIELDS = /* @__PURE__ */ new Set([
19
19
  "metadata",
20
20
  "data",
21
21
  "params",
@@ -1 +1 @@
1
- {"version":3,"file":"A2AClient.js","names":[],"sources":["../src/A2AClient.ts"],"sourcesContent":["import type {\n A2AAgentCard,\n A2AErrorInfo,\n A2AListTaskPushNotificationConfigsResponse,\n A2AListTasksRequest,\n A2AListTasksResponse,\n A2AMessage,\n A2ARole,\n A2ASendMessageConfiguration,\n A2AStreamEvent,\n A2ATask,\n A2ATaskPushNotificationConfig,\n A2ATaskState,\n} from \"./types\";\nimport { A2A_PROTOCOL_VERSION } from \"./types\";\n\nexport type A2AClientOptions = {\n baseUrl: string;\n /** Optional path prefix for all API endpoints (e.g. \"/v1\"). Does not affect agent card discovery. */\n basePath?: string | undefined;\n /** Optional tenant ID for multi-tenant servers. */\n tenant?: string | undefined;\n headers?:\n | Record<string, string>\n | (() => Record<string, string> | Promise<Record<string, string>>)\n | undefined;\n /** A2A extension URIs to negotiate. Sent as A2A-Extensions header. */\n extensions?: string[] | undefined;\n /** Extra fetch options applied to every request. */\n fetchOptions?:\n | Omit<RequestInit, \"headers\" | \"body\" | \"method\" | \"signal\">\n | undefined;\n};\n\nexport class A2AError extends Error {\n code: number;\n status: string;\n details: unknown[] | undefined;\n\n constructor(info: A2AErrorInfo) {\n super(info.message);\n this.name = \"A2AError\";\n this.code = info.code;\n this.status = info.status;\n this.details = info.details;\n }\n}\n\n// Incoming key normalization: snake_case → camelCase, plus ProtoJSON enum normalization.\nfunction toCamelCase(key: string): string {\n return key.replace(/_([a-z])/g, (_, c: string) => c.toUpperCase());\n}\n\n// Fields whose values are opaque user data (google.protobuf.Struct / Value).\n// Keys inside these objects must NOT be camelCased or have enum normalization applied.\nconst OPAQUE_FIELDS = new Set([\n \"metadata\",\n \"data\",\n \"params\",\n \"forwardedProps\",\n \"scopes\",\n]);\n\nfunction normalizeKeys(obj: unknown, opaque = false): unknown {\n if (Array.isArray(obj)) return obj.map((v) => normalizeKeys(v, opaque));\n if (obj !== null && typeof obj === \"object\") {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj as Record<string, unknown>)) {\n // Inside opaque fields: preserve keys and values as-is (only recurse arrays/objects structurally)\n if (opaque) {\n result[key] =\n typeof value === \"object\" && value !== null\n ? normalizeKeys(value, true)\n : value;\n continue;\n }\n\n const camelKey = toCamelCase(key);\n const isOpaqueChild = OPAQUE_FIELDS.has(camelKey);\n\n if (\n camelKey === \"state\" &&\n typeof value === \"string\" &&\n value.startsWith(\"TASK_STATE_\")\n ) {\n result[camelKey] = value.slice(11).toLowerCase();\n } else if (\n camelKey === \"role\" &&\n typeof value === \"string\" &&\n value.startsWith(\"ROLE_\")\n ) {\n result[camelKey] = value.slice(5).toLowerCase();\n } else if (camelKey === \"content\" && Array.isArray(value)) {\n // v0.3 servers used \"content\" for message/artifact parts; normalize to \"parts\" for backward compat\n result.parts = normalizeKeys(value, false);\n } else if (camelKey !== \"parts\" || !(\"parts\" in result)) {\n // dedup: \"content\" was already mapped to parts above; don't overwrite\n result[camelKey] = isOpaqueChild ? value : normalizeKeys(value, false);\n }\n }\n return result;\n }\n return obj;\n}\n\n// Outgoing enum conversion (v1.0 ProtoJSON format)\nfunction toWireRole(role: A2ARole): string {\n if (role === \"user\") return \"ROLE_USER\";\n if (role === \"agent\") return \"ROLE_AGENT\";\n return \"ROLE_UNSPECIFIED\";\n}\n\nfunction toWireTaskState(state: A2ATaskState): string {\n return `TASK_STATE_${state.toUpperCase()}`;\n}\n\nfunction toWireMessage(msg: A2AMessage): unknown {\n return { ...msg, role: toWireRole(msg.role) };\n}\n\nfunction discriminateStreamResponse(\n data: Record<string, unknown>,\n): A2AStreamEvent | null {\n if (\"task\" in data && data.task) {\n return { type: \"task\", task: data.task as A2ATask };\n }\n if (\"message\" in data && data.message) {\n return { type: \"message\", message: data.message as A2AMessage };\n }\n if (\"statusUpdate\" in data && data.statusUpdate) {\n return {\n type: \"statusUpdate\",\n event: data.statusUpdate as A2AStreamEvent extends {\n type: \"statusUpdate\";\n event: infer E;\n }\n ? E\n : never,\n };\n }\n if (\"artifactUpdate\" in data && data.artifactUpdate) {\n return {\n type: \"artifactUpdate\",\n event: data.artifactUpdate as A2AStreamEvent extends {\n type: \"artifactUpdate\";\n event: infer E;\n }\n ? E\n : never,\n };\n }\n return null;\n}\n\nfunction signalInit(signal?: AbortSignal): RequestInit {\n return signal ? { signal } : {};\n}\n\nexport class A2AClient {\n private baseUrl: string;\n private basePath: string;\n private tenant: string | undefined;\n private extensionUris: string[] | undefined;\n private fetchOptions: Omit<\n RequestInit,\n \"headers\" | \"body\" | \"method\" | \"signal\"\n >;\n private headersFn:\n | Record<string, string>\n | (() => Record<string, string> | Promise<Record<string, string>>);\n\n constructor(options: A2AClientOptions) {\n this.baseUrl = options.baseUrl.replace(/\\/$/, \"\");\n this.basePath = options.basePath\n ? `/${options.basePath.replace(/^\\/|\\/$/g, \"\")}`\n : \"\";\n this.tenant = options.tenant;\n this.extensionUris = options.extensions;\n const {\n headers: _h,\n body: _b,\n method: _m,\n signal: _s,\n ...safeFetchOptions\n } = (options.fetchOptions ?? {}) as RequestInit;\n this.fetchOptions = safeFetchOptions;\n this.headersFn = options.headers ?? {};\n }\n\n private getBasePath(): string {\n return `${this.basePath}${this.tenant ? `/${encodeURIComponent(this.tenant)}` : \"\"}`;\n }\n\n private async getHeaders(\n includeContentType = true,\n ): Promise<Record<string, string>> {\n const custom =\n typeof this.headersFn === \"function\"\n ? await this.headersFn()\n : this.headersFn;\n const headers: Record<string, string> = {\n Accept: \"application/a2a+json, application/json\",\n \"A2A-Version\": A2A_PROTOCOL_VERSION,\n ...custom,\n };\n if (includeContentType) {\n headers[\"Content-Type\"] = \"application/a2a+json\";\n }\n if (this.extensionUris?.length) {\n headers[\"A2A-Extensions\"] = this.extensionUris.join(\", \");\n }\n return headers;\n }\n\n private async throwResponseError(response: Response): Promise<never> {\n let errorBody: unknown;\n try {\n errorBody = await response.json();\n } catch {\n // no parseable body\n }\n\n if (errorBody && typeof errorBody === \"object\" && \"error\" in errorBody) {\n const err = (errorBody as Record<string, any>).error;\n throw new A2AError({\n code: err.code ?? response.status,\n status: err.status ?? response.statusText,\n message: err.message ?? `A2A request failed: ${response.status}`,\n details: err.details,\n });\n }\n\n throw new A2AError({\n code: response.status,\n status: response.statusText,\n message: `A2A request failed: ${response.status} ${response.statusText}`,\n });\n }\n\n private async fetchJSON<T>(\n path: string,\n options: RequestInit = {},\n ): Promise<T> {\n const isGet = !options.method || options.method.toUpperCase() === \"GET\";\n const headers = await this.getHeaders(!isGet);\n const response = await fetch(`${this.baseUrl}${path}`, {\n ...this.fetchOptions,\n ...options,\n headers: {\n ...headers,\n ...(options.headers as Record<string, string>),\n },\n });\n if (!response.ok) {\n await this.throwResponseError(response);\n }\n const json = await response.json();\n return normalizeKeys(json) as T;\n }\n\n // --- Agent Card ---\n\n async getAgentCard(signal?: AbortSignal): Promise<A2AAgentCard> {\n const headers = await this.getHeaders(false); // GET: no Content-Type\n const url = `${this.baseUrl}/.well-known/agent-card.json`;\n const response = await fetch(url, {\n ...this.fetchOptions,\n headers,\n ...signalInit(signal),\n });\n if (!response.ok) {\n await this.throwResponseError(response);\n }\n const json = await response.json();\n return normalizeKeys(json) as A2AAgentCard;\n }\n\n async getExtendedAgentCard(signal?: AbortSignal): Promise<A2AAgentCard> {\n return this.fetchJSON<A2AAgentCard>(\n `${this.getBasePath()}/extendedAgentCard`,\n signalInit(signal),\n );\n }\n\n // --- Message ---\n\n async sendMessage(\n message: A2AMessage,\n configuration?: A2ASendMessageConfiguration,\n metadata?: Record<string, unknown>,\n signal?: AbortSignal,\n ): Promise<A2ATask | A2AMessage> {\n const body: Record<string, unknown> = {\n message: toWireMessage(message),\n };\n if (configuration) body.configuration = configuration;\n if (metadata) body.metadata = metadata;\n\n const result = await this.fetchJSON<Record<string, unknown>>(\n `${this.getBasePath()}/message:send`,\n {\n method: \"POST\",\n body: JSON.stringify(body),\n ...signalInit(signal),\n },\n );\n\n // Unwrap SendMessageResponse: {task: Task} | {message: Message}\n if (\"task\" in result && result.task) return result.task as A2ATask;\n if (\"message\" in result && result.message)\n return result.message as A2AMessage;\n return result as unknown as A2ATask | A2AMessage;\n }\n\n async *streamMessage(\n message: A2AMessage,\n configuration?: A2ASendMessageConfiguration,\n metadata?: Record<string, unknown>,\n signal?: AbortSignal,\n ): AsyncGenerator<A2AStreamEvent> {\n const headers = await this.getHeaders(true);\n headers.Accept = \"text/event-stream\";\n\n const body: Record<string, unknown> = {\n message: toWireMessage(message),\n };\n if (configuration) body.configuration = configuration;\n if (metadata) body.metadata = metadata;\n\n const response = await fetch(\n `${this.baseUrl}${this.getBasePath()}/message:stream`,\n {\n ...this.fetchOptions,\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n ...signalInit(signal),\n },\n );\n if (!response.ok) {\n await this.throwResponseError(response);\n }\n\n yield* this.parseSSE(response);\n }\n\n // --- Tasks ---\n\n async getTask(\n taskId: string,\n historyLength?: number,\n signal?: AbortSignal,\n ): Promise<A2ATask> {\n const params = new URLSearchParams();\n if (historyLength !== undefined) {\n // Proto field name for HTTP transcoding query params\n params.set(\"history_length\", String(historyLength));\n }\n const qs = params.toString();\n return this.fetchJSON<A2ATask>(\n `${this.getBasePath()}/tasks/${encodeURIComponent(taskId)}${qs ? `?${qs}` : \"\"}`,\n signalInit(signal),\n );\n }\n\n async listTasks(\n request?: A2AListTasksRequest,\n signal?: AbortSignal,\n ): Promise<A2AListTasksResponse> {\n const params = new URLSearchParams();\n if (request?.contextId) params.set(\"context_id\", request.contextId);\n if (request?.status) params.set(\"status\", toWireTaskState(request.status));\n if (request?.pageSize !== undefined)\n params.set(\"page_size\", String(request.pageSize));\n if (request?.pageToken) params.set(\"page_token\", request.pageToken);\n if (request?.historyLength !== undefined)\n params.set(\"history_length\", String(request.historyLength));\n if (request?.statusTimestampAfter)\n params.set(\"status_timestamp_after\", request.statusTimestampAfter);\n if (request?.includeArtifacts !== undefined)\n params.set(\"include_artifacts\", String(request.includeArtifacts));\n const qs = params.toString();\n return this.fetchJSON<A2AListTasksResponse>(\n `${this.getBasePath()}/tasks${qs ? `?${qs}` : \"\"}`,\n signalInit(signal),\n );\n }\n\n async cancelTask(\n taskId: string,\n metadata?: Record<string, unknown>,\n signal?: AbortSignal,\n ): Promise<A2ATask> {\n const body = metadata ? { metadata } : {};\n return this.fetchJSON<A2ATask>(\n `${this.getBasePath()}/tasks/${encodeURIComponent(taskId)}:cancel`,\n {\n method: \"POST\",\n body: JSON.stringify(body),\n ...signalInit(signal),\n },\n );\n }\n\n async *subscribeToTask(\n taskId: string,\n signal?: AbortSignal,\n ): AsyncGenerator<A2AStreamEvent> {\n const headers = await this.getHeaders(false); // GET: no Content-Type\n headers.Accept = \"text/event-stream\";\n\n const response = await fetch(\n `${this.baseUrl}${this.getBasePath()}/tasks/${encodeURIComponent(taskId)}:subscribe`,\n {\n ...this.fetchOptions,\n headers,\n ...signalInit(signal),\n },\n );\n if (!response.ok) {\n await this.throwResponseError(response);\n }\n\n yield* this.parseSSE(response);\n }\n\n // --- Push Notification Configs ---\n\n async createTaskPushNotificationConfig(\n config: A2ATaskPushNotificationConfig,\n signal?: AbortSignal,\n ): Promise<A2ATaskPushNotificationConfig> {\n const taskId = config.taskId;\n if (!taskId) throw new Error(\"taskId is required\");\n return this.fetchJSON<A2ATaskPushNotificationConfig>(\n `${this.getBasePath()}/tasks/${encodeURIComponent(taskId)}/pushNotificationConfigs`,\n {\n method: \"POST\",\n body: JSON.stringify(config),\n ...signalInit(signal),\n },\n );\n }\n\n async getTaskPushNotificationConfig(\n taskId: string,\n configId: string,\n signal?: AbortSignal,\n ): Promise<A2ATaskPushNotificationConfig> {\n return this.fetchJSON<A2ATaskPushNotificationConfig>(\n `${this.getBasePath()}/tasks/${encodeURIComponent(taskId)}/pushNotificationConfigs/${encodeURIComponent(configId)}`,\n signalInit(signal),\n );\n }\n\n async listTaskPushNotificationConfigs(\n taskId: string,\n options?: { pageSize?: number; pageToken?: string },\n signal?: AbortSignal,\n ): Promise<A2AListTaskPushNotificationConfigsResponse> {\n const params = new URLSearchParams();\n if (options?.pageSize !== undefined)\n params.set(\"page_size\", String(options.pageSize));\n if (options?.pageToken) params.set(\"page_token\", options.pageToken);\n const qs = params.toString();\n return this.fetchJSON<A2AListTaskPushNotificationConfigsResponse>(\n `${this.getBasePath()}/tasks/${encodeURIComponent(taskId)}/pushNotificationConfigs${qs ? `?${qs}` : \"\"}`,\n signalInit(signal),\n );\n }\n\n async deleteTaskPushNotificationConfig(\n taskId: string,\n configId: string,\n signal?: AbortSignal,\n ): Promise<void> {\n const isGet = false;\n const headers = await this.getHeaders(!isGet);\n const response = await fetch(\n `${this.baseUrl}${this.getBasePath()}/tasks/${encodeURIComponent(taskId)}/pushNotificationConfigs/${encodeURIComponent(configId)}`,\n {\n ...this.fetchOptions,\n method: \"DELETE\",\n headers,\n ...signalInit(signal),\n },\n );\n if (!response.ok) {\n await this.throwResponseError(response);\n }\n }\n\n // --- SSE Parsing ---\n\n private async *parseSSE(response: Response): AsyncGenerator<A2AStreamEvent> {\n const reader = response.body?.getReader();\n if (!reader) throw new Error(\"No response body\");\n\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n\n let eventEnd: number = buffer.indexOf(\"\\n\\n\");\n while (eventEnd !== -1) {\n const eventText = buffer.slice(0, eventEnd);\n buffer = buffer.slice(eventEnd + 2);\n\n const dataLines: string[] = [];\n\n for (const line of eventText.split(\"\\n\")) {\n const trimmed = line.replace(/\\r$/, \"\");\n if (trimmed.startsWith(\"data:\")) {\n dataLines.push(trimmed.slice(5).trim());\n }\n // event:, id:, retry: lines are parsed but not used —\n // we discriminate event type from the JSON payload.\n }\n\n if (dataLines.length === 0) continue;\n\n try {\n let parsed = JSON.parse(dataLines.join(\"\\n\"));\n\n // Unwrap JSON-RPC envelope if present\n if (\n parsed &&\n typeof parsed === \"object\" &&\n \"jsonrpc\" in parsed &&\n \"result\" in parsed\n ) {\n parsed = parsed.result;\n }\n\n const normalized = normalizeKeys(parsed) as Record<string, unknown>;\n const event = discriminateStreamResponse(normalized);\n if (event) yield event;\n } catch {\n // Skip malformed events\n }\n eventEnd = buffer.indexOf(\"\\n\\n\");\n }\n }\n } finally {\n reader.releaseLock();\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"A2AClient.js","names":[],"sources":["../src/A2AClient.ts"],"sourcesContent":["import type {\n A2AAgentCard,\n A2AErrorInfo,\n A2AListTaskPushNotificationConfigsResponse,\n A2AListTasksRequest,\n A2AListTasksResponse,\n A2AMessage,\n A2ARole,\n A2ASendMessageConfiguration,\n A2AStreamEvent,\n A2ATask,\n A2ATaskPushNotificationConfig,\n A2ATaskState,\n} from \"./types\";\nimport { A2A_PROTOCOL_VERSION } from \"./types\";\n\nexport type A2AClientOptions = {\n baseUrl: string;\n /** Optional path prefix for all API endpoints (e.g. \"/v1\"). Does not affect agent card discovery. */\n basePath?: string | undefined;\n /** Optional tenant ID for multi-tenant servers. */\n tenant?: string | undefined;\n headers?:\n | Record<string, string>\n | (() => Record<string, string> | Promise<Record<string, string>>)\n | undefined;\n /** A2A extension URIs to negotiate. Sent as A2A-Extensions header. */\n extensions?: string[] | undefined;\n /** Extra fetch options applied to every request. */\n fetchOptions?:\n | Omit<RequestInit, \"headers\" | \"body\" | \"method\" | \"signal\">\n | undefined;\n};\n\nexport class A2AError extends Error {\n code: number;\n status: string;\n details: unknown[] | undefined;\n\n constructor(info: A2AErrorInfo) {\n super(info.message);\n this.name = \"A2AError\";\n this.code = info.code;\n this.status = info.status;\n this.details = info.details;\n }\n}\n\n// Incoming key normalization: snake_case → camelCase, plus ProtoJSON enum normalization.\nfunction toCamelCase(key: string): string {\n return key.replace(/_([a-z])/g, (_, c: string) => c.toUpperCase());\n}\n\n// Fields whose values are opaque user data (google.protobuf.Struct / Value).\n// Keys inside these objects must NOT be camelCased or have enum normalization applied.\nconst OPAQUE_FIELDS = new Set([\n \"metadata\",\n \"data\",\n \"params\",\n \"forwardedProps\",\n \"scopes\",\n]);\n\nfunction normalizeKeys(obj: unknown, opaque = false): unknown {\n if (Array.isArray(obj)) return obj.map((v) => normalizeKeys(v, opaque));\n if (obj !== null && typeof obj === \"object\") {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj as Record<string, unknown>)) {\n // Inside opaque fields: preserve keys and values as-is (only recurse arrays/objects structurally)\n if (opaque) {\n result[key] =\n typeof value === \"object\" && value !== null\n ? normalizeKeys(value, true)\n : value;\n continue;\n }\n\n const camelKey = toCamelCase(key);\n const isOpaqueChild = OPAQUE_FIELDS.has(camelKey);\n\n if (\n camelKey === \"state\" &&\n typeof value === \"string\" &&\n value.startsWith(\"TASK_STATE_\")\n ) {\n result[camelKey] = value.slice(11).toLowerCase();\n } else if (\n camelKey === \"role\" &&\n typeof value === \"string\" &&\n value.startsWith(\"ROLE_\")\n ) {\n result[camelKey] = value.slice(5).toLowerCase();\n } else if (camelKey === \"content\" && Array.isArray(value)) {\n // v0.3 servers used \"content\" for message/artifact parts; normalize to \"parts\" for backward compat\n result.parts = normalizeKeys(value, false);\n } else if (camelKey !== \"parts\" || !(\"parts\" in result)) {\n // dedup: \"content\" was already mapped to parts above; don't overwrite\n result[camelKey] = isOpaqueChild ? value : normalizeKeys(value, false);\n }\n }\n return result;\n }\n return obj;\n}\n\n// Outgoing enum conversion (v1.0 ProtoJSON format)\nfunction toWireRole(role: A2ARole): string {\n if (role === \"user\") return \"ROLE_USER\";\n if (role === \"agent\") return \"ROLE_AGENT\";\n return \"ROLE_UNSPECIFIED\";\n}\n\nfunction toWireTaskState(state: A2ATaskState): string {\n return `TASK_STATE_${state.toUpperCase()}`;\n}\n\nfunction toWireMessage(msg: A2AMessage): unknown {\n return { ...msg, role: toWireRole(msg.role) };\n}\n\nfunction discriminateStreamResponse(\n data: Record<string, unknown>,\n): A2AStreamEvent | null {\n if (\"task\" in data && data.task) {\n return { type: \"task\", task: data.task as A2ATask };\n }\n if (\"message\" in data && data.message) {\n return { type: \"message\", message: data.message as A2AMessage };\n }\n if (\"statusUpdate\" in data && data.statusUpdate) {\n return {\n type: \"statusUpdate\",\n event: data.statusUpdate as A2AStreamEvent extends {\n type: \"statusUpdate\";\n event: infer E;\n }\n ? E\n : never,\n };\n }\n if (\"artifactUpdate\" in data && data.artifactUpdate) {\n return {\n type: \"artifactUpdate\",\n event: data.artifactUpdate as A2AStreamEvent extends {\n type: \"artifactUpdate\";\n event: infer E;\n }\n ? E\n : never,\n };\n }\n return null;\n}\n\nfunction signalInit(signal?: AbortSignal): RequestInit {\n return signal ? { signal } : {};\n}\n\nexport class A2AClient {\n private baseUrl: string;\n private basePath: string;\n private tenant: string | undefined;\n private extensionUris: string[] | undefined;\n private fetchOptions: Omit<\n RequestInit,\n \"headers\" | \"body\" | \"method\" | \"signal\"\n >;\n private headersFn:\n | Record<string, string>\n | (() => Record<string, string> | Promise<Record<string, string>>);\n\n constructor(options: A2AClientOptions) {\n this.baseUrl = options.baseUrl.replace(/\\/$/, \"\");\n this.basePath = options.basePath\n ? `/${options.basePath.replace(/^\\/|\\/$/g, \"\")}`\n : \"\";\n this.tenant = options.tenant;\n this.extensionUris = options.extensions;\n const {\n headers: _h,\n body: _b,\n method: _m,\n signal: _s,\n ...safeFetchOptions\n } = (options.fetchOptions ?? {}) as RequestInit;\n this.fetchOptions = safeFetchOptions;\n this.headersFn = options.headers ?? {};\n }\n\n private getBasePath(): string {\n return `${this.basePath}${this.tenant ? `/${encodeURIComponent(this.tenant)}` : \"\"}`;\n }\n\n private async getHeaders(\n includeContentType = true,\n ): Promise<Record<string, string>> {\n const custom =\n typeof this.headersFn === \"function\"\n ? await this.headersFn()\n : this.headersFn;\n const headers: Record<string, string> = {\n Accept: \"application/a2a+json, application/json\",\n \"A2A-Version\": A2A_PROTOCOL_VERSION,\n ...custom,\n };\n if (includeContentType) {\n headers[\"Content-Type\"] = \"application/a2a+json\";\n }\n if (this.extensionUris?.length) {\n headers[\"A2A-Extensions\"] = this.extensionUris.join(\", \");\n }\n return headers;\n }\n\n private async throwResponseError(response: Response): Promise<never> {\n let errorBody: unknown;\n try {\n errorBody = await response.json();\n } catch {\n // no parseable body\n }\n\n if (errorBody && typeof errorBody === \"object\" && \"error\" in errorBody) {\n const err = (errorBody as Record<string, any>).error;\n throw new A2AError({\n code: err.code ?? response.status,\n status: err.status ?? response.statusText,\n message: err.message ?? `A2A request failed: ${response.status}`,\n details: err.details,\n });\n }\n\n throw new A2AError({\n code: response.status,\n status: response.statusText,\n message: `A2A request failed: ${response.status} ${response.statusText}`,\n });\n }\n\n private async fetchJSON<T>(\n path: string,\n options: RequestInit = {},\n ): Promise<T> {\n const isGet = !options.method || options.method.toUpperCase() === \"GET\";\n const headers = await this.getHeaders(!isGet);\n const response = await fetch(`${this.baseUrl}${path}`, {\n ...this.fetchOptions,\n ...options,\n headers: {\n ...headers,\n ...(options.headers as Record<string, string>),\n },\n });\n if (!response.ok) {\n await this.throwResponseError(response);\n }\n const json = await response.json();\n return normalizeKeys(json) as T;\n }\n\n // --- Agent Card ---\n\n async getAgentCard(signal?: AbortSignal): Promise<A2AAgentCard> {\n const headers = await this.getHeaders(false); // GET: no Content-Type\n const url = `${this.baseUrl}/.well-known/agent-card.json`;\n const response = await fetch(url, {\n ...this.fetchOptions,\n headers,\n ...signalInit(signal),\n });\n if (!response.ok) {\n await this.throwResponseError(response);\n }\n const json = await response.json();\n return normalizeKeys(json) as A2AAgentCard;\n }\n\n async getExtendedAgentCard(signal?: AbortSignal): Promise<A2AAgentCard> {\n return this.fetchJSON<A2AAgentCard>(\n `${this.getBasePath()}/extendedAgentCard`,\n signalInit(signal),\n );\n }\n\n // --- Message ---\n\n async sendMessage(\n message: A2AMessage,\n configuration?: A2ASendMessageConfiguration,\n metadata?: Record<string, unknown>,\n signal?: AbortSignal,\n ): Promise<A2ATask | A2AMessage> {\n const body: Record<string, unknown> = {\n message: toWireMessage(message),\n };\n if (configuration) body.configuration = configuration;\n if (metadata) body.metadata = metadata;\n\n const result = await this.fetchJSON<Record<string, unknown>>(\n `${this.getBasePath()}/message:send`,\n {\n method: \"POST\",\n body: JSON.stringify(body),\n ...signalInit(signal),\n },\n );\n\n // Unwrap SendMessageResponse: {task: Task} | {message: Message}\n if (\"task\" in result && result.task) return result.task as A2ATask;\n if (\"message\" in result && result.message)\n return result.message as A2AMessage;\n return result as unknown as A2ATask | A2AMessage;\n }\n\n async *streamMessage(\n message: A2AMessage,\n configuration?: A2ASendMessageConfiguration,\n metadata?: Record<string, unknown>,\n signal?: AbortSignal,\n ): AsyncGenerator<A2AStreamEvent> {\n const headers = await this.getHeaders(true);\n headers.Accept = \"text/event-stream\";\n\n const body: Record<string, unknown> = {\n message: toWireMessage(message),\n };\n if (configuration) body.configuration = configuration;\n if (metadata) body.metadata = metadata;\n\n const response = await fetch(\n `${this.baseUrl}${this.getBasePath()}/message:stream`,\n {\n ...this.fetchOptions,\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n ...signalInit(signal),\n },\n );\n if (!response.ok) {\n await this.throwResponseError(response);\n }\n\n yield* this.parseSSE(response);\n }\n\n // --- Tasks ---\n\n async getTask(\n taskId: string,\n historyLength?: number,\n signal?: AbortSignal,\n ): Promise<A2ATask> {\n const params = new URLSearchParams();\n if (historyLength !== undefined) {\n // Proto field name for HTTP transcoding query params\n params.set(\"history_length\", String(historyLength));\n }\n const qs = params.toString();\n return this.fetchJSON<A2ATask>(\n `${this.getBasePath()}/tasks/${encodeURIComponent(taskId)}${qs ? `?${qs}` : \"\"}`,\n signalInit(signal),\n );\n }\n\n async listTasks(\n request?: A2AListTasksRequest,\n signal?: AbortSignal,\n ): Promise<A2AListTasksResponse> {\n const params = new URLSearchParams();\n if (request?.contextId) params.set(\"context_id\", request.contextId);\n if (request?.status) params.set(\"status\", toWireTaskState(request.status));\n if (request?.pageSize !== undefined)\n params.set(\"page_size\", String(request.pageSize));\n if (request?.pageToken) params.set(\"page_token\", request.pageToken);\n if (request?.historyLength !== undefined)\n params.set(\"history_length\", String(request.historyLength));\n if (request?.statusTimestampAfter)\n params.set(\"status_timestamp_after\", request.statusTimestampAfter);\n if (request?.includeArtifacts !== undefined)\n params.set(\"include_artifacts\", String(request.includeArtifacts));\n const qs = params.toString();\n return this.fetchJSON<A2AListTasksResponse>(\n `${this.getBasePath()}/tasks${qs ? `?${qs}` : \"\"}`,\n signalInit(signal),\n );\n }\n\n async cancelTask(\n taskId: string,\n metadata?: Record<string, unknown>,\n signal?: AbortSignal,\n ): Promise<A2ATask> {\n const body = metadata ? { metadata } : {};\n return this.fetchJSON<A2ATask>(\n `${this.getBasePath()}/tasks/${encodeURIComponent(taskId)}:cancel`,\n {\n method: \"POST\",\n body: JSON.stringify(body),\n ...signalInit(signal),\n },\n );\n }\n\n async *subscribeToTask(\n taskId: string,\n signal?: AbortSignal,\n ): AsyncGenerator<A2AStreamEvent> {\n const headers = await this.getHeaders(false); // GET: no Content-Type\n headers.Accept = \"text/event-stream\";\n\n const response = await fetch(\n `${this.baseUrl}${this.getBasePath()}/tasks/${encodeURIComponent(taskId)}:subscribe`,\n {\n ...this.fetchOptions,\n headers,\n ...signalInit(signal),\n },\n );\n if (!response.ok) {\n await this.throwResponseError(response);\n }\n\n yield* this.parseSSE(response);\n }\n\n // --- Push Notification Configs ---\n\n async createTaskPushNotificationConfig(\n config: A2ATaskPushNotificationConfig,\n signal?: AbortSignal,\n ): Promise<A2ATaskPushNotificationConfig> {\n const taskId = config.taskId;\n if (!taskId) throw new Error(\"taskId is required\");\n return this.fetchJSON<A2ATaskPushNotificationConfig>(\n `${this.getBasePath()}/tasks/${encodeURIComponent(taskId)}/pushNotificationConfigs`,\n {\n method: \"POST\",\n body: JSON.stringify(config),\n ...signalInit(signal),\n },\n );\n }\n\n async getTaskPushNotificationConfig(\n taskId: string,\n configId: string,\n signal?: AbortSignal,\n ): Promise<A2ATaskPushNotificationConfig> {\n return this.fetchJSON<A2ATaskPushNotificationConfig>(\n `${this.getBasePath()}/tasks/${encodeURIComponent(taskId)}/pushNotificationConfigs/${encodeURIComponent(configId)}`,\n signalInit(signal),\n );\n }\n\n async listTaskPushNotificationConfigs(\n taskId: string,\n options?: { pageSize?: number; pageToken?: string },\n signal?: AbortSignal,\n ): Promise<A2AListTaskPushNotificationConfigsResponse> {\n const params = new URLSearchParams();\n if (options?.pageSize !== undefined)\n params.set(\"page_size\", String(options.pageSize));\n if (options?.pageToken) params.set(\"page_token\", options.pageToken);\n const qs = params.toString();\n return this.fetchJSON<A2AListTaskPushNotificationConfigsResponse>(\n `${this.getBasePath()}/tasks/${encodeURIComponent(taskId)}/pushNotificationConfigs${qs ? `?${qs}` : \"\"}`,\n signalInit(signal),\n );\n }\n\n async deleteTaskPushNotificationConfig(\n taskId: string,\n configId: string,\n signal?: AbortSignal,\n ): Promise<void> {\n const isGet = false;\n const headers = await this.getHeaders(!isGet);\n const response = await fetch(\n `${this.baseUrl}${this.getBasePath()}/tasks/${encodeURIComponent(taskId)}/pushNotificationConfigs/${encodeURIComponent(configId)}`,\n {\n ...this.fetchOptions,\n method: \"DELETE\",\n headers,\n ...signalInit(signal),\n },\n );\n if (!response.ok) {\n await this.throwResponseError(response);\n }\n }\n\n // --- SSE Parsing ---\n\n private async *parseSSE(response: Response): AsyncGenerator<A2AStreamEvent> {\n const reader = response.body?.getReader();\n if (!reader) throw new Error(\"No response body\");\n\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n\n let eventEnd: number = buffer.indexOf(\"\\n\\n\");\n while (eventEnd !== -1) {\n const eventText = buffer.slice(0, eventEnd);\n buffer = buffer.slice(eventEnd + 2);\n\n const dataLines: string[] = [];\n\n for (const line of eventText.split(\"\\n\")) {\n const trimmed = line.replace(/\\r$/, \"\");\n if (trimmed.startsWith(\"data:\")) {\n dataLines.push(trimmed.slice(5).trim());\n }\n // event:, id:, retry: lines are parsed but not used —\n // we discriminate event type from the JSON payload.\n }\n\n if (dataLines.length === 0) continue;\n\n try {\n let parsed = JSON.parse(dataLines.join(\"\\n\"));\n\n // Unwrap JSON-RPC envelope if present\n if (\n parsed &&\n typeof parsed === \"object\" &&\n \"jsonrpc\" in parsed &&\n \"result\" in parsed\n ) {\n parsed = parsed.result;\n }\n\n const normalized = normalizeKeys(parsed) as Record<string, unknown>;\n const event = discriminateStreamResponse(normalized);\n if (event) yield event;\n } catch {\n // Skip malformed events\n }\n eventEnd = buffer.indexOf(\"\\n\\n\");\n }\n }\n } finally {\n reader.releaseLock();\n }\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { A2AExtras } from "./types.js";
2
+
3
+ //#region src/a2aExtras.d.ts
4
+ declare const a2aExtras: import("@assistant-ui/core/internal").RuntimeExtras<A2AExtras>;
5
+ //#endregion
6
+ export { a2aExtras };
7
+ //# sourceMappingURL=a2aExtras.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"a2aExtras.d.ts","names":[],"sources":["../src/a2aExtras.ts"],"mappings":";;;cAGa,SAAA,wCAAS,aAAA,CAAA,SAAA"}
@@ -0,0 +1,7 @@
1
+ import { createRuntimeExtras } from "@assistant-ui/core/internal";
2
+ //#region src/a2aExtras.ts
3
+ const a2aExtras = createRuntimeExtras("useA2ARuntime");
4
+ //#endregion
5
+ export { a2aExtras };
6
+
7
+ //# sourceMappingURL=a2aExtras.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"a2aExtras.js","names":[],"sources":["../src/a2aExtras.ts"],"sourcesContent":["import { createRuntimeExtras } from \"@assistant-ui/core/internal\";\nimport type { A2AExtras } from \"./types\";\n\nexport const a2aExtras = createRuntimeExtras<A2AExtras>(\"useA2ARuntime\");\n"],"mappings":";;AAGA,MAAa,YAAY,oBAA+B,eAAe"}
@@ -40,13 +40,13 @@ function a2aPartToContent(part) {
40
40
  function a2aPartsToContent(parts) {
41
41
  return parts.map(a2aPartToContent);
42
42
  }
43
- const TERMINAL_STATES = new Set([
43
+ const TERMINAL_STATES = /* @__PURE__ */ new Set([
44
44
  "completed",
45
45
  "failed",
46
46
  "canceled",
47
47
  "rejected"
48
48
  ]);
49
- const INTERRUPTED_STATES = new Set(["input_required", "auth_required"]);
49
+ const INTERRUPTED_STATES = /* @__PURE__ */ new Set(["input_required", "auth_required"]);
50
50
  function isTerminalTaskState(state) {
51
51
  return TERMINAL_STATES.has(state);
52
52
  }
@@ -1 +1 @@
1
- {"version":3,"file":"conversions.js","names":[],"sources":["../src/conversions.ts"],"sourcesContent":["\"use client\";\n\nimport type { MessageStatus, ThreadAssistantMessage } from \"@assistant-ui/core\";\nimport type { A2AMessage, A2APart, A2ATaskState } from \"./types\";\n\nfunction isImageMediaType(mediaType?: string): boolean {\n return !!mediaType && mediaType.startsWith(\"image/\");\n}\n\nexport function a2aPartToContent(\n part: A2APart,\n): ThreadAssistantMessage[\"content\"][number] {\n if (part.text !== undefined) {\n return { type: \"text\", text: part.text };\n }\n if (part.url !== undefined) {\n if (isImageMediaType(part.mediaType)) {\n return { type: \"image\", image: part.url };\n }\n return {\n type: \"text\",\n text: part.filename ? `[${part.filename}](${part.url})` : part.url,\n };\n }\n if (part.raw !== undefined) {\n if (isImageMediaType(part.mediaType)) {\n return {\n type: \"image\",\n image: `data:${part.mediaType};base64,${part.raw}`,\n };\n }\n return {\n type: \"text\",\n text: `[File: ${part.filename ?? \"download\"}]`,\n };\n }\n if (part.data !== undefined) {\n return { type: \"text\", text: JSON.stringify(part.data, null, 2) };\n }\n return { type: \"text\", text: \"\" };\n}\n\nexport function a2aPartsToContent(\n parts: A2APart[],\n): ThreadAssistantMessage[\"content\"] {\n return parts.map(a2aPartToContent);\n}\n\nconst TERMINAL_STATES = new Set<A2ATaskState>([\n \"completed\",\n \"failed\",\n \"canceled\",\n \"rejected\",\n]);\n\nconst INTERRUPTED_STATES = new Set<A2ATaskState>([\n \"input_required\",\n \"auth_required\",\n]);\n\nexport function isTerminalTaskState(state: A2ATaskState): boolean {\n return TERMINAL_STATES.has(state);\n}\n\nexport function isInterruptedTaskState(state: A2ATaskState): boolean {\n return INTERRUPTED_STATES.has(state);\n}\n\nexport function taskStateToMessageStatus(state: A2ATaskState): MessageStatus {\n switch (state) {\n case \"submitted\":\n case \"working\":\n return { type: \"running\" };\n case \"completed\":\n return { type: \"complete\", reason: \"stop\" };\n case \"failed\":\n case \"rejected\":\n return { type: \"incomplete\", reason: \"error\" };\n case \"canceled\":\n return { type: \"incomplete\", reason: \"cancelled\" };\n case \"input_required\":\n case \"auth_required\":\n return { type: \"requires-action\", reason: \"interrupt\" };\n default:\n return { type: \"running\" };\n }\n}\n\nexport function contentPartsToA2AParts(\n content: ReadonlyArray<{\n type: string;\n text?: string;\n image?: string;\n }>,\n): A2APart[] {\n return content\n .map((part): A2APart | null => {\n switch (part.type) {\n case \"text\":\n return { text: part.text ?? \"\" };\n case \"image\":\n if (!part.image) return null;\n return { url: part.image, mediaType: \"image/*\" };\n default:\n return null;\n }\n })\n .filter((p): p is A2APart => p !== null);\n}\n\nexport function a2aMessageToContent(\n message: A2AMessage,\n): ThreadAssistantMessage[\"content\"] {\n return a2aPartsToContent(message.parts);\n}\n"],"mappings":";;AAKA,SAAS,iBAAiB,WAA6B;CACrD,OAAO,CAAC,CAAC,aAAa,UAAU,WAAW,QAAQ;AACrD;AAEA,SAAgB,iBACd,MAC2C;CAC3C,IAAI,KAAK,SAAS,KAAA,GAChB,OAAO;EAAE,MAAM;EAAQ,MAAM,KAAK;CAAK;CAEzC,IAAI,KAAK,QAAQ,KAAA,GAAW;EAC1B,IAAI,iBAAiB,KAAK,SAAS,GACjC,OAAO;GAAE,MAAM;GAAS,OAAO,KAAK;EAAI;EAE1C,OAAO;GACL,MAAM;GACN,MAAM,KAAK,WAAW,IAAI,KAAK,SAAS,IAAI,KAAK,IAAI,KAAK,KAAK;EACjE;CACF;CACA,IAAI,KAAK,QAAQ,KAAA,GAAW;EAC1B,IAAI,iBAAiB,KAAK,SAAS,GACjC,OAAO;GACL,MAAM;GACN,OAAO,QAAQ,KAAK,UAAU,UAAU,KAAK;EAC/C;EAEF,OAAO;GACL,MAAM;GACN,MAAM,UAAU,KAAK,YAAY,WAAW;EAC9C;CACF;CACA,IAAI,KAAK,SAAS,KAAA,GAChB,OAAO;EAAE,MAAM;EAAQ,MAAM,KAAK,UAAU,KAAK,MAAM,MAAM,CAAC;CAAE;CAElE,OAAO;EAAE,MAAM;EAAQ,MAAM;CAAG;AAClC;AAEA,SAAgB,kBACd,OACmC;CACnC,OAAO,MAAM,IAAI,gBAAgB;AACnC;AAEA,MAAM,kBAAkB,IAAI,IAAkB;CAC5C;CACA;CACA;CACA;AACF,CAAC;AAED,MAAM,qBAAqB,IAAI,IAAkB,CAC/C,kBACA,eACF,CAAC;AAED,SAAgB,oBAAoB,OAA8B;CAChE,OAAO,gBAAgB,IAAI,KAAK;AAClC;AAEA,SAAgB,uBAAuB,OAA8B;CACnE,OAAO,mBAAmB,IAAI,KAAK;AACrC;AAEA,SAAgB,yBAAyB,OAAoC;CAC3E,QAAQ,OAAR;EACE,KAAK;EACL,KAAK,WACH,OAAO,EAAE,MAAM,UAAU;EAC3B,KAAK,aACH,OAAO;GAAE,MAAM;GAAY,QAAQ;EAAO;EAC5C,KAAK;EACL,KAAK,YACH,OAAO;GAAE,MAAM;GAAc,QAAQ;EAAQ;EAC/C,KAAK,YACH,OAAO;GAAE,MAAM;GAAc,QAAQ;EAAY;EACnD,KAAK;EACL,KAAK,iBACH,OAAO;GAAE,MAAM;GAAmB,QAAQ;EAAY;EACxD,SACE,OAAO,EAAE,MAAM,UAAU;CAC7B;AACF;AAEA,SAAgB,uBACd,SAKW;CACX,OAAO,QACJ,KAAK,SAAyB;EAC7B,QAAQ,KAAK,MAAb;GACE,KAAK,QACH,OAAO,EAAE,MAAM,KAAK,QAAQ,GAAG;GACjC,KAAK;IACH,IAAI,CAAC,KAAK,OAAO,OAAO;IACxB,OAAO;KAAE,KAAK,KAAK;KAAO,WAAW;IAAU;GACjD,SACE,OAAO;EACX;CACF,CAAC,CAAC,CACD,QAAQ,MAAoB,MAAM,IAAI;AAC3C;AAEA,SAAgB,oBACd,SACmC;CACnC,OAAO,kBAAkB,QAAQ,KAAK;AACxC"}
1
+ {"version":3,"file":"conversions.js","names":[],"sources":["../src/conversions.ts"],"sourcesContent":["\"use client\";\n\nimport type { MessageStatus, ThreadAssistantMessage } from \"@assistant-ui/core\";\nimport type { A2AMessage, A2APart, A2ATaskState } from \"./types\";\n\nfunction isImageMediaType(mediaType?: string): boolean {\n return !!mediaType && mediaType.startsWith(\"image/\");\n}\n\nexport function a2aPartToContent(\n part: A2APart,\n): ThreadAssistantMessage[\"content\"][number] {\n if (part.text !== undefined) {\n return { type: \"text\", text: part.text };\n }\n if (part.url !== undefined) {\n if (isImageMediaType(part.mediaType)) {\n return { type: \"image\", image: part.url };\n }\n return {\n type: \"text\",\n text: part.filename ? `[${part.filename}](${part.url})` : part.url,\n };\n }\n if (part.raw !== undefined) {\n if (isImageMediaType(part.mediaType)) {\n return {\n type: \"image\",\n image: `data:${part.mediaType};base64,${part.raw}`,\n };\n }\n return {\n type: \"text\",\n text: `[File: ${part.filename ?? \"download\"}]`,\n };\n }\n if (part.data !== undefined) {\n return { type: \"text\", text: JSON.stringify(part.data, null, 2) };\n }\n return { type: \"text\", text: \"\" };\n}\n\nexport function a2aPartsToContent(\n parts: A2APart[],\n): ThreadAssistantMessage[\"content\"] {\n return parts.map(a2aPartToContent);\n}\n\nconst TERMINAL_STATES = new Set<A2ATaskState>([\n \"completed\",\n \"failed\",\n \"canceled\",\n \"rejected\",\n]);\n\nconst INTERRUPTED_STATES = new Set<A2ATaskState>([\n \"input_required\",\n \"auth_required\",\n]);\n\nexport function isTerminalTaskState(state: A2ATaskState): boolean {\n return TERMINAL_STATES.has(state);\n}\n\nexport function isInterruptedTaskState(state: A2ATaskState): boolean {\n return INTERRUPTED_STATES.has(state);\n}\n\nexport function taskStateToMessageStatus(state: A2ATaskState): MessageStatus {\n switch (state) {\n case \"submitted\":\n case \"working\":\n return { type: \"running\" };\n case \"completed\":\n return { type: \"complete\", reason: \"stop\" };\n case \"failed\":\n case \"rejected\":\n return { type: \"incomplete\", reason: \"error\" };\n case \"canceled\":\n return { type: \"incomplete\", reason: \"cancelled\" };\n case \"input_required\":\n case \"auth_required\":\n return { type: \"requires-action\", reason: \"interrupt\" };\n default:\n return { type: \"running\" };\n }\n}\n\nexport function contentPartsToA2AParts(\n content: ReadonlyArray<{\n type: string;\n text?: string;\n image?: string;\n }>,\n): A2APart[] {\n return content\n .map((part): A2APart | null => {\n switch (part.type) {\n case \"text\":\n return { text: part.text ?? \"\" };\n case \"image\":\n if (!part.image) return null;\n return { url: part.image, mediaType: \"image/*\" };\n default:\n return null;\n }\n })\n .filter((p): p is A2APart => p !== null);\n}\n\nexport function a2aMessageToContent(\n message: A2AMessage,\n): ThreadAssistantMessage[\"content\"] {\n return a2aPartsToContent(message.parts);\n}\n"],"mappings":";;AAKA,SAAS,iBAAiB,WAA6B;CACrD,OAAO,CAAC,CAAC,aAAa,UAAU,WAAW,QAAQ;AACrD;AAEA,SAAgB,iBACd,MAC2C;CAC3C,IAAI,KAAK,SAAS,KAAA,GAChB,OAAO;EAAE,MAAM;EAAQ,MAAM,KAAK;CAAK;CAEzC,IAAI,KAAK,QAAQ,KAAA,GAAW;EAC1B,IAAI,iBAAiB,KAAK,SAAS,GACjC,OAAO;GAAE,MAAM;GAAS,OAAO,KAAK;EAAI;EAE1C,OAAO;GACL,MAAM;GACN,MAAM,KAAK,WAAW,IAAI,KAAK,SAAS,IAAI,KAAK,IAAI,KAAK,KAAK;EACjE;CACF;CACA,IAAI,KAAK,QAAQ,KAAA,GAAW;EAC1B,IAAI,iBAAiB,KAAK,SAAS,GACjC,OAAO;GACL,MAAM;GACN,OAAO,QAAQ,KAAK,UAAU,UAAU,KAAK;EAC/C;EAEF,OAAO;GACL,MAAM;GACN,MAAM,UAAU,KAAK,YAAY,WAAW;EAC9C;CACF;CACA,IAAI,KAAK,SAAS,KAAA,GAChB,OAAO;EAAE,MAAM;EAAQ,MAAM,KAAK,UAAU,KAAK,MAAM,MAAM,CAAC;CAAE;CAElE,OAAO;EAAE,MAAM;EAAQ,MAAM;CAAG;AAClC;AAEA,SAAgB,kBACd,OACmC;CACnC,OAAO,MAAM,IAAI,gBAAgB;AACnC;AAEA,MAAM,kCAAkB,IAAI,IAAkB;CAC5C;CACA;CACA;CACA;AACF,CAAC;AAED,MAAM,qCAAqB,IAAI,IAAkB,CAC/C,kBACA,eACF,CAAC;AAED,SAAgB,oBAAoB,OAA8B;CAChE,OAAO,gBAAgB,IAAI,KAAK;AAClC;AAEA,SAAgB,uBAAuB,OAA8B;CACnE,OAAO,mBAAmB,IAAI,KAAK;AACrC;AAEA,SAAgB,yBAAyB,OAAoC;CAC3E,QAAQ,OAAR;EACE,KAAK;EACL,KAAK,WACH,OAAO,EAAE,MAAM,UAAU;EAC3B,KAAK,aACH,OAAO;GAAE,MAAM;GAAY,QAAQ;EAAO;EAC5C,KAAK;EACL,KAAK,YACH,OAAO;GAAE,MAAM;GAAc,QAAQ;EAAQ;EAC/C,KAAK,YACH,OAAO;GAAE,MAAM;GAAc,QAAQ;EAAY;EACnD,KAAK;EACL,KAAK,iBACH,OAAO;GAAE,MAAM;GAAmB,QAAQ;EAAY;EACxD,SACE,OAAO,EAAE,MAAM,UAAU;CAC7B;AACF;AAEA,SAAgB,uBACd,SAKW;CACX,OAAO,QACJ,KAAK,SAAyB;EAC7B,QAAQ,KAAK,MAAb;GACE,KAAK,QACH,OAAO,EAAE,MAAM,KAAK,QAAQ,GAAG;GACjC,KAAK;IACH,IAAI,CAAC,KAAK,OAAO,OAAO;IACxB,OAAO;KAAE,KAAK,KAAK;KAAO,WAAW;IAAU;GACjD,SACE,OAAO;EACX;CACF,CAAC,CAAC,CACD,QAAQ,MAAoB,MAAM,IAAI;AAC3C;AAEA,SAAgB,oBACd,SACmC;CACnC,OAAO,kBAAkB,QAAQ,KAAK;AACxC"}
@@ -0,0 +1,12 @@
1
+ import { A2AAgentCard, A2AArtifact, A2ATask } from "./types.js";
2
+
3
+ //#region src/hooks.d.ts
4
+ /** The current A2A task, if a run is in progress. */
5
+ declare const useA2ATask: () => A2ATask | undefined;
6
+ /** The artifacts accumulated for the current A2A run. */
7
+ declare const useA2AArtifacts: () => readonly A2AArtifact[];
8
+ /** The discovered A2A agent card. */
9
+ declare const useA2AAgentCard: () => A2AAgentCard | undefined;
10
+ //#endregion
11
+ export { useA2AAgentCard, useA2AArtifacts, useA2ATask };
12
+ //# sourceMappingURL=hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.d.ts","names":[],"sources":["../src/hooks.ts"],"mappings":";;;;cAKa,UAAA,QAA+C,OAArC;;cAGV,eAAA,iBAAyD,WAA1C;;cAGf,eAAA,QAAyD,YAA1C"}
package/dist/hooks.js ADDED
@@ -0,0 +1,13 @@
1
+ "use client";
2
+ import { a2aExtras } from "./a2aExtras.js";
3
+ //#region src/hooks.ts
4
+ /** The current A2A task, if a run is in progress. */
5
+ const useA2ATask = () => a2aExtras.use((e) => e.task);
6
+ /** The artifacts accumulated for the current A2A run. */
7
+ const useA2AArtifacts = () => a2aExtras.use((e) => e.artifacts);
8
+ /** The discovered A2A agent card. */
9
+ const useA2AAgentCard = () => a2aExtras.use((e) => e.agentCard);
10
+ //#endregion
11
+ export { useA2AAgentCard, useA2AArtifacts, useA2ATask };
12
+
13
+ //# sourceMappingURL=hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.js","names":[],"sources":["../src/hooks.ts"],"sourcesContent":["\"use client\";\n\nimport { a2aExtras } from \"./a2aExtras\";\n\n/** The current A2A task, if a run is in progress. */\nexport const useA2ATask = () => a2aExtras.use((e) => e.task);\n\n/** The artifacts accumulated for the current A2A run. */\nexport const useA2AArtifacts = () => a2aExtras.use((e) => e.artifacts);\n\n/** The discovered A2A agent card. */\nexport const useA2AAgentCard = () => a2aExtras.use((e) => e.agentCard);\n"],"mappings":";;;;AAKA,MAAa,mBAAmB,UAAU,KAAK,MAAM,EAAE,IAAI;;AAG3D,MAAa,wBAAwB,UAAU,KAAK,MAAM,EAAE,SAAS;;AAGrE,MAAa,wBAAwB,UAAU,KAAK,MAAM,EAAE,SAAS"}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
- import { A2AAgentCapabilities, A2AAgentCard, A2AAgentCardSignature, A2AAgentInterface, A2AAgentSkill, A2AApiKeySecurityScheme, A2AArtifact, A2AAuthenticationInfo, A2AAuthorizationCodeOAuthFlow, A2AClientCredentialsOAuthFlow, A2ADeviceCodeOAuthFlow, A2AErrorInfo, A2AHttpAuthSecurityScheme, A2AImplicitOAuthFlow, A2AListTaskPushNotificationConfigsResponse, A2AListTasksRequest, A2AListTasksResponse, A2AMessage, A2AMutualTlsSecurityScheme, A2AOAuth2SecurityScheme, A2AOAuthFlows, A2AOpenIdConnectSecurityScheme, A2APart, A2APasswordOAuthFlow, A2ARole, A2ASecurityRequirement, A2ASecurityScheme, A2ASendMessageConfiguration, A2AStreamEvent, A2ATask, A2ATaskArtifactUpdateEvent, A2ATaskPushNotificationConfig, A2ATaskState, A2ATaskStatus, A2ATaskStatusUpdateEvent, A2A_PROTOCOL_VERSION } from "./types.js";
1
+ import { A2AAgentCapabilities, A2AAgentCard, A2AAgentCardSignature, A2AAgentInterface, A2AAgentSkill, A2AApiKeySecurityScheme, A2AArtifact, A2AAuthenticationInfo, A2AAuthorizationCodeOAuthFlow, A2AClientCredentialsOAuthFlow, A2ADeviceCodeOAuthFlow, A2AErrorInfo, A2AHttpAuthSecurityScheme, A2AImplicitOAuthFlow, A2AListTaskPushNotificationConfigsResponse, A2AListTasksRequest, A2AListTasksResponse, A2AMessage, A2AMutualTlsSecurityScheme, A2AOAuth2SecurityScheme, A2AOAuthFlows, A2AOpenIdConnectSecurityScheme, A2APart, A2APasswordOAuthFlow, A2ARole, A2ASecurityRequirement, A2ASecurityScheme, A2ASendMessageConfiguration, A2AStreamEvent, A2ATask, A2ATaskArtifactUpdateEvent, A2ATaskPushNotificationConfig, A2ATaskState, A2ATaskStatus, A2ATaskStatusUpdateEvent, A2A_PROTOCOL_VERSION, UseA2ARuntimeOptions, UseA2AThreadListAdapter } from "./types.js";
2
2
  import { A2AClient, A2AClientOptions, A2AError } from "./A2AClient.js";
3
3
  import { a2aMessageToContent, a2aPartToContent, a2aPartsToContent, contentPartsToA2AParts, isInterruptedTaskState, isTerminalTaskState, taskStateToMessageStatus } from "./conversions.js";
4
- import { UseA2ARuntimeOptions, UseA2AThreadListAdapter, useA2AAgentCard, useA2AArtifacts, useA2ARuntime, useA2ATask } from "./useA2ARuntime.js";
4
+ import { useA2AAgentCard, useA2AArtifacts, useA2ATask } from "./hooks.js";
5
+ import { useA2ARuntime } from "./useA2ARuntime.js";
5
6
  export { type A2AAgentCapabilities, type A2AAgentCard, type A2AAgentCardSignature, type A2AAgentInterface, type A2AAgentSkill, type A2AApiKeySecurityScheme, type A2AArtifact, type A2AAuthenticationInfo, type A2AAuthorizationCodeOAuthFlow, A2AClient, type A2AClientCredentialsOAuthFlow, type A2AClientOptions, type A2ADeviceCodeOAuthFlow, A2AError, type A2AErrorInfo, type A2AHttpAuthSecurityScheme, type A2AImplicitOAuthFlow, type A2AListTaskPushNotificationConfigsResponse, type A2AListTasksRequest, type A2AListTasksResponse, type A2AMessage, type A2AMutualTlsSecurityScheme, type A2AOAuth2SecurityScheme, type A2AOAuthFlows, type A2AOpenIdConnectSecurityScheme, type A2APart, type A2APasswordOAuthFlow, type A2ARole, type A2ASecurityRequirement, type A2ASecurityScheme, type A2ASendMessageConfiguration, type A2AStreamEvent, type A2ATask, type A2ATaskArtifactUpdateEvent, type A2ATaskPushNotificationConfig, type A2ATaskState, type A2ATaskStatus, type A2ATaskStatusUpdateEvent, A2A_PROTOCOL_VERSION, type UseA2ARuntimeOptions, type UseA2AThreadListAdapter, a2aMessageToContent, a2aPartToContent, a2aPartsToContent, contentPartsToA2AParts, isInterruptedTaskState, isTerminalTaskState, taskStateToMessageStatus, useA2AAgentCard, useA2AArtifacts, useA2ARuntime, useA2ATask };
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { A2A_PROTOCOL_VERSION } from "./types.js";
2
2
  import { A2AClient, A2AError } from "./A2AClient.js";
3
3
  import { a2aMessageToContent, a2aPartToContent, a2aPartsToContent, contentPartsToA2AParts, isInterruptedTaskState, isTerminalTaskState, taskStateToMessageStatus } from "./conversions.js";
4
- import { useA2AAgentCard, useA2AArtifacts, useA2ARuntime, useA2ATask } from "./useA2ARuntime.js";
4
+ import { useA2AAgentCard, useA2AArtifacts, useA2ATask } from "./hooks.js";
5
+ import { useA2ARuntime } from "./useA2ARuntime.js";
5
6
  export { A2AClient, A2AError, A2A_PROTOCOL_VERSION, a2aMessageToContent, a2aPartToContent, a2aPartsToContent, contentPartsToA2AParts, isInterruptedTaskState, isTerminalTaskState, taskStateToMessageStatus, useA2AAgentCard, useA2AArtifacts, useA2ARuntime, useA2ATask };
package/dist/types.d.ts CHANGED
@@ -1,3 +1,6 @@
1
+ import { A2AClient, A2AClientOptions } from "./A2AClient.js";
2
+ import { AttachmentAdapter, DictationAdapter, ExternalStoreSharedOptions, FeedbackAdapter, RealtimeVoiceAdapter, SpeechSynthesisAdapter, ThreadHistoryAdapter, ThreadMessage } from "@assistant-ui/core";
3
+
1
4
  //#region src/types.d.ts
2
5
  declare const A2A_PROTOCOL_VERSION = "1.0";
3
6
  type A2ARole = "unspecified" | "user" | "agent";
@@ -234,6 +237,42 @@ type A2AAgentCard = {
234
237
  signatures?: A2AAgentCardSignature[] | undefined;
235
238
  iconUrl?: string | undefined;
236
239
  };
240
+ /** Private state `useA2ARuntime` exposes through `thread.extras`. */
241
+ type A2AExtras = {
242
+ task: A2ATask | undefined;
243
+ artifacts: readonly A2AArtifact[];
244
+ agentCard: A2AAgentCard | undefined;
245
+ };
246
+ type UseA2AThreadListAdapter = {
247
+ threadId?: string;
248
+ onSwitchToNewThread?: () => Promise<void> | void;
249
+ onSwitchToThread?: (threadId: string) => Promise<{
250
+ messages: readonly ThreadMessage[];
251
+ }>;
252
+ };
253
+ type UseA2ARuntimeOptions = ExternalStoreSharedOptions & {
254
+ /** Pre-built A2A client instance. Provide this OR baseUrl. */client?: A2AClient; /** Base URL of the A2A server. Used to create a client if `client` is not provided. */
255
+ baseUrl?: string; /** Optional path prefix for all API endpoints (e.g. "/v1"). Does not affect agent card discovery. Only used with baseUrl. */
256
+ basePath?: string; /** Optional tenant ID for multi-tenant servers. Only used with baseUrl. */
257
+ tenant?: string; /** Headers for the A2A client (only used with baseUrl). */
258
+ headers?: A2AClientOptions["headers"]; /** A2A extension URIs to negotiate. Only used with baseUrl. */
259
+ extensions?: string[]; /** Extra fetch options (e.g. `{ credentials: 'include' }`). Only used with `baseUrl`. */
260
+ fetchOptions?: A2AClientOptions["fetchOptions"]; /** Initial context ID for the conversation. */
261
+ contextId?: string; /** Default send message configuration. */
262
+ configuration?: A2ASendMessageConfiguration; /** Called when an error occurs. */
263
+ onError?: (error: Error) => void; /** Called when a run is cancelled. */
264
+ onCancel?: () => void; /** Called when an artifact is fully received (lastChunk). */
265
+ onArtifactComplete?: (artifact: A2AArtifact) => void;
266
+ adapters?: {
267
+ attachments?: AttachmentAdapter;
268
+ speech?: SpeechSynthesisAdapter;
269
+ dictation?: DictationAdapter;
270
+ voice?: RealtimeVoiceAdapter;
271
+ feedback?: FeedbackAdapter;
272
+ history?: ThreadHistoryAdapter;
273
+ threadList?: UseA2AThreadListAdapter;
274
+ };
275
+ };
237
276
  //#endregion
238
- export { A2AAgentCapabilities, A2AAgentCard, A2AAgentCardSignature, A2AAgentInterface, A2AAgentSkill, A2AApiKeySecurityScheme, A2AArtifact, A2AAuthenticationInfo, A2AAuthorizationCodeOAuthFlow, A2AClientCredentialsOAuthFlow, A2ADeviceCodeOAuthFlow, A2AErrorInfo, A2AHttpAuthSecurityScheme, A2AImplicitOAuthFlow, A2AListTaskPushNotificationConfigsResponse, A2AListTasksRequest, A2AListTasksResponse, A2AMessage, A2AMutualTlsSecurityScheme, A2AOAuth2SecurityScheme, A2AOAuthFlows, A2AOpenIdConnectSecurityScheme, A2APart, A2APasswordOAuthFlow, A2ARole, A2ASecurityRequirement, A2ASecurityScheme, A2ASendMessageConfiguration, A2AStreamEvent, A2ATask, A2ATaskArtifactUpdateEvent, A2ATaskPushNotificationConfig, A2ATaskState, A2ATaskStatus, A2ATaskStatusUpdateEvent, A2A_PROTOCOL_VERSION };
277
+ export { A2AAgentCapabilities, A2AAgentCard, A2AAgentCardSignature, A2AAgentInterface, A2AAgentSkill, A2AApiKeySecurityScheme, A2AArtifact, A2AAuthenticationInfo, A2AAuthorizationCodeOAuthFlow, A2AClientCredentialsOAuthFlow, A2ADeviceCodeOAuthFlow, A2AErrorInfo, A2AExtras, A2AHttpAuthSecurityScheme, A2AImplicitOAuthFlow, A2AListTaskPushNotificationConfigsResponse, A2AListTasksRequest, A2AListTasksResponse, A2AMessage, A2AMutualTlsSecurityScheme, A2AOAuth2SecurityScheme, A2AOAuthFlows, A2AOpenIdConnectSecurityScheme, A2APart, A2APasswordOAuthFlow, A2ARole, A2ASecurityRequirement, A2ASecurityScheme, A2ASendMessageConfiguration, A2AStreamEvent, A2ATask, A2ATaskArtifactUpdateEvent, A2ATaskPushNotificationConfig, A2ATaskState, A2ATaskStatus, A2ATaskStatusUpdateEvent, A2A_PROTOCOL_VERSION, UseA2ARuntimeOptions, UseA2AThreadListAdapter };
239
278
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","names":[],"sources":["../src/types.ts"],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","names":[],"sources":["../src/types.ts"],"mappings":"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"}
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","names":[],"sources":["../src/types.ts"],"sourcesContent":["// A2A v1.0 Protocol Types\n// Enum values use lowercase internally; normalized from ProtoJSON SCREAMING_SNAKE_CASE on read.\n// Wire format uses ROLE_USER/ROLE_AGENT and TASK_STATE_* per ADR-001.\n\nexport const A2A_PROTOCOL_VERSION = \"1.0\";\n\nexport type A2ARole = \"unspecified\" | \"user\" | \"agent\";\n\nexport type A2APart = {\n text?: string | undefined;\n raw?: string | undefined; // base64 encoded bytes\n url?: string | undefined;\n data?: unknown; // google.protobuf.Value\n\n metadata?: Record<string, unknown> | undefined;\n filename?: string | undefined;\n mediaType?: string | undefined; // MIME type\n};\n\nexport type A2AMessage = {\n messageId: string;\n contextId?: string | undefined;\n taskId?: string | undefined;\n role: A2ARole;\n parts: A2APart[];\n metadata?: Record<string, unknown> | undefined;\n extensions?: string[] | undefined;\n referenceTaskIds?: string[] | undefined;\n};\n\nexport type A2ATaskState =\n | \"unspecified\"\n | \"submitted\"\n | \"working\"\n | \"completed\"\n | \"failed\"\n | \"canceled\"\n | \"input_required\"\n | \"rejected\"\n | \"auth_required\";\n\nexport type A2ATaskStatus = {\n state: A2ATaskState;\n message?: A2AMessage | undefined;\n timestamp?: string | undefined; // ISO 8601\n};\n\nexport type A2AArtifact = {\n artifactId: string;\n name?: string | undefined;\n description?: string | undefined;\n parts: A2APart[];\n metadata?: Record<string, unknown> | undefined;\n extensions?: string[] | undefined;\n};\n\nexport type A2ATask = {\n id: string;\n contextId?: string | undefined;\n status: A2ATaskStatus;\n artifacts?: A2AArtifact[] | undefined;\n history?: A2AMessage[] | undefined;\n metadata?: Record<string, unknown> | undefined;\n};\n\n// Streaming events\nexport type A2ATaskStatusUpdateEvent = {\n taskId: string;\n contextId: string; // REQUIRED per proto\n status: A2ATaskStatus;\n metadata?: Record<string, unknown> | undefined;\n};\n\nexport type A2ATaskArtifactUpdateEvent = {\n taskId: string;\n contextId: string; // REQUIRED per proto\n artifact: A2AArtifact;\n append?: boolean | undefined;\n lastChunk?: boolean | undefined;\n metadata?: Record<string, unknown> | undefined;\n};\n\nexport type A2AStreamEvent =\n | { type: \"task\"; task: A2ATask }\n | { type: \"message\"; message: A2AMessage }\n | { type: \"statusUpdate\"; event: A2ATaskStatusUpdateEvent }\n | { type: \"artifactUpdate\"; event: A2ATaskArtifactUpdateEvent };\n\nexport type A2AAuthenticationInfo = {\n scheme: string;\n credentials?: string | undefined;\n};\n\nexport type A2ATaskPushNotificationConfig = {\n tenant?: string | undefined;\n id?: string | undefined;\n taskId?: string | undefined;\n url: string;\n token?: string | undefined;\n authentication?: A2AAuthenticationInfo | undefined;\n};\n\nexport type A2AListTaskPushNotificationConfigsResponse = {\n configs: A2ATaskPushNotificationConfig[];\n nextPageToken?: string | undefined;\n};\n\nexport type A2ASendMessageConfiguration = {\n acceptedOutputModes?: string[] | undefined;\n taskPushNotificationConfig?: A2ATaskPushNotificationConfig | undefined;\n historyLength?: number | undefined;\n returnImmediately?: boolean | undefined;\n};\n\nexport type A2AListTasksRequest = {\n contextId?: string | undefined;\n status?: A2ATaskState | undefined;\n pageSize?: number | undefined;\n pageToken?: string | undefined;\n historyLength?: number | undefined;\n statusTimestampAfter?: string | undefined; // ISO 8601\n includeArtifacts?: boolean | undefined;\n};\n\nexport type A2AListTasksResponse = {\n tasks: A2ATask[];\n nextPageToken: string;\n pageSize: number;\n totalSize: number;\n};\n\n// Structured error (google.rpc.Status)\nexport type A2AErrorInfo = {\n code: number;\n status: string;\n message: string;\n details?: unknown[] | undefined;\n};\n\nexport type A2AApiKeySecurityScheme = {\n description?: string | undefined;\n location: string; // \"query\" | \"header\" | \"cookie\"\n name: string;\n};\n\nexport type A2AHttpAuthSecurityScheme = {\n description?: string | undefined;\n scheme: string; // e.g. \"Bearer\"\n bearerFormat?: string | undefined;\n};\n\nexport type A2AAuthorizationCodeOAuthFlow = {\n authorizationUrl: string;\n tokenUrl: string;\n refreshUrl?: string | undefined;\n scopes: Record<string, string>;\n pkceRequired?: boolean | undefined;\n};\n\nexport type A2AClientCredentialsOAuthFlow = {\n tokenUrl: string;\n refreshUrl?: string | undefined;\n scopes: Record<string, string>;\n};\n\nexport type A2ADeviceCodeOAuthFlow = {\n deviceAuthorizationUrl: string;\n tokenUrl: string;\n refreshUrl?: string | undefined;\n scopes: Record<string, string>;\n};\n\n/** @deprecated Use Authorization Code + PKCE instead. */\nexport type A2AImplicitOAuthFlow = {\n authorizationUrl?: string | undefined;\n refreshUrl?: string | undefined;\n scopes?: Record<string, string> | undefined;\n};\n\n/** @deprecated Use Authorization Code + PKCE or Device Code. */\nexport type A2APasswordOAuthFlow = {\n tokenUrl?: string | undefined;\n refreshUrl?: string | undefined;\n scopes?: Record<string, string> | undefined;\n};\n\nexport type A2AOAuthFlows = {\n authorizationCode?: A2AAuthorizationCodeOAuthFlow | undefined;\n clientCredentials?: A2AClientCredentialsOAuthFlow | undefined;\n /** @deprecated */\n implicit?: A2AImplicitOAuthFlow | undefined;\n /** @deprecated */\n password?: A2APasswordOAuthFlow | undefined;\n deviceCode?: A2ADeviceCodeOAuthFlow | undefined;\n};\n\nexport type A2AOAuth2SecurityScheme = {\n description?: string | undefined;\n flows: A2AOAuthFlows;\n oauth2MetadataUrl?: string | undefined;\n};\n\nexport type A2AOpenIdConnectSecurityScheme = {\n description?: string | undefined;\n openIdConnectUrl: string;\n};\n\nexport type A2AMutualTlsSecurityScheme = {\n description?: string | undefined;\n};\n\nexport type A2ASecurityScheme = {\n apiKeySecurityScheme?: A2AApiKeySecurityScheme | undefined;\n httpAuthSecurityScheme?: A2AHttpAuthSecurityScheme | undefined;\n oauth2SecurityScheme?: A2AOAuth2SecurityScheme | undefined;\n openIdConnectSecurityScheme?: A2AOpenIdConnectSecurityScheme | undefined;\n mtlsSecurityScheme?: A2AMutualTlsSecurityScheme | undefined;\n};\n\nexport type A2ASecurityRequirement = {\n schemes: Record<string, { list: string[] }>;\n};\n\n// Agent card signature (JWS)\nexport type A2AAgentCardSignature = {\n protected: string; // base64url-encoded JWS header\n signature: string; // base64url-encoded signature\n header?: Record<string, unknown> | undefined;\n};\n\nexport type A2AAgentSkill = {\n id: string;\n name: string;\n description: string;\n tags: string[];\n examples?: string[] | undefined;\n inputModes?: string[] | undefined;\n outputModes?: string[] | undefined;\n securityRequirements?: A2ASecurityRequirement[] | undefined;\n};\n\nexport type A2AAgentCapabilities = {\n streaming?: boolean | undefined;\n pushNotifications?: boolean | undefined;\n extensions?:\n | Array<{\n uri: string;\n description?: string | undefined;\n required?: boolean | undefined;\n params?: Record<string, unknown> | undefined;\n }>\n | undefined;\n extendedAgentCard?: boolean | undefined;\n};\n\nexport type A2AAgentInterface = {\n url: string;\n protocolBinding: string;\n protocolVersion: string;\n tenant?: string | undefined;\n};\n\nexport type A2AAgentCard = {\n name: string;\n description: string;\n supportedInterfaces: A2AAgentInterface[]; // REQUIRED per proto\n provider?:\n | {\n organization: string;\n url: string;\n }\n | undefined;\n version: string;\n documentationUrl?: string | undefined;\n capabilities: A2AAgentCapabilities;\n securitySchemes?: Record<string, A2ASecurityScheme> | undefined;\n securityRequirements?: A2ASecurityRequirement[] | undefined;\n defaultInputModes: string[];\n defaultOutputModes: string[];\n skills: A2AAgentSkill[];\n signatures?: A2AAgentCardSignature[] | undefined;\n iconUrl?: string | undefined;\n};\n"],"mappings":";AAIA,MAAa,uBAAuB"}
1
+ {"version":3,"file":"types.js","names":[],"sources":["../src/types.ts"],"sourcesContent":["// A2A v1.0 Protocol Types\n// Enum values use lowercase internally; normalized from ProtoJSON SCREAMING_SNAKE_CASE on read.\n// Wire format uses ROLE_USER/ROLE_AGENT and TASK_STATE_* per ADR-001.\n\nimport type {\n AttachmentAdapter,\n DictationAdapter,\n ExternalStoreSharedOptions,\n FeedbackAdapter,\n RealtimeVoiceAdapter,\n SpeechSynthesisAdapter,\n ThreadHistoryAdapter,\n ThreadMessage,\n} from \"@assistant-ui/core\";\nimport type { A2AClient, A2AClientOptions } from \"./A2AClient\";\n\nexport const A2A_PROTOCOL_VERSION = \"1.0\";\n\nexport type A2ARole = \"unspecified\" | \"user\" | \"agent\";\n\nexport type A2APart = {\n text?: string | undefined;\n raw?: string | undefined; // base64 encoded bytes\n url?: string | undefined;\n data?: unknown; // google.protobuf.Value\n\n metadata?: Record<string, unknown> | undefined;\n filename?: string | undefined;\n mediaType?: string | undefined; // MIME type\n};\n\nexport type A2AMessage = {\n messageId: string;\n contextId?: string | undefined;\n taskId?: string | undefined;\n role: A2ARole;\n parts: A2APart[];\n metadata?: Record<string, unknown> | undefined;\n extensions?: string[] | undefined;\n referenceTaskIds?: string[] | undefined;\n};\n\nexport type A2ATaskState =\n | \"unspecified\"\n | \"submitted\"\n | \"working\"\n | \"completed\"\n | \"failed\"\n | \"canceled\"\n | \"input_required\"\n | \"rejected\"\n | \"auth_required\";\n\nexport type A2ATaskStatus = {\n state: A2ATaskState;\n message?: A2AMessage | undefined;\n timestamp?: string | undefined; // ISO 8601\n};\n\nexport type A2AArtifact = {\n artifactId: string;\n name?: string | undefined;\n description?: string | undefined;\n parts: A2APart[];\n metadata?: Record<string, unknown> | undefined;\n extensions?: string[] | undefined;\n};\n\nexport type A2ATask = {\n id: string;\n contextId?: string | undefined;\n status: A2ATaskStatus;\n artifacts?: A2AArtifact[] | undefined;\n history?: A2AMessage[] | undefined;\n metadata?: Record<string, unknown> | undefined;\n};\n\n// Streaming events\nexport type A2ATaskStatusUpdateEvent = {\n taskId: string;\n contextId: string; // REQUIRED per proto\n status: A2ATaskStatus;\n metadata?: Record<string, unknown> | undefined;\n};\n\nexport type A2ATaskArtifactUpdateEvent = {\n taskId: string;\n contextId: string; // REQUIRED per proto\n artifact: A2AArtifact;\n append?: boolean | undefined;\n lastChunk?: boolean | undefined;\n metadata?: Record<string, unknown> | undefined;\n};\n\nexport type A2AStreamEvent =\n | { type: \"task\"; task: A2ATask }\n | { type: \"message\"; message: A2AMessage }\n | { type: \"statusUpdate\"; event: A2ATaskStatusUpdateEvent }\n | { type: \"artifactUpdate\"; event: A2ATaskArtifactUpdateEvent };\n\nexport type A2AAuthenticationInfo = {\n scheme: string;\n credentials?: string | undefined;\n};\n\nexport type A2ATaskPushNotificationConfig = {\n tenant?: string | undefined;\n id?: string | undefined;\n taskId?: string | undefined;\n url: string;\n token?: string | undefined;\n authentication?: A2AAuthenticationInfo | undefined;\n};\n\nexport type A2AListTaskPushNotificationConfigsResponse = {\n configs: A2ATaskPushNotificationConfig[];\n nextPageToken?: string | undefined;\n};\n\nexport type A2ASendMessageConfiguration = {\n acceptedOutputModes?: string[] | undefined;\n taskPushNotificationConfig?: A2ATaskPushNotificationConfig | undefined;\n historyLength?: number | undefined;\n returnImmediately?: boolean | undefined;\n};\n\nexport type A2AListTasksRequest = {\n contextId?: string | undefined;\n status?: A2ATaskState | undefined;\n pageSize?: number | undefined;\n pageToken?: string | undefined;\n historyLength?: number | undefined;\n statusTimestampAfter?: string | undefined; // ISO 8601\n includeArtifacts?: boolean | undefined;\n};\n\nexport type A2AListTasksResponse = {\n tasks: A2ATask[];\n nextPageToken: string;\n pageSize: number;\n totalSize: number;\n};\n\n// Structured error (google.rpc.Status)\nexport type A2AErrorInfo = {\n code: number;\n status: string;\n message: string;\n details?: unknown[] | undefined;\n};\n\nexport type A2AApiKeySecurityScheme = {\n description?: string | undefined;\n location: string; // \"query\" | \"header\" | \"cookie\"\n name: string;\n};\n\nexport type A2AHttpAuthSecurityScheme = {\n description?: string | undefined;\n scheme: string; // e.g. \"Bearer\"\n bearerFormat?: string | undefined;\n};\n\nexport type A2AAuthorizationCodeOAuthFlow = {\n authorizationUrl: string;\n tokenUrl: string;\n refreshUrl?: string | undefined;\n scopes: Record<string, string>;\n pkceRequired?: boolean | undefined;\n};\n\nexport type A2AClientCredentialsOAuthFlow = {\n tokenUrl: string;\n refreshUrl?: string | undefined;\n scopes: Record<string, string>;\n};\n\nexport type A2ADeviceCodeOAuthFlow = {\n deviceAuthorizationUrl: string;\n tokenUrl: string;\n refreshUrl?: string | undefined;\n scopes: Record<string, string>;\n};\n\n/** @deprecated Use Authorization Code + PKCE instead. */\nexport type A2AImplicitOAuthFlow = {\n authorizationUrl?: string | undefined;\n refreshUrl?: string | undefined;\n scopes?: Record<string, string> | undefined;\n};\n\n/** @deprecated Use Authorization Code + PKCE or Device Code. */\nexport type A2APasswordOAuthFlow = {\n tokenUrl?: string | undefined;\n refreshUrl?: string | undefined;\n scopes?: Record<string, string> | undefined;\n};\n\nexport type A2AOAuthFlows = {\n authorizationCode?: A2AAuthorizationCodeOAuthFlow | undefined;\n clientCredentials?: A2AClientCredentialsOAuthFlow | undefined;\n /** @deprecated */\n implicit?: A2AImplicitOAuthFlow | undefined;\n /** @deprecated */\n password?: A2APasswordOAuthFlow | undefined;\n deviceCode?: A2ADeviceCodeOAuthFlow | undefined;\n};\n\nexport type A2AOAuth2SecurityScheme = {\n description?: string | undefined;\n flows: A2AOAuthFlows;\n oauth2MetadataUrl?: string | undefined;\n};\n\nexport type A2AOpenIdConnectSecurityScheme = {\n description?: string | undefined;\n openIdConnectUrl: string;\n};\n\nexport type A2AMutualTlsSecurityScheme = {\n description?: string | undefined;\n};\n\nexport type A2ASecurityScheme = {\n apiKeySecurityScheme?: A2AApiKeySecurityScheme | undefined;\n httpAuthSecurityScheme?: A2AHttpAuthSecurityScheme | undefined;\n oauth2SecurityScheme?: A2AOAuth2SecurityScheme | undefined;\n openIdConnectSecurityScheme?: A2AOpenIdConnectSecurityScheme | undefined;\n mtlsSecurityScheme?: A2AMutualTlsSecurityScheme | undefined;\n};\n\nexport type A2ASecurityRequirement = {\n schemes: Record<string, { list: string[] }>;\n};\n\n// Agent card signature (JWS)\nexport type A2AAgentCardSignature = {\n protected: string; // base64url-encoded JWS header\n signature: string; // base64url-encoded signature\n header?: Record<string, unknown> | undefined;\n};\n\nexport type A2AAgentSkill = {\n id: string;\n name: string;\n description: string;\n tags: string[];\n examples?: string[] | undefined;\n inputModes?: string[] | undefined;\n outputModes?: string[] | undefined;\n securityRequirements?: A2ASecurityRequirement[] | undefined;\n};\n\nexport type A2AAgentCapabilities = {\n streaming?: boolean | undefined;\n pushNotifications?: boolean | undefined;\n extensions?:\n | Array<{\n uri: string;\n description?: string | undefined;\n required?: boolean | undefined;\n params?: Record<string, unknown> | undefined;\n }>\n | undefined;\n extendedAgentCard?: boolean | undefined;\n};\n\nexport type A2AAgentInterface = {\n url: string;\n protocolBinding: string;\n protocolVersion: string;\n tenant?: string | undefined;\n};\n\nexport type A2AAgentCard = {\n name: string;\n description: string;\n supportedInterfaces: A2AAgentInterface[]; // REQUIRED per proto\n provider?:\n | {\n organization: string;\n url: string;\n }\n | undefined;\n version: string;\n documentationUrl?: string | undefined;\n capabilities: A2AAgentCapabilities;\n securitySchemes?: Record<string, A2ASecurityScheme> | undefined;\n securityRequirements?: A2ASecurityRequirement[] | undefined;\n defaultInputModes: string[];\n defaultOutputModes: string[];\n skills: A2AAgentSkill[];\n signatures?: A2AAgentCardSignature[] | undefined;\n iconUrl?: string | undefined;\n};\n\n/** Private state `useA2ARuntime` exposes through `thread.extras`. */\nexport type A2AExtras = {\n task: A2ATask | undefined;\n artifacts: readonly A2AArtifact[];\n agentCard: A2AAgentCard | undefined;\n};\n\nexport type UseA2AThreadListAdapter = {\n threadId?: string;\n onSwitchToNewThread?: () => Promise<void> | void;\n onSwitchToThread?: (threadId: string) => Promise<{\n messages: readonly ThreadMessage[];\n }>;\n};\n\nexport type UseA2ARuntimeOptions = ExternalStoreSharedOptions & {\n /** Pre-built A2A client instance. Provide this OR baseUrl. */\n client?: A2AClient;\n /** Base URL of the A2A server. Used to create a client if `client` is not provided. */\n baseUrl?: string;\n /** Optional path prefix for all API endpoints (e.g. \"/v1\"). Does not affect agent card discovery. Only used with baseUrl. */\n basePath?: string;\n /** Optional tenant ID for multi-tenant servers. Only used with baseUrl. */\n tenant?: string;\n /** Headers for the A2A client (only used with baseUrl). */\n headers?: A2AClientOptions[\"headers\"];\n /** A2A extension URIs to negotiate. Only used with baseUrl. */\n extensions?: string[];\n /** Extra fetch options (e.g. `{ credentials: 'include' }`). Only used with `baseUrl`. */\n fetchOptions?: A2AClientOptions[\"fetchOptions\"];\n\n /** Initial context ID for the conversation. */\n contextId?: string;\n /** Default send message configuration. */\n configuration?: A2ASendMessageConfiguration;\n\n /** Called when an error occurs. */\n onError?: (error: Error) => void;\n /** Called when a run is cancelled. */\n onCancel?: () => void;\n /** Called when an artifact is fully received (lastChunk). */\n onArtifactComplete?: (artifact: A2AArtifact) => void;\n\n adapters?: {\n attachments?: AttachmentAdapter;\n speech?: SpeechSynthesisAdapter;\n dictation?: DictationAdapter;\n voice?: RealtimeVoiceAdapter;\n feedback?: FeedbackAdapter;\n history?: ThreadHistoryAdapter;\n threadList?: UseA2AThreadListAdapter;\n };\n};\n"],"mappings":";AAgBA,MAAa,uBAAuB"}
@@ -1,42 +1,8 @@
1
- import { A2AAgentCard, A2AArtifact, A2ASendMessageConfiguration, A2ATask } from "./types.js";
2
- import { A2AClient, A2AClientOptions } from "./A2AClient.js";
3
- import { AssistantRuntime, AttachmentAdapter, DictationAdapter, ExternalStoreSharedOptions, FeedbackAdapter, RealtimeVoiceAdapter, SpeechSynthesisAdapter, ThreadHistoryAdapter, ThreadMessage } from "@assistant-ui/core";
1
+ import { UseA2ARuntimeOptions } from "./types.js";
2
+ import { AssistantRuntime } from "@assistant-ui/core";
4
3
 
5
4
  //#region src/useA2ARuntime.d.ts
6
- declare const useA2ATask: () => A2ATask | undefined;
7
- declare const useA2AArtifacts: () => readonly A2AArtifact[];
8
- declare const useA2AAgentCard: () => A2AAgentCard | undefined;
9
- type UseA2AThreadListAdapter = {
10
- threadId?: string;
11
- onSwitchToNewThread?: () => Promise<void> | void;
12
- onSwitchToThread?: (threadId: string) => Promise<{
13
- messages: readonly ThreadMessage[];
14
- }>;
15
- };
16
- type UseA2ARuntimeOptions = ExternalStoreSharedOptions & {
17
- /** Pre-built A2A client instance. Provide this OR baseUrl. */client?: A2AClient; /** Base URL of the A2A server. Used to create a client if `client` is not provided. */
18
- baseUrl?: string; /** Optional path prefix for all API endpoints (e.g. "/v1"). Does not affect agent card discovery. Only used with baseUrl. */
19
- basePath?: string; /** Optional tenant ID for multi-tenant servers. Only used with baseUrl. */
20
- tenant?: string; /** Headers for the A2A client (only used with baseUrl). */
21
- headers?: A2AClientOptions["headers"]; /** A2A extension URIs to negotiate. Only used with baseUrl. */
22
- extensions?: string[]; /** Extra fetch options (e.g. `{ credentials: 'include' }`). Only used with `baseUrl`. */
23
- fetchOptions?: A2AClientOptions["fetchOptions"]; /** Initial context ID for the conversation. */
24
- contextId?: string; /** Default send message configuration. */
25
- configuration?: A2ASendMessageConfiguration; /** Called when an error occurs. */
26
- onError?: (error: Error) => void; /** Called when a run is cancelled. */
27
- onCancel?: () => void; /** Called when an artifact is fully received (lastChunk). */
28
- onArtifactComplete?: (artifact: A2AArtifact) => void;
29
- adapters?: {
30
- attachments?: AttachmentAdapter;
31
- speech?: SpeechSynthesisAdapter;
32
- dictation?: DictationAdapter;
33
- voice?: RealtimeVoiceAdapter;
34
- feedback?: FeedbackAdapter;
35
- history?: ThreadHistoryAdapter;
36
- threadList?: UseA2AThreadListAdapter;
37
- };
38
- };
39
5
  declare function useA2ARuntime(options: UseA2ARuntimeOptions): AssistantRuntime;
40
6
  //#endregion
41
- export { UseA2ARuntimeOptions, UseA2AThreadListAdapter, useA2AAgentCard, useA2AArtifacts, useA2ARuntime, useA2ATask };
7
+ export { useA2ARuntime };
42
8
  //# sourceMappingURL=useA2ARuntime.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useA2ARuntime.d.ts","names":[],"sources":["../src/useA2ARuntime.ts"],"mappings":";;;;;cAyDa,UAAA,QAAU,OAAA;AAAA,cAIV,eAAA,iBAAe,WAAA;AAAA,cAIf,eAAA,QAAe,YAAA;AAAA,KAMhB,uBAAA;EACV,QAAA;EACA,mBAAA,SAA4B,OAAA;EAC5B,gBAAA,IAAoB,QAAA,aAAqB,OAAA;IACvC,QAAA,WAAmB,aAAA;EAAA;AAAA;AAAA,KAMX,oBAAA,GAAuB,0BAAA;EAhBtB,8DAkBX,MAAA,GAAS,SAAA;EAET,OAAA,WApB0B;EAsB1B,QAAA,WAhBiC;EAkBjC,MAAA,WAhB4B;EAkB5B,OAAA,GAAU,gBAAA,aAjB+B;EAmBzC,UAAA,aAnBgD;EAqBhD,YAAA,GAAe,gBAAA,kBAtBf;EAyBA,SAAA,WAxBA;EA0BA,aAAA,GAAgB,2BAAA,EA1ByB;EA6BzC,OAAA,IAAW,KAAA,EAAO,KAAA,WA5BG;EA8BrB,QAAA,eA9BkC;EAgClC,kBAAA,IAAsB,QAAA,EAJC,WAAA;EAMvB,QAAA;IACE,WAAA,GAAc,iBAAA;IACd,MAAA,GAAS,sBAAA;IACT,SAAA,GAAY,gBAAA;IACZ,KAAA,GAAQ,oBAAA;IACR,QAAA,GAAW,eAAA;IACX,OAAA,GAAU,oBAAA;IACV,UAAA,GAAa,uBAAA;EAAA;AAAA;AAAA,iBAMD,aAAA,CAAc,OAAA,EAAS,oBAAA,GAAuB,gBAAgB"}
1
+ {"version":3,"file":"useA2ARuntime.d.ts","names":[],"sources":["../src/useA2ARuntime.ts"],"mappings":";;;;iBAmBgB,aAAA,CAAc,OAAA,EAAS,oBAAA,GAAuB,gBAAgB"}
@@ -1,24 +1,10 @@
1
1
  "use client";
2
2
  import { A2AClient } from "./A2AClient.js";
3
3
  import { A2AThreadRuntimeCore } from "./A2AThreadRuntimeCore.js";
4
+ import { a2aExtras } from "./a2aExtras.js";
4
5
  import { useCallback, useEffect, useMemo, useRef, useState } from "react";
5
6
  import { useExternalStoreRuntime, useExternalStoreSharedOptions, useRuntimeAdapters } from "@assistant-ui/core/react";
6
- import { useAuiState } from "@assistant-ui/store";
7
7
  //#region src/useA2ARuntime.ts
8
- const symbolA2AExtras = Symbol("a2a-extras");
9
- const asA2AExtras = (extras) => {
10
- if (typeof extras !== "object" || extras == null || !(symbolA2AExtras in extras)) throw new Error("This hook can only be used inside a useA2ARuntime provider");
11
- return extras;
12
- };
13
- const useA2ATask = () => {
14
- return useAuiState((s) => asA2AExtras(s.thread.extras).task);
15
- };
16
- const useA2AArtifacts = () => {
17
- return useAuiState((s) => asA2AExtras(s.thread.extras).artifacts);
18
- };
19
- const useA2AAgentCard = () => {
20
- return useAuiState((s) => asA2AExtras(s.thread.extras).agentCard);
21
- };
22
8
  function useA2ARuntime(options) {
23
9
  const [_version, setVersion] = useState(0);
24
10
  const notifyUpdate = useCallback(() => setVersion((v) => v + 1), []);
@@ -93,12 +79,11 @@ function useA2ARuntime(options) {
93
79
  isLoading: core.isLoading,
94
80
  messages: core.getMessages(),
95
81
  isRunning: core.isRunning(),
96
- extras: {
97
- [symbolA2AExtras]: true,
82
+ extras: a2aExtras.provide({
98
83
  task: core.getTask(),
99
84
  artifacts: core.getArtifacts(),
100
85
  agentCard: core.getAgentCard()
101
- },
86
+ }),
102
87
  onNew: (message) => core.append(message),
103
88
  onEdit: (message) => core.edit(message),
104
89
  onReload: (parentId) => core.reload(parentId),
@@ -125,6 +110,6 @@ function useA2ARuntime(options) {
125
110
  return runtime;
126
111
  }
127
112
  //#endregion
128
- export { useA2AAgentCard, useA2AArtifacts, useA2ARuntime, useA2ATask };
113
+ export { useA2ARuntime };
129
114
 
130
115
  //# sourceMappingURL=useA2ARuntime.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useA2ARuntime.js","names":[],"sources":["../src/useA2ARuntime.ts"],"sourcesContent":["\"use client\";\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport {\n useExternalStoreRuntime,\n useExternalStoreSharedOptions,\n useRuntimeAdapters,\n} from \"@assistant-ui/core/react\";\nimport type {\n AssistantRuntime,\n AppendMessage,\n AttachmentAdapter,\n DictationAdapter,\n ExternalStoreAdapter,\n ExternalStoreSharedOptions,\n FeedbackAdapter,\n RealtimeVoiceAdapter,\n SpeechSynthesisAdapter,\n ThreadHistoryAdapter,\n ThreadMessage,\n} from \"@assistant-ui/core\";\nimport { useAuiState } from \"@assistant-ui/store\";\nimport { A2AClient } from \"./A2AClient\";\nimport type { A2AClientOptions } from \"./A2AClient\";\nimport { A2AThreadRuntimeCore } from \"./A2AThreadRuntimeCore\";\nimport type {\n A2AArtifact,\n A2AAgentCard,\n A2ASendMessageConfiguration,\n A2ATask,\n} from \"./types\";\n\n// --- Extras symbol for A2A-specific state ---\n\nconst symbolA2AExtras = Symbol(\"a2a-extras\");\n\ntype A2AExtras = {\n [symbolA2AExtras]: true;\n task: A2ATask | undefined;\n artifacts: readonly A2AArtifact[];\n agentCard: A2AAgentCard | undefined;\n};\n\nconst asA2AExtras = (extras: unknown): A2AExtras => {\n if (\n typeof extras !== \"object\" ||\n extras == null ||\n !(symbolA2AExtras in extras)\n )\n throw new Error(\n \"This hook can only be used inside a useA2ARuntime provider\",\n );\n return extras as A2AExtras;\n};\n\n// --- Public hooks for A2A state ---\n\nexport const useA2ATask = () => {\n return useAuiState((s) => asA2AExtras(s.thread.extras).task);\n};\n\nexport const useA2AArtifacts = () => {\n return useAuiState((s) => asA2AExtras(s.thread.extras).artifacts);\n};\n\nexport const useA2AAgentCard = () => {\n return useAuiState((s) => asA2AExtras(s.thread.extras).agentCard);\n};\n\n// --- Thread list adapter type ---\n\nexport type UseA2AThreadListAdapter = {\n threadId?: string;\n onSwitchToNewThread?: () => Promise<void> | void;\n onSwitchToThread?: (threadId: string) => Promise<{\n messages: readonly ThreadMessage[];\n }>;\n};\n\n// --- Options ---\n\nexport type UseA2ARuntimeOptions = ExternalStoreSharedOptions & {\n /** Pre-built A2A client instance. Provide this OR baseUrl. */\n client?: A2AClient;\n /** Base URL of the A2A server. Used to create a client if `client` is not provided. */\n baseUrl?: string;\n /** Optional path prefix for all API endpoints (e.g. \"/v1\"). Does not affect agent card discovery. Only used with baseUrl. */\n basePath?: string;\n /** Optional tenant ID for multi-tenant servers. Only used with baseUrl. */\n tenant?: string;\n /** Headers for the A2A client (only used with baseUrl). */\n headers?: A2AClientOptions[\"headers\"];\n /** A2A extension URIs to negotiate. Only used with baseUrl. */\n extensions?: string[];\n /** Extra fetch options (e.g. `{ credentials: 'include' }`). Only used with `baseUrl`. */\n fetchOptions?: A2AClientOptions[\"fetchOptions\"];\n\n /** Initial context ID for the conversation. */\n contextId?: string;\n /** Default send message configuration. */\n configuration?: A2ASendMessageConfiguration;\n\n /** Called when an error occurs. */\n onError?: (error: Error) => void;\n /** Called when a run is cancelled. */\n onCancel?: () => void;\n /** Called when an artifact is fully received (lastChunk). */\n onArtifactComplete?: (artifact: import(\"./types\").A2AArtifact) => void;\n\n adapters?: {\n attachments?: AttachmentAdapter;\n speech?: SpeechSynthesisAdapter;\n dictation?: DictationAdapter;\n voice?: RealtimeVoiceAdapter;\n feedback?: FeedbackAdapter;\n history?: ThreadHistoryAdapter;\n threadList?: UseA2AThreadListAdapter;\n };\n};\n\n// --- Main hook ---\n\nexport function useA2ARuntime(options: UseA2ARuntimeOptions): AssistantRuntime {\n const [_version, setVersion] = useState(0);\n const notifyUpdate = useCallback(() => setVersion((v) => v + 1), []);\n const runtimeAdapters = useRuntimeAdapters();\n const historyAdapter = options.adapters?.history ?? runtimeAdapters?.history;\n const threadListAdapter = options.adapters?.threadList;\n\n // Create or reuse client\n const clientRef = useRef<A2AClient | null>(null);\n if (!clientRef.current) {\n if (options.client) {\n clientRef.current = options.client;\n } else if (options.baseUrl) {\n clientRef.current = new A2AClient({\n baseUrl: options.baseUrl,\n basePath: options.basePath,\n tenant: options.tenant,\n headers: options.headers,\n extensions: options.extensions,\n fetchOptions: options.fetchOptions,\n });\n } else {\n throw new Error(\"useA2ARuntime requires either `client` or `baseUrl`\");\n }\n }\n const client = clientRef.current;\n\n // Create or reuse core\n const coreRef = useRef<A2AThreadRuntimeCore | null>(null);\n if (!coreRef.current) {\n coreRef.current = new A2AThreadRuntimeCore({\n client,\n contextId: options.contextId,\n configuration: options.configuration,\n ...(options.onError && { onError: options.onError }),\n ...(options.onCancel && { onCancel: options.onCancel }),\n ...(options.onArtifactComplete && {\n onArtifactComplete: options.onArtifactComplete,\n }),\n ...(historyAdapter && { history: historyAdapter }),\n notifyUpdate,\n });\n }\n\n const core = coreRef.current;\n core.updateOptions({\n client,\n contextId: options.contextId,\n configuration: options.configuration,\n ...(options.onError && { onError: options.onError }),\n ...(options.onCancel && { onCancel: options.onCancel }),\n ...(options.onArtifactComplete && {\n onArtifactComplete: options.onArtifactComplete,\n }),\n ...(historyAdapter && { history: historyAdapter }),\n });\n\n // Thread list\n const threadList = useMemo(() => {\n if (!threadListAdapter) return undefined;\n\n const { onSwitchToNewThread, onSwitchToThread } = threadListAdapter;\n\n return {\n threadId: threadListAdapter.threadId,\n onSwitchToNewThread: onSwitchToNewThread\n ? async () => {\n await onSwitchToNewThread();\n core.applyExternalMessages([]);\n }\n : undefined,\n onSwitchToThread: onSwitchToThread\n ? async (threadId: string) => {\n const result = await onSwitchToThread(threadId);\n core.applyExternalMessages(result.messages);\n }\n : undefined,\n };\n }, [threadListAdapter, core]);\n\n // Adapters\n const adapters = options.adapters;\n const adapterAdapters = useMemo(\n () => ({\n attachments: adapters?.attachments ?? runtimeAdapters?.attachments,\n speech: adapters?.speech,\n dictation: adapters?.dictation,\n voice: adapters?.voice,\n feedback: adapters?.feedback,\n threadList,\n }),\n [adapters, runtimeAdapters, threadList],\n );\n\n // Build store adapter\n const shared = useExternalStoreSharedOptions(options);\n const store = useMemo(() => {\n void _version;\n\n return {\n ...shared,\n isLoading: core.isLoading,\n messages: core.getMessages(),\n isRunning: core.isRunning(),\n extras: {\n [symbolA2AExtras]: true,\n task: core.getTask(),\n artifacts: core.getArtifacts(),\n agentCard: core.getAgentCard(),\n } satisfies A2AExtras,\n onNew: (message: AppendMessage) => core.append(message),\n onEdit: (message: AppendMessage) => core.edit(message),\n onReload: (parentId: string | null) => core.reload(parentId),\n onCancel: () => core.cancel(),\n setMessages: (messages: readonly ThreadMessage[]) =>\n core.applyExternalMessages(messages),\n onImport: (messages: readonly ThreadMessage[]) =>\n core.applyExternalMessages(messages),\n adapters: adapterAdapters,\n } satisfies ExternalStoreAdapter<ThreadMessage>;\n }, [adapterAdapters, core, _version, shared]);\n\n const runtime = useExternalStoreRuntime(store);\n\n useEffect(() => {\n core.attachRuntime(runtime);\n return () => {\n core.detachRuntime();\n };\n }, [core, runtime]);\n\n useEffect(() => {\n core.__internal_load();\n }, [core]);\n\n return runtime;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"useA2ARuntime.js","names":[],"sources":["../src/useA2ARuntime.ts"],"sourcesContent":["\"use client\";\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport {\n useExternalStoreRuntime,\n useExternalStoreSharedOptions,\n useRuntimeAdapters,\n} from \"@assistant-ui/core/react\";\nimport type {\n AssistantRuntime,\n AppendMessage,\n ExternalStoreAdapter,\n ThreadMessage,\n} from \"@assistant-ui/core\";\nimport { A2AClient } from \"./A2AClient\";\nimport { A2AThreadRuntimeCore } from \"./A2AThreadRuntimeCore\";\nimport { a2aExtras } from \"./a2aExtras\";\nimport type { UseA2ARuntimeOptions } from \"./types\";\n\nexport function useA2ARuntime(options: UseA2ARuntimeOptions): AssistantRuntime {\n const [_version, setVersion] = useState(0);\n const notifyUpdate = useCallback(() => setVersion((v) => v + 1), []);\n const runtimeAdapters = useRuntimeAdapters();\n const historyAdapter = options.adapters?.history ?? runtimeAdapters?.history;\n const threadListAdapter = options.adapters?.threadList;\n\n // Create or reuse client\n const clientRef = useRef<A2AClient | null>(null);\n if (!clientRef.current) {\n if (options.client) {\n clientRef.current = options.client;\n } else if (options.baseUrl) {\n clientRef.current = new A2AClient({\n baseUrl: options.baseUrl,\n basePath: options.basePath,\n tenant: options.tenant,\n headers: options.headers,\n extensions: options.extensions,\n fetchOptions: options.fetchOptions,\n });\n } else {\n throw new Error(\"useA2ARuntime requires either `client` or `baseUrl`\");\n }\n }\n const client = clientRef.current;\n\n // Create or reuse core\n const coreRef = useRef<A2AThreadRuntimeCore | null>(null);\n if (!coreRef.current) {\n coreRef.current = new A2AThreadRuntimeCore({\n client,\n contextId: options.contextId,\n configuration: options.configuration,\n ...(options.onError && { onError: options.onError }),\n ...(options.onCancel && { onCancel: options.onCancel }),\n ...(options.onArtifactComplete && {\n onArtifactComplete: options.onArtifactComplete,\n }),\n ...(historyAdapter && { history: historyAdapter }),\n notifyUpdate,\n });\n }\n\n const core = coreRef.current;\n core.updateOptions({\n client,\n contextId: options.contextId,\n configuration: options.configuration,\n ...(options.onError && { onError: options.onError }),\n ...(options.onCancel && { onCancel: options.onCancel }),\n ...(options.onArtifactComplete && {\n onArtifactComplete: options.onArtifactComplete,\n }),\n ...(historyAdapter && { history: historyAdapter }),\n });\n\n // Thread list\n const threadList = useMemo(() => {\n if (!threadListAdapter) return undefined;\n\n const { onSwitchToNewThread, onSwitchToThread } = threadListAdapter;\n\n return {\n threadId: threadListAdapter.threadId,\n onSwitchToNewThread: onSwitchToNewThread\n ? async () => {\n await onSwitchToNewThread();\n core.applyExternalMessages([]);\n }\n : undefined,\n onSwitchToThread: onSwitchToThread\n ? async (threadId: string) => {\n const result = await onSwitchToThread(threadId);\n core.applyExternalMessages(result.messages);\n }\n : undefined,\n };\n }, [threadListAdapter, core]);\n\n // Adapters\n const adapters = options.adapters;\n const adapterAdapters = useMemo(\n () => ({\n attachments: adapters?.attachments ?? runtimeAdapters?.attachments,\n speech: adapters?.speech,\n dictation: adapters?.dictation,\n voice: adapters?.voice,\n feedback: adapters?.feedback,\n threadList,\n }),\n [adapters, runtimeAdapters, threadList],\n );\n\n // Build store adapter\n const shared = useExternalStoreSharedOptions(options);\n const store = useMemo(() => {\n void _version;\n\n return {\n ...shared,\n isLoading: core.isLoading,\n messages: core.getMessages(),\n isRunning: core.isRunning(),\n extras: a2aExtras.provide({\n task: core.getTask(),\n artifacts: core.getArtifacts(),\n agentCard: core.getAgentCard(),\n }),\n onNew: (message: AppendMessage) => core.append(message),\n onEdit: (message: AppendMessage) => core.edit(message),\n onReload: (parentId: string | null) => core.reload(parentId),\n onCancel: () => core.cancel(),\n setMessages: (messages: readonly ThreadMessage[]) =>\n core.applyExternalMessages(messages),\n onImport: (messages: readonly ThreadMessage[]) =>\n core.applyExternalMessages(messages),\n adapters: adapterAdapters,\n } satisfies ExternalStoreAdapter<ThreadMessage>;\n }, [adapterAdapters, core, _version, shared]);\n\n const runtime = useExternalStoreRuntime(store);\n\n useEffect(() => {\n core.attachRuntime(runtime);\n return () => {\n core.detachRuntime();\n };\n }, [core, runtime]);\n\n useEffect(() => {\n core.__internal_load();\n }, [core]);\n\n return runtime;\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@assistant-ui/react-a2a",
3
- "version": "0.2.20",
3
+ "version": "0.2.21",
4
4
  "description": "A2A (Agent-to-Agent) v1.0 protocol adapter for assistant-ui",
5
5
  "keywords": [
6
6
  "a2a",
@@ -29,8 +29,8 @@
29
29
  ],
30
30
  "sideEffects": false,
31
31
  "dependencies": {
32
- "@assistant-ui/core": "^0.2.17",
33
- "@assistant-ui/store": "^0.2.18"
32
+ "@assistant-ui/core": "^0.2.19",
33
+ "@assistant-ui/store": "^0.2.19"
34
34
  },
35
35
  "peerDependencies": {
36
36
  "@types/react": "*",
@@ -44,8 +44,8 @@
44
44
  "devDependencies": {
45
45
  "@types/react": "^19.2.17",
46
46
  "react": "^19.2.7",
47
- "vitest": "^4.1.8",
48
- "@assistant-ui/x-buildutils": "0.0.15"
47
+ "vitest": "^4.1.9",
48
+ "@assistant-ui/x-buildutils": "0.0.16"
49
49
  },
50
50
  "publishConfig": {
51
51
  "access": "public",
@@ -0,0 +1,4 @@
1
+ import { createRuntimeExtras } from "@assistant-ui/core/internal";
2
+ import type { A2AExtras } from "./types";
3
+
4
+ export const a2aExtras = createRuntimeExtras<A2AExtras>("useA2ARuntime");
package/src/hooks.ts ADDED
@@ -0,0 +1,12 @@
1
+ "use client";
2
+
3
+ import { a2aExtras } from "./a2aExtras";
4
+
5
+ /** The current A2A task, if a run is in progress. */
6
+ export const useA2ATask = () => a2aExtras.use((e) => e.task);
7
+
8
+ /** The artifacts accumulated for the current A2A run. */
9
+ export const useA2AArtifacts = () => a2aExtras.use((e) => e.artifacts);
10
+
11
+ /** The discovered A2A agent card. */
12
+ export const useA2AAgentCard = () => a2aExtras.use((e) => e.agentCard);
package/src/index.ts CHANGED
@@ -1,14 +1,7 @@
1
1
  // Main hook
2
- export {
3
- useA2ARuntime,
4
- useA2ATask,
5
- useA2AArtifacts,
6
- useA2AAgentCard,
7
- } from "./useA2ARuntime";
8
- export type {
9
- UseA2ARuntimeOptions,
10
- UseA2AThreadListAdapter,
11
- } from "./useA2ARuntime";
2
+ export { useA2ARuntime } from "./useA2ARuntime";
3
+ export { useA2ATask, useA2AArtifacts, useA2AAgentCard } from "./hooks";
4
+ export type { UseA2ARuntimeOptions, UseA2AThreadListAdapter } from "./types";
12
5
 
13
6
  // Client
14
7
  export { A2AClient, A2AError } from "./A2AClient";
package/src/types.ts CHANGED
@@ -2,6 +2,18 @@
2
2
  // Enum values use lowercase internally; normalized from ProtoJSON SCREAMING_SNAKE_CASE on read.
3
3
  // Wire format uses ROLE_USER/ROLE_AGENT and TASK_STATE_* per ADR-001.
4
4
 
5
+ import type {
6
+ AttachmentAdapter,
7
+ DictationAdapter,
8
+ ExternalStoreSharedOptions,
9
+ FeedbackAdapter,
10
+ RealtimeVoiceAdapter,
11
+ SpeechSynthesisAdapter,
12
+ ThreadHistoryAdapter,
13
+ ThreadMessage,
14
+ } from "@assistant-ui/core";
15
+ import type { A2AClient, A2AClientOptions } from "./A2AClient";
16
+
5
17
  export const A2A_PROTOCOL_VERSION = "1.0";
6
18
 
7
19
  export type A2ARole = "unspecified" | "user" | "agent";
@@ -281,3 +293,57 @@ export type A2AAgentCard = {
281
293
  signatures?: A2AAgentCardSignature[] | undefined;
282
294
  iconUrl?: string | undefined;
283
295
  };
296
+
297
+ /** Private state `useA2ARuntime` exposes through `thread.extras`. */
298
+ export type A2AExtras = {
299
+ task: A2ATask | undefined;
300
+ artifacts: readonly A2AArtifact[];
301
+ agentCard: A2AAgentCard | undefined;
302
+ };
303
+
304
+ export type UseA2AThreadListAdapter = {
305
+ threadId?: string;
306
+ onSwitchToNewThread?: () => Promise<void> | void;
307
+ onSwitchToThread?: (threadId: string) => Promise<{
308
+ messages: readonly ThreadMessage[];
309
+ }>;
310
+ };
311
+
312
+ export type UseA2ARuntimeOptions = ExternalStoreSharedOptions & {
313
+ /** Pre-built A2A client instance. Provide this OR baseUrl. */
314
+ client?: A2AClient;
315
+ /** Base URL of the A2A server. Used to create a client if `client` is not provided. */
316
+ baseUrl?: string;
317
+ /** Optional path prefix for all API endpoints (e.g. "/v1"). Does not affect agent card discovery. Only used with baseUrl. */
318
+ basePath?: string;
319
+ /** Optional tenant ID for multi-tenant servers. Only used with baseUrl. */
320
+ tenant?: string;
321
+ /** Headers for the A2A client (only used with baseUrl). */
322
+ headers?: A2AClientOptions["headers"];
323
+ /** A2A extension URIs to negotiate. Only used with baseUrl. */
324
+ extensions?: string[];
325
+ /** Extra fetch options (e.g. `{ credentials: 'include' }`). Only used with `baseUrl`. */
326
+ fetchOptions?: A2AClientOptions["fetchOptions"];
327
+
328
+ /** Initial context ID for the conversation. */
329
+ contextId?: string;
330
+ /** Default send message configuration. */
331
+ configuration?: A2ASendMessageConfiguration;
332
+
333
+ /** Called when an error occurs. */
334
+ onError?: (error: Error) => void;
335
+ /** Called when a run is cancelled. */
336
+ onCancel?: () => void;
337
+ /** Called when an artifact is fully received (lastChunk). */
338
+ onArtifactComplete?: (artifact: A2AArtifact) => void;
339
+
340
+ adapters?: {
341
+ attachments?: AttachmentAdapter;
342
+ speech?: SpeechSynthesisAdapter;
343
+ dictation?: DictationAdapter;
344
+ voice?: RealtimeVoiceAdapter;
345
+ feedback?: FeedbackAdapter;
346
+ history?: ThreadHistoryAdapter;
347
+ threadList?: UseA2AThreadListAdapter;
348
+ };
349
+ };
@@ -9,116 +9,13 @@ import {
9
9
  import type {
10
10
  AssistantRuntime,
11
11
  AppendMessage,
12
- AttachmentAdapter,
13
- DictationAdapter,
14
12
  ExternalStoreAdapter,
15
- ExternalStoreSharedOptions,
16
- FeedbackAdapter,
17
- RealtimeVoiceAdapter,
18
- SpeechSynthesisAdapter,
19
- ThreadHistoryAdapter,
20
13
  ThreadMessage,
21
14
  } from "@assistant-ui/core";
22
- import { useAuiState } from "@assistant-ui/store";
23
15
  import { A2AClient } from "./A2AClient";
24
- import type { A2AClientOptions } from "./A2AClient";
25
16
  import { A2AThreadRuntimeCore } from "./A2AThreadRuntimeCore";
26
- import type {
27
- A2AArtifact,
28
- A2AAgentCard,
29
- A2ASendMessageConfiguration,
30
- A2ATask,
31
- } from "./types";
32
-
33
- // --- Extras symbol for A2A-specific state ---
34
-
35
- const symbolA2AExtras = Symbol("a2a-extras");
36
-
37
- type A2AExtras = {
38
- [symbolA2AExtras]: true;
39
- task: A2ATask | undefined;
40
- artifacts: readonly A2AArtifact[];
41
- agentCard: A2AAgentCard | undefined;
42
- };
43
-
44
- const asA2AExtras = (extras: unknown): A2AExtras => {
45
- if (
46
- typeof extras !== "object" ||
47
- extras == null ||
48
- !(symbolA2AExtras in extras)
49
- )
50
- throw new Error(
51
- "This hook can only be used inside a useA2ARuntime provider",
52
- );
53
- return extras as A2AExtras;
54
- };
55
-
56
- // --- Public hooks for A2A state ---
57
-
58
- export const useA2ATask = () => {
59
- return useAuiState((s) => asA2AExtras(s.thread.extras).task);
60
- };
61
-
62
- export const useA2AArtifacts = () => {
63
- return useAuiState((s) => asA2AExtras(s.thread.extras).artifacts);
64
- };
65
-
66
- export const useA2AAgentCard = () => {
67
- return useAuiState((s) => asA2AExtras(s.thread.extras).agentCard);
68
- };
69
-
70
- // --- Thread list adapter type ---
71
-
72
- export type UseA2AThreadListAdapter = {
73
- threadId?: string;
74
- onSwitchToNewThread?: () => Promise<void> | void;
75
- onSwitchToThread?: (threadId: string) => Promise<{
76
- messages: readonly ThreadMessage[];
77
- }>;
78
- };
79
-
80
- // --- Options ---
81
-
82
- export type UseA2ARuntimeOptions = ExternalStoreSharedOptions & {
83
- /** Pre-built A2A client instance. Provide this OR baseUrl. */
84
- client?: A2AClient;
85
- /** Base URL of the A2A server. Used to create a client if `client` is not provided. */
86
- baseUrl?: string;
87
- /** Optional path prefix for all API endpoints (e.g. "/v1"). Does not affect agent card discovery. Only used with baseUrl. */
88
- basePath?: string;
89
- /** Optional tenant ID for multi-tenant servers. Only used with baseUrl. */
90
- tenant?: string;
91
- /** Headers for the A2A client (only used with baseUrl). */
92
- headers?: A2AClientOptions["headers"];
93
- /** A2A extension URIs to negotiate. Only used with baseUrl. */
94
- extensions?: string[];
95
- /** Extra fetch options (e.g. `{ credentials: 'include' }`). Only used with `baseUrl`. */
96
- fetchOptions?: A2AClientOptions["fetchOptions"];
97
-
98
- /** Initial context ID for the conversation. */
99
- contextId?: string;
100
- /** Default send message configuration. */
101
- configuration?: A2ASendMessageConfiguration;
102
-
103
- /** Called when an error occurs. */
104
- onError?: (error: Error) => void;
105
- /** Called when a run is cancelled. */
106
- onCancel?: () => void;
107
- /** Called when an artifact is fully received (lastChunk). */
108
- onArtifactComplete?: (artifact: import("./types").A2AArtifact) => void;
109
-
110
- adapters?: {
111
- attachments?: AttachmentAdapter;
112
- speech?: SpeechSynthesisAdapter;
113
- dictation?: DictationAdapter;
114
- voice?: RealtimeVoiceAdapter;
115
- feedback?: FeedbackAdapter;
116
- history?: ThreadHistoryAdapter;
117
- threadList?: UseA2AThreadListAdapter;
118
- };
119
- };
120
-
121
- // --- Main hook ---
17
+ import { a2aExtras } from "./a2aExtras";
18
+ import type { UseA2ARuntimeOptions } from "./types";
122
19
 
123
20
  export function useA2ARuntime(options: UseA2ARuntimeOptions): AssistantRuntime {
124
21
  const [_version, setVersion] = useState(0);
@@ -224,12 +121,11 @@ export function useA2ARuntime(options: UseA2ARuntimeOptions): AssistantRuntime {
224
121
  isLoading: core.isLoading,
225
122
  messages: core.getMessages(),
226
123
  isRunning: core.isRunning(),
227
- extras: {
228
- [symbolA2AExtras]: true,
124
+ extras: a2aExtras.provide({
229
125
  task: core.getTask(),
230
126
  artifacts: core.getArtifacts(),
231
127
  agentCard: core.getAgentCard(),
232
- } satisfies A2AExtras,
128
+ }),
233
129
  onNew: (message: AppendMessage) => core.append(message),
234
130
  onEdit: (message: AppendMessage) => core.edit(message),
235
131
  onReload: (parentId: string | null) => core.reload(parentId),