@agent-native/toolkit 0.214.0 → 0.217.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/agent-native.eject.json +5 -0
- package/dist/app/agentkit/react/chat.d.ts.map +1 -1
- package/dist/app/agentkit/react/chat.js +2 -2
- package/dist/app/agentkit/react/chat.js.map +1 -1
- package/dist/app/agentkit/react/components.d.ts +4 -1
- package/dist/app/agentkit/react/components.d.ts.map +1 -1
- package/dist/app/agentkit/react/components.js +69 -15
- package/dist/app/agentkit/react/components.js.map +1 -1
- package/dist/app/agentkit/react/context.d.ts +7 -1
- package/dist/app/agentkit/react/context.d.ts.map +1 -1
- package/dist/app/agentkit/react/context.js +5 -1
- package/dist/app/agentkit/react/context.js.map +1 -1
- package/dist/app/agentkit/react/index.d.ts +1 -0
- package/dist/app/agentkit/react/index.d.ts.map +1 -1
- package/dist/app/agentkit/react/index.js +1 -0
- package/dist/app/agentkit/react/index.js.map +1 -1
- package/dist/app/agentkit/react/root.d.ts +4 -1
- package/dist/app/agentkit/react/root.d.ts.map +1 -1
- package/dist/app/agentkit/react/root.js +2 -2
- package/dist/app/agentkit/react/root.js.map +1 -1
- package/dist/app/agentkit/react/styles.css +43 -6
- package/dist/app/agentkit/react/transcript-layout.d.ts +51 -0
- package/dist/app/agentkit/react/transcript-layout.d.ts.map +1 -0
- package/dist/app/agentkit/react/transcript-layout.js +34 -0
- package/dist/app/agentkit/react/transcript-layout.js.map +1 -0
- package/dist/app/auth/AuthPage.d.ts.map +1 -1
- package/dist/app/auth/AuthPage.js +33 -44
- package/dist/app/auth/AuthPage.js.map +1 -1
- package/dist/app/chat/AgentKitAssistantChat.d.ts.map +1 -1
- package/dist/app/chat/AgentKitAssistantChat.js +3 -3
- package/dist/app/chat/AgentKitAssistantChat.js.map +1 -1
- package/dist/app/chat/AgentPanel.d.ts +2 -0
- package/dist/app/chat/AgentPanel.d.ts.map +1 -1
- package/dist/app/chat/AgentPanel.js +6 -2
- package/dist/app/chat/AgentPanel.js.map +1 -1
- package/dist/app/chat/chat/index.d.ts +2 -0
- package/dist/app/chat/chat/index.d.ts.map +1 -1
- package/dist/app/chat/chat/index.js.map +1 -1
- package/dist/app/chat/chat/surface-types.d.ts +7 -0
- package/dist/app/chat/chat/surface-types.d.ts.map +1 -1
- package/dist/app/chat/chat/surface-types.js.map +1 -1
- package/dist/app/chat/chat/tool-call-display.d.ts +7 -2
- package/dist/app/chat/chat/tool-call-display.d.ts.map +1 -1
- package/dist/app/chat/chat/tool-call-display.js +10 -9
- package/dist/app/chat/chat/tool-call-display.js.map +1 -1
- package/dist/app/chat/chat/widgets/DataChartRenderer.d.ts.map +1 -1
- package/dist/app/chat/chat/widgets/DataChartRenderer.js +196 -26
- package/dist/app/chat/chat/widgets/DataChartRenderer.js.map +1 -1
- package/dist/app/chat/chat/widgets/DataChartWidget.d.ts.map +1 -1
- package/dist/app/chat/chat/widgets/DataChartWidget.js +5 -1
- package/dist/app/chat/chat/widgets/DataChartWidget.js.map +1 -1
- package/dist/app/chat/chat/widgets/DataWidgetDisplayControls.d.ts +2 -2
- package/dist/app/chat/chat/widgets/DataWidgetDisplayControls.d.ts.map +1 -1
- package/dist/app/chat/chat/widgets/DataWidgetDisplayControls.js +6 -4
- package/dist/app/chat/chat/widgets/DataWidgetDisplayControls.js.map +1 -1
- package/dist/app/i18n/catalogs/ar-SA.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/ar-SA.js +1 -0
- package/dist/app/i18n/catalogs/ar-SA.js.map +1 -1
- package/dist/app/i18n/catalogs/de-DE.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/de-DE.js +1 -0
- package/dist/app/i18n/catalogs/de-DE.js.map +1 -1
- package/dist/app/i18n/catalogs/en-US.d.ts +1 -0
- package/dist/app/i18n/catalogs/en-US.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/en-US.js +1 -0
- package/dist/app/i18n/catalogs/en-US.js.map +1 -1
- package/dist/app/i18n/catalogs/es-ES.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/es-ES.js +1 -0
- package/dist/app/i18n/catalogs/es-ES.js.map +1 -1
- package/dist/app/i18n/catalogs/fr-FR.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/fr-FR.js +1 -0
- package/dist/app/i18n/catalogs/fr-FR.js.map +1 -1
- package/dist/app/i18n/catalogs/hi-IN.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/hi-IN.js +1 -0
- package/dist/app/i18n/catalogs/hi-IN.js.map +1 -1
- package/dist/app/i18n/catalogs/ja-JP.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/ja-JP.js +1 -0
- package/dist/app/i18n/catalogs/ja-JP.js.map +1 -1
- package/dist/app/i18n/catalogs/ko-KR.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/ko-KR.js +1 -0
- package/dist/app/i18n/catalogs/ko-KR.js.map +1 -1
- package/dist/app/i18n/catalogs/pt-BR.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/pt-BR.js +1 -0
- package/dist/app/i18n/catalogs/pt-BR.js.map +1 -1
- package/dist/app/i18n/catalogs/zh-CN.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/zh-CN.js +1 -0
- package/dist/app/i18n/catalogs/zh-CN.js.map +1 -1
- package/dist/app/i18n/catalogs/zh-TW.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/zh-TW.js +1 -0
- package/dist/app/i18n/catalogs/zh-TW.js.map +1 -1
- package/dist/app/onboarding/GettingStartedCard.d.ts +35 -0
- package/dist/app/onboarding/GettingStartedCard.d.ts.map +1 -0
- package/dist/app/onboarding/GettingStartedCard.js +38 -0
- package/dist/app/onboarding/GettingStartedCard.js.map +1 -0
- package/dist/app/onboarding/index.d.ts +1 -0
- package/dist/app/onboarding/index.d.ts.map +1 -1
- package/dist/app/onboarding/index.js +1 -0
- package/dist/app/onboarding/index.js.map +1 -1
- package/dist/app/providers/AppProviders.d.ts.map +1 -1
- package/dist/app/providers/AppProviders.js +3 -1
- package/dist/app/providers/AppProviders.js.map +1 -1
- package/dist/app/settings/AccountSettingsCard.d.ts.map +1 -1
- package/dist/app/settings/AccountSettingsCard.js +2 -1
- package/dist/app/settings/AccountSettingsCard.js.map +1 -1
- package/dist/app/settings/index.d.ts +1 -0
- package/dist/app/settings/index.d.ts.map +1 -1
- package/dist/app/settings/index.js +1 -0
- package/dist/app/settings/index.js.map +1 -1
- package/dist/app/settings/shell/SettingsShell.d.ts +40 -1
- package/dist/app/settings/shell/SettingsShell.d.ts.map +1 -1
- package/dist/app/settings/shell/SettingsShell.js +87 -20
- package/dist/app/settings/shell/SettingsShell.js.map +1 -1
- package/dist/app/settings/shell/bridge.d.ts +5 -3
- package/dist/app/settings/shell/bridge.d.ts.map +1 -1
- package/dist/app/settings/shell/bridge.js +8 -5
- package/dist/app/settings/shell/bridge.js.map +1 -1
- package/dist/app/settings/shell/index.d.ts +2 -2
- package/dist/app/settings/shell/index.d.ts.map +1 -1
- package/dist/app/settings/shell/index.js.map +1 -1
- package/dist/app/settings/shell/registry.d.ts +9 -1
- package/dist/app/settings/shell/registry.d.ts.map +1 -1
- package/dist/app/settings/shell/registry.js +16 -0
- package/dist/app/settings/shell/registry.js.map +1 -1
- package/dist/app/settings/shell/routing.d.ts +5 -4
- package/dist/app/settings/shell/routing.d.ts.map +1 -1
- package/dist/app/settings/shell/routing.js +38 -10
- package/dist/app/settings/shell/routing.js.map +1 -1
- package/dist/app/shared/CommandMenu.d.ts +86 -6
- package/dist/app/shared/CommandMenu.d.ts.map +1 -1
- package/dist/app/shared/CommandMenu.js +303 -41
- package/dist/app/shared/CommandMenu.js.map +1 -1
- package/dist/app/shared/ConsentBanner.d.ts +9 -0
- package/dist/app/shared/ConsentBanner.d.ts.map +1 -0
- package/dist/app/shared/ConsentBanner.js +35 -0
- package/dist/app/shared/ConsentBanner.js.map +1 -0
- package/dist/composer/ComposerContextBanner.d.ts +3 -1
- package/dist/composer/ComposerContextBanner.d.ts.map +1 -1
- package/dist/composer/ComposerContextBanner.js +2 -2
- package/dist/composer/ComposerContextBanner.js.map +1 -1
- package/dist/ui/sonner.d.ts +2 -2
- package/dist/ui/sonner.d.ts.map +1 -1
- package/dist/ui/sonner.js +2 -2
- package/dist/ui/sonner.js.map +1 -1
- package/package.json +3 -3
- package/src/app/agentkit/react/chat.tsx +2 -0
- package/src/app/agentkit/react/components.interaction.spec.tsx +107 -0
- package/src/app/agentkit/react/components.spec.tsx +28 -1
- package/src/app/agentkit/react/components.tsx +153 -17
- package/src/app/agentkit/react/context.tsx +12 -0
- package/src/app/agentkit/react/index.ts +1 -0
- package/src/app/agentkit/react/lifecycle.spec.tsx +186 -16
- package/src/app/agentkit/react/root.tsx +7 -0
- package/src/app/agentkit/react/styles.css +43 -6
- package/src/app/agentkit/react/transcript-layout.spec.ts +72 -0
- package/src/app/agentkit/react/transcript-layout.ts +97 -0
- package/src/app/auth/AuthPage.attribution.spec.tsx +6 -0
- package/src/app/auth/AuthPage.interaction.spec.tsx +74 -0
- package/src/app/auth/AuthPage.tsx +32 -39
- package/src/app/chat/AgentKitAssistantChat.spec.tsx +39 -0
- package/src/app/chat/AgentKitAssistantChat.tsx +5 -0
- package/src/app/chat/AgentPanel.page-header-share.spec.tsx +101 -0
- package/src/app/chat/AgentPanel.tsx +14 -2
- package/src/app/chat/chat/index.ts +2 -0
- package/src/app/chat/chat/surface-types.ts +10 -0
- package/src/app/chat/chat/tool-call-display.spec.tsx +83 -0
- package/src/app/chat/chat/tool-call-display.tsx +40 -8
- package/src/app/chat/chat/widgets/DataChartRenderer.spec.tsx +632 -0
- package/src/app/chat/chat/widgets/DataChartRenderer.tsx +308 -51
- package/src/app/chat/chat/widgets/DataChartWidget.spec.tsx +126 -23
- package/src/app/chat/chat/widgets/DataChartWidget.tsx +10 -0
- package/src/app/chat/chat/widgets/DataWidgetDisplayControls.tsx +26 -6
- package/src/app/i18n/catalogs/ar-SA.ts +1 -0
- package/src/app/i18n/catalogs/de-DE.ts +2 -0
- package/src/app/i18n/catalogs/en-US.ts +2 -0
- package/src/app/i18n/catalogs/es-ES.ts +2 -0
- package/src/app/i18n/catalogs/fr-FR.ts +2 -0
- package/src/app/i18n/catalogs/hi-IN.ts +1 -0
- package/src/app/i18n/catalogs/ja-JP.ts +2 -0
- package/src/app/i18n/catalogs/ko-KR.ts +1 -0
- package/src/app/i18n/catalogs/pt-BR.ts +2 -0
- package/src/app/i18n/catalogs/zh-CN.ts +1 -0
- package/src/app/i18n/catalogs/zh-TW.ts +1 -0
- package/src/app/onboarding/GettingStartedCard.tsx +203 -0
- package/src/app/onboarding/index.ts +1 -0
- package/src/app/providers/AppProviders.tsx +7 -1
- package/src/app/settings/AccountSettingsCard.spec.tsx +31 -0
- package/src/app/settings/AccountSettingsCard.tsx +8 -0
- package/src/app/settings/index.ts +1 -0
- package/src/app/settings/shell/SettingsShell.spec.tsx +472 -1
- package/src/app/settings/shell/SettingsShell.tsx +245 -31
- package/src/app/settings/shell/bridge.spec.ts +12 -0
- package/src/app/settings/shell/bridge.ts +17 -4
- package/src/app/settings/shell/index.ts +6 -1
- package/src/app/settings/shell/registry.ts +33 -1
- package/src/app/settings/shell/routing.spec.ts +92 -1
- package/src/app/settings/shell/routing.ts +52 -9
- package/src/app/shared/CommandMenu.spec.tsx +1662 -1
- package/src/app/shared/CommandMenu.tsx +763 -164
- package/src/app/shared/ConsentBanner.spec.tsx +141 -0
- package/src/app/shared/ConsentBanner.tsx +141 -0
- package/src/composer/ComposerContextBanner.spec.tsx +31 -5
- package/src/composer/ComposerContextBanner.tsx +7 -2
- package/src/ui/sonner.spec.ts +10 -0
- package/src/ui/sonner.tsx +2 -2
|
@@ -44,6 +44,7 @@ import {
|
|
|
44
44
|
} from "react";
|
|
45
45
|
|
|
46
46
|
import type { AgentMessageContentOrderResolver } from "./message-content-order.js";
|
|
47
|
+
import type { AgentChatWorkedForRowLayout } from "./transcript-layout.js";
|
|
47
48
|
|
|
48
49
|
export interface AgentKitRenderProps<T> {
|
|
49
50
|
value: T;
|
|
@@ -87,6 +88,7 @@ export interface AgentKitWorkedForSummaryRenderProps {
|
|
|
87
88
|
expandable: boolean;
|
|
88
89
|
open: boolean;
|
|
89
90
|
current?: ReactNode;
|
|
91
|
+
layout?: AgentChatWorkedForRowLayout;
|
|
90
92
|
}
|
|
91
93
|
|
|
92
94
|
export interface AgentConnectionErrorRenderProps {
|
|
@@ -495,6 +497,8 @@ export interface AgentKitProviderProps {
|
|
|
495
497
|
/** Receives full renderer failures while the UI shows a safe fallback. */
|
|
496
498
|
onRenderError?: (failure: AgentKitRenderFailure) => void;
|
|
497
499
|
resolveMessageContentOrder?: AgentMessageContentOrderResolver;
|
|
500
|
+
workedForRowLayout?: AgentChatWorkedForRowLayout;
|
|
501
|
+
formatWorkedForDuration?: (durationMs: number) => string;
|
|
498
502
|
onClientEffect?: (effect: {
|
|
499
503
|
type: "client.effect" | "client.deeplink";
|
|
500
504
|
name: string;
|
|
@@ -525,6 +529,8 @@ export interface AgentKitContextValue {
|
|
|
525
529
|
onConnectionRequest?: AgentKitProviderProps["onConnectionRequest"];
|
|
526
530
|
onRenderError?: (failure: AgentKitRenderFailure) => void;
|
|
527
531
|
resolveMessageContentOrder?: AgentMessageContentOrderResolver;
|
|
532
|
+
workedForRowLayout?: AgentChatWorkedForRowLayout;
|
|
533
|
+
formatWorkedForDuration?: (durationMs: number) => string;
|
|
528
534
|
registerComposerFocus: (threadId: ThreadId, focus: () => void) => () => void;
|
|
529
535
|
requestComposerFocus: (threadId: ThreadId) => void;
|
|
530
536
|
}
|
|
@@ -546,6 +552,8 @@ export function AgentKitProvider({
|
|
|
546
552
|
onConnectionRequest,
|
|
547
553
|
onRenderError,
|
|
548
554
|
resolveMessageContentOrder,
|
|
555
|
+
workedForRowLayout,
|
|
556
|
+
formatWorkedForDuration,
|
|
549
557
|
onClientEffect,
|
|
550
558
|
children,
|
|
551
559
|
}: AgentKitProviderProps) {
|
|
@@ -613,6 +621,8 @@ export function AgentKitProvider({
|
|
|
613
621
|
onConnectionRequest,
|
|
614
622
|
onRenderError,
|
|
615
623
|
resolveMessageContentOrder,
|
|
624
|
+
workedForRowLayout,
|
|
625
|
+
formatWorkedForDuration,
|
|
616
626
|
registerComposerFocus,
|
|
617
627
|
requestComposerFocus,
|
|
618
628
|
}),
|
|
@@ -631,6 +641,8 @@ export function AgentKitProvider({
|
|
|
631
641
|
onConnectionRequest,
|
|
632
642
|
onRenderError,
|
|
633
643
|
resolveMessageContentOrder,
|
|
644
|
+
workedForRowLayout,
|
|
645
|
+
formatWorkedForDuration,
|
|
634
646
|
registerComposerFocus,
|
|
635
647
|
requestComposerFocus,
|
|
636
648
|
],
|
|
@@ -185,7 +185,7 @@ describe("AgentChat lifecycle", () => {
|
|
|
185
185
|
});
|
|
186
186
|
const tree = mount();
|
|
187
187
|
|
|
188
|
-
|
|
188
|
+
const renderChat = (enablePostWidgetText: boolean) => (
|
|
189
189
|
<AgentKitProvider
|
|
190
190
|
controller={observable.controller}
|
|
191
191
|
threadId={threadId}
|
|
@@ -213,24 +213,152 @@ describe("AgentChat lifecycle", () => {
|
|
|
213
213
|
},
|
|
214
214
|
}}
|
|
215
215
|
slots={{
|
|
216
|
-
text: ({ value }) =>
|
|
216
|
+
text: ({ value }) => (
|
|
217
|
+
<div className="agentkit-markdown" data-chat-part>
|
|
218
|
+
<p>{value.text}</p>
|
|
219
|
+
</div>
|
|
220
|
+
),
|
|
217
221
|
}}
|
|
218
222
|
>
|
|
219
|
-
<AgentKitChat
|
|
220
|
-
|
|
223
|
+
<AgentKitChat
|
|
224
|
+
composer={false}
|
|
225
|
+
transcriptLayout={
|
|
226
|
+
enablePostWidgetText
|
|
227
|
+
? {
|
|
228
|
+
postWidgetText: {
|
|
229
|
+
tone: "muted",
|
|
230
|
+
paragraphPaddingBlock: 4,
|
|
231
|
+
},
|
|
232
|
+
}
|
|
233
|
+
: undefined
|
|
234
|
+
}
|
|
235
|
+
/>
|
|
236
|
+
</AgentKitProvider>
|
|
221
237
|
);
|
|
238
|
+
await tree.render(renderChat(true));
|
|
222
239
|
|
|
223
240
|
const content = tree.container.querySelector(
|
|
224
241
|
`[data-message-id="${message.id}"] .agentkit-message-content`,
|
|
225
242
|
);
|
|
243
|
+
const transcriptContent = tree.container.querySelector(
|
|
244
|
+
".agentkit-transcript-content",
|
|
245
|
+
);
|
|
226
246
|
const renderedOrder = [...(content?.children ?? [])].map((element) =>
|
|
227
|
-
element.hasAttribute("data-
|
|
247
|
+
element.hasAttribute("data-post-widget-text")
|
|
228
248
|
? element.textContent
|
|
229
|
-
: element.hasAttribute("data-
|
|
230
|
-
?
|
|
231
|
-
: "
|
|
249
|
+
: element.hasAttribute("data-chat-part")
|
|
250
|
+
? element.textContent
|
|
251
|
+
: element.hasAttribute("data-chart-result")
|
|
252
|
+
? "chart"
|
|
253
|
+
: "other",
|
|
232
254
|
);
|
|
233
255
|
expect(renderedOrder).toEqual(["Intro. ", "chart", "Summary."]);
|
|
256
|
+
expect(content?.children[0].hasAttribute("data-post-widget-text")).toBe(
|
|
257
|
+
false,
|
|
258
|
+
);
|
|
259
|
+
expect(content?.children[2].hasAttribute("data-post-widget-text")).toBe(
|
|
260
|
+
true,
|
|
261
|
+
);
|
|
262
|
+
expect(
|
|
263
|
+
content?.children[2].querySelector(".agentkit-markdown p"),
|
|
264
|
+
).not.toBeNull();
|
|
265
|
+
expect(transcriptContent?.getAttribute("style")).toContain(
|
|
266
|
+
"--agentkit-transcript-post-widget-text-color: var(--agentkit-text-muted)",
|
|
267
|
+
);
|
|
268
|
+
expect(transcriptContent?.getAttribute("style")).toContain(
|
|
269
|
+
"--agentkit-transcript-post-widget-paragraph-padding-block: 4px",
|
|
270
|
+
);
|
|
271
|
+
|
|
272
|
+
await tree.render(renderChat(false));
|
|
273
|
+
const defaultContent = tree.container.querySelector(
|
|
274
|
+
`[data-message-id="${message.id}"] .agentkit-message-content`,
|
|
275
|
+
);
|
|
276
|
+
expect(
|
|
277
|
+
[...(defaultContent?.children ?? [])].some((element) =>
|
|
278
|
+
element.hasAttribute("data-post-widget-text"),
|
|
279
|
+
),
|
|
280
|
+
).toBe(false);
|
|
281
|
+
await tree.unmount();
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
it("styles assistant text after an embedded widget part", async () => {
|
|
285
|
+
const threadId = "thread-embedded-content-order";
|
|
286
|
+
const widget = {
|
|
287
|
+
id: "chart-embedded-content-order",
|
|
288
|
+
kind: "test-chart",
|
|
289
|
+
data: {},
|
|
290
|
+
};
|
|
291
|
+
const message = {
|
|
292
|
+
id: "assistant-embedded-content-order",
|
|
293
|
+
role: "assistant" as const,
|
|
294
|
+
status: "complete" as const,
|
|
295
|
+
parts: [
|
|
296
|
+
{ type: "text" as const, text: "Intro." },
|
|
297
|
+
{ type: "widget" as const, widget },
|
|
298
|
+
{ type: "text" as const, text: "Summary." },
|
|
299
|
+
],
|
|
300
|
+
};
|
|
301
|
+
const thread = {
|
|
302
|
+
...createAgentThreadState(threadId),
|
|
303
|
+
messages: [message],
|
|
304
|
+
};
|
|
305
|
+
const observable = observableController({
|
|
306
|
+
connection: "connected",
|
|
307
|
+
capabilities: {},
|
|
308
|
+
capabilitiesStatus: "ready",
|
|
309
|
+
threads: { [threadId]: thread },
|
|
310
|
+
revision: 0,
|
|
311
|
+
});
|
|
312
|
+
const tree = mount();
|
|
313
|
+
|
|
314
|
+
await tree.render(
|
|
315
|
+
<AgentKitProvider
|
|
316
|
+
controller={observable.controller}
|
|
317
|
+
threadId={threadId}
|
|
318
|
+
registry={{
|
|
319
|
+
widgets: {
|
|
320
|
+
"test-chart": () => <span data-chart-result>Chart</span>,
|
|
321
|
+
},
|
|
322
|
+
}}
|
|
323
|
+
slots={{
|
|
324
|
+
text: ({ value }) => (
|
|
325
|
+
<div data-chat-part>
|
|
326
|
+
<p>{value.text}</p>
|
|
327
|
+
</div>
|
|
328
|
+
),
|
|
329
|
+
}}
|
|
330
|
+
>
|
|
331
|
+
<AgentKitChat
|
|
332
|
+
composer={false}
|
|
333
|
+
transcriptLayout={{
|
|
334
|
+
postWidgetText: {
|
|
335
|
+
tone: "muted",
|
|
336
|
+
paragraphPaddingBlock: 4,
|
|
337
|
+
},
|
|
338
|
+
}}
|
|
339
|
+
/>
|
|
340
|
+
</AgentKitProvider>,
|
|
341
|
+
);
|
|
342
|
+
|
|
343
|
+
const content = tree.container.querySelector(
|
|
344
|
+
`[data-message-id="${message.id}"] .agentkit-message-content`,
|
|
345
|
+
);
|
|
346
|
+
const renderedOrder = [...(content?.children ?? [])].map((element) =>
|
|
347
|
+
element.hasAttribute("data-post-widget-text")
|
|
348
|
+
? element.textContent
|
|
349
|
+
: element.hasAttribute("data-chat-part")
|
|
350
|
+
? element.textContent
|
|
351
|
+
: element.hasAttribute("data-chart-result")
|
|
352
|
+
? "chart"
|
|
353
|
+
: "other",
|
|
354
|
+
);
|
|
355
|
+
expect(renderedOrder).toEqual(["Intro.", "chart", "Summary."]);
|
|
356
|
+
expect(content?.children[0].hasAttribute("data-post-widget-text")).toBe(
|
|
357
|
+
false,
|
|
358
|
+
);
|
|
359
|
+
expect(content?.children[2].hasAttribute("data-post-widget-text")).toBe(
|
|
360
|
+
true,
|
|
361
|
+
);
|
|
234
362
|
await tree.unmount();
|
|
235
363
|
});
|
|
236
364
|
|
|
@@ -1686,7 +1814,7 @@ describe("AgentChat lifecycle", () => {
|
|
|
1686
1814
|
await tree.unmount();
|
|
1687
1815
|
});
|
|
1688
1816
|
|
|
1689
|
-
it("preserves visible reasoning
|
|
1817
|
+
it("preserves visible reasoning and applies the worked-row layout", async () => {
|
|
1690
1818
|
const threadId = "thread-reasoning-work";
|
|
1691
1819
|
const runId = "run-reasoning-work";
|
|
1692
1820
|
const base = (sequence: number, seconds: number = sequence) => ({
|
|
@@ -1771,10 +1899,24 @@ describe("AgentChat lifecycle", () => {
|
|
|
1771
1899
|
});
|
|
1772
1900
|
const observable = observableController(snapshot(0));
|
|
1773
1901
|
const tree = mount();
|
|
1902
|
+
const workedForRowLayout = {
|
|
1903
|
+
chevronSize: 12,
|
|
1904
|
+
iconGap: 8,
|
|
1905
|
+
marginBlockStart: -12,
|
|
1906
|
+
fontSize: 13,
|
|
1907
|
+
lineHeight: 16,
|
|
1908
|
+
paddingBlock: 2,
|
|
1909
|
+
paddingInline: 4,
|
|
1910
|
+
};
|
|
1911
|
+
const formatWorkedForDuration = (durationMs: number) =>
|
|
1912
|
+
`${Math.round(durationMs / 1000)} seconds`;
|
|
1774
1913
|
await tree.render(
|
|
1775
|
-
<
|
|
1914
|
+
<AgentKitRoot
|
|
1776
1915
|
controller={observable.controller}
|
|
1777
1916
|
threadId={threadId}
|
|
1917
|
+
load="manual"
|
|
1918
|
+
workedForRowLayout={workedForRowLayout}
|
|
1919
|
+
formatWorkedForDuration={formatWorkedForDuration}
|
|
1778
1920
|
registry={{
|
|
1779
1921
|
activities: {
|
|
1780
1922
|
reasoning: ({ value }) => (
|
|
@@ -1791,11 +1933,15 @@ describe("AgentChat lifecycle", () => {
|
|
|
1791
1933
|
}}
|
|
1792
1934
|
>
|
|
1793
1935
|
<AgentKitChat composer={false} />
|
|
1794
|
-
</
|
|
1936
|
+
</AgentKitRoot>,
|
|
1795
1937
|
);
|
|
1796
1938
|
const work = tree.container.querySelector<HTMLDetailsElement>(
|
|
1797
1939
|
".agentkit-activities",
|
|
1798
1940
|
)!;
|
|
1941
|
+
expect(
|
|
1942
|
+
work.querySelector<HTMLElement>(".agentkit-activities-summary")?.style
|
|
1943
|
+
.marginBlockStart,
|
|
1944
|
+
).toBe("-12px");
|
|
1799
1945
|
expect(work.open).toBe(false);
|
|
1800
1946
|
expect(
|
|
1801
1947
|
tree.container.querySelectorAll(".agentkit-activities"),
|
|
@@ -1821,10 +1967,19 @@ describe("AgentChat lifecycle", () => {
|
|
|
1821
1967
|
".agentkit-activities-summary > .agentkit-summary-chevron",
|
|
1822
1968
|
),
|
|
1823
1969
|
).not.toBeNull();
|
|
1970
|
+
expect(work.querySelector("summary")?.getAttribute("style")).toContain(
|
|
1971
|
+
"gap: 8px",
|
|
1972
|
+
);
|
|
1973
|
+
expect(
|
|
1974
|
+
work.querySelector<HTMLElement>(".agentkit-summary-chevron")?.style.width,
|
|
1975
|
+
).toBe("12px");
|
|
1824
1976
|
await tree.render(
|
|
1825
|
-
<
|
|
1977
|
+
<AgentKitRoot
|
|
1826
1978
|
controller={observable.controller}
|
|
1827
1979
|
threadId={threadId}
|
|
1980
|
+
load="manual"
|
|
1981
|
+
workedForRowLayout={workedForRowLayout}
|
|
1982
|
+
formatWorkedForDuration={formatWorkedForDuration}
|
|
1828
1983
|
registry={{
|
|
1829
1984
|
activities: {
|
|
1830
1985
|
reasoning: ({ value }) => (
|
|
@@ -1838,8 +1993,12 @@ describe("AgentChat lifecycle", () => {
|
|
|
1838
1993
|
{value.text}
|
|
1839
1994
|
</span>
|
|
1840
1995
|
),
|
|
1841
|
-
workedForSummary: ({ label, open, current }) => (
|
|
1842
|
-
<span
|
|
1996
|
+
workedForSummary: ({ label, open, current, layout }) => (
|
|
1997
|
+
<span
|
|
1998
|
+
data-work-summary
|
|
1999
|
+
data-open={open}
|
|
2000
|
+
data-icon-gap={layout?.iconGap}
|
|
2001
|
+
>
|
|
1843
2002
|
<span>{label}</span>
|
|
1844
2003
|
<span data-work-chevron aria-hidden="true">
|
|
1845
2004
|
›
|
|
@@ -1850,12 +2009,15 @@ describe("AgentChat lifecycle", () => {
|
|
|
1850
2009
|
}}
|
|
1851
2010
|
>
|
|
1852
2011
|
<AgentKitChat composer={false} />
|
|
1853
|
-
</
|
|
2012
|
+
</AgentKitRoot>,
|
|
1854
2013
|
);
|
|
1855
2014
|
expect(work.querySelector("[data-work-summary]")?.textContent).toContain(
|
|
1856
2015
|
"Searching documentation",
|
|
1857
2016
|
);
|
|
1858
2017
|
expect(work.querySelector("[data-work-chevron]")).not.toBeNull();
|
|
2018
|
+
expect(work.querySelector("[data-work-summary]")?.dataset.iconGap).toBe(
|
|
2019
|
+
"8",
|
|
2020
|
+
);
|
|
1859
2021
|
expect(
|
|
1860
2022
|
work.querySelector("[data-work-summary]")?.getAttribute("data-open"),
|
|
1861
2023
|
).toBe("false");
|
|
@@ -1880,7 +2042,15 @@ describe("AgentChat lifecycle", () => {
|
|
|
1880
2042
|
await flush();
|
|
1881
2043
|
expect(tree.container.querySelector(".agentkit-activities")).toBe(work);
|
|
1882
2044
|
expect(work.open).toBe(false);
|
|
1883
|
-
expect(work.querySelector("summary")?.textContent).toBe(
|
|
2045
|
+
expect(work.querySelector("summary")?.textContent).toBe(
|
|
2046
|
+
"Worked for 18 seconds›",
|
|
2047
|
+
);
|
|
2048
|
+
expect(work.querySelector<HTMLElement>("summary")?.style.fontSize).toBe(
|
|
2049
|
+
"13px",
|
|
2050
|
+
);
|
|
2051
|
+
expect(work.querySelector<HTMLElement>("summary")?.style.lineHeight).toBe(
|
|
2052
|
+
"16px",
|
|
2053
|
+
);
|
|
1884
2054
|
expect(work.querySelector("[data-agentkit-current-activity]")).toBeNull();
|
|
1885
2055
|
expect(tree.container.querySelectorAll("article")).toHaveLength(1);
|
|
1886
2056
|
const answer = tree.container.querySelector(
|
|
@@ -31,6 +31,7 @@ import {
|
|
|
31
31
|
type AgentKitSlots,
|
|
32
32
|
} from "./context.js";
|
|
33
33
|
import type { AgentMessageContentOrderResolver } from "./message-content-order.js";
|
|
34
|
+
import type { AgentChatWorkedForRowLayout } from "./transcript-layout.js";
|
|
34
35
|
|
|
35
36
|
const mountedManagedClients = new WeakMap<AgentKitClient, number>();
|
|
36
37
|
|
|
@@ -86,6 +87,8 @@ export interface AgentKitRootBaseProps {
|
|
|
86
87
|
) => Promise<AgentConnectionResponse>;
|
|
87
88
|
onRenderError?: (failure: AgentKitRenderFailure) => void;
|
|
88
89
|
resolveMessageContentOrder?: AgentMessageContentOrderResolver;
|
|
90
|
+
workedForRowLayout?: AgentChatWorkedForRowLayout;
|
|
91
|
+
formatWorkedForDuration?: (durationMs: number) => string;
|
|
89
92
|
onClientEffect?: (effect: {
|
|
90
93
|
type: "client.effect" | "client.deeplink";
|
|
91
94
|
name: string;
|
|
@@ -116,6 +119,8 @@ export function AgentKitRoot({
|
|
|
116
119
|
onConnectionRequest,
|
|
117
120
|
onRenderError,
|
|
118
121
|
resolveMessageContentOrder,
|
|
122
|
+
workedForRowLayout,
|
|
123
|
+
formatWorkedForDuration,
|
|
119
124
|
onClientEffect,
|
|
120
125
|
load = "auto",
|
|
121
126
|
onLoadError,
|
|
@@ -294,6 +299,8 @@ export function AgentKitRoot({
|
|
|
294
299
|
onConnectionRequest={onConnectionRequest}
|
|
295
300
|
onRenderError={onRenderError}
|
|
296
301
|
resolveMessageContentOrder={resolveMessageContentOrder}
|
|
302
|
+
workedForRowLayout={workedForRowLayout}
|
|
303
|
+
formatWorkedForDuration={formatWorkedForDuration}
|
|
297
304
|
onClientEffect={onClientEffect}
|
|
298
305
|
>
|
|
299
306
|
{children}
|
|
@@ -669,11 +669,18 @@ body:has(> [data-agent-native-composer-popover="true"]) > .fixed.inset-0 {
|
|
|
669
669
|
}
|
|
670
670
|
|
|
671
671
|
.agentkit-transcript-content {
|
|
672
|
+
position: relative;
|
|
672
673
|
box-sizing: border-box;
|
|
673
|
-
inline-size: min(100%, 47rem);
|
|
674
|
+
inline-size: min(100%, var(--agentkit-transcript-lane-width, 47rem));
|
|
674
675
|
min-inline-size: 0;
|
|
675
676
|
margin-inline: auto;
|
|
677
|
+
inset-inline-start: clamp(
|
|
678
|
+
calc((100% - min(100%, var(--agentkit-transcript-lane-width, 47rem))) / -2),
|
|
679
|
+
var(--agentkit-transcript-lane-offset-inline, 0px),
|
|
680
|
+
calc((100% - min(100%, var(--agentkit-transcript-lane-width, 47rem))) / 2)
|
|
681
|
+
);
|
|
676
682
|
padding: 1.5rem 1rem;
|
|
683
|
+
padding-block-start: var(--agentkit-transcript-top-inset, 1.5rem);
|
|
677
684
|
}
|
|
678
685
|
|
|
679
686
|
.agentkit-scroll-to-bottom-control {
|
|
@@ -710,13 +717,21 @@ body:has(> [data-agent-native-composer-popover="true"]) > .fixed.inset-0 {
|
|
|
710
717
|
display: flex;
|
|
711
718
|
flex-direction: column;
|
|
712
719
|
align-items: flex-start;
|
|
713
|
-
margin-block: 0 1.25rem;
|
|
720
|
+
margin-block: 0 var(--agentkit-transcript-message-gap, 1.25rem);
|
|
714
721
|
font-size: 0.875rem;
|
|
715
|
-
|
|
722
|
+
font-family: var(
|
|
723
|
+
--agentkit-transcript-font-family,
|
|
724
|
+
var(--font-sans, inherit)
|
|
725
|
+
);
|
|
726
|
+
line-height: var(--agentkit-transcript-message-line-height, 1.52);
|
|
716
727
|
}
|
|
717
728
|
|
|
718
729
|
.agentkit-message[data-role="user"] {
|
|
719
730
|
align-items: flex-end;
|
|
731
|
+
line-height: var(
|
|
732
|
+
--agentkit-user-bubble-line-height,
|
|
733
|
+
var(--agentkit-transcript-message-line-height, 1.52)
|
|
734
|
+
);
|
|
720
735
|
}
|
|
721
736
|
|
|
722
737
|
.agentkit-message-content {
|
|
@@ -726,8 +741,11 @@ body:has(> [data-agent-native-composer-popover="true"]) > .fixed.inset-0 {
|
|
|
726
741
|
}
|
|
727
742
|
|
|
728
743
|
.agentkit-message[data-role="user"] .agentkit-message-content {
|
|
729
|
-
|
|
730
|
-
|
|
744
|
+
position: relative;
|
|
745
|
+
inset-inline-start: var(--agentkit-user-bubble-offset-inline, 0px);
|
|
746
|
+
max-inline-size: min(88%, var(--agentkit-user-bubble-max-width, 38rem));
|
|
747
|
+
padding: var(--agentkit-user-bubble-padding-block, 0.625rem)
|
|
748
|
+
var(--agentkit-user-bubble-padding-inline, 0.8125rem);
|
|
731
749
|
border-radius: var(--agentkit-radius-inner);
|
|
732
750
|
background: var(--agentkit-subtle);
|
|
733
751
|
}
|
|
@@ -845,6 +863,25 @@ body:has(> [data-agent-native-composer-popover="true"]) > .fixed.inset-0 {
|
|
|
845
863
|
background: var(--agentkit-canvas);
|
|
846
864
|
}
|
|
847
865
|
|
|
866
|
+
.agentkit-message-content [data-post-widget-text="true"] {
|
|
867
|
+
display: contents;
|
|
868
|
+
color: var(--agentkit-transcript-post-widget-text-color, inherit);
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
.agentkit-message-content [data-post-widget-text="true"] > p,
|
|
872
|
+
.agentkit-message-content [data-post-widget-text="true"] .agentkit-markdown p {
|
|
873
|
+
padding-block: var(
|
|
874
|
+
--agentkit-transcript-post-widget-paragraph-padding-block,
|
|
875
|
+
0px
|
|
876
|
+
);
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
.agentkit-message-content
|
|
880
|
+
> [data-post-widget-text="true"]:last-child
|
|
881
|
+
> :last-child {
|
|
882
|
+
margin-block-end: 0;
|
|
883
|
+
}
|
|
884
|
+
|
|
848
885
|
.agentkit-image-preview img {
|
|
849
886
|
max-inline-size: 92vw;
|
|
850
887
|
max-block-size: 90vh;
|
|
@@ -2133,6 +2170,6 @@ button.agentkit-object {
|
|
|
2133
2170
|
}
|
|
2134
2171
|
|
|
2135
2172
|
.agentkit-message[data-role="user"] .agentkit-message-content {
|
|
2136
|
-
max-inline-size: 94
|
|
2173
|
+
max-inline-size: min(94%, var(--agentkit-user-bubble-max-width, 38rem));
|
|
2137
2174
|
}
|
|
2138
2175
|
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type { AgentKitController } from "@agent-native/agentkit/client";
|
|
2
|
+
import { createElement } from "react";
|
|
3
|
+
import { renderToStaticMarkup } from "react-dom/server";
|
|
4
|
+
import { describe, expect, it } from "vitest";
|
|
5
|
+
|
|
6
|
+
import { useAgentKit } from "./context.js";
|
|
7
|
+
import { AgentKitRoot } from "./root.js";
|
|
8
|
+
import {
|
|
9
|
+
workedForRowChevronStyle,
|
|
10
|
+
workedForRowSummaryStyle,
|
|
11
|
+
} from "./transcript-layout.js";
|
|
12
|
+
|
|
13
|
+
function WorkedForLayoutProbe() {
|
|
14
|
+
const { workedForRowLayout, formatWorkedForDuration } = useAgentKit();
|
|
15
|
+
return createElement("span", {
|
|
16
|
+
"data-icon-gap": workedForRowLayout?.iconGap,
|
|
17
|
+
"data-duration": formatWorkedForDuration?.(16_000),
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
describe("worked-for row layout", () => {
|
|
22
|
+
it("applies shared dimensions to the summary and leading chevron", () => {
|
|
23
|
+
const layout = {
|
|
24
|
+
chevronSize: 12,
|
|
25
|
+
iconGap: 8,
|
|
26
|
+
fontSize: 13,
|
|
27
|
+
lineHeight: 16,
|
|
28
|
+
paddingBlock: 2,
|
|
29
|
+
paddingInline: 4,
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
expect(workedForRowSummaryStyle(layout)).toEqual({
|
|
33
|
+
gap: "8px",
|
|
34
|
+
fontSize: "13px",
|
|
35
|
+
lineHeight: "16px",
|
|
36
|
+
paddingBlock: "2px",
|
|
37
|
+
paddingInline: "4px",
|
|
38
|
+
fontFamily: "inherit",
|
|
39
|
+
});
|
|
40
|
+
expect(workedForRowChevronStyle(layout)).toEqual({
|
|
41
|
+
width: "12px",
|
|
42
|
+
height: "12px",
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it("rejects invalid CSS dimensions", () => {
|
|
47
|
+
expect(() => workedForRowSummaryStyle({ fontSize: 0 })).toThrow(
|
|
48
|
+
"workedForRowLayout.fontSize must be a valid CSS length",
|
|
49
|
+
);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it("carries the layout from the AgentKit root into shared context", () => {
|
|
53
|
+
const layout = { iconGap: 8 };
|
|
54
|
+
const formatWorkedForDuration = (durationMs: number) =>
|
|
55
|
+
`${Math.round(durationMs / 1000)} seconds`;
|
|
56
|
+
const markup = renderToStaticMarkup(
|
|
57
|
+
createElement(
|
|
58
|
+
AgentKitRoot,
|
|
59
|
+
{
|
|
60
|
+
controller: {} as AgentKitController,
|
|
61
|
+
threadId: "thread",
|
|
62
|
+
workedForRowLayout: layout,
|
|
63
|
+
formatWorkedForDuration,
|
|
64
|
+
},
|
|
65
|
+
createElement(WorkedForLayoutProbe),
|
|
66
|
+
),
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
expect(markup).toContain('data-icon-gap="8"');
|
|
70
|
+
expect(markup).toContain('data-duration="16 seconds"');
|
|
71
|
+
});
|
|
72
|
+
});
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import type { CSSProperties } from "react";
|
|
2
|
+
|
|
3
|
+
export interface AgentChatTranscriptLayout {
|
|
4
|
+
/** Top padding above transcript messages, in CSS pixels. */
|
|
5
|
+
topInset?: number;
|
|
6
|
+
/** Maximum centered message lane width, in CSS pixels. */
|
|
7
|
+
messageLaneWidth?: number;
|
|
8
|
+
/** Signed inline offset for the centered message lane, in CSS pixels. */
|
|
9
|
+
messageLaneOffsetInline?: number;
|
|
10
|
+
/** Space after each message, in CSS pixels. */
|
|
11
|
+
messageGap?: number;
|
|
12
|
+
/** Assistant message line height, in CSS pixels. */
|
|
13
|
+
messageLineHeight?: number;
|
|
14
|
+
/** Font family for transcript messages. Omitted uses the shared semantic font. */
|
|
15
|
+
fontFamily?: string;
|
|
16
|
+
/** Optional appearance for assistant text displayed after a widget. */
|
|
17
|
+
postWidgetText?: {
|
|
18
|
+
tone?: "muted";
|
|
19
|
+
paragraphPaddingBlock?: number;
|
|
20
|
+
};
|
|
21
|
+
/** User bubble line height, in CSS pixels. */
|
|
22
|
+
userBubbleLineHeight?: number;
|
|
23
|
+
/** Maximum user bubble width, in CSS pixels. */
|
|
24
|
+
userBubbleMaxWidth?: number;
|
|
25
|
+
/** Signed inline offset for the user bubble, in CSS pixels. */
|
|
26
|
+
userBubbleOffsetInline?: number;
|
|
27
|
+
/** User bubble padding on the block and inline axes, in CSS pixels. */
|
|
28
|
+
userBubblePadding?: { block?: number; inline?: number };
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** Optional geometry for the completed-work disclosure row in chat. */
|
|
32
|
+
export interface AgentChatWorkedForRowLayout {
|
|
33
|
+
/** Chevron width and height, in CSS pixels. */
|
|
34
|
+
chevronSize?: number;
|
|
35
|
+
/** Space between the chevron and label, in CSS pixels. */
|
|
36
|
+
iconGap?: number;
|
|
37
|
+
/** Signed margin before the row, in CSS pixels. */
|
|
38
|
+
marginBlockStart?: number;
|
|
39
|
+
/** Label font size, in CSS pixels. */
|
|
40
|
+
fontSize?: number;
|
|
41
|
+
/** Label line height, in CSS pixels. */
|
|
42
|
+
lineHeight?: number;
|
|
43
|
+
/** Padding on the block axis, in CSS pixels. */
|
|
44
|
+
paddingBlock?: number;
|
|
45
|
+
/** Padding on the inline axis, in CSS pixels. */
|
|
46
|
+
paddingInline?: number;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function workedForRowLength(
|
|
50
|
+
value: number | undefined,
|
|
51
|
+
name: keyof AgentChatWorkedForRowLayout,
|
|
52
|
+
positive = false,
|
|
53
|
+
) {
|
|
54
|
+
if (value === undefined) return undefined;
|
|
55
|
+
if (!Number.isFinite(value) || value < 0 || (positive && value === 0)) {
|
|
56
|
+
throw new RangeError(
|
|
57
|
+
`workedForRowLayout.${name} must be a valid CSS length`,
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
return `${value}px`;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function workedForRowOffset(
|
|
64
|
+
value: number | undefined,
|
|
65
|
+
name: keyof AgentChatWorkedForRowLayout,
|
|
66
|
+
) {
|
|
67
|
+
if (value === undefined) return undefined;
|
|
68
|
+
if (!Number.isFinite(value)) {
|
|
69
|
+
throw new RangeError(`workedForRowLayout.${name} must be finite`);
|
|
70
|
+
}
|
|
71
|
+
return `${value}px`;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function workedForRowSummaryStyle(
|
|
75
|
+
layout?: AgentChatWorkedForRowLayout,
|
|
76
|
+
): CSSProperties | undefined {
|
|
77
|
+
if (!layout) return undefined;
|
|
78
|
+
return {
|
|
79
|
+
gap: workedForRowLength(layout.iconGap, "iconGap"),
|
|
80
|
+
marginBlockStart: workedForRowOffset(
|
|
81
|
+
layout.marginBlockStart,
|
|
82
|
+
"marginBlockStart",
|
|
83
|
+
),
|
|
84
|
+
fontSize: workedForRowLength(layout.fontSize, "fontSize", true),
|
|
85
|
+
lineHeight: workedForRowLength(layout.lineHeight, "lineHeight", true),
|
|
86
|
+
paddingBlock: workedForRowLength(layout.paddingBlock, "paddingBlock"),
|
|
87
|
+
paddingInline: workedForRowLength(layout.paddingInline, "paddingInline"),
|
|
88
|
+
fontFamily: "inherit",
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export function workedForRowChevronStyle(
|
|
93
|
+
layout?: AgentChatWorkedForRowLayout,
|
|
94
|
+
): CSSProperties | undefined {
|
|
95
|
+
const size = workedForRowLength(layout?.chevronSize, "chevronSize", true);
|
|
96
|
+
return size ? { width: size, height: size } : undefined;
|
|
97
|
+
}
|
|
@@ -129,6 +129,12 @@ async function recordBoth(
|
|
|
129
129
|
|
|
130
130
|
describe("AuthPage attribution", () => {
|
|
131
131
|
beforeEach(() => {
|
|
132
|
+
// Attribution storage depends on the visitor's time zone, so pin it.
|
|
133
|
+
const realOptions = new Intl.DateTimeFormat().resolvedOptions();
|
|
134
|
+
vi.spyOn(Intl.DateTimeFormat.prototype, "resolvedOptions").mockReturnValue({
|
|
135
|
+
...realOptions,
|
|
136
|
+
timeZone: "America/Los_Angeles",
|
|
137
|
+
});
|
|
132
138
|
vi.useFakeTimers({ toFake: ["Date"] });
|
|
133
139
|
vi.stubGlobal("IS_REACT_ACT_ENVIRONMENT", true);
|
|
134
140
|
vi.stubGlobal(
|