@agent-native/toolkit 0.201.1 → 0.202.0-nightly-20261006033736

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 (229) hide show
  1. package/agent-native.eject.json +39 -12
  2. package/dist/app/agentkit/react/components.d.ts.map +1 -1
  3. package/dist/app/agentkit/react/components.js +292 -23
  4. package/dist/app/agentkit/react/components.js.map +1 -1
  5. package/dist/app/agentkit/react/context.d.ts +5 -0
  6. package/dist/app/agentkit/react/context.d.ts.map +1 -1
  7. package/dist/app/agentkit/react/context.js +5 -0
  8. package/dist/app/agentkit/react/context.js.map +1 -1
  9. package/dist/app/agentkit/react/styles.css +78 -3
  10. package/dist/app/auth/AuthPage.d.ts.map +1 -1
  11. package/dist/app/auth/AuthPage.js +7 -14
  12. package/dist/app/auth/AuthPage.js.map +1 -1
  13. package/dist/app/auth/server.d.ts +6 -0
  14. package/dist/app/auth/server.d.ts.map +1 -0
  15. package/dist/app/auth/server.js +19 -0
  16. package/dist/app/auth/server.js.map +1 -0
  17. package/dist/app/chat/AgentKitAssistantChat.d.ts.map +1 -1
  18. package/dist/app/chat/AgentKitAssistantChat.js +164 -83
  19. package/dist/app/chat/AgentKitAssistantChat.js.map +1 -1
  20. package/dist/app/chat/AgentSidebar.d.ts +2 -1
  21. package/dist/app/chat/AgentSidebar.d.ts.map +1 -1
  22. package/dist/app/chat/AgentSidebar.js +2 -2
  23. package/dist/app/chat/AgentSidebar.js.map +1 -1
  24. package/dist/app/chat/agentkit-chat/guided-questions.d.ts.map +1 -1
  25. package/dist/app/chat/agentkit-chat/guided-questions.js +13 -3
  26. package/dist/app/chat/agentkit-chat/guided-questions.js.map +1 -1
  27. package/dist/app/chat/chat/surface-types.d.ts +2 -0
  28. package/dist/app/chat/chat/surface-types.d.ts.map +1 -1
  29. package/dist/app/i18n/catalogs/ar-SA.d.ts.map +1 -1
  30. package/dist/app/i18n/catalogs/ar-SA.js +41 -0
  31. package/dist/app/i18n/catalogs/ar-SA.js.map +1 -1
  32. package/dist/app/i18n/catalogs/de-DE.d.ts.map +1 -1
  33. package/dist/app/i18n/catalogs/de-DE.js +41 -0
  34. package/dist/app/i18n/catalogs/de-DE.js.map +1 -1
  35. package/dist/app/i18n/catalogs/en-US.d.ts +41 -0
  36. package/dist/app/i18n/catalogs/en-US.d.ts.map +1 -1
  37. package/dist/app/i18n/catalogs/en-US.js +41 -0
  38. package/dist/app/i18n/catalogs/en-US.js.map +1 -1
  39. package/dist/app/i18n/catalogs/es-ES.d.ts.map +1 -1
  40. package/dist/app/i18n/catalogs/es-ES.js +41 -0
  41. package/dist/app/i18n/catalogs/es-ES.js.map +1 -1
  42. package/dist/app/i18n/catalogs/fr-FR.d.ts.map +1 -1
  43. package/dist/app/i18n/catalogs/fr-FR.js +41 -0
  44. package/dist/app/i18n/catalogs/fr-FR.js.map +1 -1
  45. package/dist/app/i18n/catalogs/hi-IN.d.ts.map +1 -1
  46. package/dist/app/i18n/catalogs/hi-IN.js +41 -0
  47. package/dist/app/i18n/catalogs/hi-IN.js.map +1 -1
  48. package/dist/app/i18n/catalogs/ja-JP.d.ts.map +1 -1
  49. package/dist/app/i18n/catalogs/ja-JP.js +41 -0
  50. package/dist/app/i18n/catalogs/ja-JP.js.map +1 -1
  51. package/dist/app/i18n/catalogs/ko-KR.d.ts.map +1 -1
  52. package/dist/app/i18n/catalogs/ko-KR.js +41 -0
  53. package/dist/app/i18n/catalogs/ko-KR.js.map +1 -1
  54. package/dist/app/i18n/catalogs/pt-BR.d.ts.map +1 -1
  55. package/dist/app/i18n/catalogs/pt-BR.js +41 -0
  56. package/dist/app/i18n/catalogs/pt-BR.js.map +1 -1
  57. package/dist/app/i18n/catalogs/zh-CN.d.ts.map +1 -1
  58. package/dist/app/i18n/catalogs/zh-CN.js +41 -0
  59. package/dist/app/i18n/catalogs/zh-CN.js.map +1 -1
  60. package/dist/app/i18n/catalogs/zh-TW.d.ts.map +1 -1
  61. package/dist/app/i18n/catalogs/zh-TW.js +41 -0
  62. package/dist/app/i18n/catalogs/zh-TW.js.map +1 -1
  63. package/dist/app/shared/StarfieldBackground.d.ts +1 -6
  64. package/dist/app/shared/StarfieldBackground.d.ts.map +1 -1
  65. package/dist/app/shared/StarfieldBackground.js +1 -368
  66. package/dist/app/shared/StarfieldBackground.js.map +1 -1
  67. package/dist/app/shared/WaveBackground.d.ts +5 -0
  68. package/dist/app/shared/WaveBackground.d.ts.map +1 -0
  69. package/dist/app/shared/WaveBackground.js +34 -0
  70. package/dist/app/shared/WaveBackground.js.map +1 -0
  71. package/dist/app/shared/WebGlWaveBackground.d.ts +9 -0
  72. package/dist/app/shared/WebGlWaveBackground.d.ts.map +1 -0
  73. package/dist/app/shared/WebGlWaveBackground.js +433 -0
  74. package/dist/app/shared/WebGlWaveBackground.js.map +1 -0
  75. package/dist/app/shared/index.d.ts +1 -0
  76. package/dist/app/shared/index.d.ts.map +1 -1
  77. package/dist/app/shared/index.js +1 -0
  78. package/dist/app/shared/index.js.map +1 -1
  79. package/dist/app/shared/ocean/bloom-blur.wgsl +43 -0
  80. package/dist/app/shared/ocean/bloom-blur.wgsl.js +1 -0
  81. package/dist/app/shared/ocean/bloom-bright.wgsl +21 -0
  82. package/dist/app/shared/ocean/bloom-bright.wgsl.js +1 -0
  83. package/dist/app/shared/ocean/bloom-composite.wgsl +40 -0
  84. package/dist/app/shared/ocean/bloom-composite.wgsl.js +1 -0
  85. package/dist/app/shared/ocean/brand-colors.d.ts +9 -0
  86. package/dist/app/shared/ocean/brand-colors.d.ts.map +1 -0
  87. package/dist/app/shared/ocean/brand-colors.js +45 -0
  88. package/dist/app/shared/ocean/brand-colors.js.map +1 -0
  89. package/dist/app/shared/ocean/camera.d.ts +5 -0
  90. package/dist/app/shared/ocean/camera.d.ts.map +1 -0
  91. package/dist/app/shared/ocean/camera.js +24 -0
  92. package/dist/app/shared/ocean/camera.js.map +1 -0
  93. package/dist/app/shared/ocean/hero-ocean-background.d.ts +8 -0
  94. package/dist/app/shared/ocean/hero-ocean-background.d.ts.map +1 -0
  95. package/dist/app/shared/ocean/hero-ocean-background.js +186 -0
  96. package/dist/app/shared/ocean/hero-ocean-background.js.map +1 -0
  97. package/dist/app/shared/ocean/ifft-stage.wgsl +36 -0
  98. package/dist/app/shared/ocean/ifft-stage.wgsl.js +1 -0
  99. package/dist/app/shared/ocean/initial-spectrum.wgsl +36 -0
  100. package/dist/app/shared/ocean/initial-spectrum.wgsl.js +1 -0
  101. package/dist/app/shared/ocean/noise.wgsl +24 -0
  102. package/dist/app/shared/ocean/noise.wgsl.js +1 -0
  103. package/dist/app/shared/ocean/normal-foam.wgsl +32 -0
  104. package/dist/app/shared/ocean/normal-foam.wgsl.js +1 -0
  105. package/dist/app/shared/ocean/ocean-colors.d.ts +6 -0
  106. package/dist/app/shared/ocean/ocean-colors.d.ts.map +1 -0
  107. package/dist/app/shared/ocean/ocean-colors.js +6 -0
  108. package/dist/app/shared/ocean/ocean-colors.js.map +1 -0
  109. package/dist/app/shared/ocean/ocean-common.wgsl +15 -0
  110. package/dist/app/shared/ocean/ocean-common.wgsl.js +1 -0
  111. package/dist/app/shared/ocean/ocean-graph.d.ts +12 -0
  112. package/dist/app/shared/ocean/ocean-graph.d.ts.map +1 -0
  113. package/dist/app/shared/ocean/ocean-graph.js +16 -0
  114. package/dist/app/shared/ocean/ocean-graph.js.map +1 -0
  115. package/dist/app/shared/ocean/particles.wgsl +139 -0
  116. package/dist/app/shared/ocean/particles.wgsl.js +1 -0
  117. package/dist/app/shared/ocean/present.wgsl +40 -0
  118. package/dist/app/shared/ocean/present.wgsl.js +1 -0
  119. package/dist/app/shared/ocean/renderer.d.ts +66 -0
  120. package/dist/app/shared/ocean/renderer.d.ts.map +1 -0
  121. package/dist/app/shared/ocean/renderer.js +535 -0
  122. package/dist/app/shared/ocean/renderer.js.map +1 -0
  123. package/dist/app/shared/ocean/spectrum.wgsl +35 -0
  124. package/dist/app/shared/ocean/spectrum.wgsl.js +1 -0
  125. package/dist/app/shared/ocean/tuning.d.ts +48 -0
  126. package/dist/app/shared/ocean/tuning.d.ts.map +1 -0
  127. package/dist/app/shared/ocean/tuning.js +74 -0
  128. package/dist/app/shared/ocean/tuning.js.map +1 -0
  129. package/dist/app/shared/ocean/webgpu-support.d.ts +3 -0
  130. package/dist/app/shared/ocean/webgpu-support.d.ts.map +1 -0
  131. package/dist/app/shared/ocean/webgpu-support.js +13 -0
  132. package/dist/app/shared/ocean/webgpu-support.js.map +1 -0
  133. package/dist/app/sharing/AccessRequestApprovalPage.d.ts +23 -0
  134. package/dist/app/sharing/AccessRequestApprovalPage.d.ts.map +1 -0
  135. package/dist/app/sharing/AccessRequestApprovalPage.js +95 -0
  136. package/dist/app/sharing/AccessRequestApprovalPage.js.map +1 -0
  137. package/dist/app/sharing/AccessRequestsSection.d.ts +5 -0
  138. package/dist/app/sharing/AccessRequestsSection.d.ts.map +1 -0
  139. package/dist/app/sharing/AccessRequestsSection.js +47 -0
  140. package/dist/app/sharing/AccessRequestsSection.js.map +1 -0
  141. package/dist/app/sharing/ResourceAccessScreen.d.ts +53 -0
  142. package/dist/app/sharing/ResourceAccessScreen.d.ts.map +1 -0
  143. package/dist/app/sharing/ResourceAccessScreen.js +132 -0
  144. package/dist/app/sharing/ResourceAccessScreen.js.map +1 -0
  145. package/dist/app/sharing/ShareButton.d.ts.map +1 -1
  146. package/dist/app/sharing/ShareButton.js +4 -2
  147. package/dist/app/sharing/ShareButton.js.map +1 -1
  148. package/dist/app/sharing/ShareDialog.d.ts.map +1 -1
  149. package/dist/app/sharing/ShareDialog.js +7 -5
  150. package/dist/app/sharing/ShareDialog.js.map +1 -1
  151. package/dist/app/sharing/index.d.ts +2 -0
  152. package/dist/app/sharing/index.d.ts.map +1 -1
  153. package/dist/app/sharing/index.js +2 -0
  154. package/dist/app/sharing/index.js.map +1 -1
  155. package/dist/app/styles/agent-native.css +21 -1
  156. package/dist/app/styles/tokens/agent-kit.css +3 -1
  157. package/dist/composer/AgentSuggestionBar.d.ts +1 -1
  158. package/dist/composer/AgentSuggestionBar.d.ts.map +1 -1
  159. package/dist/composer/AgentSuggestionBar.js +75 -6
  160. package/dist/composer/AgentSuggestionBar.js.map +1 -1
  161. package/package.json +14 -4
  162. package/src/app/agentkit/react/components.tsx +492 -60
  163. package/src/app/agentkit/react/context.tsx +10 -0
  164. package/src/app/agentkit/react/lifecycle.spec.tsx +487 -1
  165. package/src/app/agentkit/react/styles.css +78 -3
  166. package/src/app/auth/AuthPage.spec.tsx +11 -7
  167. package/src/app/auth/AuthPage.tsx +16 -35
  168. package/src/app/auth/server.spec.ts +68 -0
  169. package/src/app/auth/server.ts +29 -0
  170. package/src/app/chat/AgentKitAssistantChat.spec.tsx +287 -290
  171. package/src/app/chat/AgentKitAssistantChat.tsx +219 -116
  172. package/src/app/chat/AgentSidebar.tsx +3 -0
  173. package/src/app/chat/agentkit-chat/guided-questions.flow.spec.tsx +85 -0
  174. package/src/app/chat/agentkit-chat/guided-questions.tsx +12 -5
  175. package/src/app/chat/chat/surface-types.ts +2 -0
  176. package/src/app/i18n/catalogs/ar-SA.ts +44 -0
  177. package/src/app/i18n/catalogs/de-DE.ts +55 -0
  178. package/src/app/i18n/catalogs/en-US.ts +46 -0
  179. package/src/app/i18n/catalogs/es-ES.ts +53 -0
  180. package/src/app/i18n/catalogs/fr-FR.ts +53 -0
  181. package/src/app/i18n/catalogs/hi-IN.ts +47 -0
  182. package/src/app/i18n/catalogs/ja-JP.ts +54 -0
  183. package/src/app/i18n/catalogs/ko-KR.ts +50 -0
  184. package/src/app/i18n/catalogs/pt-BR.ts +52 -0
  185. package/src/app/i18n/catalogs/zh-CN.ts +42 -0
  186. package/src/app/i18n/catalogs/zh-TW.ts +43 -0
  187. package/src/app/shared/StarfieldBackground.tsx +4 -423
  188. package/src/app/shared/WaveBackground.spec.tsx +104 -0
  189. package/src/app/shared/WaveBackground.tsx +60 -0
  190. package/src/app/shared/WebGlWaveBackground.spec.tsx +106 -0
  191. package/src/app/shared/WebGlWaveBackground.tsx +499 -0
  192. package/src/app/shared/index.ts +1 -0
  193. package/src/app/shared/ocean/bloom-blur.wgsl +43 -0
  194. package/src/app/shared/ocean/bloom-bright.wgsl +21 -0
  195. package/src/app/shared/ocean/bloom-composite.wgsl +40 -0
  196. package/src/app/shared/ocean/brand-colors.ts +49 -0
  197. package/src/app/shared/ocean/camera.ts +28 -0
  198. package/src/app/shared/ocean/hero-ocean-background.spec.tsx +369 -0
  199. package/src/app/shared/ocean/hero-ocean-background.tsx +238 -0
  200. package/src/app/shared/ocean/ifft-stage.wgsl +36 -0
  201. package/src/app/shared/ocean/initial-spectrum.wgsl +36 -0
  202. package/src/app/shared/ocean/noise.wgsl +24 -0
  203. package/src/app/shared/ocean/normal-foam.wgsl +32 -0
  204. package/src/app/shared/ocean/ocean-colors.ts +11 -0
  205. package/src/app/shared/ocean/ocean-common.wgsl +15 -0
  206. package/src/app/shared/ocean/ocean-graph.ts +29 -0
  207. package/src/app/shared/ocean/particles.wgsl +139 -0
  208. package/src/app/shared/ocean/present.wgsl +40 -0
  209. package/src/app/shared/ocean/renderer.spec.ts +100 -0
  210. package/src/app/shared/ocean/renderer.ts +693 -0
  211. package/src/app/shared/ocean/spectrum.wgsl +35 -0
  212. package/src/app/shared/ocean/tuning.ts +131 -0
  213. package/src/app/shared/ocean/webgpu-support.ts +12 -0
  214. package/src/app/sharing/AccessRequestApprovalPage.spec.tsx +276 -0
  215. package/src/app/sharing/AccessRequestApprovalPage.tsx +307 -0
  216. package/src/app/sharing/AccessRequestsSection.tsx +163 -0
  217. package/src/app/sharing/ResourceAccessScreen.spec.tsx +235 -0
  218. package/src/app/sharing/ResourceAccessScreen.tsx +331 -0
  219. package/src/app/sharing/ShareButton.spec.tsx +171 -5
  220. package/src/app/sharing/ShareButton.tsx +15 -2
  221. package/src/app/sharing/ShareDialog.spec.tsx +71 -2
  222. package/src/app/sharing/ShareDialog.tsx +24 -2
  223. package/src/app/sharing/index.ts +2 -0
  224. package/src/app/styles/agent-native.css +21 -1
  225. package/src/app/styles/agent-native.spec.ts +16 -3
  226. package/src/app/styles/tokens/agent-kit.css +3 -1
  227. package/src/composer/AgentSuggestionBar.overflow.spec.tsx +277 -0
  228. package/src/composer/AgentSuggestionBar.tsx +113 -8
  229. package/src/wgsl-env.d.ts +6 -0
@@ -213,6 +213,11 @@ export interface AgentKitLabels {
213
213
  durationSecondShort: string;
214
214
  agents: string;
215
215
  tasks: string;
216
+ toolInput?: string;
217
+ toolResult?: string;
218
+ activityValueIdentifierHidden?: string;
219
+ activityValueOmitted?: string;
220
+ activityValueCircular?: string;
216
221
  composerLabel: string;
217
222
  composerPlaceholder: string;
218
223
  queue: string;
@@ -309,6 +314,11 @@ export const defaultAgentKitLabels: AgentKitLabels = {
309
314
  durationSecondShort: "s",
310
315
  agents: "Agent collaboration",
311
316
  tasks: "Agent tasks",
317
+ toolInput: "Input",
318
+ toolResult: "Result",
319
+ activityValueIdentifierHidden: "[Identifier hidden]",
320
+ activityValueOmitted: "[Content omitted]",
321
+ activityValueCircular: "[Circular reference]",
312
322
  composerLabel: "Message agent",
313
323
  composerPlaceholder: "Ask the agent to explore, build, or explain…",
314
324
  queue: "Queued messages",
@@ -9,7 +9,10 @@ import {
9
9
  } from "@agent-native/agentkit/client";
10
10
  import { createAgentKitHttpHandler } from "@agent-native/agentkit/http";
11
11
  import type {
12
+ AgentActivity,
12
13
  AgentEvent,
14
+ AgentObjectReference,
15
+ AgentTask,
13
16
  AgentToolCall,
14
17
  AgentTransport,
15
18
  } from "@agent-native/agentkit/protocol";
@@ -32,6 +35,7 @@ import {
32
35
  AgentConnectionRequestCard,
33
36
  AgentKitChat,
34
37
  AgentMessageActions,
38
+ AgentTaskGroup,
35
39
  formatAgentKitDuration,
36
40
  } from "./components.js";
37
41
  import {
@@ -2249,7 +2253,7 @@ describe("AgentChat lifecycle", () => {
2249
2253
  ).find(
2250
2254
  (row) =>
2251
2255
  row.querySelector(".agentkit-activity-label")?.textContent ===
2252
- "update-slide",
2256
+ "Update Slide",
2253
2257
  );
2254
2258
  expect(failedToolRow?.textContent).not.toContain(
2255
2259
  "slide_content_edit_failed",
@@ -2699,6 +2703,155 @@ describe("AgentChat lifecycle", () => {
2699
2703
  await tree.unmount();
2700
2704
  });
2701
2705
 
2706
+ it("preserves distinct agent sources and hides UUID-only labels", async () => {
2707
+ const threadId = "thread-agent-sources";
2708
+ const runId = "run-agent-sources";
2709
+ const internalId = "550e8400-e29b-41d4-a716-446655440000";
2710
+ const source: AgentObjectReference = {
2711
+ id: "source-agent",
2712
+ kind: "agent",
2713
+ label: "Source Agent",
2714
+ };
2715
+ const activities: AgentActivity[] = [
2716
+ ...["activity-1", "activity-2"].map((id) => ({
2717
+ id,
2718
+ kind: "read",
2719
+ label: "Read files",
2720
+ status: "completed" as const,
2721
+ agentId: "actor-agent",
2722
+ runId,
2723
+ source,
2724
+ })),
2725
+ {
2726
+ id: "activity-uuid-label",
2727
+ kind: internalId,
2728
+ label: internalId,
2729
+ status: "completed",
2730
+ runId,
2731
+ object: { id: internalId, kind: internalId, label: internalId },
2732
+ },
2733
+ ];
2734
+ const interaction = {
2735
+ id: "interaction-source",
2736
+ kind: internalId,
2737
+ agentId: "actor-agent",
2738
+ targetAgentId: "target-agent",
2739
+ source,
2740
+ } as const;
2741
+ const task: AgentTask = {
2742
+ id: "task-source",
2743
+ title: "Review report",
2744
+ status: "completed",
2745
+ assignedAgentId: "actor-agent",
2746
+ runId,
2747
+ source,
2748
+ };
2749
+ const events: AgentEvent[] = [
2750
+ ...activities.map(
2751
+ (activity, index): AgentEvent => ({
2752
+ id: `event-${activity.id}`,
2753
+ threadId,
2754
+ runId,
2755
+ sequence: index + 1,
2756
+ occurredAt: `2026-10-01T00:00:0${index + 1}.000Z`,
2757
+ type: "activity.completed",
2758
+ activity,
2759
+ }),
2760
+ ),
2761
+ {
2762
+ id: "event-interaction-source",
2763
+ threadId,
2764
+ runId,
2765
+ sequence: 4,
2766
+ occurredAt: "2026-10-01T00:00:04.000Z",
2767
+ type: "agent.interaction",
2768
+ interaction,
2769
+ },
2770
+ {
2771
+ id: "event-task-source",
2772
+ threadId,
2773
+ runId,
2774
+ sequence: 5,
2775
+ occurredAt: "2026-10-01T00:00:05.000Z",
2776
+ type: "task.created",
2777
+ task,
2778
+ },
2779
+ ];
2780
+ const thread = {
2781
+ ...createAgentThreadState(threadId),
2782
+ events,
2783
+ activities: Object.fromEntries(
2784
+ activities.map((activity) => [activity.id, activity]),
2785
+ ),
2786
+ tasks: { [task.id]: task },
2787
+ runs: {
2788
+ [runId]: {
2789
+ id: runId,
2790
+ status: "completed" as const,
2791
+ lastSequence: 5,
2792
+ startedAt: "2026-10-01T00:00:00.000Z",
2793
+ completedAt: "2026-10-01T00:00:06.000Z",
2794
+ },
2795
+ },
2796
+ };
2797
+ const { controller } = observableController({
2798
+ connection: "connected",
2799
+ capabilities: {},
2800
+ capabilitiesStatus: "ready",
2801
+ threads: { [threadId]: thread },
2802
+ revision: 0,
2803
+ });
2804
+ const tree = mount();
2805
+
2806
+ await tree.render(
2807
+ <AgentKitProvider controller={controller} threadId={threadId}>
2808
+ <AgentActivityGroup runId={runId} />
2809
+ <AgentCollaborationFeed runId={runId} />
2810
+ <AgentTaskGroup runId={runId} />
2811
+ </AgentKitProvider>,
2812
+ );
2813
+
2814
+ const cluster = tree.container.querySelector(".agentkit-activity-cluster");
2815
+ expect(
2816
+ cluster?.querySelector("summary .agentkit-agent-name")?.textContent,
2817
+ ).toBe("Assistant");
2818
+ expect(
2819
+ cluster?.querySelector("summary .agentkit-object-label")?.textContent,
2820
+ ).toBe("Source Agent");
2821
+ expect(
2822
+ cluster?.querySelector(
2823
+ ".agentkit-activity-cluster-items .agentkit-object-label",
2824
+ )?.textContent,
2825
+ ).toBe("Source Agent");
2826
+
2827
+ const interactionRow = tree.container.querySelector(
2828
+ ".agentkit-agent-interaction",
2829
+ );
2830
+ expect(
2831
+ interactionRow?.querySelector(".agentkit-agent-interaction-label")
2832
+ ?.textContent,
2833
+ ).toBe("Working");
2834
+ expect(
2835
+ interactionRow?.querySelector(".agentkit-object-label")?.textContent,
2836
+ ).toBe("Source Agent");
2837
+
2838
+ expect(
2839
+ tree.container.querySelector(".agentkit-task-row .agentkit-object-label")
2840
+ ?.textContent,
2841
+ ).toBe("Source Agent");
2842
+ const uuidActivity = Array.from(
2843
+ tree.container.querySelectorAll<HTMLElement>(".agentkit-activity-item"),
2844
+ ).find((item) => item.dataset.activityKind === internalId);
2845
+ expect(
2846
+ uuidActivity?.querySelector(".agentkit-activity-label")?.textContent,
2847
+ ).toBe("Working");
2848
+ expect(
2849
+ uuidActivity?.querySelector(".agentkit-object-label")?.textContent,
2850
+ ).toBe("Assistant");
2851
+ expect(tree.container.textContent).not.toContain(internalId);
2852
+ await tree.unmount();
2853
+ });
2854
+
2702
2855
  it("keeps generic tool results in collapsed history but preserves rich surfaces", async () => {
2703
2856
  const threadId = "thread-collapsed-tool-results";
2704
2857
  const runId = "run-collapsed-tool-results";
@@ -2855,6 +3008,339 @@ describe("AgentChat lifecycle", () => {
2855
3008
  ).toBe("The file could not be saved.");
2856
3009
  });
2857
3010
 
3011
+ it("sanitizes and bounds expanded tool details for keyboard access", async () => {
3012
+ const threadId = "thread-bounded-tool-details";
3013
+ const runId = "run-bounded-tool-details";
3014
+ const internalId = "550e8400-e29b-41d4-a716-446655440000";
3015
+ const sparseOutput = new Array(100_000);
3016
+ sparseOutput[99_999] = "beyond preview";
3017
+ const tool: AgentToolCall = {
3018
+ id: "tool-read-file",
3019
+ name: "read-file",
3020
+ status: "completed",
3021
+ input: {
3022
+ documentId: internalId,
3023
+ resource: `document_${internalId}_revision`,
3024
+ empty: "",
3025
+ whitespace: " ",
3026
+ },
3027
+ output: {
3028
+ documentId: internalId,
3029
+ resource: `document_${internalId}_revision`,
3030
+ entries: sparseOutput,
3031
+ },
3032
+ };
3033
+ const thread = reduceAgentEvent(createAgentThreadState(threadId), {
3034
+ id: "event-read-file",
3035
+ threadId,
3036
+ runId,
3037
+ sequence: 1,
3038
+ occurredAt: "2026-10-01T00:00:00.000Z",
3039
+ type: "tool.updated",
3040
+ toolCall: tool,
3041
+ });
3042
+ const { controller } = observableController({
3043
+ connection: "connected",
3044
+ capabilities: {},
3045
+ capabilitiesStatus: "ready",
3046
+ threads: { [threadId]: thread },
3047
+ revision: 0,
3048
+ });
3049
+ const tree = mount();
3050
+ await tree.render(
3051
+ <AgentKitProvider controller={controller} threadId={threadId}>
3052
+ <AgentActivityGroup runId={runId} />
3053
+ </AgentKitProvider>,
3054
+ );
3055
+
3056
+ const work = tree.container.querySelector<HTMLDetailsElement>(
3057
+ ".agentkit-activities",
3058
+ );
3059
+ await act(async () => work?.querySelector("summary")?.click());
3060
+ const row = Array.from(
3061
+ work?.querySelectorAll<HTMLElement>(".agentkit-activity-item") ?? [],
3062
+ ).find(
3063
+ (item) =>
3064
+ item.querySelector(".agentkit-activity-label")?.textContent ===
3065
+ "Read File",
3066
+ );
3067
+ expect(row?.textContent).not.toContain(internalId);
3068
+ await act(async () => row?.querySelector("button")?.click());
3069
+
3070
+ const details = Array.from(
3071
+ row?.querySelectorAll<HTMLPreElement>(
3072
+ ".agentkit-activity-summary-value",
3073
+ ) ?? [],
3074
+ );
3075
+ expect(details.map((detail) => detail.getAttribute("aria-label"))).toEqual([
3076
+ "Input",
3077
+ "Result",
3078
+ ]);
3079
+ expect(
3080
+ details.every((detail) => detail.getAttribute("role") === "region"),
3081
+ ).toBe(true);
3082
+ expect(details.every((detail) => detail.tabIndex === 0)).toBe(true);
3083
+ expect(details[0]?.textContent).toContain("[Identifier hidden]");
3084
+ expect(details[1]?.textContent).toContain("[Identifier hidden]");
3085
+ expect(details[0]?.textContent).toContain(
3086
+ '"resource": "document__revision"',
3087
+ );
3088
+ expect(details[0]?.textContent).toContain('"empty": ""');
3089
+ expect(details[0]?.textContent).toContain('"whitespace": " "');
3090
+ expect(details[1]?.textContent).toContain("[Content omitted]");
3091
+ expect(details[1]?.textContent).not.toContain(internalId);
3092
+ expect(details[1]?.textContent).not.toContain("beyond preview");
3093
+ await tree.unmount();
3094
+ });
3095
+
3096
+ it("keeps the omission marker visible when formatted tool output expands", async () => {
3097
+ const threadId = "thread-expanded-tool-output";
3098
+ const runId = "run-expanded-tool-output";
3099
+ const output = Object.fromEntries(
3100
+ Array.from({ length: 79 }, (_, index) => [
3101
+ `field-${index}-${"x".repeat(20)}`,
3102
+ "",
3103
+ ]),
3104
+ );
3105
+ const tool: AgentToolCall = {
3106
+ id: "tool-large-output",
3107
+ name: "read-records",
3108
+ input: { query: "all records" },
3109
+ output,
3110
+ status: "completed",
3111
+ };
3112
+ const thread = {
3113
+ ...createAgentThreadState(threadId),
3114
+ tools: { [tool.id]: tool },
3115
+ events: [
3116
+ {
3117
+ id: "event-large-output",
3118
+ threadId,
3119
+ runId,
3120
+ sequence: 1,
3121
+ occurredAt: "2026-10-01T00:00:01.000Z",
3122
+ type: "tool.started" as const,
3123
+ toolCall: { ...tool, status: "running" as const },
3124
+ },
3125
+ ],
3126
+ runs: {
3127
+ [runId]: {
3128
+ id: runId,
3129
+ status: "completed" as const,
3130
+ lastSequence: 1,
3131
+ startedAt: "2026-10-01T00:00:00.000Z",
3132
+ completedAt: "2026-10-01T00:00:02.000Z",
3133
+ },
3134
+ },
3135
+ };
3136
+ const { controller } = observableController({
3137
+ connection: "connected",
3138
+ capabilities: {},
3139
+ capabilitiesStatus: "ready",
3140
+ threads: { [threadId]: thread },
3141
+ revision: 0,
3142
+ });
3143
+ const tree = mount();
3144
+ await tree.render(
3145
+ <AgentKitProvider controller={controller} threadId={threadId}>
3146
+ <AgentActivityGroup runId={runId} />
3147
+ </AgentKitProvider>,
3148
+ );
3149
+
3150
+ const work = tree.container.querySelector<HTMLDetailsElement>(
3151
+ ".agentkit-activities",
3152
+ );
3153
+ await act(async () => work?.querySelector("summary")?.click());
3154
+ const row = tree.container.querySelector<HTMLElement>(
3155
+ ".agentkit-activity-item",
3156
+ );
3157
+ await act(async () => row?.querySelector("button")?.click());
3158
+ const result = row?.querySelector<HTMLPreElement>('[aria-label="Result"]');
3159
+ expect(result?.textContent?.length).toBeLessThanOrEqual(2_000);
3160
+ expect(result?.textContent).toContain("[Content omitted]");
3161
+ expect(result?.textContent).toMatch(/…\n\[Content omitted\]$/);
3162
+ await tree.unmount();
3163
+ });
3164
+
3165
+ it("keeps distinct agent sources visible and sanitizes fallback labels", async () => {
3166
+ const threadId = "thread-agent-source-labels";
3167
+ const runId = "run-agent-source-labels";
3168
+ const internalId = "550e8400-e29b-41d4-a716-446655440000";
3169
+ const source = {
3170
+ id: "external-agent",
3171
+ kind: "agent",
3172
+ label: "Different source agent",
3173
+ };
3174
+ const repeatedActivity = (id: string): AgentActivity => ({
3175
+ id,
3176
+ kind: "read",
3177
+ label: "Reading a file",
3178
+ status: "completed",
3179
+ agentId: "displayed-agent",
3180
+ source,
3181
+ });
3182
+ const sourceEvents: AgentEvent[] = ["source-a", "source-b"].map(
3183
+ (id, index) => ({
3184
+ id: `event-${id}`,
3185
+ threadId,
3186
+ runId,
3187
+ sequence: index + 1,
3188
+ occurredAt: `2026-10-01T00:00:0${index + 1}.000Z`,
3189
+ type: "activity.completed",
3190
+ activity: repeatedActivity(id),
3191
+ }),
3192
+ );
3193
+ const privateLabelActivity: AgentActivity = {
3194
+ id: "activity-private-label",
3195
+ kind: internalId,
3196
+ label: internalId,
3197
+ status: "running",
3198
+ agentId: "displayed-agent",
3199
+ object: { id: "private-object", kind: internalId, label: internalId },
3200
+ };
3201
+ const events: AgentEvent[] = [
3202
+ ...sourceEvents,
3203
+ {
3204
+ id: "event-private-label",
3205
+ threadId,
3206
+ runId,
3207
+ sequence: 3,
3208
+ occurredAt: "2026-10-01T00:00:03.000Z",
3209
+ type: "activity.started",
3210
+ activity: privateLabelActivity,
3211
+ },
3212
+ ];
3213
+ const thread = {
3214
+ ...createAgentThreadState(threadId),
3215
+ events,
3216
+ activities: {
3217
+ [privateLabelActivity.id]: privateLabelActivity,
3218
+ },
3219
+ runs: {
3220
+ [runId]: {
3221
+ id: runId,
3222
+ status: "running" as const,
3223
+ lastSequence: 3,
3224
+ startedAt: "2026-10-01T00:00:00.000Z",
3225
+ },
3226
+ },
3227
+ activeRunIds: [runId],
3228
+ };
3229
+ const { controller } = observableController({
3230
+ connection: "connected",
3231
+ capabilities: {},
3232
+ capabilitiesStatus: "ready",
3233
+ threads: { [threadId]: thread },
3234
+ revision: 0,
3235
+ });
3236
+ const tree = mount();
3237
+ await tree.render(
3238
+ <AgentKitProvider controller={controller} threadId={threadId}>
3239
+ <AgentActivityGroup runId={runId} />
3240
+ </AgentKitProvider>,
3241
+ );
3242
+
3243
+ const work = tree.container.querySelector<HTMLDetailsElement>(
3244
+ ".agentkit-activities",
3245
+ );
3246
+ expect(
3247
+ work?.querySelectorAll(
3248
+ ".agentkit-activity-cluster summary .agentkit-object-label",
3249
+ ),
3250
+ ).toHaveLength(1);
3251
+ expect(
3252
+ work?.querySelector(
3253
+ ".agentkit-activity-cluster summary .agentkit-object-label",
3254
+ )?.textContent,
3255
+ ).toBe("Different source agent");
3256
+ const privateRow = Array.from(
3257
+ work?.querySelectorAll<HTMLElement>(".agentkit-activity-item") ?? [],
3258
+ ).find((row) => row.dataset.activityKind === internalId);
3259
+ expect(
3260
+ privateRow?.querySelector(".agentkit-activity-label")?.textContent,
3261
+ ).toBe("Working");
3262
+ expect(
3263
+ privateRow?.querySelector(".agentkit-object-label")?.textContent,
3264
+ ).toBe("Assistant");
3265
+ expect(work?.textContent).not.toContain(internalId);
3266
+ await tree.unmount();
3267
+ });
3268
+
3269
+ it("keeps the omission marker after pretty-print expansion exceeds its budget", async () => {
3270
+ const threadId = "thread-formatted-tool-budget";
3271
+ const runId = "run-formatted-tool-budget";
3272
+ const formattedOutput = Object.fromEntries(
3273
+ Array.from({ length: 38 }, (_, index) => [
3274
+ `property_${String(index).padStart(2, "0")}_long_name_for_serialization`,
3275
+ "0123456789",
3276
+ ]),
3277
+ );
3278
+ const tool: AgentToolCall = {
3279
+ id: "tool-formatted-output",
3280
+ name: "read-file",
3281
+ input: { path: "guide.md" },
3282
+ output: formattedOutput,
3283
+ status: "completed",
3284
+ };
3285
+ const thread = {
3286
+ ...createAgentThreadState(threadId),
3287
+ tools: { [tool.id]: tool },
3288
+ events: [
3289
+ {
3290
+ id: "event-formatted-output",
3291
+ threadId,
3292
+ runId,
3293
+ sequence: 1,
3294
+ occurredAt: "2026-10-01T00:00:00.000Z",
3295
+ type: "tool.updated" as const,
3296
+ toolCall: tool,
3297
+ },
3298
+ ],
3299
+ runs: {
3300
+ [runId]: {
3301
+ id: runId,
3302
+ status: "completed" as const,
3303
+ lastSequence: 1,
3304
+ startedAt: "2026-10-01T00:00:00.000Z",
3305
+ completedAt: "2026-10-01T00:00:01.000Z",
3306
+ },
3307
+ },
3308
+ };
3309
+ const { controller } = observableController({
3310
+ connection: "connected",
3311
+ capabilities: {},
3312
+ capabilitiesStatus: "ready",
3313
+ threads: { [threadId]: thread },
3314
+ revision: 0,
3315
+ });
3316
+ const tree = mount();
3317
+ await tree.render(
3318
+ <AgentKitProvider controller={controller} threadId={threadId}>
3319
+ <AgentActivityGroup runId={runId} />
3320
+ </AgentKitProvider>,
3321
+ );
3322
+
3323
+ const work = tree.container.querySelector<HTMLDetailsElement>(
3324
+ ".agentkit-activities",
3325
+ );
3326
+ await act(async () => work?.querySelector("summary")?.click());
3327
+ const row = Array.from(
3328
+ tree.container.querySelectorAll<HTMLElement>(".agentkit-activity-item"),
3329
+ ).find(
3330
+ (item) =>
3331
+ item.querySelector(".agentkit-activity-label")?.textContent ===
3332
+ "Read File",
3333
+ );
3334
+ await act(async () => row?.querySelector("button")?.click());
3335
+ const result = row?.querySelectorAll<HTMLPreElement>(
3336
+ ".agentkit-activity-summary-value",
3337
+ )[1]?.textContent;
3338
+ expect(result).toBeDefined();
3339
+ expect(result!.length).toBeLessThanOrEqual(2_000);
3340
+ expect(result).toMatch(/\[Content omitted\]$/);
3341
+ await tree.unmount();
3342
+ });
3343
+
2858
3344
  it("resets disclosure state when switching threads with reused run ids", async () => {
2859
3345
  const threads = Object.fromEntries(
2860
3346
  ["thread-a", "thread-b"].map((threadId) => [
@@ -99,7 +99,10 @@
99
99
  border-color: var(--agentkit-composer-border) !important;
100
100
  border-radius: var(--agentkit-radius);
101
101
  color: var(--agentkit-text);
102
- background: var(--agentkit-surface);
102
+ background: var(
103
+ --agentkit-composer-background,
104
+ var(--agent-kit-composer-surface, var(--agentkit-surface))
105
+ );
103
106
  box-shadow: var(--agentkit-elevation);
104
107
  }
105
108
 
@@ -373,11 +376,10 @@
373
376
  }
374
377
 
375
378
  .agentkit-suggestions [data-agent-suggestion-scroller="true"] {
376
- display: flex;
377
379
  inline-size: 100%;
378
- gap: 0.375rem;
379
380
  overflow-x: auto;
380
381
  overscroll-behavior-inline: contain;
382
+ scroll-padding-inline: 1.5rem;
381
383
  scrollbar-width: none;
382
384
  }
383
385
 
@@ -386,6 +388,46 @@
386
388
  display: none;
387
389
  }
388
390
 
391
+ .agentkit-suggestions [data-agent-suggestion-track="true"] {
392
+ display: flex;
393
+ flex-wrap: wrap;
394
+ inline-size: var(--agent-suggestion-track-width);
395
+ min-inline-size: 100%;
396
+ gap: 0.375rem;
397
+ }
398
+
399
+ [data-agent-suggestion-scroller="true"]:is(
400
+ [data-overflow-start],
401
+ [data-overflow-end]
402
+ ) {
403
+ -webkit-mask-image: linear-gradient(
404
+ var(--agent-suggestion-fade-direction, to right),
405
+ transparent 0,
406
+ black var(--agent-suggestion-fade-start, 0px),
407
+ black calc(100% - var(--agent-suggestion-fade-end, 0px)),
408
+ transparent 100%
409
+ );
410
+ mask-image: linear-gradient(
411
+ var(--agent-suggestion-fade-direction, to right),
412
+ transparent 0,
413
+ black var(--agent-suggestion-fade-start, 0px),
414
+ black calc(100% - var(--agent-suggestion-fade-end, 0px)),
415
+ transparent 100%
416
+ );
417
+ }
418
+
419
+ [data-agent-suggestion-scroller="true"]:dir(rtl) {
420
+ --agent-suggestion-fade-direction: to left;
421
+ }
422
+
423
+ [data-agent-suggestion-scroller="true"][data-overflow-start] {
424
+ --agent-suggestion-fade-start: 1.5rem;
425
+ }
426
+
427
+ [data-agent-suggestion-scroller="true"][data-overflow-end] {
428
+ --agent-suggestion-fade-end: 1.5rem;
429
+ }
430
+
389
431
  .agentkit-suggestions button {
390
432
  flex: none;
391
433
  padding: 0.375rem 0.625rem;
@@ -1478,6 +1520,39 @@ button.agentkit-object {
1478
1520
  color: var(--agentkit-text);
1479
1521
  }
1480
1522
 
1523
+ .agentkit-activity-summary-section {
1524
+ display: grid;
1525
+ gap: 0.25rem;
1526
+ margin-block-start: 0.5rem;
1527
+ }
1528
+
1529
+ .agentkit-activity-summary-label {
1530
+ color: var(--agentkit-text-muted);
1531
+ font-size: 0.6875rem;
1532
+ font-weight: 500;
1533
+ }
1534
+
1535
+ .agentkit-activity-summary-value {
1536
+ max-block-size: 12rem;
1537
+ overflow: auto;
1538
+ border: 1px solid var(--agentkit-border);
1539
+ border-radius: var(--radius-md, var(--radius));
1540
+ padding: 0.5rem 0.625rem;
1541
+ background: var(--agentkit-subtle);
1542
+ color: var(--agentkit-text);
1543
+ font: inherit;
1544
+ font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
1545
+ font-size: 0.75rem;
1546
+ line-height: 1.5;
1547
+ white-space: pre-wrap;
1548
+ overflow-wrap: anywhere;
1549
+ }
1550
+
1551
+ .agentkit-activity-summary-value:focus-visible {
1552
+ outline: 2px solid var(--agentkit-focus);
1553
+ outline-offset: 2px;
1554
+ }
1555
+
1481
1556
  .agentkit-approval,
1482
1557
  .agentkit-connection-request,
1483
1558
  .agentkit-widget {
@@ -275,19 +275,23 @@ describe("AuthPage", () => {
275
275
  );
276
276
  expect(html).toContain(">Learn more</a>");
277
277
  expect(html).toContain('class="oss-badge"');
278
- expect(html).not.toContain("data-agent-native-starfield");
278
+ expect(html).toContain('data-agent-native-wave="true"');
279
+ expect(html).not.toContain("data-agent-native-marketing-background");
279
280
  });
280
281
 
281
- it("places a transparent animated wave after the signup legal notice", () => {
282
+ it("renders one full-page WebGL wave on login and signup", () => {
282
283
  const props = propsFromHtml(
283
284
  getOnboardingHtml({ requestHost: "slides.agent-native.com" }),
284
285
  );
285
- const html = renderToString(<AuthPage {...props} initialView="signup" />);
286
286
 
287
- expect(html.indexOf('class="legal-note"')).toBeLessThan(
288
- html.indexOf('data-agent-native-starfield-transparent="true"'),
289
- );
290
- expect(html).toContain('class="auth-marketing-signup-wave-canvas"');
287
+ for (const initialView of ["login", "signup"] as const) {
288
+ const html = renderToString(
289
+ <AuthPage {...props} initialView={initialView} />,
290
+ );
291
+ expect(html.match(/data-agent-native-wave="true"/g)).toHaveLength(1);
292
+ expect(html).toContain('class="auth-wave-background"');
293
+ expect(html).not.toContain("auth-marketing-signup-wave");
294
+ }
291
295
  });
292
296
 
293
297
  it("keeps the whole marketing panel in English when localized copy is incomplete", () => {