@assistant-ui/react-a2a 0.2.15 → 0.2.17

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.
@@ -1,48 +1,42 @@
1
- /// <reference types="@assistant-ui/core/store" />
2
- import type { AssistantRuntime, AttachmentAdapter, FeedbackAdapter, SpeechSynthesisAdapter, ThreadHistoryAdapter, ThreadMessage } from "@assistant-ui/core";
3
- import { A2AClient } from "./A2AClient.js";
4
- import type { A2AClientOptions } from "./A2AClient.js";
5
- import type { A2AArtifact, A2AAgentCard, A2ASendMessageConfiguration, A2ATask } from "./types.js";
6
- export declare const useA2ATask: () => A2ATask | undefined;
7
- export declare const useA2AArtifacts: () => readonly A2AArtifact[];
8
- export declare const useA2AAgentCard: () => A2AAgentCard | undefined;
9
- export type UseA2AThreadListAdapter = {
10
- threadId?: string;
11
- onSwitchToNewThread?: () => Promise<void> | void;
12
- onSwitchToThread?: (threadId: string) => Promise<{
13
- messages: readonly ThreadMessage[];
14
- }>;
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";
4
+
5
+ //#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
15
  };
16
- export type UseA2ARuntimeOptions = {
17
- /** Pre-built A2A client instance. Provide this OR baseUrl. */
18
- client?: A2AClient;
19
- /** Base URL of the A2A server. Used to create a client if `client` is not provided. */
20
- baseUrl?: string;
21
- /** Optional path prefix for all API endpoints (e.g. "/v1"). Does not affect agent card discovery. Only used with baseUrl. */
22
- basePath?: string;
23
- /** Optional tenant ID for multi-tenant servers. Only used with baseUrl. */
24
- tenant?: string;
25
- /** Headers for the A2A client (only used with baseUrl). */
26
- headers?: A2AClientOptions["headers"];
27
- /** A2A extension URIs to negotiate. Only used with baseUrl. */
28
- extensions?: string[];
29
- /** Initial context ID for the conversation. */
30
- contextId?: string;
31
- /** Default send message configuration. */
32
- configuration?: A2ASendMessageConfiguration;
33
- /** Called when an error occurs. */
34
- onError?: (error: Error) => void;
35
- /** Called when a run is cancelled. */
36
- onCancel?: () => void;
37
- /** Called when an artifact is fully received (lastChunk). */
38
- onArtifactComplete?: (artifact: import("./types").A2AArtifact) => void;
39
- adapters?: {
40
- attachments?: AttachmentAdapter;
41
- speech?: SpeechSynthesisAdapter;
42
- feedback?: FeedbackAdapter;
43
- history?: ThreadHistoryAdapter;
44
- threadList?: UseA2AThreadListAdapter;
45
- };
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
+ };
46
38
  };
47
- export declare function useA2ARuntime(options: UseA2ARuntimeOptions): AssistantRuntime;
39
+ declare function useA2ARuntime(options: UseA2ARuntimeOptions): AssistantRuntime;
40
+ //#endregion
41
+ export { UseA2ARuntimeOptions, UseA2AThreadListAdapter, useA2AAgentCard, useA2AArtifacts, useA2ARuntime, useA2ATask };
48
42
  //# sourceMappingURL=useA2ARuntime.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useA2ARuntime.d.ts","sourceRoot":"","sources":["../src/useA2ARuntime.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACV,gBAAgB,EAEhB,iBAAiB,EAEjB,eAAe,EACf,sBAAsB,EACtB,oBAAoB,EACpB,aAAa,EACd,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,SAAS,EAAE,uBAAoB;AACxC,OAAO,KAAK,EAAE,gBAAgB,EAAE,uBAAoB;AAEpD,OAAO,KAAK,EACV,WAAW,EACX,YAAY,EACZ,2BAA2B,EAC3B,OAAO,EACR,mBAAgB;AA2BjB,eAAO,MAAM,UAAU,2BAEtB,CAAC;AAEF,eAAO,MAAM,eAAe,8BAE3B,CAAC;AAEF,eAAO,MAAM,eAAe,gCAE3B,CAAC;AAIF,MAAM,MAAM,uBAAuB,GAAG;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mBAAmB,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACjD,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;QAC/C,QAAQ,EAAE,SAAS,aAAa,EAAE,CAAC;KACpC,CAAC,CAAC;CACJ,CAAC;AAIF,MAAM,MAAM,oBAAoB,GAAG;IACjC,8DAA8D;IAC9D,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,uFAAuF;IACvF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6HAA6H;IAC7H,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2EAA2E;IAC3E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2DAA2D;IAC3D,OAAO,CAAC,EAAE,gBAAgB,CAAC,SAAS,CAAC,CAAC;IACtC,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IAEtB,+CAA+C;IAC/C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0CAA0C;IAC1C,aAAa,CAAC,EAAE,2BAA2B,CAAC;IAE5C,mCAAmC;IACnC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,sCAAsC;IACtC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,6DAA6D;IAC7D,kBAAkB,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,SAAS,EAAE,WAAW,KAAK,IAAI,CAAC;IAEvE,QAAQ,CAAC,EAAE;QACT,WAAW,CAAC,EAAE,iBAAiB,CAAC;QAChC,MAAM,CAAC,EAAE,sBAAsB,CAAC;QAChC,QAAQ,CAAC,EAAE,eAAe,CAAC;QAC3B,OAAO,CAAC,EAAE,oBAAoB,CAAC;QAC/B,UAAU,CAAC,EAAE,uBAAuB,CAAC;KACtC,CAAC;CACH,CAAC;AAIF,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,gBAAgB,CAmI7E"}
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,145 +1,130 @@
1
- /// <reference types="@assistant-ui/core/store" />
2
1
  "use client";
3
- import { useCallback, useEffect, useMemo, useRef, useState } from "react";
4
- import { useExternalStoreRuntime, useRuntimeAdapters, } from "@assistant-ui/core/react";
5
- import { useAuiState } from "@assistant-ui/store";
6
2
  import { A2AClient } from "./A2AClient.js";
7
3
  import { A2AThreadRuntimeCore } from "./A2AThreadRuntimeCore.js";
8
- // --- Extras symbol for A2A-specific state ---
4
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
5
+ import { useExternalStoreRuntime, useExternalStoreSharedOptions, useRuntimeAdapters } from "@assistant-ui/core/react";
6
+ import { useAuiState } from "@assistant-ui/store";
7
+ //#region src/useA2ARuntime.ts
9
8
  const symbolA2AExtras = Symbol("a2a-extras");
10
9
  const asA2AExtras = (extras) => {
11
- if (typeof extras !== "object" ||
12
- extras == null ||
13
- !(symbolA2AExtras in extras))
14
- throw new Error("This hook can only be used inside a useA2ARuntime provider");
15
- return 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;
16
12
  };
17
- // --- Public hooks for A2A state ---
18
- export const useA2ATask = () => {
19
- return useAuiState((s) => asA2AExtras(s.thread.extras).task);
13
+ const useA2ATask = () => {
14
+ return useAuiState((s) => asA2AExtras(s.thread.extras).task);
20
15
  };
21
- export const useA2AArtifacts = () => {
22
- return useAuiState((s) => asA2AExtras(s.thread.extras).artifacts);
16
+ const useA2AArtifacts = () => {
17
+ return useAuiState((s) => asA2AExtras(s.thread.extras).artifacts);
23
18
  };
24
- export const useA2AAgentCard = () => {
25
- return useAuiState((s) => asA2AExtras(s.thread.extras).agentCard);
19
+ const useA2AAgentCard = () => {
20
+ return useAuiState((s) => asA2AExtras(s.thread.extras).agentCard);
26
21
  };
27
- // --- Main hook ---
28
- export function useA2ARuntime(options) {
29
- const [_version, setVersion] = useState(0);
30
- const notifyUpdate = useCallback(() => setVersion((v) => v + 1), []);
31
- const runtimeAdapters = useRuntimeAdapters();
32
- const historyAdapter = options.adapters?.history ?? runtimeAdapters?.history;
33
- const threadListAdapter = options.adapters?.threadList;
34
- // Create or reuse client
35
- const clientRef = useRef(null);
36
- if (!clientRef.current) {
37
- if (options.client) {
38
- clientRef.current = options.client;
39
- }
40
- else if (options.baseUrl) {
41
- clientRef.current = new A2AClient({
42
- baseUrl: options.baseUrl,
43
- basePath: options.basePath,
44
- tenant: options.tenant,
45
- headers: options.headers,
46
- extensions: options.extensions,
47
- });
48
- }
49
- else {
50
- throw new Error("useA2ARuntime requires either `client` or `baseUrl`");
51
- }
52
- }
53
- const client = clientRef.current;
54
- // Create or reuse core
55
- const coreRef = useRef(null);
56
- if (!coreRef.current) {
57
- coreRef.current = new A2AThreadRuntimeCore({
58
- client,
59
- contextId: options.contextId,
60
- configuration: options.configuration,
61
- ...(options.onError && { onError: options.onError }),
62
- ...(options.onCancel && { onCancel: options.onCancel }),
63
- ...(options.onArtifactComplete && {
64
- onArtifactComplete: options.onArtifactComplete,
65
- }),
66
- ...(historyAdapter && { history: historyAdapter }),
67
- notifyUpdate,
68
- });
69
- }
70
- const core = coreRef.current;
71
- core.updateOptions({
72
- client,
73
- contextId: options.contextId,
74
- configuration: options.configuration,
75
- ...(options.onError && { onError: options.onError }),
76
- ...(options.onCancel && { onCancel: options.onCancel }),
77
- ...(options.onArtifactComplete && {
78
- onArtifactComplete: options.onArtifactComplete,
79
- }),
80
- ...(historyAdapter && { history: historyAdapter }),
81
- });
82
- // Thread list
83
- const threadList = useMemo(() => {
84
- if (!threadListAdapter)
85
- return undefined;
86
- const { onSwitchToNewThread, onSwitchToThread } = threadListAdapter;
87
- return {
88
- threadId: threadListAdapter.threadId,
89
- onSwitchToNewThread: onSwitchToNewThread
90
- ? async () => {
91
- await onSwitchToNewThread();
92
- core.applyExternalMessages([]);
93
- }
94
- : undefined,
95
- onSwitchToThread: onSwitchToThread
96
- ? async (threadId) => {
97
- const result = await onSwitchToThread(threadId);
98
- core.applyExternalMessages(result.messages);
99
- }
100
- : undefined,
101
- };
102
- }, [threadListAdapter, core]);
103
- // Adapters
104
- const adapters = options.adapters;
105
- const adapterAdapters = useMemo(() => ({
106
- attachments: adapters?.attachments ?? runtimeAdapters?.attachments,
107
- speech: adapters?.speech,
108
- feedback: adapters?.feedback,
109
- threadList,
110
- }), [adapters, runtimeAdapters, threadList]);
111
- // Build store adapter
112
- const store = useMemo(() => {
113
- void _version;
114
- return {
115
- isLoading: core.isLoading,
116
- messages: core.getMessages(),
117
- isRunning: core.isRunning(),
118
- extras: {
119
- [symbolA2AExtras]: true,
120
- task: core.getTask(),
121
- artifacts: core.getArtifacts(),
122
- agentCard: core.getAgentCard(),
123
- },
124
- onNew: (message) => core.append(message),
125
- onEdit: (message) => core.edit(message),
126
- onReload: (parentId) => core.reload(parentId),
127
- onCancel: () => core.cancel(),
128
- setMessages: (messages) => core.applyExternalMessages(messages),
129
- onImport: (messages) => core.applyExternalMessages(messages),
130
- adapters: adapterAdapters,
131
- };
132
- }, [adapterAdapters, core, _version]);
133
- const runtime = useExternalStoreRuntime(store);
134
- useEffect(() => {
135
- core.attachRuntime(runtime);
136
- return () => {
137
- core.detachRuntime();
138
- };
139
- }, [core, runtime]);
140
- useEffect(() => {
141
- core.__internal_load();
142
- }, [core]);
143
- return runtime;
22
+ function useA2ARuntime(options) {
23
+ const [_version, setVersion] = useState(0);
24
+ const notifyUpdate = useCallback(() => setVersion((v) => v + 1), []);
25
+ const runtimeAdapters = useRuntimeAdapters();
26
+ const historyAdapter = options.adapters?.history ?? runtimeAdapters?.history;
27
+ const threadListAdapter = options.adapters?.threadList;
28
+ const clientRef = useRef(null);
29
+ if (!clientRef.current) if (options.client) clientRef.current = options.client;
30
+ else if (options.baseUrl) clientRef.current = new A2AClient({
31
+ baseUrl: options.baseUrl,
32
+ basePath: options.basePath,
33
+ tenant: options.tenant,
34
+ headers: options.headers,
35
+ extensions: options.extensions,
36
+ fetchOptions: options.fetchOptions
37
+ });
38
+ else throw new Error("useA2ARuntime requires either `client` or `baseUrl`");
39
+ const client = clientRef.current;
40
+ const coreRef = useRef(null);
41
+ if (!coreRef.current) coreRef.current = new A2AThreadRuntimeCore({
42
+ client,
43
+ contextId: options.contextId,
44
+ configuration: options.configuration,
45
+ ...options.onError && { onError: options.onError },
46
+ ...options.onCancel && { onCancel: options.onCancel },
47
+ ...options.onArtifactComplete && { onArtifactComplete: options.onArtifactComplete },
48
+ ...historyAdapter && { history: historyAdapter },
49
+ notifyUpdate
50
+ });
51
+ const core = coreRef.current;
52
+ core.updateOptions({
53
+ client,
54
+ contextId: options.contextId,
55
+ configuration: options.configuration,
56
+ ...options.onError && { onError: options.onError },
57
+ ...options.onCancel && { onCancel: options.onCancel },
58
+ ...options.onArtifactComplete && { onArtifactComplete: options.onArtifactComplete },
59
+ ...historyAdapter && { history: historyAdapter }
60
+ });
61
+ const threadList = useMemo(() => {
62
+ if (!threadListAdapter) return void 0;
63
+ const { onSwitchToNewThread, onSwitchToThread } = threadListAdapter;
64
+ return {
65
+ threadId: threadListAdapter.threadId,
66
+ onSwitchToNewThread: onSwitchToNewThread ? async () => {
67
+ await onSwitchToNewThread();
68
+ core.applyExternalMessages([]);
69
+ } : void 0,
70
+ onSwitchToThread: onSwitchToThread ? async (threadId) => {
71
+ const result = await onSwitchToThread(threadId);
72
+ core.applyExternalMessages(result.messages);
73
+ } : void 0
74
+ };
75
+ }, [threadListAdapter, core]);
76
+ const adapters = options.adapters;
77
+ const adapterAdapters = useMemo(() => ({
78
+ attachments: adapters?.attachments ?? runtimeAdapters?.attachments,
79
+ speech: adapters?.speech,
80
+ dictation: adapters?.dictation,
81
+ voice: adapters?.voice,
82
+ feedback: adapters?.feedback,
83
+ threadList
84
+ }), [
85
+ adapters,
86
+ runtimeAdapters,
87
+ threadList
88
+ ]);
89
+ const shared = useExternalStoreSharedOptions(options);
90
+ const runtime = useExternalStoreRuntime(useMemo(() => {
91
+ return {
92
+ ...shared,
93
+ isLoading: core.isLoading,
94
+ messages: core.getMessages(),
95
+ isRunning: core.isRunning(),
96
+ extras: {
97
+ [symbolA2AExtras]: true,
98
+ task: core.getTask(),
99
+ artifacts: core.getArtifacts(),
100
+ agentCard: core.getAgentCard()
101
+ },
102
+ onNew: (message) => core.append(message),
103
+ onEdit: (message) => core.edit(message),
104
+ onReload: (parentId) => core.reload(parentId),
105
+ onCancel: () => core.cancel(),
106
+ setMessages: (messages) => core.applyExternalMessages(messages),
107
+ onImport: (messages) => core.applyExternalMessages(messages),
108
+ adapters: adapterAdapters
109
+ };
110
+ }, [
111
+ adapterAdapters,
112
+ core,
113
+ _version,
114
+ shared
115
+ ]));
116
+ useEffect(() => {
117
+ core.attachRuntime(runtime);
118
+ return () => {
119
+ core.detachRuntime();
120
+ };
121
+ }, [core, runtime]);
122
+ useEffect(() => {
123
+ core.__internal_load();
124
+ }, [core]);
125
+ return runtime;
144
126
  }
127
+ //#endregion
128
+ export { useA2AAgentCard, useA2AArtifacts, useA2ARuntime, useA2ATask };
129
+
145
130
  //# sourceMappingURL=useA2ARuntime.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useA2ARuntime.js","sourceRoot":"","sources":["../src/useA2ARuntime.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAClD,YAAY,CAAC;AAEb,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC1E,OAAO,EACL,uBAAuB,EACvB,kBAAkB,GACnB,MAAM,0BAA0B,CAAC;AAWlC,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,uBAAoB;AAExC,OAAO,EAAE,oBAAoB,EAAE,kCAA+B;AAQ9D,+CAA+C;AAE/C,MAAM,eAAe,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC;AAS7C,MAAM,WAAW,GAAG,CAAC,MAAe,EAAa,EAAE;IACjD,IACE,OAAO,MAAM,KAAK,QAAQ;QAC1B,MAAM,IAAI,IAAI;QACd,CAAC,CAAC,eAAe,IAAI,MAAM,CAAC;QAE5B,MAAM,IAAI,KAAK,CACb,4DAA4D,CAC7D,CAAC;IACJ,OAAO,MAAmB,CAAC;AAC7B,CAAC,CAAC;AAEF,qCAAqC;AAErC,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,EAAE;IAC7B,OAAO,WAAW,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC;AAC/D,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,EAAE;IAClC,OAAO,WAAW,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC;AACpE,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,EAAE;IAClC,OAAO,WAAW,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC;AACpE,CAAC,CAAC;AAiDF,oBAAoB;AAEpB,MAAM,UAAU,aAAa,CAAC,OAA6B;IACzD,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC3C,MAAM,YAAY,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACrE,MAAM,eAAe,GAAG,kBAAkB,EAAE,CAAC;IAC7C,MAAM,cAAc,GAAG,OAAO,CAAC,QAAQ,EAAE,OAAO,IAAI,eAAe,EAAE,OAAO,CAAC;IAC7E,MAAM,iBAAiB,GAAG,OAAO,CAAC,QAAQ,EAAE,UAAU,CAAC;IAEvD,yBAAyB;IACzB,MAAM,SAAS,GAAG,MAAM,CAAmB,IAAI,CAAC,CAAC;IACjD,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;QACvB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACnB,SAAS,CAAC,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;QACrC,CAAC;aAAM,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YAC3B,SAAS,CAAC,OAAO,GAAG,IAAI,SAAS,CAAC;gBAChC,OAAO,EAAE,OAAO,CAAC,OAAO;gBACxB,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,OAAO,EAAE,OAAO,CAAC,OAAO;gBACxB,UAAU,EAAE,OAAO,CAAC,UAAU;aAC/B,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;QACzE,CAAC;IACH,CAAC;IACD,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC;IAEjC,uBAAuB;IACvB,MAAM,OAAO,GAAG,MAAM,CAA8B,IAAI,CAAC,CAAC;IAC1D,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;QACrB,OAAO,CAAC,OAAO,GAAG,IAAI,oBAAoB,CAAC;YACzC,MAAM;YACN,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,aAAa,EAAE,OAAO,CAAC,aAAa;YACpC,GAAG,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC;YACpD,GAAG,CAAC,OAAO,CAAC,QAAQ,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC;YACvD,GAAG,CAAC,OAAO,CAAC,kBAAkB,IAAI;gBAChC,kBAAkB,EAAE,OAAO,CAAC,kBAAkB;aAC/C,CAAC;YACF,GAAG,CAAC,cAAc,IAAI,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC;YAClD,YAAY;SACb,CAAC,CAAC;IACL,CAAC;IAED,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC;IAC7B,IAAI,CAAC,aAAa,CAAC;QACjB,MAAM;QACN,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,aAAa,EAAE,OAAO,CAAC,aAAa;QACpC,GAAG,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC;QACpD,GAAG,CAAC,OAAO,CAAC,QAAQ,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC;QACvD,GAAG,CAAC,OAAO,CAAC,kBAAkB,IAAI;YAChC,kBAAkB,EAAE,OAAO,CAAC,kBAAkB;SAC/C,CAAC;QACF,GAAG,CAAC,cAAc,IAAI,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC;KACnD,CAAC,CAAC;IAEH,cAAc;IACd,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE;QAC9B,IAAI,CAAC,iBAAiB;YAAE,OAAO,SAAS,CAAC;QAEzC,MAAM,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,GAAG,iBAAiB,CAAC;QAEpE,OAAO;YACL,QAAQ,EAAE,iBAAiB,CAAC,QAAQ;YACpC,mBAAmB,EAAE,mBAAmB;gBACtC,CAAC,CAAC,KAAK,IAAI,EAAE;oBACT,MAAM,mBAAmB,EAAE,CAAC;oBAC5B,IAAI,CAAC,qBAAqB,CAAC,EAAE,CAAC,CAAC;gBACjC,CAAC;gBACH,CAAC,CAAC,SAAS;YACb,gBAAgB,EAAE,gBAAgB;gBAChC,CAAC,CAAC,KAAK,EAAE,QAAgB,EAAE,EAAE;oBACzB,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,QAAQ,CAAC,CAAC;oBAChD,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;gBAC9C,CAAC;gBACH,CAAC,CAAC,SAAS;SACd,CAAC;IACJ,CAAC,EAAE,CAAC,iBAAiB,EAAE,IAAI,CAAC,CAAC,CAAC;IAE9B,WAAW;IACX,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAClC,MAAM,eAAe,GAAG,OAAO,CAC7B,GAAG,EAAE,CAAC,CAAC;QACL,WAAW,EAAE,QAAQ,EAAE,WAAW,IAAI,eAAe,EAAE,WAAW;QAClE,MAAM,EAAE,QAAQ,EAAE,MAAM;QACxB,QAAQ,EAAE,QAAQ,EAAE,QAAQ;QAC5B,UAAU;KACX,CAAC,EACF,CAAC,QAAQ,EAAE,eAAe,EAAE,UAAU,CAAC,CACxC,CAAC;IAEF,sBAAsB;IACtB,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,EAAE;QACzB,KAAK,QAAQ,CAAC;QAEd,OAAO;YACL,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,QAAQ,EAAE,IAAI,CAAC,WAAW,EAAE;YAC5B,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE;YAC3B,MAAM,EAAE;gBACN,CAAC,eAAe,CAAC,EAAE,IAAI;gBACvB,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE;gBACpB,SAAS,EAAE,IAAI,CAAC,YAAY,EAAE;gBAC9B,SAAS,EAAE,IAAI,CAAC,YAAY,EAAE;aACX;YACrB,KAAK,EAAE,CAAC,OAAsB,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;YACvD,MAAM,EAAE,CAAC,OAAsB,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;YACtD,QAAQ,EAAE,CAAC,QAAuB,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;YAC5D,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE;YAC7B,WAAW,EAAE,CAAC,QAAkC,EAAE,EAAE,CAClD,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAC;YACtC,QAAQ,EAAE,CAAC,QAAkC,EAAE,EAAE,CAC/C,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAC;YACtC,QAAQ,EAAE,eAAe;SACoB,CAAC;IAClD,CAAC,EAAE,CAAC,eAAe,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;IAEtC,MAAM,OAAO,GAAG,uBAAuB,CAAC,KAAK,CAAC,CAAC;IAE/C,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QAC5B,OAAO,GAAG,EAAE;YACV,IAAI,CAAC,aAAa,EAAE,CAAC;QACvB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;IAEpB,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,eAAe,EAAE,CAAC;IACzB,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IAEX,OAAO,OAAO,CAAC;AACjB,CAAC"}
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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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@assistant-ui/react-a2a",
3
- "version": "0.2.15",
3
+ "version": "0.2.17",
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.3",
33
- "@assistant-ui/store": "^0.2.11"
32
+ "@assistant-ui/core": "^0.2.8",
33
+ "@assistant-ui/store": "^0.2.13"
34
34
  },
35
35
  "peerDependencies": {
36
36
  "@types/react": "*",
@@ -42,10 +42,10 @@
42
42
  }
43
43
  },
44
44
  "devDependencies": {
45
- "@types/react": "^19.2.14",
46
- "react": "^19.2.5",
47
- "vitest": "^4.1.5",
48
- "@assistant-ui/x-buildutils": "0.0.8"
45
+ "@types/react": "^19.2.15",
46
+ "react": "^19.2.6",
47
+ "vitest": "^4.1.7",
48
+ "@assistant-ui/x-buildutils": "0.0.10"
49
49
  },
50
50
  "publishConfig": {
51
51
  "access": "public",
@@ -148,6 +148,115 @@ describe("A2AClient", () => {
148
148
  });
149
149
  });
150
150
 
151
+ describe("fetchOptions", () => {
152
+ it("applies fetchOptions to all request types", async () => {
153
+ const fetchOptionsClient = new A2AClient({
154
+ baseUrl: "https://agent.test",
155
+ fetchOptions: { credentials: "include" },
156
+ });
157
+
158
+ fetchMock
159
+ .mockResolvedValueOnce(
160
+ mockFetchResponse({
161
+ task: { id: "t1", status: { state: "completed" } },
162
+ }),
163
+ )
164
+ .mockResolvedValueOnce(
165
+ mockFetchResponse({
166
+ name: "Test Agent",
167
+ description: "A test",
168
+ version: "1.0",
169
+ supportedInterfaces: [],
170
+ capabilities: {},
171
+ defaultInputModes: [],
172
+ defaultOutputModes: [],
173
+ skills: [],
174
+ }),
175
+ )
176
+ .mockResolvedValueOnce(
177
+ mockSSEResponse([
178
+ `data: ${JSON.stringify({ status_update: { task_id: "t1", context_id: "ctx-1", status: { state: "TASK_STATE_WORKING" } } })}`,
179
+ "",
180
+ "",
181
+ ]),
182
+ )
183
+ .mockResolvedValueOnce(
184
+ mockSSEResponse([
185
+ `data: ${JSON.stringify({ status_update: { task_id: "t1", context_id: "ctx-1", status: { state: "TASK_STATE_WORKING" } } })}`,
186
+ "",
187
+ "",
188
+ ]),
189
+ )
190
+ .mockResolvedValueOnce({
191
+ ok: true,
192
+ status: 204,
193
+ statusText: "No Content",
194
+ headers: new Headers(),
195
+ });
196
+
197
+ await fetchOptionsClient.sendMessage(userMessage);
198
+ await fetchOptionsClient.getAgentCard();
199
+ for await (const _ of fetchOptionsClient.streamMessage(userMessage)) {
200
+ void _;
201
+ }
202
+ for await (const _ of fetchOptionsClient.subscribeToTask("t1")) {
203
+ void _;
204
+ }
205
+ await fetchOptionsClient.deleteTaskPushNotificationConfig("t1", "pnc-1");
206
+
207
+ for (const [, init] of fetchMock.mock.calls) {
208
+ expect(init.credentials).toBe("include");
209
+ }
210
+ });
211
+
212
+ it("strips internally-managed fields even when smuggled via cast", async () => {
213
+ const smuggledSignal = new AbortController().signal;
214
+ const fetchOptionsClient = new A2AClient({
215
+ baseUrl: "https://agent.test",
216
+ fetchOptions: {
217
+ method: "GET",
218
+ headers: { "X-Injected": "1" },
219
+ body: "smuggled",
220
+ signal: smuggledSignal,
221
+ } as RequestInit,
222
+ });
223
+
224
+ fetchMock
225
+ .mockResolvedValueOnce(
226
+ mockFetchResponse({
227
+ task: { id: "t1", status: { state: "completed" } },
228
+ }),
229
+ )
230
+ .mockResolvedValueOnce(
231
+ mockFetchResponse({
232
+ name: "Test",
233
+ description: "desc",
234
+ version: "1.0",
235
+ supportedInterfaces: [],
236
+ capabilities: {},
237
+ defaultInputModes: [],
238
+ defaultOutputModes: [],
239
+ skills: [],
240
+ }),
241
+ );
242
+
243
+ await fetchOptionsClient.sendMessage(userMessage);
244
+ await fetchOptionsClient.getAgentCard();
245
+
246
+ for (const [, init] of fetchMock.mock.calls) {
247
+ expect(init.headers["X-Injected"]).toBeUndefined();
248
+ expect(init.body).not.toBe("smuggled");
249
+ expect(init.signal).not.toBe(smuggledSignal);
250
+ }
251
+
252
+ expect(fetchMock.mock.calls[0]![1].method).toBe("POST");
253
+ expect(fetchMock.mock.calls[0]![1].headers["Content-Type"]).toBe(
254
+ "application/a2a+json",
255
+ );
256
+ expect(fetchMock.mock.calls[1]![1].method).toBeUndefined();
257
+ });
258
+ });
259
+
151
260
  // --- Tenant ---
152
261
 
153
262
  describe("tenant", () => {
@@ -275,7 +384,7 @@ describe("A2AClient", () => {
275
384
  expect(body.message.messageId).toBe("msg-1");
276
385
  });
277
386
 
278
- it("sends 'content' not 'parts' per A2A v1.0 proto spec", async () => {
387
+ it("sends 'parts' per A2A v1.0 spec (gRPC + JSON-RPC unified in a2aproject/A2A#1100)", async () => {
279
388
  fetchMock.mockResolvedValue(
280
389
  mockFetchResponse({
281
390
  task: { id: "t1", status: { state: "completed" } },
@@ -285,8 +394,8 @@ describe("A2AClient", () => {
285
394
  await client.sendMessage(userMessage);
286
395
 
287
396
  const body = JSON.parse(fetchMock.mock.calls[0]![1].body);
288
- expect(body.message.content).toEqual([{ text: "Hello" }]);
289
- expect(body.message.parts).toBeUndefined();
397
+ expect(body.message.parts).toEqual([{ text: "Hello" }]);
398
+ expect(body.message.content).toBeUndefined();
290
399
  });
291
400
 
292
401
  it("unwraps task from SendMessageResponse", async () => {
@@ -320,7 +429,7 @@ describe("A2AClient", () => {
320
429
  expect((result as any).role).toBe("agent");
321
430
  });
322
431
 
323
- it("normalizes 'content' array from v1.0 server response to internal 'parts'", async () => {
432
+ it("normalizes 'content' array from v0.3 server response to internal 'parts'", async () => {
324
433
  fetchMock.mockResolvedValue(
325
434
  mockFetchResponse({
326
435
  message: {
@@ -778,7 +887,7 @@ describe("A2AClient", () => {
778
887
  expect(events).toHaveLength(2);
779
888
  });
780
889
 
781
- it("normalizes v1.0 'content' to 'parts' in SSE artifact update events", async () => {
890
+ it("normalizes 'content' array from v0.3 server response to 'parts' in SSE artifact update events", async () => {
782
891
  const sseData = JSON.stringify({
783
892
  artifact_update: {
784
893
  task_id: "t1",
@@ -810,7 +919,7 @@ describe("A2AClient", () => {
810
919
  expect((evt.event.artifact as any).content).toBeUndefined();
811
920
  });
812
921
 
813
- it("normalizes v1.0 'content' to 'parts' in SSE status update messages", async () => {
922
+ it("normalizes 'content' array from v0.3 server response to 'parts' in SSE status update messages", async () => {
814
923
  const sseData = JSON.stringify({
815
924
  status_update: {
816
925
  task_id: "t1",