@assistant-ui/react-a2a 0.2.48 → 0.2.50

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
@@ -1,7 +1,7 @@
1
1
  import "./types.js";
2
2
  import { SSEEventDecoder } from "assistant-stream/utils";
3
3
  import { isRecord, raceWithAbortSignal } from "@assistant-ui/core/internal";
4
- //#region src/A2AClient.ts
4
+ // src/A2AClient.ts
5
5
  var A2AError = class extends Error {
6
6
  code;
7
7
  status;
@@ -630,7 +630,6 @@ var A2AClient = class {
630
630
  return firstSkipReason;
631
631
  }
632
632
  };
633
- //#endregion
634
633
  export { A2AClient, A2AError };
635
634
 
636
635
  //# sourceMappingURL=A2AClient.js.map
@@ -4,7 +4,7 @@ import { createA2AThreadState, reduceA2AThreadState } from "./a2aThreadState.js"
4
4
  import { RunLeases, appendToolInteraction, createHistoryWriteChain, createMessageRepositorySession, invokeUserCallback } from "@assistant-ui/core/internal";
5
5
  import { fromThreadMessageLike, generateId } from "@assistant-ui/core";
6
6
  import { surfaceToPresentToolCall } from "@assistant-ui/generative-ui/a2ui";
7
- //#region src/A2AThreadController.ts
7
+ // src/A2AThreadController.ts
8
8
  const INITIAL_AGENT_CARD_RETRY_DELAY_MS = 5e3;
9
9
  const MAX_AGENT_CARD_RETRY_DELAY_MS = 3e5;
10
10
  const isRecord$1 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
@@ -641,7 +641,6 @@ var A2AThreadController = class {
641
641
  return write;
642
642
  }
643
643
  };
644
- //#endregion
645
644
  export { A2AThreadController };
646
645
 
647
646
  //# sourceMappingURL=A2AThreadController.js.map
package/dist/a2aExtras.js CHANGED
@@ -1,7 +1,6 @@
1
1
  import { createRuntimeExtras } from "@assistant-ui/core/react";
2
- //#region src/a2aExtras.ts
2
+ // src/a2aExtras.ts
3
3
  const a2aExtras = createRuntimeExtras("useA2ARuntime");
4
- //#endregion
5
4
  export { a2aExtras };
6
5
 
7
6
  //# sourceMappingURL=a2aExtras.js.map
@@ -1,6 +1,6 @@
1
1
  import { a2uiPartsToOperations, isTerminalTaskState } from "./conversions.js";
2
2
  import { applyA2uiOperations } from "@assistant-ui/generative-ui/a2ui";
3
- //#region src/a2aThreadState.ts
3
+ // src/a2aThreadState.ts
4
4
  const createA2AThreadState = (contextId) => ({
5
5
  currentTask: void 0,
6
6
  currentArtifacts: [],
@@ -146,7 +146,6 @@ const reduceA2AThreadState = (state, action) => {
146
146
  };
147
147
  }
148
148
  };
149
- //#endregion
150
149
  export { createA2AThreadState, reduceA2AThreadState };
151
150
 
152
151
  //# sourceMappingURL=a2aThreadState.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"conversions.d.ts","sourceRoot":"","sources":["../src/conversions.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,aAAa,EACb,sBAAsB,EACtB,aAAa,EACd,MAAM,oBAAoB,CAAC;AAM5B,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,EAAE,mBAAgB;AAwBjE,wBAAgB,cAAc,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAarD;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,OAAO,GAAG,SAAS,OAAO,EAAE,CAGtE;AAED,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,SAAS,OAAO,EAAE,GACxB,SAAS,OAAO,EAAE,CAGpB;AAED,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,OAAO,GACZ,sBAAsB,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAwC3C;AAED,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,OAAO,EAAE,GACf,sBAAsB,CAAC,SAAS,CAAC,CAInC;AAcD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAEhE;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAEnE;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,YAAY,GAAG,aAAa,CAkB3E;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,aAAa,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,UAAU,CAAC,EAAE,KAAK,GAAG,IAAI,GAAG,SAAS,CAAC;IACtC,KAAK,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;CACtD,CAAC,EACF,gBAAgB,CAAC,EAAE,MAAM,GACxB,OAAO,EAAE,CA0EX;AAED,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,UAAU,GAClB,sBAAsB,CAAC,SAAS,CAAC,CAEnC;AAED,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,aAAa,EACtB,OAAO,GAAE;IACP,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACxB,GACL,UAAU,CA6BZ"}
1
+ {"version":3,"file":"conversions.d.ts","sourceRoot":"","sources":["../src/conversions.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,aAAa,EACb,sBAAsB,EACtB,aAAa,EACd,MAAM,oBAAoB,CAAC;AAO5B,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,EAAE,mBAAgB;AAwBjE,wBAAgB,cAAc,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAarD;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,OAAO,GAAG,SAAS,OAAO,EAAE,CAGtE;AAED,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,SAAS,OAAO,EAAE,GACxB,SAAS,OAAO,EAAE,CAGpB;AAED,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,OAAO,GACZ,sBAAsB,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAwC3C;AAED,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,OAAO,EAAE,GACf,sBAAsB,CAAC,SAAS,CAAC,CAInC;AAcD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAEhE;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAEnE;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,YAAY,GAAG,aAAa,CAkB3E;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,aAAa,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,UAAU,CAAC,EAAE,KAAK,GAAG,IAAI,GAAG,SAAS,CAAC;IACtC,KAAK,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;CACtD,CAAC,EACF,gBAAgB,CAAC,EAAE,MAAM,GACxB,OAAO,EAAE,CA8EX;AAED,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,UAAU,GAClB,sBAAsB,CAAC,SAAS,CAAC,CAEnC;AAED,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,aAAa,EACtB,OAAO,GAAE;IACP,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACxB,GACL,UAAU,CA6BZ"}
@@ -1,6 +1,6 @@
1
1
  "use client";
2
- import { parseDataUrl, resolveFilePartSource, resolveImageMediaType } from "@assistant-ui/core/internal";
3
- //#region src/conversions.ts
2
+ import { parseBase64, parseDataUrl, resolveFilePartSource, resolveImageMediaType } from "@assistant-ui/core/internal";
3
+ // src/conversions.ts
4
4
  function isImageMediaType(mediaType) {
5
5
  return !!mediaType && mediaType.startsWith("image/");
6
6
  }
@@ -119,9 +119,10 @@ function contentPartsToA2AParts(content, fallbackMimeType) {
119
119
  case "image": {
120
120
  if (!part.image) return null;
121
121
  const parsed = parseDataUrl(part.image);
122
- if (parsed) return {
123
- raw: parsed.data,
124
- mediaType: resolveImageMediaType(part.image, fallbackMimeType),
122
+ const data = parsed?.data ?? parseBase64(part.image);
123
+ if (data !== null) return {
124
+ raw: data,
125
+ mediaType: resolveImageMediaType(parsed ? part.image : data, fallbackMimeType),
125
126
  ...part.filename && { filename: part.filename }
126
127
  };
127
128
  return {
@@ -190,7 +191,6 @@ function threadMessageToA2AMessage(message, options = {}) {
190
191
  if (options.taskId) a2aMsg.taskId = options.taskId;
191
192
  return a2aMsg;
192
193
  }
193
- //#endregion
194
194
  export { a2aMessageToContent, a2aPartToContent, a2aPartsToContent, a2uiPartToOperations, a2uiPartsToOperations, contentPartsToA2AParts, isA2uiDataPart, isInterruptedTaskState, isTerminalTaskState, taskStateToMessageStatus, threadMessageToA2AMessage };
195
195
 
196
196
  //# sourceMappingURL=conversions.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"conversions.js","names":["isRecord"],"sources":["../src/conversions.ts"],"sourcesContent":["\"use client\";\n\nimport type {\n MessageStatus,\n ThreadAssistantMessage,\n ThreadMessage,\n} from \"@assistant-ui/core\";\nimport {\n parseDataUrl,\n resolveFilePartSource,\n resolveImageMediaType,\n} from \"@assistant-ui/core/internal\";\nimport type { A2AMessage, A2APart, A2ATaskState } from \"./types\";\n\nfunction isImageMediaType(mediaType?: string): boolean {\n return !!mediaType && mediaType.startsWith(\"image/\");\n}\n\nconst A2UI_OPERATION_KEYS = [\n \"createSurface\",\n \"updateComponents\",\n \"updateDataModel\",\n \"deleteSurface\",\n] as const;\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst isA2uiOperation = (value: unknown): boolean =>\n isRecord(value) &&\n typeof value.version === \"string\" &&\n A2UI_OPERATION_KEYS.some((key) => Object.hasOwn(value, key));\n\nconst hasA2uiMediaType = (value: unknown): boolean =>\n typeof value === \"string\" && value.toLowerCase().includes(\"a2ui\");\n\nexport function isA2uiDataPart(part: A2APart): boolean {\n if (part.data === undefined) return false;\n\n const metadata = isRecord(part.metadata) ? part.metadata : {};\n return (\n hasA2uiMediaType(part.mediaType) ||\n hasA2uiMediaType(metadata.mimeType) ||\n hasA2uiMediaType(metadata.mediaType) ||\n isA2uiOperation(part.data) ||\n (Array.isArray(part.data) &&\n part.data.length > 0 &&\n part.data.every(isA2uiOperation))\n );\n}\n\nexport function a2uiPartToOperations(part: A2APart): readonly unknown[] {\n if (!isA2uiDataPart(part)) return [];\n return Array.isArray(part.data) ? part.data : [part.data];\n}\n\nexport function a2uiPartsToOperations(\n parts: readonly A2APart[],\n): readonly unknown[] {\n if (!Array.isArray(parts)) return [];\n return parts.flatMap(a2uiPartToOperations);\n}\n\nexport function a2aPartToContent(\n part: A2APart,\n): ThreadAssistantMessage[\"content\"][number] {\n if (!isRecord(part)) return { type: \"text\", text: \"\" };\n if (part.text != null) {\n return { type: \"text\", text: part.text };\n }\n if (part.url != null) {\n if (isImageMediaType(part.mediaType)) {\n return {\n type: \"image\",\n image: part.url,\n ...(part.filename && { filename: part.filename }),\n };\n }\n return {\n type: \"file\",\n data: part.url,\n mimeType: part.mediaType ?? \"application/octet-stream\",\n sourceType: \"url\",\n ...(part.filename && { filename: part.filename }),\n };\n }\n if (part.raw != null) {\n if (isImageMediaType(part.mediaType)) {\n return {\n type: \"image\",\n image: `data:${part.mediaType};base64,${part.raw}`,\n ...(part.filename && { filename: part.filename }),\n };\n }\n return {\n type: \"file\",\n data: part.raw,\n mimeType: part.mediaType ?? \"application/octet-stream\",\n ...(part.filename && { filename: part.filename }),\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 (Array.isArray(parts) ? parts : [])\n .filter((part) => isRecord(part) && !isA2uiDataPart(part))\n .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 | undefined;\n image?: string | undefined;\n data?: unknown;\n mimeType?: string | undefined;\n filename?: string | undefined;\n sourceType?: \"url\" | \"id\" | undefined;\n audio?: { data: string; format: string } | undefined;\n }>,\n fallbackMimeType?: string,\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 const parsed = parseDataUrl(part.image);\n if (parsed) {\n return {\n raw: parsed.data,\n mediaType: resolveImageMediaType(part.image, fallbackMimeType),\n ...(part.filename && { filename: part.filename }),\n };\n }\n return {\n url: part.image,\n ...(fallbackMimeType && { mediaType: fallbackMimeType }),\n ...(part.filename && { filename: part.filename }),\n };\n }\n case \"file\": {\n if (typeof part.data !== \"string\") return null;\n const declaredMimeType = part.mimeType || fallbackMimeType;\n const source = resolveFilePartSource({\n data: part.data,\n mimeType: declaredMimeType ?? \"application/octet-stream\",\n sourceType: part.sourceType,\n });\n if (source.kind === \"url\") {\n return {\n url: source.url,\n ...(declaredMimeType && { mediaType: declaredMimeType }),\n ...(part.filename && { filename: part.filename }),\n };\n }\n const parsed = parseDataUrl(part.data);\n if (parsed) {\n return {\n raw: source.data,\n mediaType: source.mimeType,\n ...(part.filename && { filename: part.filename }),\n };\n }\n if (/^data:/i.test(part.data)) {\n return {\n url: part.data,\n ...(declaredMimeType && { mediaType: declaredMimeType }),\n ...(part.filename && { filename: part.filename }),\n };\n }\n return {\n raw: source.data,\n ...(declaredMimeType && { mediaType: declaredMimeType }),\n ...(part.filename && { filename: part.filename }),\n };\n }\n case \"audio\": {\n if (!part.audio) return null;\n return {\n raw: parseDataUrl(part.audio.data)?.data ?? part.audio.data,\n mediaType: `audio/${part.audio.format}`,\n };\n }\n case \"data\": {\n if (part.data === undefined) return null;\n return { data: part.data };\n }\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\nexport function threadMessageToA2AMessage(\n message: ThreadMessage,\n options: {\n contextId?: string | undefined;\n taskId?: string | undefined;\n } = {},\n): A2AMessage {\n const parts: A2APart[] = [];\n\n if (message.role === \"user\") {\n parts.push(...contentPartsToA2AParts(message.content));\n for (const attachment of message.attachments ?? []) {\n parts.push(\n ...contentPartsToA2AParts(\n attachment.content ?? [],\n attachment.contentType,\n ),\n );\n }\n }\n\n const a2aMsg: A2AMessage = {\n messageId: message.id,\n role: \"user\",\n parts,\n };\n\n if (options.contextId) {\n a2aMsg.contextId = options.contextId;\n }\n if (options.taskId) {\n a2aMsg.taskId = options.taskId;\n }\n\n return a2aMsg;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"conversions.js","names":["isRecord"],"sources":["../src/conversions.ts"],"sourcesContent":["\"use client\";\n\nimport type {\n MessageStatus,\n ThreadAssistantMessage,\n ThreadMessage,\n} from \"@assistant-ui/core\";\nimport {\n parseBase64,\n parseDataUrl,\n resolveFilePartSource,\n resolveImageMediaType,\n} from \"@assistant-ui/core/internal\";\nimport type { A2AMessage, A2APart, A2ATaskState } from \"./types\";\n\nfunction isImageMediaType(mediaType?: string): boolean {\n return !!mediaType && mediaType.startsWith(\"image/\");\n}\n\nconst A2UI_OPERATION_KEYS = [\n \"createSurface\",\n \"updateComponents\",\n \"updateDataModel\",\n \"deleteSurface\",\n] as const;\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst isA2uiOperation = (value: unknown): boolean =>\n isRecord(value) &&\n typeof value.version === \"string\" &&\n A2UI_OPERATION_KEYS.some((key) => Object.hasOwn(value, key));\n\nconst hasA2uiMediaType = (value: unknown): boolean =>\n typeof value === \"string\" && value.toLowerCase().includes(\"a2ui\");\n\nexport function isA2uiDataPart(part: A2APart): boolean {\n if (part.data === undefined) return false;\n\n const metadata = isRecord(part.metadata) ? part.metadata : {};\n return (\n hasA2uiMediaType(part.mediaType) ||\n hasA2uiMediaType(metadata.mimeType) ||\n hasA2uiMediaType(metadata.mediaType) ||\n isA2uiOperation(part.data) ||\n (Array.isArray(part.data) &&\n part.data.length > 0 &&\n part.data.every(isA2uiOperation))\n );\n}\n\nexport function a2uiPartToOperations(part: A2APart): readonly unknown[] {\n if (!isA2uiDataPart(part)) return [];\n return Array.isArray(part.data) ? part.data : [part.data];\n}\n\nexport function a2uiPartsToOperations(\n parts: readonly A2APart[],\n): readonly unknown[] {\n if (!Array.isArray(parts)) return [];\n return parts.flatMap(a2uiPartToOperations);\n}\n\nexport function a2aPartToContent(\n part: A2APart,\n): ThreadAssistantMessage[\"content\"][number] {\n if (!isRecord(part)) return { type: \"text\", text: \"\" };\n if (part.text != null) {\n return { type: \"text\", text: part.text };\n }\n if (part.url != null) {\n if (isImageMediaType(part.mediaType)) {\n return {\n type: \"image\",\n image: part.url,\n ...(part.filename && { filename: part.filename }),\n };\n }\n return {\n type: \"file\",\n data: part.url,\n mimeType: part.mediaType ?? \"application/octet-stream\",\n sourceType: \"url\",\n ...(part.filename && { filename: part.filename }),\n };\n }\n if (part.raw != null) {\n if (isImageMediaType(part.mediaType)) {\n return {\n type: \"image\",\n image: `data:${part.mediaType};base64,${part.raw}`,\n ...(part.filename && { filename: part.filename }),\n };\n }\n return {\n type: \"file\",\n data: part.raw,\n mimeType: part.mediaType ?? \"application/octet-stream\",\n ...(part.filename && { filename: part.filename }),\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 (Array.isArray(parts) ? parts : [])\n .filter((part) => isRecord(part) && !isA2uiDataPart(part))\n .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 | undefined;\n image?: string | undefined;\n data?: unknown;\n mimeType?: string | undefined;\n filename?: string | undefined;\n sourceType?: \"url\" | \"id\" | undefined;\n audio?: { data: string; format: string } | undefined;\n }>,\n fallbackMimeType?: string,\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 const parsed = parseDataUrl(part.image);\n const data = parsed?.data ?? parseBase64(part.image);\n if (data !== null) {\n return {\n raw: data,\n mediaType: resolveImageMediaType(\n parsed ? part.image : data,\n fallbackMimeType,\n ),\n ...(part.filename && { filename: part.filename }),\n };\n }\n return {\n url: part.image,\n ...(fallbackMimeType && { mediaType: fallbackMimeType }),\n ...(part.filename && { filename: part.filename }),\n };\n }\n case \"file\": {\n if (typeof part.data !== \"string\") return null;\n const declaredMimeType = part.mimeType || fallbackMimeType;\n const source = resolveFilePartSource({\n data: part.data,\n mimeType: declaredMimeType ?? \"application/octet-stream\",\n sourceType: part.sourceType,\n });\n if (source.kind === \"url\") {\n return {\n url: source.url,\n ...(declaredMimeType && { mediaType: declaredMimeType }),\n ...(part.filename && { filename: part.filename }),\n };\n }\n const parsed = parseDataUrl(part.data);\n if (parsed) {\n return {\n raw: source.data,\n mediaType: source.mimeType,\n ...(part.filename && { filename: part.filename }),\n };\n }\n if (/^data:/i.test(part.data)) {\n return {\n url: part.data,\n ...(declaredMimeType && { mediaType: declaredMimeType }),\n ...(part.filename && { filename: part.filename }),\n };\n }\n return {\n raw: source.data,\n ...(declaredMimeType && { mediaType: declaredMimeType }),\n ...(part.filename && { filename: part.filename }),\n };\n }\n case \"audio\": {\n if (!part.audio) return null;\n return {\n raw: parseDataUrl(part.audio.data)?.data ?? part.audio.data,\n mediaType: `audio/${part.audio.format}`,\n };\n }\n case \"data\": {\n if (part.data === undefined) return null;\n return { data: part.data };\n }\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\nexport function threadMessageToA2AMessage(\n message: ThreadMessage,\n options: {\n contextId?: string | undefined;\n taskId?: string | undefined;\n } = {},\n): A2AMessage {\n const parts: A2APart[] = [];\n\n if (message.role === \"user\") {\n parts.push(...contentPartsToA2AParts(message.content));\n for (const attachment of message.attachments ?? []) {\n parts.push(\n ...contentPartsToA2AParts(\n attachment.content ?? [],\n attachment.contentType,\n ),\n );\n }\n }\n\n const a2aMsg: A2AMessage = {\n messageId: message.id,\n role: \"user\",\n parts,\n };\n\n if (options.contextId) {\n a2aMsg.contextId = options.contextId;\n }\n if (options.taskId) {\n a2aMsg.taskId = options.taskId;\n }\n\n return a2aMsg;\n}\n"],"mappings":"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"}
package/dist/hooks.js CHANGED
@@ -1,13 +1,12 @@
1
1
  "use client";
2
2
  import { a2aExtras } from "./a2aExtras.js";
3
- //#region src/hooks.ts
3
+ // src/hooks.ts
4
4
  /** The current A2A task, if a run is in progress. */
5
5
  const useA2ATask = () => a2aExtras.use((e) => e.task);
6
6
  /** The artifacts accumulated for the current A2A run. */
7
7
  const useA2AArtifacts = () => a2aExtras.use((e) => e.artifacts);
8
8
  /** The discovered A2A agent card. */
9
9
  const useA2AAgentCard = () => a2aExtras.use((e) => e.agentCard);
10
- //#endregion
11
10
  export { useA2AAgentCard, useA2AArtifacts, useA2ATask };
12
11
 
13
12
  //# sourceMappingURL=hooks.js.map
package/dist/types.js CHANGED
@@ -1,6 +1,5 @@
1
- //#region src/types.ts
1
+ // src/types.ts
2
2
  const A2A_PROTOCOL_VERSION = "1.0";
3
- //#endregion
4
3
  export { A2A_PROTOCOL_VERSION };
5
4
 
6
5
  //# sourceMappingURL=types.js.map
@@ -5,7 +5,7 @@ import { a2aExtras } from "./a2aExtras.js";
5
5
  import { useExternalStoreRuntime, useExternalStoreSharedOptions, useRuntimeAdapters } from "@assistant-ui/core/react";
6
6
  import { useCallback, useEffect, useInsertionEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
7
7
  import { useReplaySafeEffect } from "@assistant-ui/store/internal";
8
- //#region src/useA2ARuntime.ts
8
+ // src/useA2ARuntime.ts
9
9
  const serializeManagedClientOptions = (options) => {
10
10
  const fetchOptions = Object.fromEntries(Object.entries(options.fetchOptions ?? {}).sort(([a], [b]) => a.localeCompare(b)));
11
11
  return JSON.stringify({
@@ -182,7 +182,6 @@ function useA2ARuntime(options) {
182
182
  }, [core]);
183
183
  return runtime;
184
184
  }
185
- //#endregion
186
185
  export { useA2ARuntime };
187
186
 
188
187
  //# sourceMappingURL=useA2ARuntime.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@assistant-ui/react-a2a",
3
- "version": "0.2.48",
3
+ "version": "0.2.50",
4
4
  "description": "A2A (Agent-to-Agent) v1.0 protocol adapter for assistant-ui",
5
5
  "keywords": [
6
6
  "a2a",
@@ -29,10 +29,10 @@
29
29
  ],
30
30
  "sideEffects": false,
31
31
  "dependencies": {
32
- "@assistant-ui/core": "^0.3.31",
33
- "@assistant-ui/generative-ui": "^0.0.7",
34
- "@assistant-ui/store": "^0.3.22",
35
- "assistant-stream": "^0.3.54"
32
+ "@assistant-ui/core": "^0.3.33",
33
+ "@assistant-ui/generative-ui": "^0.0.9",
34
+ "@assistant-ui/store": "^0.3.23",
35
+ "assistant-stream": "^0.3.56"
36
36
  },
37
37
  "peerDependencies": {
38
38
  "@types/react": "*",
@@ -44,7 +44,7 @@
44
44
  }
45
45
  },
46
46
  "devDependencies": {
47
- "@assistant-ui/x-buildutils": "0.0.31",
47
+ "@assistant-ui/x-buildutils": "0.0.32",
48
48
  "@assistant-ui/x-react18": "0.0.0",
49
49
  "@testing-library/dom": "^10.4.2",
50
50
  "@testing-library/react": "^16.3.3",
@@ -475,6 +475,34 @@ describe("isInterruptedTaskState", () => {
475
475
  });
476
476
 
477
477
  describe("contentPartsToA2AParts", () => {
478
+ it.each([
479
+ [
480
+ "image/png",
481
+ "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR4nGP4z8DwHwAFAAH/iZk9HQAAAABJRU5ErkJggg==",
482
+ ],
483
+ ["image/jpeg", "/9j/4AAQSkZJRg=="],
484
+ ["image/jpeg", "/9j/4AAQ\r\nSkZJRg==", "/9j/4AAQSkZJRg=="],
485
+ ["image/png", "PHN2Zy8+"],
486
+ ])(
487
+ "sends bare base64 %s images as raw image bytes",
488
+ (mediaType, image, data = image) => {
489
+ expect(
490
+ contentPartsToA2AParts([
491
+ { type: "image", image, filename: "pixel.png" },
492
+ ]),
493
+ ).toEqual([{ raw: data, mediaType, filename: "pixel.png" }]);
494
+ },
495
+ );
496
+
497
+ it.each(["/uploads/cat.png", "/9j/uploads/cat.png"])(
498
+ "preserves relative image reference %s",
499
+ (image) => {
500
+ expect(
501
+ contentPartsToA2AParts([{ type: "image", image, filename: "cat.png" }]),
502
+ ).toEqual([{ url: image, filename: "cat.png" }]);
503
+ },
504
+ );
505
+
478
506
  it.each(["application/pdf", ""])(
479
507
  "unwraps a media-less data URL while retaining the adapter's %j MIME fallback",
480
508
  (mimeType) => {
@@ -6,6 +6,7 @@ import type {
6
6
  ThreadMessage,
7
7
  } from "@assistant-ui/core";
8
8
  import {
9
+ parseBase64,
9
10
  parseDataUrl,
10
11
  resolveFilePartSource,
11
12
  resolveImageMediaType,
@@ -174,10 +175,14 @@ export function contentPartsToA2AParts(
174
175
  case "image": {
175
176
  if (!part.image) return null;
176
177
  const parsed = parseDataUrl(part.image);
177
- if (parsed) {
178
+ const data = parsed?.data ?? parseBase64(part.image);
179
+ if (data !== null) {
178
180
  return {
179
- raw: parsed.data,
180
- mediaType: resolveImageMediaType(part.image, fallbackMimeType),
181
+ raw: data,
182
+ mediaType: resolveImageMediaType(
183
+ parsed ? part.image : data,
184
+ fallbackMimeType,
185
+ ),
181
186
  ...(part.filename && { filename: part.filename }),
182
187
  };
183
188
  }