@assistant-ui/react-google-adk 0.0.30 → 0.0.31

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.
Files changed (72) hide show
  1. package/dist/AdkClient.d.ts +2 -3
  2. package/dist/AdkClient.d.ts.map +1 -1
  3. package/dist/AdkEventAccumulator.d.ts +3 -5
  4. package/dist/AdkEventAccumulator.d.ts.map +1 -1
  5. package/dist/AdkEventAccumulator.js +63 -99
  6. package/dist/AdkEventAccumulator.js.map +1 -1
  7. package/dist/AdkSessionAdapter.d.ts +7 -4
  8. package/dist/AdkSessionAdapter.d.ts.map +1 -1
  9. package/dist/AdkSessionAdapter.js +7 -4
  10. package/dist/AdkSessionAdapter.js.map +1 -1
  11. package/dist/adkExtras.d.ts +1 -2
  12. package/dist/adkExtras.d.ts.map +1 -1
  13. package/dist/adkToolApproval.d.ts +6 -7
  14. package/dist/adkToolApproval.d.ts.map +1 -1
  15. package/dist/adkToolApproval.js +1 -3
  16. package/dist/adkToolApproval.js.map +1 -1
  17. package/dist/contentToParts.d.ts +1 -2
  18. package/dist/contentToParts.d.ts.map +1 -1
  19. package/dist/convertAdkMessages.d.ts +2 -3
  20. package/dist/convertAdkMessages.d.ts.map +1 -1
  21. package/dist/convertToAdkMessages.d.ts +5 -6
  22. package/dist/convertToAdkMessages.d.ts.map +1 -1
  23. package/dist/hooks.d.ts +15 -16
  24. package/dist/hooks.d.ts.map +1 -1
  25. package/dist/hooks.js +1 -1
  26. package/dist/normalizeAdkPart.d.ts +4 -0
  27. package/dist/normalizeAdkPart.d.ts.map +1 -0
  28. package/dist/normalizeAdkPart.js +31 -0
  29. package/dist/normalizeAdkPart.js.map +1 -0
  30. package/dist/parseAdkEvent.d.ts +1 -2
  31. package/dist/parseAdkEvent.d.ts.map +1 -1
  32. package/dist/sdkIdentity.d.ts +1 -2
  33. package/dist/sdkIdentity.d.ts.map +1 -1
  34. package/dist/sdkIdentity.js +1 -1
  35. package/dist/server/adkEventStream.d.ts +2 -3
  36. package/dist/server/adkEventStream.d.ts.map +1 -1
  37. package/dist/server/createAdkApiRoute.d.ts +2 -3
  38. package/dist/server/createAdkApiRoute.d.ts.map +1 -1
  39. package/dist/server/parseAdkRequest.d.ts +2 -3
  40. package/dist/server/parseAdkRequest.d.ts.map +1 -1
  41. package/dist/structuredEvents.d.ts +1 -2
  42. package/dist/structuredEvents.d.ts.map +1 -1
  43. package/dist/structuredEvents.js +1 -1
  44. package/dist/structuredEvents.js.map +1 -1
  45. package/dist/toAdkFunctionResponse.d.ts +2 -3
  46. package/dist/toAdkFunctionResponse.d.ts.map +1 -1
  47. package/dist/trimTrailingSlashes.d.ts +1 -2
  48. package/dist/trimTrailingSlashes.d.ts.map +1 -1
  49. package/dist/types.d.ts +22 -23
  50. package/dist/types.d.ts.map +1 -1
  51. package/dist/types.js.map +1 -1
  52. package/dist/useAdkMessages.d.ts +2 -3
  53. package/dist/useAdkMessages.d.ts.map +1 -1
  54. package/dist/useAdkMessages.js +2 -0
  55. package/dist/useAdkMessages.js.map +1 -1
  56. package/dist/useAdkRuntime.d.ts +2 -3
  57. package/dist/useAdkRuntime.d.ts.map +1 -1
  58. package/dist/useAdkRuntime.js +1 -1
  59. package/package.json +10 -9
  60. package/src/AdkEventAccumulator.test.ts +312 -11
  61. package/src/AdkEventAccumulator.ts +68 -142
  62. package/src/AdkSessionAdapter.test.ts +267 -1
  63. package/src/AdkSessionAdapter.ts +24 -5
  64. package/src/adkToolApproval.test.ts +0 -4
  65. package/src/adkToolApproval.ts +1 -3
  66. package/src/normalizeAdkPart.ts +35 -0
  67. package/src/structuredEvents.test.ts +69 -0
  68. package/src/structuredEvents.ts +4 -1
  69. package/src/types.ts +1 -1
  70. package/src/useAdkMessages.test.ts +102 -3
  71. package/src/useAdkMessages.ts +2 -0
  72. package/src/useAdkRuntime.replacement.test.tsx +11 -7
@@ -1 +1 @@
1
- {"version":3,"file":"trimTrailingSlashes.d.ts","names":[],"sources":["../src/trimTrailingSlashes.ts"],"mappings":";cAAa,sBAAuB"}
1
+ {"version":3,"file":"trimTrailingSlashes.d.ts","names":[],"sources":["../src/trimTrailingSlashes.ts"],"mappings":";qBAAa,sBAAuB"}
package/dist/types.d.ts CHANGED
@@ -1,13 +1,13 @@
1
1
  import { ReadonlyJSONObject } from "assistant-stream/utils";
2
2
  import { MessageStatus } from "@assistant-ui/core";
3
3
  //#region src/types.d.ts
4
- type AdkEventPart = {
4
+ export type AdkEventPart = {
5
5
  text?: string;
6
6
  thought?: boolean;
7
7
  functionCall?: {
8
8
  name: string;
9
9
  id?: string;
10
- args: Record<string, unknown>;
10
+ args?: Record<string, unknown>;
11
11
  };
12
12
  functionResponse?: {
13
13
  name: string;
@@ -31,7 +31,7 @@ type AdkEventPart = {
31
31
  mimeType?: string;
32
32
  };
33
33
  };
34
- type AdkEventActions = {
34
+ export type AdkEventActions = {
35
35
  stateDelta?: Record<string, unknown> | undefined;
36
36
  artifactDelta?: Record<string, number> | undefined;
37
37
  transferToAgent?: string | undefined;
@@ -40,7 +40,7 @@ type AdkEventActions = {
40
40
  requestedAuthConfigs?: Record<string, unknown> | undefined;
41
41
  requestedToolConfirmations?: Record<string, unknown> | undefined;
42
42
  };
43
- type AdkEvent = {
43
+ export type AdkEvent = {
44
44
  id: string;
45
45
  invocationId?: string | undefined;
46
46
  author?: string | undefined;
@@ -63,13 +63,13 @@ type AdkEvent = {
63
63
  usageMetadata?: unknown;
64
64
  customMetadata?: Record<string, unknown> | undefined;
65
65
  };
66
- type AdkToolCall = {
66
+ export type AdkToolCall = {
67
67
  id: string;
68
68
  name: string;
69
69
  args: ReadonlyJSONObject;
70
70
  argsText?: string;
71
71
  };
72
- type AdkMessage = {
72
+ export type AdkMessage = {
73
73
  id: string;
74
74
  type: "human";
75
75
  content: string | AdkMessageContentPart[];
@@ -90,7 +90,7 @@ type AdkMessage = {
90
90
  status?: "success" | "error" | undefined;
91
91
  artifact?: unknown;
92
92
  };
93
- type AdkMessageContentPart = {
93
+ export type AdkMessageContentPart = {
94
94
  type: "text";
95
95
  text: string;
96
96
  } | {
@@ -124,7 +124,7 @@ type AdkMessageContentPart = {
124
124
  type: "activity";
125
125
  message: string;
126
126
  };
127
- type AdkToolConfirmation = {
127
+ export type AdkToolConfirmation = {
128
128
  toolCallId: string;
129
129
  toolName: string;
130
130
  args: Record<string, unknown>;
@@ -132,8 +132,8 @@ type AdkToolConfirmation = {
132
132
  confirmed: boolean;
133
133
  payload?: unknown;
134
134
  };
135
- type AdkAuthCredentialType = "apiKey" | "http" | "oauth2" | "openIdConnect" | "serviceAccount";
136
- type AdkAuthCredential = {
135
+ export type AdkAuthCredentialType = "apiKey" | "http" | "oauth2" | "openIdConnect" | "serviceAccount";
136
+ export type AdkAuthCredential = {
137
137
  authType: AdkAuthCredentialType;
138
138
  resourceRef?: string | undefined;
139
139
  apiKey?: string | undefined;
@@ -160,16 +160,16 @@ type AdkAuthCredential = {
160
160
  } | undefined;
161
161
  serviceAccount?: unknown;
162
162
  };
163
- type AdkAuthRequest = {
163
+ export type AdkAuthRequest = {
164
164
  toolCallId: string;
165
165
  authConfig: unknown;
166
166
  };
167
- type AdkMessageMetadata = {
167
+ export type AdkMessageMetadata = {
168
168
  groundingMetadata?: unknown;
169
169
  citationMetadata?: unknown;
170
170
  usageMetadata?: unknown;
171
171
  };
172
- type AdkRunConfig = {
172
+ export type AdkRunConfig = {
173
173
  streamingMode?: "none" | "sse" | "bidi" | undefined;
174
174
  pauseOnToolCalls?: boolean | undefined;
175
175
  maxLlmCalls?: number | undefined;
@@ -183,7 +183,7 @@ type AdkRunConfig = {
183
183
  proactivity?: unknown;
184
184
  realtimeInputConfig?: unknown;
185
185
  };
186
- type AdkSendMessageConfig = {
186
+ export type AdkSendMessageConfig = {
187
187
  /**
188
188
  * ADK RunConfig. Typed as `unknown` for compatibility with
189
189
  * assistant-ui core's RunConfig type. Use `AdkRunConfig` when
@@ -193,7 +193,7 @@ type AdkSendMessageConfig = {
193
193
  checkpointId?: string | undefined;
194
194
  stateDelta?: Record<string, unknown> | undefined;
195
195
  };
196
- declare const AdkEventType: {
196
+ export declare const AdkEventType: {
197
197
  readonly THOUGHT: "thought";
198
198
  readonly CONTENT: "content";
199
199
  readonly TOOL_CALL: "tool_call";
@@ -205,7 +205,7 @@ declare const AdkEventType: {
205
205
  readonly TOOL_CONFIRMATION: "tool_confirmation";
206
206
  readonly FINISHED: "finished";
207
207
  };
208
- type AdkStructuredEvent = {
208
+ export type AdkStructuredEvent = {
209
209
  type: "thought";
210
210
  content: string;
211
211
  } | {
@@ -250,18 +250,18 @@ type AdkStructuredEvent = {
250
250
  } | {
251
251
  type: "finished";
252
252
  };
253
- type AdkStreamCallback = (messages: AdkMessage[], config: AdkSendMessageConfig & {
253
+ export type AdkStreamCallback = (messages: AdkMessage[], config: AdkSendMessageConfig & {
254
254
  abortSignal: AbortSignal;
255
255
  initialize: () => Promise<{
256
256
  remoteId: string;
257
257
  externalId: string | undefined;
258
258
  }>;
259
259
  }) => Promise<AsyncGenerator<AdkEvent>> | AsyncGenerator<AdkEvent>;
260
- type OnAdkErrorCallback = (error: unknown) => void | Promise<void>;
261
- type OnAdkCustomEventCallback = (type: string, data: unknown) => void | Promise<void>;
262
- type OnAdkAgentTransferCallback = (toAgent: string) => void | Promise<void>;
260
+ export type OnAdkErrorCallback = (error: unknown) => void | Promise<void>;
261
+ export type OnAdkCustomEventCallback = (type: string, data: unknown) => void | Promise<void>;
262
+ export type OnAdkAgentTransferCallback = (toAgent: string) => void | Promise<void>;
263
263
  /** Private state and actions `useAdkRuntime` exposes through `thread.extras`. */
264
- type AdkRuntimeExtras = {
264
+ export type AdkRuntimeExtras = {
265
265
  send: (messages: AdkMessage[], config: AdkSendMessageConfig) => Promise<void>;
266
266
  agentInfo: {
267
267
  name?: string | undefined;
@@ -282,7 +282,7 @@ type AdkRuntimeExtras = {
282
282
  * clears it, since a snapshot that cannot describe the state is not evidence
283
283
  * that the state survived.
284
284
  */
285
- type AdkThreadSnapshot = {
285
+ export type AdkThreadSnapshot = {
286
286
  messages: AdkMessage[];
287
287
  longRunningToolIds?: string[] | undefined;
288
288
  toolConfirmations?: AdkToolConfirmation[] | undefined;
@@ -297,5 +297,4 @@ type AdkThreadSnapshot = {
297
297
  } | undefined;
298
298
  };
299
299
  //#endregion
300
- export { AdkAuthCredential, AdkAuthCredentialType, AdkAuthRequest, AdkEvent, AdkEventActions, AdkEventPart, AdkEventType, AdkMessage, AdkMessageContentPart, AdkMessageMetadata, AdkRunConfig, AdkRuntimeExtras, AdkSendMessageConfig, AdkStreamCallback, AdkStructuredEvent, AdkThreadSnapshot, AdkToolCall, AdkToolConfirmation, OnAdkAgentTransferCallback, OnAdkCustomEventCallback, OnAdkErrorCallback };
301
300
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","names":[],"sources":["../src/types.ts"],"mappings":";;;KAKY;EACV;EACA;EACA;IACE;IACA;IACA,MAAM;;EAER;IACE;IACA;IACA;;EAEF;IACE;IACA;;EAEF;IACE;IACA;;EAEF;IACE;IACA;;EAEF;IACE;IACA;;;KAIQ;EACV,aAAa;EACb,gBAAgB;EAChB;EACA;EACA;EACA,uBAAuB;EACvB,6BAA6B;;KAGnB;EACV;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;IAEM;IACA,QAAQ;;EAGd,UAAU;EACV;EACA;EACA;EACA;EACA;EACA;EACA,iBAAiB;;KAKP;EACV;EACA;EACA,MAAM;EACN;;KAGU;EAEN;EACA;EACA,kBAAkB;;EAGlB;EACA;EACA,kBAAkB;EAClB,aAAa;EACb;EACA;EACA,SAAS;;EAGT;EACA;EACA;EACA;EACA;EACA;EACA;;KAGM;EACN;EAAc;;EACd;EAAmB;;EACnB;EAAe;EAAkB;;EACjC;EAAmB;;EAEnB;EACA;EACA;EACA;;EAGA;EACA;EACA;;EAEA;EAAc;EAAc;;EAC5B;EAAqB;EAAgB;;EACrC;EAAkB;;KAIZ;EACV;EACA;EACA,MAAM;EACN;EACA;EACA;;KAGU;KAOA;EACV,UAAU;EACV;EACA;EACA;IAEM;IACA;MACE;MACA;MACA;;;EAIR;IAEM;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;EAGN;;KAGU;EACV;EACA;;KAGU;EACV;EACA;EACA;;KAKU;EACV;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;KAKU;;;;;;EAMV;EACA;EACA,aAAa;;cAKF;;;;;;;;;;;;KAaD;EACN;EAAiB;;EACjB;EAAiB;;EAEjB;EACA;IAAQ;IAAc;IAAa,MAAM;;;EAGzC;EACA;IAAU;IAAc;IAAa;;;EAErC;EAAmB;IAAQ;IAAc;;;EACzC;EAAqB;IAAU;IAAgB;;;EAC/C;EAAe;EAAoB;;EACnC;EAAkB;;EAElB;EACA,eAAe;;EAEf;;KAEM,qBACV,UAAU,cACV,QAAQ;EACN,aAAa;EACb,kBAAkB;IAChB;IACA;;MAGD,QAAQ,eAAe,aAAa,eAAe;KAI5C,sBAAsB,0BAA0B;KAEhD,4BACV,cACA,yBACU;KAEA,8BACV,2BACU;;KAGA;EACV,OAAO,UAAU,cAAc,QAAQ,yBAAyB;EAChE;IAAa;IAA2B;;EACxC,YAAY;EACZ,eAAe;EACf;EACA,mBAAmB;EACnB,cAAc;EACd;EACA,iBAAiB,YAAY;;;;;;;;;KAUnB;EACV,UAAU;EACV;EACA,oBAAoB;EACpB,eAAe;EACf;EACA,kBAAkB,YAAY;EAC9B,aAAa;EACb,gBAAgB;EAChB;IACM;IAA2B"}
1
+ {"version":3,"file":"types.d.ts","names":[],"sources":["../src/types.ts"],"mappings":";;;YAKY;EACV;EACA;EACA;IACE;IACA;IACA,OAAO;;EAET;IACE;IACA;IACA;;EAEF;IACE;IACA;;EAEF;IACE;IACA;;EAEF;IACE;IACA;;EAEF;IACE;IACA;;;YAIQ;EACV,aAAa;EACb,gBAAgB;EAChB;EACA;EACA;EACA,uBAAuB;EACvB,6BAA6B;;YAGnB;EACV;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;IAEM;IACA,QAAQ;;EAGd,UAAU;EACV;EACA;EACA;EACA;EACA;EACA;EACA,iBAAiB;;YAKP;EACV;EACA;EACA,MAAM;EACN;;YAGU;EAEN;EACA;EACA,kBAAkB;;EAGlB;EACA;EACA,kBAAkB;EAClB,aAAa;EACb;EACA;EACA,SAAS;;EAGT;EACA;EACA;EACA;EACA;EACA;EACA;;YAGM;EACN;EAAc;;EACd;EAAmB;;EACnB;EAAe;EAAkB;;EACjC;EAAmB;;EAEnB;EACA;EACA;EACA;;EAGA;EACA;EACA;;EAEA;EAAc;EAAc;;EAC5B;EAAqB;EAAgB;;EACrC;EAAkB;;YAIZ;EACV;EACA;EACA,MAAM;EACN;EACA;EACA;;YAGU;YAOA;EACV,UAAU;EACV;EACA;EACA;IAEM;IACA;MACE;MACA;MACA;;;EAIR;IAEM;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;EAGN;;YAGU;EACV;EACA;;YAGU;EACV;EACA;EACA;;YAKU;EACV;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;YAKU;;;;;;EAMV;EACA;EACA,aAAa;;qBAKF;;;;;;;;;;;;YAaD;EACN;EAAiB;;EACjB;EAAiB;;EAEjB;EACA;IAAQ;IAAc;IAAa,MAAM;;;EAGzC;EACA;IAAU;IAAc;IAAa;;;EAErC;EAAmB;IAAQ;IAAc;;;EACzC;EAAqB;IAAU;IAAgB;;;EAC/C;EAAe;EAAoB;;EACnC;EAAkB;;EAElB;EACA,eAAe;;EAEf;;YAEM,qBACV,UAAU,cACV,QAAQ;EACN,aAAa;EACb,kBAAkB;IAChB;IACA;;MAGD,QAAQ,eAAe,aAAa,eAAe;YAI5C,sBAAsB,0BAA0B;YAEhD,4BACV,cACA,yBACU;YAEA,8BACV,2BACU;;YAGA;EACV,OAAO,UAAU,cAAc,QAAQ,yBAAyB;EAChE;IAAa;IAA2B;;EACxC,YAAY;EACZ,eAAe;EACf;EACA,mBAAmB;EACnB,cAAc;EACd;EACA,iBAAiB,YAAY;;;;;;;;;YAUnB;EACV,UAAU;EACV;EACA,oBAAoB;EACpB,eAAe;EACf;EACA,kBAAkB,YAAY;EAC9B,aAAa;EACb,gBAAgB;EAChB;IACM;IAA2B"}
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","names":[],"sources":["../src/types.ts"],"sourcesContent":["import type { MessageStatus } from \"@assistant-ui/core\";\nimport type { ReadonlyJSONObject } from \"assistant-stream/utils\";\n\n// ── ADK Event wire types (lightweight, no @google/adk dependency) ──\n\nexport type AdkEventPart = {\n text?: string;\n thought?: boolean;\n functionCall?: {\n name: string;\n id?: string;\n args: Record<string, unknown>;\n };\n functionResponse?: {\n name: string;\n id?: string;\n response: unknown;\n };\n executableCode?: {\n code: string;\n language?: string;\n };\n codeExecutionResult?: {\n output: string;\n outcome?: string;\n };\n inlineData?: {\n mimeType: string;\n data: string;\n };\n fileData?: {\n fileUri: string;\n mimeType?: string;\n };\n};\n\nexport type AdkEventActions = {\n stateDelta?: Record<string, unknown> | undefined;\n artifactDelta?: Record<string, number> | undefined;\n transferToAgent?: string | undefined;\n escalate?: boolean | undefined;\n skipSummarization?: boolean | undefined;\n requestedAuthConfigs?: Record<string, unknown> | undefined;\n requestedToolConfirmations?: Record<string, unknown> | undefined;\n};\n\nexport type AdkEvent = {\n id: string;\n invocationId?: string | undefined;\n author?: string | undefined;\n branch?: string | undefined;\n partial?: boolean | undefined;\n turnComplete?: boolean | undefined;\n interrupted?: boolean | undefined;\n finishReason?: string | undefined;\n timestamp?: number | undefined;\n content?:\n | {\n role?: string | undefined;\n parts?: AdkEventPart[] | undefined;\n }\n | undefined;\n actions?: AdkEventActions | undefined;\n longRunningToolIds?: string[] | undefined;\n errorCode?: string | undefined;\n errorMessage?: string | undefined;\n groundingMetadata?: unknown;\n citationMetadata?: unknown;\n usageMetadata?: unknown;\n customMetadata?: Record<string, unknown> | undefined;\n};\n\n// ── ADK Message types (accumulated from events) ──\n\nexport type AdkToolCall = {\n id: string;\n name: string;\n args: ReadonlyJSONObject;\n argsText?: string;\n};\n\nexport type AdkMessage =\n | {\n id: string;\n type: \"human\";\n content: string | AdkMessageContentPart[];\n }\n | {\n id: string;\n type: \"ai\";\n content: string | AdkMessageContentPart[];\n tool_calls?: AdkToolCall[] | undefined;\n author?: string | undefined;\n branch?: string | undefined;\n status?: MessageStatus | undefined;\n }\n | {\n id: string;\n type: \"tool\";\n content: string;\n tool_call_id: string;\n name: string;\n status?: \"success\" | \"error\" | undefined;\n artifact?: unknown;\n };\n\nexport type AdkMessageContentPart =\n | { type: \"text\"; text: string }\n | { type: \"reasoning\"; text: string }\n | { type: \"image\"; mimeType: string; data: string }\n | { type: \"image_url\"; url: string }\n | {\n type: \"file\";\n mimeType: string;\n data: string;\n filename?: string | undefined;\n }\n | {\n type: \"file_url\";\n url: string;\n mimeType?: string | undefined;\n }\n | { type: \"code\"; code: string; language: string }\n | { type: \"code_result\"; output: string; outcome: string }\n | { type: \"activity\"; message: string };\n\n// ── ADK-specific state types ──\n\nexport type AdkToolConfirmation = {\n toolCallId: string;\n toolName: string;\n args: Record<string, unknown>;\n hint: string;\n confirmed: boolean;\n payload?: unknown;\n};\n\nexport type AdkAuthCredentialType =\n | \"apiKey\"\n | \"http\"\n | \"oauth2\"\n | \"openIdConnect\"\n | \"serviceAccount\";\n\nexport type AdkAuthCredential = {\n authType: AdkAuthCredentialType;\n resourceRef?: string | undefined;\n apiKey?: string | undefined;\n http?:\n | {\n scheme: string;\n credentials: {\n username?: string;\n password?: string;\n token?: string;\n };\n }\n | undefined;\n oauth2?:\n | {\n clientId?: string;\n clientSecret?: string;\n authUri?: string;\n state?: string;\n redirectUri?: string;\n authResponseUri?: string;\n authCode?: string;\n accessToken?: string;\n refreshToken?: string;\n expiresAt?: number;\n expiresIn?: number;\n }\n | undefined;\n serviceAccount?: unknown;\n};\n\nexport type AdkAuthRequest = {\n toolCallId: string;\n authConfig: unknown;\n};\n\nexport type AdkMessageMetadata = {\n groundingMetadata?: unknown;\n citationMetadata?: unknown;\n usageMetadata?: unknown;\n};\n\n// ── RunConfig ──\n\nexport type AdkRunConfig = {\n streamingMode?: \"none\" | \"sse\" | \"bidi\" | undefined;\n pauseOnToolCalls?: boolean | undefined;\n maxLlmCalls?: number | undefined;\n saveInputBlobsAsArtifacts?: boolean | undefined;\n supportCfc?: boolean | undefined;\n speechConfig?: unknown;\n responseModalities?: string[] | undefined;\n outputAudioTranscription?: unknown;\n inputAudioTranscription?: unknown;\n enableAffectiveDialog?: boolean | undefined;\n proactivity?: unknown;\n realtimeInputConfig?: unknown;\n};\n\n// ── Stream callback types ──\n\nexport type AdkSendMessageConfig = {\n /**\n * ADK RunConfig. Typed as `unknown` for compatibility with\n * assistant-ui core's RunConfig type. Use `AdkRunConfig` when\n * constructing configs manually for type safety.\n */\n runConfig?: unknown;\n checkpointId?: string | undefined;\n stateDelta?: Record<string, unknown> | undefined;\n};\n\n// ── Structured events ──\n\nexport const AdkEventType = {\n THOUGHT: \"thought\",\n CONTENT: \"content\",\n TOOL_CALL: \"tool_call\",\n TOOL_RESULT: \"tool_result\",\n CALL_CODE: \"call_code\",\n CODE_RESULT: \"code_result\",\n ERROR: \"error\",\n ACTIVITY: \"activity\",\n TOOL_CONFIRMATION: \"tool_confirmation\",\n FINISHED: \"finished\",\n} as const;\n\nexport type AdkStructuredEvent =\n | { type: \"thought\"; content: string }\n | { type: \"content\"; content: string }\n | {\n type: \"tool_call\";\n call: { name: string; id?: string; args: Record<string, unknown> };\n }\n | {\n type: \"tool_result\";\n result: { name: string; id?: string; response: unknown };\n }\n | { type: \"call_code\"; code: { code: string; language?: string } }\n | { type: \"code_result\"; result: { output: string; outcome?: string } }\n | { type: \"error\"; errorCode?: string; errorMessage?: string }\n | { type: \"activity\"; message: string }\n | {\n type: \"tool_confirmation\";\n confirmations: Record<string, unknown>;\n }\n | { type: \"finished\" };\n\nexport type AdkStreamCallback = (\n messages: AdkMessage[],\n config: AdkSendMessageConfig & {\n abortSignal: AbortSignal;\n initialize: () => Promise<{\n remoteId: string;\n externalId: string | undefined;\n }>;\n },\n) => Promise<AsyncGenerator<AdkEvent>> | AsyncGenerator<AdkEvent>;\n\n// ── Event handler callbacks ──\n\nexport type OnAdkErrorCallback = (error: unknown) => void | Promise<void>;\n\nexport type OnAdkCustomEventCallback = (\n type: string,\n data: unknown,\n) => void | Promise<void>;\n\nexport type OnAdkAgentTransferCallback = (\n toAgent: string,\n) => void | Promise<void>;\n\n/** Private state and actions `useAdkRuntime` exposes through `thread.extras`. */\nexport type AdkRuntimeExtras = {\n send: (messages: AdkMessage[], config: AdkSendMessageConfig) => Promise<void>;\n agentInfo: { name?: string | undefined; branch?: string | undefined };\n stateDelta: Record<string, unknown>;\n artifactDelta: Record<string, number>;\n longRunningToolIds: string[];\n toolConfirmations: AdkToolConfirmation[];\n authRequests: AdkAuthRequest[];\n escalated: boolean;\n messageMetadata: Map<string, AdkMessageMetadata>;\n};\n\n/**\n * What a session load reconstructs. The messages are the whole thread; the\n * rest is the per-turn state the events imply, which a caller that replays\n * them through {@link AdkEventAccumulator} already has. Omitting a field\n * clears it, since a snapshot that cannot describe the state is not evidence\n * that the state survived.\n */\nexport type AdkThreadSnapshot = {\n messages: AdkMessage[];\n longRunningToolIds?: string[] | undefined;\n toolConfirmations?: AdkToolConfirmation[] | undefined;\n authRequests?: AdkAuthRequest[] | undefined;\n escalated?: boolean | undefined;\n messageMetadata?: Map<string, AdkMessageMetadata> | undefined;\n stateDelta?: Record<string, unknown> | undefined;\n artifactDelta?: Record<string, number> | undefined;\n agentInfo?:\n | { name?: string | undefined; branch?: string | undefined }\n | undefined;\n};\n"],"mappings":";AA2NA,MAAa,eAAe;CAC1B,SAAS;CACT,SAAS;CACT,WAAW;CACX,aAAa;CACb,WAAW;CACX,aAAa;CACb,OAAO;CACP,UAAU;CACV,mBAAmB;CACnB,UAAU;AACZ"}
1
+ {"version":3,"file":"types.js","names":[],"sources":["../src/types.ts"],"sourcesContent":["import type { MessageStatus } from \"@assistant-ui/core\";\nimport type { ReadonlyJSONObject } from \"assistant-stream/utils\";\n\n// ── ADK Event wire types (lightweight, no @google/adk dependency) ──\n\nexport type AdkEventPart = {\n text?: string;\n thought?: boolean;\n functionCall?: {\n name: string;\n id?: string;\n args?: Record<string, unknown>;\n };\n functionResponse?: {\n name: string;\n id?: string;\n response: unknown;\n };\n executableCode?: {\n code: string;\n language?: string;\n };\n codeExecutionResult?: {\n output: string;\n outcome?: string;\n };\n inlineData?: {\n mimeType: string;\n data: string;\n };\n fileData?: {\n fileUri: string;\n mimeType?: string;\n };\n};\n\nexport type AdkEventActions = {\n stateDelta?: Record<string, unknown> | undefined;\n artifactDelta?: Record<string, number> | undefined;\n transferToAgent?: string | undefined;\n escalate?: boolean | undefined;\n skipSummarization?: boolean | undefined;\n requestedAuthConfigs?: Record<string, unknown> | undefined;\n requestedToolConfirmations?: Record<string, unknown> | undefined;\n};\n\nexport type AdkEvent = {\n id: string;\n invocationId?: string | undefined;\n author?: string | undefined;\n branch?: string | undefined;\n partial?: boolean | undefined;\n turnComplete?: boolean | undefined;\n interrupted?: boolean | undefined;\n finishReason?: string | undefined;\n timestamp?: number | undefined;\n content?:\n | {\n role?: string | undefined;\n parts?: AdkEventPart[] | undefined;\n }\n | undefined;\n actions?: AdkEventActions | undefined;\n longRunningToolIds?: string[] | undefined;\n errorCode?: string | undefined;\n errorMessage?: string | undefined;\n groundingMetadata?: unknown;\n citationMetadata?: unknown;\n usageMetadata?: unknown;\n customMetadata?: Record<string, unknown> | undefined;\n};\n\n// ── ADK Message types (accumulated from events) ──\n\nexport type AdkToolCall = {\n id: string;\n name: string;\n args: ReadonlyJSONObject;\n argsText?: string;\n};\n\nexport type AdkMessage =\n | {\n id: string;\n type: \"human\";\n content: string | AdkMessageContentPart[];\n }\n | {\n id: string;\n type: \"ai\";\n content: string | AdkMessageContentPart[];\n tool_calls?: AdkToolCall[] | undefined;\n author?: string | undefined;\n branch?: string | undefined;\n status?: MessageStatus | undefined;\n }\n | {\n id: string;\n type: \"tool\";\n content: string;\n tool_call_id: string;\n name: string;\n status?: \"success\" | \"error\" | undefined;\n artifact?: unknown;\n };\n\nexport type AdkMessageContentPart =\n | { type: \"text\"; text: string }\n | { type: \"reasoning\"; text: string }\n | { type: \"image\"; mimeType: string; data: string }\n | { type: \"image_url\"; url: string }\n | {\n type: \"file\";\n mimeType: string;\n data: string;\n filename?: string | undefined;\n }\n | {\n type: \"file_url\";\n url: string;\n mimeType?: string | undefined;\n }\n | { type: \"code\"; code: string; language: string }\n | { type: \"code_result\"; output: string; outcome: string }\n | { type: \"activity\"; message: string };\n\n// ── ADK-specific state types ──\n\nexport type AdkToolConfirmation = {\n toolCallId: string;\n toolName: string;\n args: Record<string, unknown>;\n hint: string;\n confirmed: boolean;\n payload?: unknown;\n};\n\nexport type AdkAuthCredentialType =\n | \"apiKey\"\n | \"http\"\n | \"oauth2\"\n | \"openIdConnect\"\n | \"serviceAccount\";\n\nexport type AdkAuthCredential = {\n authType: AdkAuthCredentialType;\n resourceRef?: string | undefined;\n apiKey?: string | undefined;\n http?:\n | {\n scheme: string;\n credentials: {\n username?: string;\n password?: string;\n token?: string;\n };\n }\n | undefined;\n oauth2?:\n | {\n clientId?: string;\n clientSecret?: string;\n authUri?: string;\n state?: string;\n redirectUri?: string;\n authResponseUri?: string;\n authCode?: string;\n accessToken?: string;\n refreshToken?: string;\n expiresAt?: number;\n expiresIn?: number;\n }\n | undefined;\n serviceAccount?: unknown;\n};\n\nexport type AdkAuthRequest = {\n toolCallId: string;\n authConfig: unknown;\n};\n\nexport type AdkMessageMetadata = {\n groundingMetadata?: unknown;\n citationMetadata?: unknown;\n usageMetadata?: unknown;\n};\n\n// ── RunConfig ──\n\nexport type AdkRunConfig = {\n streamingMode?: \"none\" | \"sse\" | \"bidi\" | undefined;\n pauseOnToolCalls?: boolean | undefined;\n maxLlmCalls?: number | undefined;\n saveInputBlobsAsArtifacts?: boolean | undefined;\n supportCfc?: boolean | undefined;\n speechConfig?: unknown;\n responseModalities?: string[] | undefined;\n outputAudioTranscription?: unknown;\n inputAudioTranscription?: unknown;\n enableAffectiveDialog?: boolean | undefined;\n proactivity?: unknown;\n realtimeInputConfig?: unknown;\n};\n\n// ── Stream callback types ──\n\nexport type AdkSendMessageConfig = {\n /**\n * ADK RunConfig. Typed as `unknown` for compatibility with\n * assistant-ui core's RunConfig type. Use `AdkRunConfig` when\n * constructing configs manually for type safety.\n */\n runConfig?: unknown;\n checkpointId?: string | undefined;\n stateDelta?: Record<string, unknown> | undefined;\n};\n\n// ── Structured events ──\n\nexport const AdkEventType = {\n THOUGHT: \"thought\",\n CONTENT: \"content\",\n TOOL_CALL: \"tool_call\",\n TOOL_RESULT: \"tool_result\",\n CALL_CODE: \"call_code\",\n CODE_RESULT: \"code_result\",\n ERROR: \"error\",\n ACTIVITY: \"activity\",\n TOOL_CONFIRMATION: \"tool_confirmation\",\n FINISHED: \"finished\",\n} as const;\n\nexport type AdkStructuredEvent =\n | { type: \"thought\"; content: string }\n | { type: \"content\"; content: string }\n | {\n type: \"tool_call\";\n call: { name: string; id?: string; args: Record<string, unknown> };\n }\n | {\n type: \"tool_result\";\n result: { name: string; id?: string; response: unknown };\n }\n | { type: \"call_code\"; code: { code: string; language?: string } }\n | { type: \"code_result\"; result: { output: string; outcome?: string } }\n | { type: \"error\"; errorCode?: string; errorMessage?: string }\n | { type: \"activity\"; message: string }\n | {\n type: \"tool_confirmation\";\n confirmations: Record<string, unknown>;\n }\n | { type: \"finished\" };\n\nexport type AdkStreamCallback = (\n messages: AdkMessage[],\n config: AdkSendMessageConfig & {\n abortSignal: AbortSignal;\n initialize: () => Promise<{\n remoteId: string;\n externalId: string | undefined;\n }>;\n },\n) => Promise<AsyncGenerator<AdkEvent>> | AsyncGenerator<AdkEvent>;\n\n// ── Event handler callbacks ──\n\nexport type OnAdkErrorCallback = (error: unknown) => void | Promise<void>;\n\nexport type OnAdkCustomEventCallback = (\n type: string,\n data: unknown,\n) => void | Promise<void>;\n\nexport type OnAdkAgentTransferCallback = (\n toAgent: string,\n) => void | Promise<void>;\n\n/** Private state and actions `useAdkRuntime` exposes through `thread.extras`. */\nexport type AdkRuntimeExtras = {\n send: (messages: AdkMessage[], config: AdkSendMessageConfig) => Promise<void>;\n agentInfo: { name?: string | undefined; branch?: string | undefined };\n stateDelta: Record<string, unknown>;\n artifactDelta: Record<string, number>;\n longRunningToolIds: string[];\n toolConfirmations: AdkToolConfirmation[];\n authRequests: AdkAuthRequest[];\n escalated: boolean;\n messageMetadata: Map<string, AdkMessageMetadata>;\n};\n\n/**\n * What a session load reconstructs. The messages are the whole thread; the\n * rest is the per-turn state the events imply, which a caller that replays\n * them through {@link AdkEventAccumulator} already has. Omitting a field\n * clears it, since a snapshot that cannot describe the state is not evidence\n * that the state survived.\n */\nexport type AdkThreadSnapshot = {\n messages: AdkMessage[];\n longRunningToolIds?: string[] | undefined;\n toolConfirmations?: AdkToolConfirmation[] | undefined;\n authRequests?: AdkAuthRequest[] | undefined;\n escalated?: boolean | undefined;\n messageMetadata?: Map<string, AdkMessageMetadata> | undefined;\n stateDelta?: Record<string, unknown> | undefined;\n artifactDelta?: Record<string, number> | undefined;\n agentInfo?:\n | { name?: string | undefined; branch?: string | undefined }\n | undefined;\n};\n"],"mappings":";AA2NA,MAAa,eAAe;CAC1B,SAAS;CACT,SAAS;CACT,WAAW;CACX,aAAa;CACb,WAAW;CACX,aAAa;CACb,OAAO;CACP,UAAU;CACV,mBAAmB;CACnB,UAAU;AACZ"}
@@ -1,6 +1,6 @@
1
1
  import { AdkAuthRequest, AdkMessage, AdkMessageMetadata, AdkSendMessageConfig, AdkStreamCallback, AdkThreadSnapshot, AdkToolConfirmation, OnAdkAgentTransferCallback, OnAdkCustomEventCallback, OnAdkErrorCallback } from "./types.js";
2
2
  //#region src/useAdkMessages.d.ts
3
- type UseAdkMessagesOptions = {
3
+ export type UseAdkMessagesOptions = {
4
4
  stream: AdkStreamCallback;
5
5
  eventHandlers?: {
6
6
  onError?: OnAdkErrorCallback;
@@ -8,7 +8,7 @@ type UseAdkMessagesOptions = {
8
8
  onAgentTransfer?: OnAdkAgentTransferCallback;
9
9
  };
10
10
  };
11
- declare const useAdkMessages: ({ stream, eventHandlers }: UseAdkMessagesOptions) => {
11
+ export declare const useAdkMessages: ({ stream, eventHandlers }: UseAdkMessagesOptions) => {
12
12
  messages: AdkMessage[];
13
13
  stateDelta: Record<string, unknown>;
14
14
  agentInfo: {
@@ -28,5 +28,4 @@ declare const useAdkMessages: ({ stream, eventHandlers }: UseAdkMessagesOptions)
28
28
  applySnapshot: (snapshot: AdkThreadSnapshot) => void;
29
29
  };
30
30
  //#endregion
31
- export { UseAdkMessagesOptions, useAdkMessages };
32
31
  //# sourceMappingURL=useAdkMessages.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useAdkMessages.d.ts","names":[],"sources":["../src/useAdkMessages.ts"],"mappings":";;KAgCY;EACV,QAAQ;EACR;IACE,UAAU;IACV,gBAAgB;IAChB,kBAAkB;;;cAcT,mBAAkB,QAAA,iBAG5B;;;;IAIQ;IACE;;;;;;;;EAsFW,cAAA,aAAA,cAAY,QAAU,yBAAoB;;EAvDhB,cAAA,MAAA;EAmCvC,kBAAA,MAAA;EAnBI,gBAAA,UAAA"}
1
+ {"version":3,"file":"useAdkMessages.d.ts","names":[],"sources":["../src/useAdkMessages.ts"],"mappings":";;YAgCY;EACV,QAAQ;EACR;IACE,UAAU;IACV,gBAAgB;IAChB,kBAAkB;;;qBAcT,mBAAkB,QAAA,iBAG5B;;;;IAIQ;IACE;;;;;;;;EAsFW,cAAA,aAAA,cAAY,QAAU,yBAAoB;;EAvDhB,cAAA,MAAA;EAmCvC,kBAAA,MAAA;EAnBI,gBAAA,UAAA"}
@@ -81,6 +81,8 @@ const useAdkMessages = ({ stream, eventHandlers }) => {
81
81
  for (const event of messagesToEvents(newMessagesWithId)) accumulator.processEvent(event);
82
82
  setMessagesImmediate(accumulator.getMessages());
83
83
  setLongRunningToolIds(accumulator.getLongRunningToolIds());
84
+ setToolConfirmations(accumulator.getToolConfirmations());
85
+ setAuthRequests(accumulator.getAuthRequests());
84
86
  abortControllerRef.current?.abort();
85
87
  const abortController = new AbortController();
86
88
  abortControllerRef.current = abortController;
@@ -1 +1 @@
1
- {"version":3,"file":"useAdkMessages.js","names":[],"sources":["../src/useAdkMessages.ts"],"sourcesContent":["import {\n useState,\n useCallback,\n useEffect,\n useInsertionEffect,\n useRef,\n useMemo,\n} from \"react\";\nimport { generateId } from \"@assistant-ui/core\";\nimport { useAui } from \"@assistant-ui/store\";\nimport {\n abortableIterable,\n invokeUserCallback,\n openAbortableIterable,\n} from \"@assistant-ui/core/internal\";\nimport { AdkEventAccumulator } from \"./AdkEventAccumulator\";\nimport { contentToParts } from \"./contentToParts\";\nimport { toAdkFunctionResponse } from \"./toAdkFunctionResponse\";\nimport type {\n AdkEvent,\n AdkMessage,\n AdkMessageMetadata,\n AdkSendMessageConfig,\n AdkStreamCallback,\n AdkToolConfirmation,\n AdkAuthRequest,\n AdkThreadSnapshot,\n OnAdkErrorCallback,\n OnAdkCustomEventCallback,\n OnAdkAgentTransferCallback,\n} from \"./types\";\n\nexport type UseAdkMessagesOptions = {\n stream: AdkStreamCallback;\n eventHandlers?: {\n onError?: OnAdkErrorCallback;\n onCustomEvent?: OnAdkCustomEventCallback;\n onAgentTransfer?: OnAdkAgentTransferCallback;\n };\n};\n\ntype AdkRuntimeCallbackName = \"onError\" | \"onCustomEvent\" | \"onAgentTransfer\";\n\nconst invokeAdkRuntimeCallback = <TArgs extends readonly unknown[]>(\n name: AdkRuntimeCallbackName,\n callback: ((...args: TArgs) => unknown) | undefined,\n ...args: TArgs\n): void => {\n void invokeUserCallback(\"react-google-adk\", name, callback, ...args);\n};\n\nexport const useAdkMessages = ({\n stream,\n eventHandlers,\n}: UseAdkMessagesOptions) => {\n const [messages, _setMessages] = useState<AdkMessage[]>([]);\n const [stateDelta, setStateDelta] = useState<Record<string, unknown>>({});\n const [agentInfo, setAgentInfo] = useState<{\n name?: string | undefined;\n branch?: string | undefined;\n }>({});\n const [longRunningToolIds, _setLongRunningToolIds] = useState<string[]>([]);\n const [artifactDelta, setArtifactDelta] = useState<Record<string, number>>(\n {},\n );\n const [toolConfirmations, setToolConfirmations] = useState<\n AdkToolConfirmation[]\n >([]);\n const [authRequests, setAuthRequests] = useState<AdkAuthRequest[]>([]);\n const [escalated, setEscalated] = useState(false);\n const [messageMetadata, setMessageMetadata] = useState<\n Map<string, AdkMessageMetadata>\n >(new Map());\n const lastTransferToAgentRef = useRef<string | undefined>(undefined);\n // setMessagesImmediate and setLongRunningToolIds are the only writers of their state and publish these refs with it, so neither ref trails a commit.\n const messagesRef = useRef(messages);\n const longRunningToolIdsRef = useRef(longRunningToolIds);\n const stateDeltaRef = useRef(stateDelta);\n useInsertionEffect(() => {\n stateDeltaRef.current = stateDelta;\n }, [stateDelta]);\n const artifactDeltaRef = useRef(artifactDelta);\n useInsertionEffect(() => {\n artifactDeltaRef.current = artifactDelta;\n }, [artifactDelta]);\n const messageMetadataRef = useRef(messageMetadata);\n useInsertionEffect(() => {\n messageMetadataRef.current = messageMetadata;\n }, [messageMetadata]);\n\n const setMessagesImmediate = useCallback((msgs: AdkMessage[]) => {\n messagesRef.current = msgs;\n _setMessages(msgs);\n }, []);\n const setLongRunningToolIds = useCallback((ids: string[]) => {\n longRunningToolIdsRef.current = ids;\n _setLongRunningToolIds(ids);\n }, []);\n\n /**\n * Swap the thread over to a loaded snapshot in one commit. Unlike\n * {@link replaceMessages} this never passes through a cleared state, so a\n * refetch that lands while a confirmation is on screen replaces it rather\n * than blanking it first.\n */\n const applySnapshot = useCallback(\n (snapshot: AdkThreadSnapshot) => {\n setMessagesImmediate(snapshot.messages);\n setLongRunningToolIds(snapshot.longRunningToolIds ?? []);\n setToolConfirmations(snapshot.toolConfirmations ?? []);\n setAuthRequests(snapshot.authRequests ?? []);\n setEscalated(snapshot.escalated ?? false);\n setMessageMetadata(snapshot.messageMetadata ?? new Map());\n setStateDelta(snapshot.stateDelta ?? {});\n setArtifactDelta(snapshot.artifactDelta ?? {});\n setAgentInfo(snapshot.agentInfo ?? {});\n },\n [setLongRunningToolIds, setMessagesImmediate],\n );\n\n // Replace the message list AND reset derived per-turn HITL state.\n // Used by truncation paths (edit, reload) so that stale interrupt\n // markers and per-message metadata from the removed messages don't leak\n // into the next turn.\n const replaceMessages = useCallback(\n (msgs: AdkMessage[]) => {\n setMessagesImmediate(msgs);\n setLongRunningToolIds([]);\n setToolConfirmations([]);\n setAuthRequests([]);\n setEscalated(false);\n setMessageMetadata(new Map());\n },\n [setLongRunningToolIds, setMessagesImmediate],\n );\n\n const abortControllerRef = useRef<AbortController | null>(null);\n\n const { onError, onCustomEvent, onAgentTransfer } = useMemo(\n () => eventHandlers ?? {},\n [eventHandlers],\n );\n\n const aui = useAui();\n const sendMessage = useCallback(\n async (newMessages: AdkMessage[], config: AdkSendMessageConfig) => {\n const newMessagesWithId = newMessages.map((m) =>\n m.id ? m : { ...m, id: generateId() },\n ) as AdkMessage[];\n\n // A staged message is already in the thread under its own id, and the\n // merged event below re-emits the whole batch under the first one. Seeding\n // with the originals would leave every later staged id beside the merged\n // copy of itself.\n const resentIds = new Set(newMessagesWithId.map((m) => m.id));\n // The optimistic event for a tool-only batch carries no author, so the accumulator cannot settle the calls this send answers.\n const answeredToolCallIds = new Set(\n newMessagesWithId.flatMap((m) =>\n m.type === \"tool\" ? [m.tool_call_id] : [],\n ),\n );\n const accumulator = new AdkEventAccumulator(\n messagesRef.current.filter((m) => !resentIds.has(m.id)),\n longRunningToolIdsRef.current.filter(\n (id) => !answeredToolCallIds.has(id),\n ),\n );\n for (const event of messagesToEvents(newMessagesWithId)) {\n accumulator.processEvent(event);\n }\n setMessagesImmediate(accumulator.getMessages());\n setLongRunningToolIds(accumulator.getLongRunningToolIds());\n\n // Google ADK replaces active runs, while React LangGraph queues sends.\n abortControllerRef.current?.abort();\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n\n try {\n const response = await openAbortableIterable(\n stream(newMessagesWithId, {\n ...config,\n abortSignal: abortController.signal,\n initialize: async () => {\n return await aui.threadListItem.initialize();\n },\n }),\n abortController.signal,\n );\n if (!response) return;\n\n for await (const event of abortableIterable(\n response,\n abortController.signal,\n )) {\n if (\n abortController.signal.aborted ||\n abortControllerRef.current !== abortController\n ) {\n break;\n }\n const updatedMessages = accumulator.processEvent(event);\n setMessagesImmediate(updatedMessages);\n setStateDelta({\n ...stateDeltaRef.current,\n ...accumulator.getStateDelta(),\n });\n setAgentInfo(accumulator.getAgentInfo());\n setLongRunningToolIds(accumulator.getLongRunningToolIds());\n setArtifactDelta({\n ...artifactDeltaRef.current,\n ...accumulator.getArtifactDelta(),\n });\n setToolConfirmations(accumulator.getToolConfirmations());\n setAuthRequests(accumulator.getAuthRequests());\n setEscalated(accumulator.isEscalated());\n {\n const newMeta = accumulator.getMessageMetadata();\n if (newMeta.size > 0) {\n setMessageMetadata(\n new Map([...messageMetadataRef.current, ...newMeta]),\n );\n }\n }\n\n const transfer = accumulator.getLastTransferToAgent();\n if (transfer && transfer !== lastTransferToAgentRef.current) {\n lastTransferToAgentRef.current = transfer;\n invokeAdkRuntimeCallback(\n \"onAgentTransfer\",\n onAgentTransfer,\n transfer,\n );\n }\n\n // Fire custom event callback for events with customMetadata\n if (event.customMetadata && onCustomEvent) {\n for (const [key, value] of Object.entries(event.customMetadata)) {\n invokeAdkRuntimeCallback(\n \"onCustomEvent\",\n onCustomEvent,\n key,\n value,\n );\n }\n }\n\n if (event.errorCode || event.errorMessage) {\n invokeAdkRuntimeCallback(\n \"onError\",\n onError,\n event.errorMessage ?? event.errorCode,\n );\n }\n }\n } catch (error) {\n if (\n !abortController.signal.aborted &&\n abortControllerRef.current === abortController &&\n !(error instanceof Error && error.name === \"AbortError\")\n ) {\n throw error;\n }\n } finally {\n if (abortControllerRef.current === abortController) {\n abortControllerRef.current = null;\n }\n }\n },\n [\n aui,\n setMessagesImmediate,\n setLongRunningToolIds,\n stream,\n onError,\n onCustomEvent,\n onAgentTransfer,\n ],\n );\n\n const cancel = useCallback(() => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n }, []);\n\n useEffect(() => cancel, [cancel]);\n\n return {\n messages,\n stateDelta,\n agentInfo,\n longRunningToolIds,\n artifactDelta,\n toolConfirmations,\n authRequests,\n escalated,\n messageMetadata,\n sendMessage,\n cancel,\n setMessages: setMessagesImmediate,\n replaceMessages,\n applySnapshot,\n };\n};\n\n/**\n * Transport sends every human and tool message of one `send` call as a single\n * ADK `Content`, and ADK parses that event's function responses before running\n * any tool, so the batch runs whole or not at all. The optimistic projection\n * has to sit on the same boundary, so a run of those messages becomes one\n * synthetic event whose parts come from the same per-message conversion.\n *\n * The transport drops `ai` messages from that `Content`, so one interleaved\n * between two replies does not split the batch on the wire and must not split\n * it here either. It still becomes its own event, placed after the merged one,\n * so the optimistic projection keeps the assistant turn.\n *\n * @internal — exported for unit tests.\n */\nexport const messagesToEvents = (messages: AdkMessage[]): AdkEvent[] => {\n // A reload sends no messages at all, and the empty user content the transport\n // puts on the wire for it is not part of the optimistic view: projecting one\n // would put an empty user bubble above every regenerated turn.\n if (messages.length === 0) return [];\n\n const events: AdkEvent[] = [];\n const run: AdkMessage[] = [];\n let runIndex = 0;\n\n for (const msg of messages) {\n if (msg.type === \"ai\") {\n events.push(messageToEvent(msg));\n } else {\n if (run.length === 0) runIndex = events.length;\n run.push(msg);\n }\n }\n\n const parts = run.flatMap((m) => messageToEvent(m).content?.parts ?? []);\n const human = run.find((m) => m.type === \"human\");\n\n // A batch that contributes no part still reaches the wire: the transport\n // sends an empty user `Content`, which a reload replays as an empty human\n // message. Emitting it here keeps the optimistic view equal to that replay.\n if (parts.length === 0) parts.push({ text: \"\" });\n\n const event: AdkEvent = { id: (human ?? run[0])?.id ?? generateId() };\n if (human || run.length === 0) event.author = \"user\";\n event.content = { role: \"user\", parts };\n events.splice(run.length > 0 ? runIndex : events.length, 0, event);\n\n return events;\n};\n\n/** @internal — exported for unit tests. */\nexport const messageToEvent = (msg: AdkMessage): AdkEvent => {\n if (msg.type === \"human\") {\n return {\n id: msg.id ?? generateId(),\n author: \"user\",\n content: { role: \"user\", parts: contentToParts(msg.content) },\n };\n }\n\n if (msg.type === \"tool\") {\n let response: unknown;\n try {\n response = JSON.parse(msg.content);\n } catch {\n response = msg.content;\n }\n return {\n id: msg.id ?? generateId(),\n content: {\n role: \"user\",\n parts: [\n {\n functionResponse: {\n name: msg.name,\n id: msg.tool_call_id,\n response: toAdkFunctionResponse(response, msg.status === \"error\"),\n },\n },\n ],\n },\n };\n }\n\n const result: AdkEvent = { id: msg.id ?? generateId() };\n if (msg.author != null) result.author = msg.author;\n result.content = {\n role: \"model\",\n parts: [\n ...contentToParts(msg.content),\n ...(msg.tool_calls?.map((tc) => ({\n functionCall: { name: tc.name, id: tc.id, args: { ...tc.args } },\n })) ?? []),\n ],\n };\n return result;\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"useAdkMessages.js","names":[],"sources":["../src/useAdkMessages.ts"],"sourcesContent":["import {\n useState,\n useCallback,\n useEffect,\n useInsertionEffect,\n useRef,\n useMemo,\n} from \"react\";\nimport { generateId } from \"@assistant-ui/core\";\nimport { useAui } from \"@assistant-ui/store\";\nimport {\n abortableIterable,\n invokeUserCallback,\n openAbortableIterable,\n} from \"@assistant-ui/core/internal\";\nimport { AdkEventAccumulator } from \"./AdkEventAccumulator\";\nimport { contentToParts } from \"./contentToParts\";\nimport { toAdkFunctionResponse } from \"./toAdkFunctionResponse\";\nimport type {\n AdkEvent,\n AdkMessage,\n AdkMessageMetadata,\n AdkSendMessageConfig,\n AdkStreamCallback,\n AdkToolConfirmation,\n AdkAuthRequest,\n AdkThreadSnapshot,\n OnAdkErrorCallback,\n OnAdkCustomEventCallback,\n OnAdkAgentTransferCallback,\n} from \"./types\";\n\nexport type UseAdkMessagesOptions = {\n stream: AdkStreamCallback;\n eventHandlers?: {\n onError?: OnAdkErrorCallback;\n onCustomEvent?: OnAdkCustomEventCallback;\n onAgentTransfer?: OnAdkAgentTransferCallback;\n };\n};\n\ntype AdkRuntimeCallbackName = \"onError\" | \"onCustomEvent\" | \"onAgentTransfer\";\n\nconst invokeAdkRuntimeCallback = <TArgs extends readonly unknown[]>(\n name: AdkRuntimeCallbackName,\n callback: ((...args: TArgs) => unknown) | undefined,\n ...args: TArgs\n): void => {\n void invokeUserCallback(\"react-google-adk\", name, callback, ...args);\n};\n\nexport const useAdkMessages = ({\n stream,\n eventHandlers,\n}: UseAdkMessagesOptions) => {\n const [messages, _setMessages] = useState<AdkMessage[]>([]);\n const [stateDelta, setStateDelta] = useState<Record<string, unknown>>({});\n const [agentInfo, setAgentInfo] = useState<{\n name?: string | undefined;\n branch?: string | undefined;\n }>({});\n const [longRunningToolIds, _setLongRunningToolIds] = useState<string[]>([]);\n const [artifactDelta, setArtifactDelta] = useState<Record<string, number>>(\n {},\n );\n const [toolConfirmations, setToolConfirmations] = useState<\n AdkToolConfirmation[]\n >([]);\n const [authRequests, setAuthRequests] = useState<AdkAuthRequest[]>([]);\n const [escalated, setEscalated] = useState(false);\n const [messageMetadata, setMessageMetadata] = useState<\n Map<string, AdkMessageMetadata>\n >(new Map());\n const lastTransferToAgentRef = useRef<string | undefined>(undefined);\n // setMessagesImmediate and setLongRunningToolIds are the only writers of their state and publish these refs with it, so neither ref trails a commit.\n const messagesRef = useRef(messages);\n const longRunningToolIdsRef = useRef(longRunningToolIds);\n const stateDeltaRef = useRef(stateDelta);\n useInsertionEffect(() => {\n stateDeltaRef.current = stateDelta;\n }, [stateDelta]);\n const artifactDeltaRef = useRef(artifactDelta);\n useInsertionEffect(() => {\n artifactDeltaRef.current = artifactDelta;\n }, [artifactDelta]);\n const messageMetadataRef = useRef(messageMetadata);\n useInsertionEffect(() => {\n messageMetadataRef.current = messageMetadata;\n }, [messageMetadata]);\n\n const setMessagesImmediate = useCallback((msgs: AdkMessage[]) => {\n messagesRef.current = msgs;\n _setMessages(msgs);\n }, []);\n const setLongRunningToolIds = useCallback((ids: string[]) => {\n longRunningToolIdsRef.current = ids;\n _setLongRunningToolIds(ids);\n }, []);\n\n /**\n * Swap the thread over to a loaded snapshot in one commit. Unlike\n * {@link replaceMessages} this never passes through a cleared state, so a\n * refetch that lands while a confirmation is on screen replaces it rather\n * than blanking it first.\n */\n const applySnapshot = useCallback(\n (snapshot: AdkThreadSnapshot) => {\n setMessagesImmediate(snapshot.messages);\n setLongRunningToolIds(snapshot.longRunningToolIds ?? []);\n setToolConfirmations(snapshot.toolConfirmations ?? []);\n setAuthRequests(snapshot.authRequests ?? []);\n setEscalated(snapshot.escalated ?? false);\n setMessageMetadata(snapshot.messageMetadata ?? new Map());\n setStateDelta(snapshot.stateDelta ?? {});\n setArtifactDelta(snapshot.artifactDelta ?? {});\n setAgentInfo(snapshot.agentInfo ?? {});\n },\n [setLongRunningToolIds, setMessagesImmediate],\n );\n\n // Replace the message list AND reset derived per-turn HITL state.\n // Used by truncation paths (edit, reload) so that stale interrupt\n // markers and per-message metadata from the removed messages don't leak\n // into the next turn.\n const replaceMessages = useCallback(\n (msgs: AdkMessage[]) => {\n setMessagesImmediate(msgs);\n setLongRunningToolIds([]);\n setToolConfirmations([]);\n setAuthRequests([]);\n setEscalated(false);\n setMessageMetadata(new Map());\n },\n [setLongRunningToolIds, setMessagesImmediate],\n );\n\n const abortControllerRef = useRef<AbortController | null>(null);\n\n const { onError, onCustomEvent, onAgentTransfer } = useMemo(\n () => eventHandlers ?? {},\n [eventHandlers],\n );\n\n const aui = useAui();\n const sendMessage = useCallback(\n async (newMessages: AdkMessage[], config: AdkSendMessageConfig) => {\n const newMessagesWithId = newMessages.map((m) =>\n m.id ? m : { ...m, id: generateId() },\n ) as AdkMessage[];\n\n // A staged message is already in the thread under its own id, and the\n // merged event below re-emits the whole batch under the first one. Seeding\n // with the originals would leave every later staged id beside the merged\n // copy of itself.\n const resentIds = new Set(newMessagesWithId.map((m) => m.id));\n // The optimistic event for a tool-only batch carries no author, so the accumulator cannot settle the calls this send answers.\n const answeredToolCallIds = new Set(\n newMessagesWithId.flatMap((m) =>\n m.type === \"tool\" ? [m.tool_call_id] : [],\n ),\n );\n const accumulator = new AdkEventAccumulator(\n messagesRef.current.filter((m) => !resentIds.has(m.id)),\n longRunningToolIdsRef.current.filter(\n (id) => !answeredToolCallIds.has(id),\n ),\n );\n for (const event of messagesToEvents(newMessagesWithId)) {\n accumulator.processEvent(event);\n }\n setMessagesImmediate(accumulator.getMessages());\n setLongRunningToolIds(accumulator.getLongRunningToolIds());\n setToolConfirmations(accumulator.getToolConfirmations());\n setAuthRequests(accumulator.getAuthRequests());\n\n // Google ADK replaces active runs, while React LangGraph queues sends.\n abortControllerRef.current?.abort();\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n\n try {\n const response = await openAbortableIterable(\n stream(newMessagesWithId, {\n ...config,\n abortSignal: abortController.signal,\n initialize: async () => {\n return await aui.threadListItem.initialize();\n },\n }),\n abortController.signal,\n );\n if (!response) return;\n\n for await (const event of abortableIterable(\n response,\n abortController.signal,\n )) {\n if (\n abortController.signal.aborted ||\n abortControllerRef.current !== abortController\n ) {\n break;\n }\n const updatedMessages = accumulator.processEvent(event);\n setMessagesImmediate(updatedMessages);\n setStateDelta({\n ...stateDeltaRef.current,\n ...accumulator.getStateDelta(),\n });\n setAgentInfo(accumulator.getAgentInfo());\n setLongRunningToolIds(accumulator.getLongRunningToolIds());\n setArtifactDelta({\n ...artifactDeltaRef.current,\n ...accumulator.getArtifactDelta(),\n });\n setToolConfirmations(accumulator.getToolConfirmations());\n setAuthRequests(accumulator.getAuthRequests());\n setEscalated(accumulator.isEscalated());\n {\n const newMeta = accumulator.getMessageMetadata();\n if (newMeta.size > 0) {\n setMessageMetadata(\n new Map([...messageMetadataRef.current, ...newMeta]),\n );\n }\n }\n\n const transfer = accumulator.getLastTransferToAgent();\n if (transfer && transfer !== lastTransferToAgentRef.current) {\n lastTransferToAgentRef.current = transfer;\n invokeAdkRuntimeCallback(\n \"onAgentTransfer\",\n onAgentTransfer,\n transfer,\n );\n }\n\n // Fire custom event callback for events with customMetadata\n if (event.customMetadata && onCustomEvent) {\n for (const [key, value] of Object.entries(event.customMetadata)) {\n invokeAdkRuntimeCallback(\n \"onCustomEvent\",\n onCustomEvent,\n key,\n value,\n );\n }\n }\n\n if (event.errorCode || event.errorMessage) {\n invokeAdkRuntimeCallback(\n \"onError\",\n onError,\n event.errorMessage ?? event.errorCode,\n );\n }\n }\n } catch (error) {\n if (\n !abortController.signal.aborted &&\n abortControllerRef.current === abortController &&\n !(error instanceof Error && error.name === \"AbortError\")\n ) {\n throw error;\n }\n } finally {\n if (abortControllerRef.current === abortController) {\n abortControllerRef.current = null;\n }\n }\n },\n [\n aui,\n setMessagesImmediate,\n setLongRunningToolIds,\n stream,\n onError,\n onCustomEvent,\n onAgentTransfer,\n ],\n );\n\n const cancel = useCallback(() => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n }, []);\n\n useEffect(() => cancel, [cancel]);\n\n return {\n messages,\n stateDelta,\n agentInfo,\n longRunningToolIds,\n artifactDelta,\n toolConfirmations,\n authRequests,\n escalated,\n messageMetadata,\n sendMessage,\n cancel,\n setMessages: setMessagesImmediate,\n replaceMessages,\n applySnapshot,\n };\n};\n\n/**\n * Transport sends every human and tool message of one `send` call as a single\n * ADK `Content`, and ADK parses that event's function responses before running\n * any tool, so the batch runs whole or not at all. The optimistic projection\n * has to sit on the same boundary, so a run of those messages becomes one\n * synthetic event whose parts come from the same per-message conversion.\n *\n * The transport drops `ai` messages from that `Content`, so one interleaved\n * between two replies does not split the batch on the wire and must not split\n * it here either. It still becomes its own event, placed after the merged one,\n * so the optimistic projection keeps the assistant turn.\n *\n * @internal — exported for unit tests.\n */\nexport const messagesToEvents = (messages: AdkMessage[]): AdkEvent[] => {\n // A reload sends no messages at all, and the empty user content the transport\n // puts on the wire for it is not part of the optimistic view: projecting one\n // would put an empty user bubble above every regenerated turn.\n if (messages.length === 0) return [];\n\n const events: AdkEvent[] = [];\n const run: AdkMessage[] = [];\n let runIndex = 0;\n\n for (const msg of messages) {\n if (msg.type === \"ai\") {\n events.push(messageToEvent(msg));\n } else {\n if (run.length === 0) runIndex = events.length;\n run.push(msg);\n }\n }\n\n const parts = run.flatMap((m) => messageToEvent(m).content?.parts ?? []);\n const human = run.find((m) => m.type === \"human\");\n\n // A batch that contributes no part still reaches the wire: the transport\n // sends an empty user `Content`, which a reload replays as an empty human\n // message. Emitting it here keeps the optimistic view equal to that replay.\n if (parts.length === 0) parts.push({ text: \"\" });\n\n const event: AdkEvent = { id: (human ?? run[0])?.id ?? generateId() };\n if (human || run.length === 0) event.author = \"user\";\n event.content = { role: \"user\", parts };\n events.splice(run.length > 0 ? runIndex : events.length, 0, event);\n\n return events;\n};\n\n/** @internal — exported for unit tests. */\nexport const messageToEvent = (msg: AdkMessage): AdkEvent => {\n if (msg.type === \"human\") {\n return {\n id: msg.id ?? generateId(),\n author: \"user\",\n content: { role: \"user\", parts: contentToParts(msg.content) },\n };\n }\n\n if (msg.type === \"tool\") {\n let response: unknown;\n try {\n response = JSON.parse(msg.content);\n } catch {\n response = msg.content;\n }\n return {\n id: msg.id ?? generateId(),\n content: {\n role: \"user\",\n parts: [\n {\n functionResponse: {\n name: msg.name,\n id: msg.tool_call_id,\n response: toAdkFunctionResponse(response, msg.status === \"error\"),\n },\n },\n ],\n },\n };\n }\n\n const result: AdkEvent = { id: msg.id ?? generateId() };\n if (msg.author != null) result.author = msg.author;\n result.content = {\n role: \"model\",\n parts: [\n ...contentToParts(msg.content),\n ...(msg.tool_calls?.map((tc) => ({\n functionCall: { name: tc.name, id: tc.id, args: { ...tc.args } },\n })) ?? []),\n ],\n };\n return result;\n};\n"],"mappings":"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"}
@@ -2,7 +2,7 @@ import { AdkMessage, AdkStreamCallback, AdkThreadSnapshot, OnAdkAgentTransferCal
2
2
  import { AttachmentAdapter, DictationAdapter, ExternalStoreSharedOptions, FeedbackAdapter, RealtimeVoiceAdapter, RemoteThreadListAdapter, SpeechSynthesisAdapter } from "@assistant-ui/core";
3
3
  import { AssistantCloud } from "assistant-cloud";
4
4
  //#region src/useAdkRuntime.d.ts
5
- type UseAdkRuntimeOptions = ExternalStoreSharedOptions & {
5
+ export type UseAdkRuntimeOptions = ExternalStoreSharedOptions & {
6
6
  stream: AdkStreamCallback;
7
7
  /**
8
8
  * Called whenever the active thread's canonical (remote) ID changes, so the
@@ -48,7 +48,6 @@ type UseAdkRuntimeOptions = ExternalStoreSharedOptions & {
48
48
  */
49
49
  sessionAdapter?: RemoteThreadListAdapter | undefined;
50
50
  };
51
- declare const useAdkRuntime: ({ cloud, sessionAdapter, create, delete: deleteFn, onThreadIdChange, ...options }: UseAdkRuntimeOptions) => import("@assistant-ui/core").AssistantRuntime;
51
+ export declare const useAdkRuntime: ({ cloud, sessionAdapter, create, delete: deleteFn, onThreadIdChange, ...options }: UseAdkRuntimeOptions) => import("@assistant-ui/core").AssistantRuntime;
52
52
  //#endregion
53
- export { UseAdkRuntimeOptions, useAdkRuntime };
54
53
  //# sourceMappingURL=useAdkRuntime.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useAdkRuntime.d.ts","names":[],"sources":["../src/useAdkRuntime.ts"],"mappings":";;;;KA6DY,uBAAuB;EACjC,QAAQ;;;;;;;;;EASR,qBAAqB;EACrB;EACA;EACA,mBACE,kBACA,gBAAgB,iBACb;;;;;;;EAOL,QACE,kBACA;IAAY,SAAS;QAClB,QAAQ;EACb,eAAe;IAAU;;EACzB,UAAU,qBAAqB;EAC/B;IAEM,cAAc;IACd,SAAS;IACT,YAAY;IACZ,QAAQ;IACR,WAAW;;EAGjB;IAEM,UAAU;IACV,gBAAgB;IAChB,kBAAkB;;EAGxB,QAAQ;;;;;EAKR,iBAAiB;;cAkYN,kBAAiB,OAAA,gBAAA,QAAA,QAAA,UAAA,qBAAA,WAO3B,sDAAoB"}
1
+ {"version":3,"file":"useAdkRuntime.d.ts","names":[],"sources":["../src/useAdkRuntime.ts"],"mappings":";;;;YA6DY,uBAAuB;EACjC,QAAQ;;;;;;;;;EASR,qBAAqB;EACrB;EACA;EACA,mBACE,kBACA,gBAAgB,iBACb;;;;;;;EAOL,QACE,kBACA;IAAY,SAAS;QAClB,QAAQ;EACb,eAAe;IAAU;;EACzB,UAAU,qBAAqB;EAC/B;IAEM,cAAc;IACd,SAAS;IACT,YAAY;IACZ,QAAQ;IACR,WAAW;;EAGjB;IAEM,UAAU;IACV,gBAAgB;IAChB,kBAAkB;;EAGxB,QAAQ;;;;;EAKR,iBAAiB;;qBAkYN,kBAAiB,OAAA,gBAAA,QAAA,QAAA,UAAA,qBAAA,WAO3B,sDAAoB"}
@@ -1,5 +1,5 @@
1
- import { adkExtras } from "./adkExtras.js";
2
1
  import { projectAdkToolApprovals, toAdkToolConfirmationReply } from "./adkToolApproval.js";
2
+ import { adkExtras } from "./adkExtras.js";
3
3
  import { convertAdkMessage, createAdkMessageConverter } from "./convertAdkMessages.js";
4
4
  import { getMessageContent, getPendingCancellations, toAdkUserMessage, truncateAdkMessages } from "./convertToAdkMessages.js";
5
5
  import { useAdkMessages } from "./useAdkMessages.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@assistant-ui/react-google-adk",
3
- "version": "0.0.30",
3
+ "version": "0.0.31",
4
4
  "description": "Google ADK adapter for assistant-ui",
5
5
  "keywords": [
6
6
  "google-adk",
@@ -34,10 +34,10 @@
34
34
  ],
35
35
  "sideEffects": false,
36
36
  "dependencies": {
37
- "@assistant-ui/core": "^0.3.19",
38
- "@assistant-ui/store": "^0.3.13",
37
+ "@assistant-ui/core": "^0.3.20",
38
+ "@assistant-ui/store": "^0.3.14",
39
39
  "assistant-cloud": "*",
40
- "assistant-stream": "^0.3.43"
40
+ "assistant-stream": "^0.3.44"
41
41
  },
42
42
  "peerDependencies": {
43
43
  "@google/adk": ">=0.5.0",
@@ -53,13 +53,13 @@
53
53
  }
54
54
  },
55
55
  "devDependencies": {
56
- "@assistant-ui/x-buildutils": "0.0.27",
57
- "@testing-library/dom": "^10.4.1",
56
+ "@assistant-ui/x-buildutils": "0.0.28",
57
+ "@testing-library/dom": "^10.4.2",
58
58
  "@testing-library/react": "^16.3.3",
59
- "@types/react": "^19.2.18",
59
+ "@types/react": "^19.3.0",
60
60
  "jsdom": "^30.0.1",
61
- "react": "^19.2.8",
62
- "vitest": "^5.0.0"
61
+ "react": "^19.3.0",
62
+ "vitest": "^5.0.1"
63
63
  },
64
64
  "publishConfig": {
65
65
  "access": "public",
@@ -77,6 +77,7 @@
77
77
  "scripts": {
78
78
  "build": "aui-build",
79
79
  "test": "vitest run",
80
+ "typecheck": "tsc --noEmit",
80
81
  "test:watch": "vitest"
81
82
  }
82
83
  }