@agent-native/toolkit 0.198.3 → 0.198.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/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 +12 -4
- package/dist/app/agentkit/react/components.js.map +1 -1
- package/dist/app/chat/AgentKitAssistantChat.d.ts.map +1 -1
- package/dist/app/chat/AgentKitAssistantChat.js +43 -21
- package/dist/app/chat/AgentKitAssistantChat.js.map +1 -1
- package/dist/app/chat/AgentSidebar.d.ts.map +1 -1
- package/dist/app/chat/AgentSidebar.js +2 -0
- package/dist/app/chat/AgentSidebar.js.map +1 -1
- package/dist/app/chat/FileStorageSetupPopover.js +2 -2
- package/dist/app/chat/FileStorageSetupPopover.js.map +1 -1
- package/dist/app/chat/MultiTabAssistantChat.js +1 -1
- package/dist/app/chat/agentkit-chat/connections.d.ts +1 -4
- package/dist/app/chat/agentkit-chat/connections.d.ts.map +1 -1
- package/dist/app/chat/agentkit-chat/connections.js +1 -26
- package/dist/app/chat/agentkit-chat/connections.js.map +1 -1
- package/dist/app/chat/agentkit-chat/history.d.ts +4 -1
- package/dist/app/chat/agentkit-chat/history.d.ts.map +1 -1
- package/dist/app/chat/agentkit-chat/history.js +17 -5
- package/dist/app/chat/agentkit-chat/history.js.map +1 -1
- package/dist/app/chat/chat/history-types.d.ts +1 -1
- package/dist/app/chat/chat/history-types.d.ts.map +1 -1
- package/dist/app/chat/chat-first/copy.d.ts +1 -2
- package/dist/app/chat/chat-first/copy.d.ts.map +1 -1
- package/dist/app/chat/chat-first/copy.js +1 -121
- package/dist/app/chat/chat-first/copy.js.map +1 -1
- package/dist/app/chat/chat-first-copy.d.ts +3 -0
- package/dist/app/chat/chat-first-copy.d.ts.map +1 -0
- package/dist/app/chat/chat-first-copy.js +122 -0
- package/dist/app/chat/chat-first-copy.js.map +1 -0
- package/dist/app/feature-flags/FeatureFlagsPanel.d.ts.map +1 -1
- package/dist/app/feature-flags/FeatureFlagsPanel.js +1 -0
- package/dist/app/feature-flags/FeatureFlagsPanel.js.map +1 -1
- package/dist/app/i18n/catalogs/ar-SA.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/ar-SA.js +2 -1
- 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 +2 -1
- package/dist/app/i18n/catalogs/de-DE.js.map +1 -1
- package/dist/app/i18n/catalogs/en-US.d.ts +2 -1
- package/dist/app/i18n/catalogs/en-US.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/en-US.js +2 -1
- 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 +2 -1
- 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 +2 -1
- 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 +2 -1
- 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 +2 -1
- 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 +2 -1
- 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 +2 -1
- 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 +2 -1
- 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 +2 -1
- package/dist/app/i18n/catalogs/zh-TW.js.map +1 -1
- package/dist/app/labs/LabsSettings.d.ts.map +1 -1
- package/dist/app/labs/LabsSettings.js +7 -3
- package/dist/app/labs/LabsSettings.js.map +1 -1
- package/dist/app/org/OrgGeneralSection.d.ts.map +1 -1
- package/dist/app/org/OrgGeneralSection.js +21 -18
- package/dist/app/org/OrgGeneralSection.js.map +1 -1
- package/dist/app/org/OrgSwitcher.d.ts.map +1 -1
- package/dist/app/org/OrgSwitcher.js +3 -2
- package/dist/app/org/OrgSwitcher.js.map +1 -1
- package/dist/app/org/workspace-app-links.d.ts +1 -0
- package/dist/app/org/workspace-app-links.d.ts.map +1 -1
- package/dist/app/org/workspace-app-links.js +3 -0
- package/dist/app/org/workspace-app-links.js.map +1 -1
- package/dist/app/resources/McpAgentKitConnectionRequest.d.ts +7 -2
- package/dist/app/resources/McpAgentKitConnectionRequest.d.ts.map +1 -1
- package/dist/app/resources/McpAgentKitConnectionRequest.js +132 -13
- package/dist/app/resources/McpAgentKitConnectionRequest.js.map +1 -1
- package/dist/icons/ResourceIconPicker.d.ts +6 -1
- package/dist/icons/ResourceIconPicker.d.ts.map +1 -1
- package/dist/icons/ResourceIconPicker.js +45 -6
- package/dist/icons/ResourceIconPicker.js.map +1 -1
- package/package.json +6 -4
- package/src/app/agentkit/react/components.spec.tsx +3 -3
- package/src/app/agentkit/react/components.tsx +22 -4
- package/src/app/agentkit/react/lifecycle.spec.tsx +42 -0
- package/src/app/chat/AgentKitAssistantChat.spec.tsx +114 -11
- package/src/app/chat/AgentKitAssistantChat.tsx +78 -17
- package/src/app/chat/AgentPanel.header.spec.ts +59 -22
- package/src/app/chat/AgentSidebar.tsx +2 -0
- package/src/app/chat/FileStorageSetupPopover.tsx +2 -2
- package/src/app/chat/MultiTabAssistantChat.messageCount.spec.tsx +3 -1
- package/src/app/chat/MultiTabAssistantChat.spec.tsx +8 -4
- package/src/app/chat/MultiTabAssistantChat.tsx +1 -1
- package/src/app/chat/agentkit-chat/action-widget.spec.tsx +5 -17
- package/src/app/chat/agentkit-chat/connections.spec.tsx +137 -0
- package/src/app/chat/agentkit-chat/connections.ts +2 -37
- package/src/app/chat/agentkit-chat/history.tsx +23 -8
- package/src/app/chat/chat/history-types.ts +1 -1
- package/src/app/chat/chat/tool-call-display.spec.tsx +2 -2
- package/src/app/chat/chat/widgets/record-change-widget.spec.tsx +20 -29
- package/src/app/chat/chat-first/copy.ts +1 -133
- package/src/app/chat/chat-first-copy.ts +133 -0
- package/src/app/chat/composer/use-agentkit-capabilities.hardening.spec.tsx +3 -2
- package/src/app/feature-flags/FeatureFlagsPanel.tsx +1 -0
- package/src/app/i18n/catalogs/ar-SA.ts +2 -1
- package/src/app/i18n/catalogs/de-DE.ts +3 -1
- package/src/app/i18n/catalogs/en-US.ts +2 -1
- package/src/app/i18n/catalogs/es-ES.ts +2 -1
- package/src/app/i18n/catalogs/fr-FR.ts +3 -1
- package/src/app/i18n/catalogs/hi-IN.ts +2 -1
- package/src/app/i18n/catalogs/ja-JP.ts +2 -1
- package/src/app/i18n/catalogs/ko-KR.ts +2 -1
- package/src/app/i18n/catalogs/pt-BR.ts +3 -1
- package/src/app/i18n/catalogs/zh-CN.ts +2 -1
- package/src/app/i18n/catalogs/zh-TW.ts +2 -1
- package/src/app/integrations/IntegrationDetailPage.spec.tsx +1 -1
- package/src/app/labs/LabsSettings.tsx +46 -10
- package/src/app/observability/ThumbsFeedback.spec.tsx +15 -0
- package/src/app/onboarding/FirstRunOnboarding.spec.tsx +4 -0
- package/src/app/org/OrgGeneralSection.tsx +32 -22
- package/src/app/org/OrgSwitcher.tsx +3 -2
- package/src/app/org/workspace-app-links.spec.ts +4 -0
- package/src/app/org/workspace-app-links.ts +8 -1
- package/src/app/resources/McpAgentKitConnectionRequest.spec.tsx +371 -2
- package/src/app/resources/McpAgentKitConnectionRequest.tsx +171 -11
- package/src/app/settings/SettingsTabsPage.spec.tsx +4 -2
- package/src/app/settings/shell/SettingsShell.spec.tsx +14 -8
- package/src/app/settings/shell/pages/app-group-pages.spec.tsx +35 -5
- package/src/app/settings/shell/pages/resource-pages.spec.tsx +3 -0
- package/src/app/settings/usage/UsagePage.spec.tsx +3 -3
- package/src/app/shared/lazy-chunk-error-boundary.spec.tsx +2 -0
- package/src/app-shell/sidebar-overflow.spec.tsx +4 -1
- package/src/design-tweaks/visual-style-controls.spec.tsx +38 -0
- package/src/editor/useCollabReconcile.concurrent.spec.ts +2 -1
- package/src/icons/ResourceIconPicker.spec.tsx +270 -0
- package/src/icons/ResourceIconPicker.tsx +72 -4
|
@@ -234,6 +234,18 @@ vi.mock("../agentkit/react/root.js", async () => {
|
|
|
234
234
|
return {
|
|
235
235
|
AgentKitRoot: (props: any) => {
|
|
236
236
|
chatMocks.rootProps = props;
|
|
237
|
+
if (chatMocks.useRealRoot) {
|
|
238
|
+
return React.createElement(actual.AgentKitRoot, {
|
|
239
|
+
...props,
|
|
240
|
+
...(chatMocks.realComposerController
|
|
241
|
+
? {
|
|
242
|
+
controller: chatMocks.realComposerController,
|
|
243
|
+
transport: undefined,
|
|
244
|
+
endpoint: undefined,
|
|
245
|
+
}
|
|
246
|
+
: {}),
|
|
247
|
+
});
|
|
248
|
+
}
|
|
237
249
|
if (chatMocks.realComposerController) {
|
|
238
250
|
return React.createElement(AgentKitProvider, {
|
|
239
251
|
...props,
|
|
@@ -747,6 +759,29 @@ afterEach(async () => {
|
|
|
747
759
|
});
|
|
748
760
|
|
|
749
761
|
describe("AgentKitAssistantChat host behavior", () => {
|
|
762
|
+
it("shows a retry when chat history fails to load", async () => {
|
|
763
|
+
const retryHistory = vi.fn();
|
|
764
|
+
chatMocks.history = {
|
|
765
|
+
historyLoadFailed: true,
|
|
766
|
+
isRetryingHistory: false,
|
|
767
|
+
retryHistory,
|
|
768
|
+
};
|
|
769
|
+
|
|
770
|
+
await mount(baseProps());
|
|
771
|
+
|
|
772
|
+
expect(container.querySelector('[role="alert"]')?.textContent).toContain(
|
|
773
|
+
"agentChat.message.historyUnavailable",
|
|
774
|
+
);
|
|
775
|
+
const retry = [...container.querySelectorAll("button")].find(
|
|
776
|
+
(button) => button.textContent === "agentChat.common.retry",
|
|
777
|
+
);
|
|
778
|
+
expect(retry).toBeDefined();
|
|
779
|
+
|
|
780
|
+
await act(async () => retry?.click());
|
|
781
|
+
|
|
782
|
+
expect(retryHistory).toHaveBeenCalledOnce();
|
|
783
|
+
});
|
|
784
|
+
|
|
750
785
|
it("shows Thinking in the transcript while a submitted user message is pending", async () => {
|
|
751
786
|
chatMocks.history = { isSubmissionInFlight: true };
|
|
752
787
|
chatMocks.thread.messages = [
|
|
@@ -759,6 +794,8 @@ describe("AgentKitAssistantChat host behavior", () => {
|
|
|
759
794
|
];
|
|
760
795
|
await mount(baseProps());
|
|
761
796
|
|
|
797
|
+
expect(chatMocks.composerProps.disabled).toBe(false);
|
|
798
|
+
expect(chatMocks.composerProps.submissionDisabled).toBe(true);
|
|
762
799
|
expect(container.querySelector('[role="status"]')?.textContent).toBe(
|
|
763
800
|
"agentChat.status.thinking",
|
|
764
801
|
);
|
|
@@ -847,6 +884,29 @@ describe("AgentKitAssistantChat host behavior", () => {
|
|
|
847
884
|
return client;
|
|
848
885
|
}
|
|
849
886
|
|
|
887
|
+
it("keeps the real editor editable while a submission is in flight", async () => {
|
|
888
|
+
chatMocks.useRealChat = true;
|
|
889
|
+
chatMocks.history = { isSubmissionInFlight: true };
|
|
890
|
+
await useRealComposer();
|
|
891
|
+
await mount(baseProps({ showModelSelector: false }));
|
|
892
|
+
|
|
893
|
+
const editor = container.querySelector<HTMLElement>(
|
|
894
|
+
'[contenteditable="true"]',
|
|
895
|
+
);
|
|
896
|
+
expect(editor).not.toBeNull();
|
|
897
|
+
expect(chatMocks.composerProps.submissionDisabled).toBe(true);
|
|
898
|
+
|
|
899
|
+
await act(async () =>
|
|
900
|
+
chatMocks.composerProps.composerRef.current.setText("Keep this draft"),
|
|
901
|
+
);
|
|
902
|
+
expect(editor?.textContent).toBe("Keep this draft");
|
|
903
|
+
expect(
|
|
904
|
+
container.querySelector<HTMLButtonElement>(
|
|
905
|
+
'[data-agent-composer-slot="send-button"]',
|
|
906
|
+
)?.disabled,
|
|
907
|
+
).toBe(true);
|
|
908
|
+
});
|
|
909
|
+
|
|
850
910
|
it.each(["default", "compact"] as const)(
|
|
851
911
|
"clears the real %s composer before startRun resolves and preserves the next draft",
|
|
852
912
|
async (composerLayoutVariant) => {
|
|
@@ -855,12 +915,13 @@ describe("AgentKitAssistantChat host behavior", () => {
|
|
|
855
915
|
chatMocks.useRealChat = true;
|
|
856
916
|
const client = await useRealComposer(startRun);
|
|
857
917
|
try {
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
918
|
+
const props = baseProps({
|
|
919
|
+
composerLayoutVariant,
|
|
920
|
+
showModelSelector: false,
|
|
921
|
+
});
|
|
922
|
+
const openThread = vi.spyOn(client, "openThread");
|
|
923
|
+
chatMocks.useRealRoot = true;
|
|
924
|
+
await mount(props);
|
|
864
925
|
container.style.width =
|
|
865
926
|
composerLayoutVariant === "compact" ? "320px" : "960px";
|
|
866
927
|
const composer = chatMocks.composerProps.composerRef.current;
|
|
@@ -884,6 +945,19 @@ describe("AgentKitAssistantChat host behavior", () => {
|
|
|
884
945
|
expect(client.getThread(chatMocks.threadId).activeRunIds).toEqual([]);
|
|
885
946
|
expect(editor.textContent).toBe("");
|
|
886
947
|
|
|
948
|
+
await act(async () =>
|
|
949
|
+
root.render(<AgentKitAssistantChat {...props} isNewThread={false} />),
|
|
950
|
+
);
|
|
951
|
+
await flush();
|
|
952
|
+
|
|
953
|
+
expect(chatMocks.rootProps.load).toBe("manual");
|
|
954
|
+
expect(openThread).not.toHaveBeenCalled();
|
|
955
|
+
expect(
|
|
956
|
+
container
|
|
957
|
+
.querySelector<HTMLElement>("[contenteditable]")
|
|
958
|
+
?.getAttribute("contenteditable"),
|
|
959
|
+
).toBe("true");
|
|
960
|
+
|
|
887
961
|
await act(async () => composer.setText("Next draft"));
|
|
888
962
|
await act(async () => started.resolve({ runId: "run-latency" }));
|
|
889
963
|
|
|
@@ -1585,7 +1659,7 @@ describe("AgentKitAssistantChat host behavior", () => {
|
|
|
1585
1659
|
expect(chatMocks.appState.has(stateKey!)).toBe(false);
|
|
1586
1660
|
});
|
|
1587
1661
|
|
|
1588
|
-
it("
|
|
1662
|
+
it("preserves queued intent when its run finishes during provider discovery", async () => {
|
|
1589
1663
|
chatMocks.readiness = {
|
|
1590
1664
|
canChat: false,
|
|
1591
1665
|
missing: false,
|
|
@@ -1611,12 +1685,27 @@ describe("AgentKitAssistantChat host behavior", () => {
|
|
|
1611
1685
|
[],
|
|
1612
1686
|
[],
|
|
1613
1687
|
{ intent: "queued" },
|
|
1688
|
+
async () => ({}),
|
|
1614
1689
|
);
|
|
1615
1690
|
});
|
|
1616
1691
|
|
|
1617
1692
|
expect(chatMocks.control.sendMessage).not.toHaveBeenCalled();
|
|
1618
1693
|
expect(chatMocks.control.queueMessage).not.toHaveBeenCalled();
|
|
1619
1694
|
|
|
1695
|
+
const stateKey = [...chatMocks.appState.keys()].find((key) =>
|
|
1696
|
+
key.startsWith("agentkit-deferred-provider-submissions:"),
|
|
1697
|
+
);
|
|
1698
|
+
expect(chatMocks.appState.get(stateKey!)).toMatchObject({
|
|
1699
|
+
submissions: [
|
|
1700
|
+
{
|
|
1701
|
+
composerOptions: {
|
|
1702
|
+
intent: "queued",
|
|
1703
|
+
queuedWhileRunActive: true,
|
|
1704
|
+
},
|
|
1705
|
+
},
|
|
1706
|
+
],
|
|
1707
|
+
});
|
|
1708
|
+
|
|
1620
1709
|
chatMocks.thread.activeRunIds = [];
|
|
1621
1710
|
chatMocks.thread.runs["analytics-run"].status = "completed";
|
|
1622
1711
|
chatMocks.readiness = {
|
|
@@ -1640,6 +1729,7 @@ describe("AgentKitAssistantChat host behavior", () => {
|
|
|
1640
1729
|
}),
|
|
1641
1730
|
);
|
|
1642
1731
|
expect(chatMocks.control.sendMessage).not.toHaveBeenCalled();
|
|
1732
|
+
expect(chatMocks.appState.has(stateKey!)).toBe(false);
|
|
1643
1733
|
});
|
|
1644
1734
|
|
|
1645
1735
|
it("keeps the draft rejected if provider status becomes missing before submit", async () => {
|
|
@@ -3338,11 +3428,11 @@ describe("AgentKitAssistantChat host behavior", () => {
|
|
|
3338
3428
|
chatMocks.thread.activeRunIds = ["run-1"];
|
|
3339
3429
|
await mount(baseProps());
|
|
3340
3430
|
|
|
3341
|
-
|
|
3342
|
-
|
|
3343
|
-
message: "Continue after connecting the integration.",
|
|
3344
|
-
});
|
|
3431
|
+
const resume = chatMocks.resumeProps.onMessageResume({
|
|
3432
|
+
message: "Continue after connecting the integration.",
|
|
3345
3433
|
});
|
|
3434
|
+
expect(resume).toBeInstanceOf(Promise);
|
|
3435
|
+
await act(async () => resume);
|
|
3346
3436
|
expect(chatMocks.control.queueMessage).toHaveBeenCalledWith(
|
|
3347
3437
|
expect.objectContaining({
|
|
3348
3438
|
text: "Continue after connecting the integration.",
|
|
@@ -3382,6 +3472,19 @@ describe("AgentKitAssistantChat host behavior", () => {
|
|
|
3382
3472
|
expect(chatMocks.control.sendMessage).not.toHaveBeenCalled();
|
|
3383
3473
|
});
|
|
3384
3474
|
|
|
3475
|
+
it("keeps failed integration prompt submissions resumable", async () => {
|
|
3476
|
+
chatMocks.thread.activeRunIds = ["run-1"];
|
|
3477
|
+
const submissionError = new Error("Temporary send failure");
|
|
3478
|
+
chatMocks.control.queueMessage.mockRejectedValueOnce(submissionError);
|
|
3479
|
+
await mount(baseProps());
|
|
3480
|
+
|
|
3481
|
+
await expect(
|
|
3482
|
+
chatMocks.resumeProps.onMessageResume({
|
|
3483
|
+
message: "Continue after OAuth.",
|
|
3484
|
+
}),
|
|
3485
|
+
).rejects.toBe(submissionError);
|
|
3486
|
+
});
|
|
3487
|
+
|
|
3385
3488
|
it("shows the missing-final-response warning from recovered run metadata", async () => {
|
|
3386
3489
|
chatMocks.thread.messages = [
|
|
3387
3490
|
{
|
|
@@ -460,6 +460,15 @@ type AgentKitSuggestionSubmitOptions = PromptComposerSubmitOptions & {
|
|
|
460
460
|
queuedWhileRunActive?: boolean;
|
|
461
461
|
};
|
|
462
462
|
|
|
463
|
+
function preserveQueuedIntent(
|
|
464
|
+
preparedOptions: PromptComposerSubmitOptions,
|
|
465
|
+
originalOptions: PromptComposerSubmitOptions,
|
|
466
|
+
): PromptComposerSubmitOptions {
|
|
467
|
+
return originalOptions.intent === "queued"
|
|
468
|
+
? { ...preparedOptions, intent: "queued" }
|
|
469
|
+
: preparedOptions;
|
|
470
|
+
}
|
|
471
|
+
|
|
463
472
|
function captureQueuedRunState(
|
|
464
473
|
options: PromptComposerSubmitOptions,
|
|
465
474
|
runWasActive: boolean,
|
|
@@ -594,8 +603,13 @@ export const AgentKitAssistantChat = forwardRef<
|
|
|
594
603
|
: readAgentKitThreadHandoffSnapshot(
|
|
595
604
|
createAgentKitThreadHandoffKey(props, threadId),
|
|
596
605
|
);
|
|
606
|
+
const [manualLoadThreadId, setManualLoadThreadId] = useState<string | null>(
|
|
607
|
+
() => (props.isNewThread ? threadId : null),
|
|
608
|
+
);
|
|
609
|
+
const hasManualLoadForCurrentThread =
|
|
610
|
+
props.isNewThread || manualLoadThreadId === threadId;
|
|
597
611
|
const [threadRestore, setThreadRestore] = useState<ThreadRestoreState>(() =>
|
|
598
|
-
props.isThreadStateLoading || !
|
|
612
|
+
props.isThreadStateLoading || !hasManualLoadForCurrentThread
|
|
599
613
|
? { status: "loading" }
|
|
600
614
|
: { status: "ready" },
|
|
601
615
|
);
|
|
@@ -611,15 +625,25 @@ export const AgentKitAssistantChat = forwardRef<
|
|
|
611
625
|
setRestoreRetryLoadPhase("idle");
|
|
612
626
|
setRestoreRetryThreadId(null);
|
|
613
627
|
}, []);
|
|
628
|
+
useEffect(() => {
|
|
629
|
+
setManualLoadThreadId((current) =>
|
|
630
|
+
props.isNewThread ? threadId : current === threadId ? current : null,
|
|
631
|
+
);
|
|
632
|
+
}, [props.isNewThread, threadId]);
|
|
614
633
|
useEffect(() => {
|
|
615
634
|
setThreadRestore(
|
|
616
|
-
props.isThreadStateLoading || !
|
|
635
|
+
props.isThreadStateLoading || !hasManualLoadForCurrentThread
|
|
617
636
|
? { status: "loading" }
|
|
618
637
|
: { status: "ready" },
|
|
619
638
|
);
|
|
620
639
|
setRestoreRetryLoadPhase("idle");
|
|
621
640
|
setRestoreRetryThreadId(null);
|
|
622
|
-
}, [
|
|
641
|
+
}, [
|
|
642
|
+
hasManualLoadForCurrentThread,
|
|
643
|
+
props.isNewThread,
|
|
644
|
+
props.isThreadStateLoading,
|
|
645
|
+
threadId,
|
|
646
|
+
]);
|
|
623
647
|
const onThreadRestoreLoadError = useCallback(
|
|
624
648
|
(error: unknown) => {
|
|
625
649
|
const record = asRecord(error);
|
|
@@ -989,7 +1013,7 @@ export const AgentKitAssistantChat = forwardRef<
|
|
|
989
1013
|
]);
|
|
990
1014
|
const agentKitLoad =
|
|
991
1015
|
props.isThreadStateLoading ||
|
|
992
|
-
|
|
1016
|
+
hasManualLoadForCurrentThread ||
|
|
993
1017
|
(restoreRetryThreadId === threadId && restoreRetryLoadPhase === "release")
|
|
994
1018
|
? "manual"
|
|
995
1019
|
: "auto";
|
|
@@ -2204,7 +2228,7 @@ const AgentKitAssistantChatBody = forwardRef<
|
|
|
2204
2228
|
try {
|
|
2205
2229
|
const preparedOptions = prepare ? await prepare() : composerOptions;
|
|
2206
2230
|
const submittedOptions = captureQueuedRunState(
|
|
2207
|
-
preparedOptions,
|
|
2231
|
+
preserveQueuedIntent(preparedOptions, composerOptions),
|
|
2208
2232
|
runWasActiveAtSubmit,
|
|
2209
2233
|
);
|
|
2210
2234
|
const result = await submit(
|
|
@@ -2231,7 +2255,10 @@ const AgentKitAssistantChatBody = forwardRef<
|
|
|
2231
2255
|
text,
|
|
2232
2256
|
files,
|
|
2233
2257
|
references,
|
|
2234
|
-
captureQueuedRunState(
|
|
2258
|
+
captureQueuedRunState(
|
|
2259
|
+
preserveQueuedIntent(preparedOptions, composerOptions),
|
|
2260
|
+
runWasActiveAtSubmit,
|
|
2261
|
+
),
|
|
2235
2262
|
);
|
|
2236
2263
|
} catch (error) {
|
|
2237
2264
|
dispatchSetupRequiredEvent(error, props.tabId, threadId);
|
|
@@ -2552,11 +2579,19 @@ const AgentKitAssistantChatBody = forwardRef<
|
|
|
2552
2579
|
[isThreadRunning, submit],
|
|
2553
2580
|
);
|
|
2554
2581
|
const resumeIntegrationPrompt = useCallback(
|
|
2555
|
-
(message: string) => {
|
|
2556
|
-
if (props.isActiveComposer === false)
|
|
2557
|
-
|
|
2582
|
+
async (message: string) => {
|
|
2583
|
+
if (props.isActiveComposer === false) {
|
|
2584
|
+
throw new Error("Cannot resume a request in an inactive chat.");
|
|
2585
|
+
}
|
|
2586
|
+
try {
|
|
2587
|
+
const result = await send(message);
|
|
2588
|
+
if (result.status === "rejected") {
|
|
2589
|
+
throw new Error(`Chat resume was rejected: ${result.reason}.`);
|
|
2590
|
+
}
|
|
2591
|
+
} catch (error) {
|
|
2558
2592
|
dispatchSetupRequiredEvent(error, props.tabId, threadId);
|
|
2559
|
-
|
|
2593
|
+
throw error;
|
|
2594
|
+
}
|
|
2560
2595
|
},
|
|
2561
2596
|
[props.isActiveComposer, props.tabId, send, threadId],
|
|
2562
2597
|
);
|
|
@@ -2775,15 +2810,19 @@ const AgentKitAssistantChatBody = forwardRef<
|
|
|
2775
2810
|
{ threadId: targetThreadId, runId, requestId },
|
|
2776
2811
|
request,
|
|
2777
2812
|
) => {
|
|
2778
|
-
if (targetThreadId !== threadId)
|
|
2813
|
+
if (targetThreadId !== threadId) {
|
|
2814
|
+
throw new Error(
|
|
2815
|
+
"Cannot resume a connection request in another chat.",
|
|
2816
|
+
);
|
|
2817
|
+
}
|
|
2779
2818
|
return control.resolveConnectionRequest(runId, requestId, {
|
|
2780
2819
|
status: "connected",
|
|
2781
2820
|
message: request.message,
|
|
2782
2821
|
});
|
|
2783
2822
|
}}
|
|
2784
|
-
onMessageResume={(request) =>
|
|
2785
|
-
resumeIntegrationPrompt(request.message)
|
|
2786
|
-
}
|
|
2823
|
+
onMessageResume={(request) =>
|
|
2824
|
+
resumeIntegrationPrompt(request.message)
|
|
2825
|
+
}
|
|
2787
2826
|
/>
|
|
2788
2827
|
)}
|
|
2789
2828
|
<RunStuckBanner
|
|
@@ -2805,6 +2844,24 @@ const AgentKitAssistantChatBody = forwardRef<
|
|
|
2805
2844
|
void sendRecoveryMessage(RECOVERY_CONTINUE_PROMPT, "continue")
|
|
2806
2845
|
}
|
|
2807
2846
|
/>
|
|
2847
|
+
{history?.historyLoadFailed ? (
|
|
2848
|
+
<div
|
|
2849
|
+
role="alert"
|
|
2850
|
+
className="mx-3 mb-2 flex items-center justify-between gap-3 rounded-md border border-border px-3 py-2 text-xs"
|
|
2851
|
+
>
|
|
2852
|
+
<span className="text-muted-foreground">
|
|
2853
|
+
{t("agentChat.message.historyUnavailable")}
|
|
2854
|
+
</span>
|
|
2855
|
+
<button
|
|
2856
|
+
type="button"
|
|
2857
|
+
onClick={history.retryHistory}
|
|
2858
|
+
disabled={history.isRetryingHistory}
|
|
2859
|
+
className="shrink-0 font-medium text-foreground hover:underline disabled:cursor-not-allowed disabled:opacity-50"
|
|
2860
|
+
>
|
|
2861
|
+
{t("agentChat.common.retry")}
|
|
2862
|
+
</button>
|
|
2863
|
+
</div>
|
|
2864
|
+
) : null}
|
|
2808
2865
|
<AgentKitChat
|
|
2809
2866
|
className={props.className}
|
|
2810
2867
|
composerProps={{ attachmentsEnabled: fileStorageConfigured }}
|
|
@@ -3668,12 +3725,12 @@ function AgentKitComposerSurface({
|
|
|
3668
3725
|
disabled={
|
|
3669
3726
|
(!canChat && !providerSubmissionPending) ||
|
|
3670
3727
|
props.composerDisabled ||
|
|
3671
|
-
isRestoring
|
|
3672
|
-
isSubmissionInFlight
|
|
3728
|
+
isRestoring
|
|
3673
3729
|
}
|
|
3674
3730
|
submissionDisabled={
|
|
3675
3731
|
(!canChat && !providerSubmissionPending) ||
|
|
3676
|
-
props.composerSubmissionDisabled === true
|
|
3732
|
+
props.composerSubmissionDisabled === true ||
|
|
3733
|
+
isSubmissionInFlight
|
|
3677
3734
|
}
|
|
3678
3735
|
onDisabledClick={
|
|
3679
3736
|
props.composerDisabled || !setupMissing
|
|
@@ -4128,6 +4185,10 @@ function AgentKitConnectionRequest({
|
|
|
4128
4185
|
<McpAgentKitConnectionRequestCard
|
|
4129
4186
|
provider={value.provider}
|
|
4130
4187
|
detail={value.detail}
|
|
4188
|
+
reason={value.reason}
|
|
4189
|
+
status={value.status}
|
|
4190
|
+
appId={value.appId}
|
|
4191
|
+
source={value.source}
|
|
4131
4192
|
target={{ threadId, runId, requestId: value.id }}
|
|
4132
4193
|
onConnected={() =>
|
|
4133
4194
|
control.resolveConnectionRequest(runId, value.id, {
|
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
import { readFileSync } from "node:fs";
|
|
4
4
|
|
|
5
|
+
import {
|
|
6
|
+
DropdownMenu,
|
|
7
|
+
DropdownMenuContent,
|
|
8
|
+
DropdownMenuTrigger,
|
|
9
|
+
} from "@agent-native/toolkit/ui/dropdown-menu";
|
|
5
10
|
import React, { act } from "react";
|
|
6
11
|
import { createRoot, type Root } from "react-dom/client";
|
|
7
12
|
import { MemoryRouter, useLocation } from "react-router";
|
|
8
13
|
import { describe, expect, it, vi } from "vitest";
|
|
9
14
|
|
|
10
|
-
import {
|
|
11
|
-
DropdownMenu,
|
|
12
|
-
DropdownMenuContent,
|
|
13
|
-
DropdownMenuTrigger,
|
|
14
|
-
} from "../../ui/dropdown-menu.js";
|
|
15
15
|
import {
|
|
16
16
|
AgentChatSurface,
|
|
17
17
|
AgentPanelFullViewMenuItem,
|
|
@@ -51,6 +51,13 @@ import {
|
|
|
51
51
|
preloadAgentChatSurface,
|
|
52
52
|
} from "./AgentSidebar.js";
|
|
53
53
|
|
|
54
|
+
function readSource(
|
|
55
|
+
path: string,
|
|
56
|
+
_options?: "utf8" | { encoding: "utf8" },
|
|
57
|
+
): string {
|
|
58
|
+
return readFileSync(path, "utf8").replace(/\r\n/g, "\n");
|
|
59
|
+
}
|
|
60
|
+
|
|
54
61
|
describe("AgentPanel compatibility exports", () => {
|
|
55
62
|
it("preserves the legacy sidebar entry point", () => {
|
|
56
63
|
expect(LegacyAgentSidebar).toBe(AgentSidebar);
|
|
@@ -60,7 +67,7 @@ describe("AgentPanel compatibility exports", () => {
|
|
|
60
67
|
});
|
|
61
68
|
|
|
62
69
|
it("uses a stable-ref link in the full-view menu item", () => {
|
|
63
|
-
const source =
|
|
70
|
+
const source = readSource("src/app/chat/AgentPanel.tsx", "utf8").replace(
|
|
64
71
|
/\s+/g,
|
|
65
72
|
" ",
|
|
66
73
|
);
|
|
@@ -150,7 +157,7 @@ describe("AgentPanel fullscreen menu", () => {
|
|
|
150
157
|
|
|
151
158
|
describe("AgentPanel suggestion placement", () => {
|
|
152
159
|
it("forwards explicit placement and defaults to context chips", () => {
|
|
153
|
-
const source =
|
|
160
|
+
const source = readSource("src/app/chat/AgentPanel.tsx", {
|
|
154
161
|
encoding: "utf8",
|
|
155
162
|
});
|
|
156
163
|
|
|
@@ -323,7 +330,7 @@ describe("AgentPanel header tab visibility", () => {
|
|
|
323
330
|
});
|
|
324
331
|
|
|
325
332
|
it("exposes page header composition without moving it into app chrome", () => {
|
|
326
|
-
const source =
|
|
333
|
+
const source = readSource("src/app/chat/AgentPanel.tsx", "utf8");
|
|
327
334
|
|
|
328
335
|
expect(source).toContain('data-agent-page-chat-header=""');
|
|
329
336
|
expect(source).toContain("pageHeaderLeadingSlot");
|
|
@@ -699,7 +706,7 @@ describe("AgentPanel Integrations link", () => {
|
|
|
699
706
|
});
|
|
700
707
|
|
|
701
708
|
it("sits right after Open full view and shares its separator", () => {
|
|
702
|
-
const source =
|
|
709
|
+
const source = readSource("src/app/chat/AgentPanel.tsx", {
|
|
703
710
|
encoding: "utf8",
|
|
704
711
|
});
|
|
705
712
|
const overflowMenu = source.slice(
|
|
@@ -820,6 +827,36 @@ describe("AgentSidebar composer focus", () => {
|
|
|
820
827
|
}
|
|
821
828
|
});
|
|
822
829
|
|
|
830
|
+
it("stops retrying when the document is torn down", () => {
|
|
831
|
+
vi.useFakeTimers();
|
|
832
|
+
const previousRequestAnimationFrame = window.requestAnimationFrame;
|
|
833
|
+
const frames: Array<FrameRequestCallback> = [];
|
|
834
|
+
const panel = document.createElement("div");
|
|
835
|
+
panel.className = "agent-sidebar-panel";
|
|
836
|
+
panel.dataset.agentSidebarState = "open";
|
|
837
|
+
document.body.appendChild(panel);
|
|
838
|
+
|
|
839
|
+
window.requestAnimationFrame = ((callback: FrameRequestCallback) => {
|
|
840
|
+
frames.push(callback);
|
|
841
|
+
return frames.length;
|
|
842
|
+
}) as typeof window.requestAnimationFrame;
|
|
843
|
+
|
|
844
|
+
try {
|
|
845
|
+
focusAgentChat();
|
|
846
|
+
frames[0]!(0);
|
|
847
|
+
vi.stubGlobal("document", undefined);
|
|
848
|
+
|
|
849
|
+
expect(() => vi.advanceTimersByTime(50)).not.toThrow();
|
|
850
|
+
expect(vi.getTimerCount()).toBe(0);
|
|
851
|
+
} finally {
|
|
852
|
+
vi.unstubAllGlobals();
|
|
853
|
+
window.requestAnimationFrame = previousRequestAnimationFrame;
|
|
854
|
+
panel.remove();
|
|
855
|
+
vi.clearAllTimers();
|
|
856
|
+
vi.useRealTimers();
|
|
857
|
+
}
|
|
858
|
+
});
|
|
859
|
+
|
|
823
860
|
it("focuses a frame-owned composer", () => {
|
|
824
861
|
const previousRequestAnimationFrame = window.requestAnimationFrame;
|
|
825
862
|
const frames: Array<FrameRequestCallback> = [];
|
|
@@ -914,10 +951,10 @@ describe("AgentPanel header overflow actions", () => {
|
|
|
914
951
|
});
|
|
915
952
|
|
|
916
953
|
it("keeps width and full-view actions out of the icon row", () => {
|
|
917
|
-
const source =
|
|
954
|
+
const source = readSource("src/app/chat/AgentPanel.tsx", {
|
|
918
955
|
encoding: "utf8",
|
|
919
956
|
});
|
|
920
|
-
const sidebarSource =
|
|
957
|
+
const sidebarSource = readSource("src/app/chat/AgentSidebar.tsx", {
|
|
921
958
|
encoding: "utf8",
|
|
922
959
|
});
|
|
923
960
|
const headerActions = source.slice(
|
|
@@ -957,7 +994,7 @@ describe("AgentPanel header overflow actions", () => {
|
|
|
957
994
|
});
|
|
958
995
|
|
|
959
996
|
it("keeps the overflow menu scrollable within the viewport", () => {
|
|
960
|
-
const source =
|
|
997
|
+
const source = readSource("src/app/chat/AgentPanel.tsx", {
|
|
961
998
|
encoding: "utf8",
|
|
962
999
|
});
|
|
963
1000
|
const overflowMenu = source.slice(
|
|
@@ -972,7 +1009,7 @@ describe("AgentPanel header overflow actions", () => {
|
|
|
972
1009
|
});
|
|
973
1010
|
|
|
974
1011
|
it("offers sharing from the sidebar overflow for an active chat", () => {
|
|
975
|
-
const source =
|
|
1012
|
+
const source = readSource("src/app/chat/AgentPanel.tsx", {
|
|
976
1013
|
encoding: "utf8",
|
|
977
1014
|
});
|
|
978
1015
|
const overflowMenu = source.slice(
|
|
@@ -992,7 +1029,7 @@ describe("AgentPanel header overflow actions", () => {
|
|
|
992
1029
|
});
|
|
993
1030
|
|
|
994
1031
|
it("keeps chat headers persistent while switching app surfaces", () => {
|
|
995
|
-
const source =
|
|
1032
|
+
const source = readSource("src/app/chat/AgentPanel.tsx", {
|
|
996
1033
|
encoding: "utf8",
|
|
997
1034
|
});
|
|
998
1035
|
|
|
@@ -1002,10 +1039,10 @@ describe("AgentPanel header overflow actions", () => {
|
|
|
1002
1039
|
});
|
|
1003
1040
|
|
|
1004
1041
|
it("supports a persistent two-state sidebar toggle", () => {
|
|
1005
|
-
const source =
|
|
1042
|
+
const source = readSource("src/app/chat/AgentSidebar.tsx", {
|
|
1006
1043
|
encoding: "utf8",
|
|
1007
1044
|
});
|
|
1008
|
-
const panelSource =
|
|
1045
|
+
const panelSource = readSource("src/app/chat/AgentPanel.tsx", {
|
|
1009
1046
|
encoding: "utf8",
|
|
1010
1047
|
});
|
|
1011
1048
|
|
|
@@ -1021,7 +1058,7 @@ describe("AgentPanel header overflow actions", () => {
|
|
|
1021
1058
|
});
|
|
1022
1059
|
|
|
1023
1060
|
it("keeps host CLI tabs mounted while chat is active", () => {
|
|
1024
|
-
const source =
|
|
1061
|
+
const source = readSource("src/app/chat/AgentPanel.tsx", {
|
|
1025
1062
|
encoding: "utf8",
|
|
1026
1063
|
});
|
|
1027
1064
|
|
|
@@ -1035,7 +1072,7 @@ describe("AgentPanel header overflow actions", () => {
|
|
|
1035
1072
|
});
|
|
1036
1073
|
|
|
1037
1074
|
it("only shows tabs for the active desktop surface", () => {
|
|
1038
|
-
const source =
|
|
1075
|
+
const source = readSource("src/app/chat/AgentPanel.tsx", {
|
|
1039
1076
|
encoding: "utf8",
|
|
1040
1077
|
});
|
|
1041
1078
|
|
|
@@ -1046,7 +1083,7 @@ describe("AgentPanel header overflow actions", () => {
|
|
|
1046
1083
|
|
|
1047
1084
|
describe("AgentSidebar wide drawer layout", () => {
|
|
1048
1085
|
it("can disable the panel without unmounting the app surface", () => {
|
|
1049
|
-
const source =
|
|
1086
|
+
const source = readSource("src/app/chat/AgentSidebar.tsx", {
|
|
1050
1087
|
encoding: "utf8",
|
|
1051
1088
|
});
|
|
1052
1089
|
|
|
@@ -1058,7 +1095,7 @@ describe("AgentSidebar wide drawer layout", () => {
|
|
|
1058
1095
|
});
|
|
1059
1096
|
|
|
1060
1097
|
it("does not reserve the drawer placeholder after the panel closes", () => {
|
|
1061
|
-
const source =
|
|
1098
|
+
const source = readSource("src/app/chat/AgentSidebar.tsx", {
|
|
1062
1099
|
encoding: "utf8",
|
|
1063
1100
|
});
|
|
1064
1101
|
const placeholderStart = source.indexOf("const drawerPlaceholder");
|
|
@@ -1083,7 +1120,7 @@ describe("AgentChatSurface chrome defaults", () => {
|
|
|
1083
1120
|
});
|
|
1084
1121
|
|
|
1085
1122
|
it("keeps settings out of every chat surface", () => {
|
|
1086
|
-
const source =
|
|
1123
|
+
const source = readSource("src/app/chat/AgentPanel.tsx", {
|
|
1087
1124
|
encoding: "utf8",
|
|
1088
1125
|
});
|
|
1089
1126
|
|
|
@@ -1117,7 +1154,7 @@ describe("AgentChatSurface chrome defaults", () => {
|
|
|
1117
1154
|
|
|
1118
1155
|
describe("AgentPanel stale lazy chunk recovery", () => {
|
|
1119
1156
|
it("uses the guarded reload path before the panel reset fallback", () => {
|
|
1120
|
-
const source =
|
|
1157
|
+
const source = readSource("src/app/chat/AgentPanel.tsx", {
|
|
1121
1158
|
encoding: "utf8",
|
|
1122
1159
|
});
|
|
1123
1160
|
const componentDidCatch = source.slice(
|
|
@@ -1331,6 +1331,8 @@ export function focusAgentChat() {
|
|
|
1331
1331
|
|
|
1332
1332
|
function focusAgentChatComposer() {
|
|
1333
1333
|
const focusComposer = (attempt = 0) => {
|
|
1334
|
+
if (typeof window === "undefined" || typeof document === "undefined")
|
|
1335
|
+
return;
|
|
1334
1336
|
const panel = document.querySelector(
|
|
1335
1337
|
".agent-sidebar-panel[data-agent-sidebar-state='open'], " +
|
|
1336
1338
|
".agent-frame-sidebar[data-agent-frame-sidebar-state='open']",
|
|
@@ -8,8 +8,8 @@ import {
|
|
|
8
8
|
import { IconCloudUpload } from "@tabler/icons-react";
|
|
9
9
|
import { useRef, type RefObject } from "react";
|
|
10
10
|
|
|
11
|
-
import { BuilderConnectPopover } from "../settings/
|
|
12
|
-
import { BuilderConnectCard } from "../setup-connections/
|
|
11
|
+
import { DeferredBuilderConnectPopover as BuilderConnectPopover } from "../settings/deferred-builder-connect-popover.js";
|
|
12
|
+
import { BuilderConnectCard } from "../setup-connections/BuilderConnectCard.js";
|
|
13
13
|
|
|
14
14
|
type FileStorageSetupPopoverCommonProps = {
|
|
15
15
|
open: boolean;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { describe, expect, it, vi } from "vitest";
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import rawMultiTabSource from "./MultiTabAssistantChat.tsx?raw";
|
|
4
|
+
|
|
5
|
+
const MultiTabSource = rawMultiTabSource.replace(/\r\n/g, "\n");
|
|
4
6
|
|
|
5
7
|
describe("MultiTabAssistantChat message count", () => {
|
|
6
8
|
it("forwards the host callback instead of only counting tabs", () => {
|
|
@@ -210,9 +210,11 @@ const modelCatalogMocks = vi.hoisted(() => ({
|
|
|
210
210
|
load: null as null | (() => Promise<unknown>),
|
|
211
211
|
}));
|
|
212
212
|
|
|
213
|
-
vi.mock("@agent-native/core/client/
|
|
213
|
+
vi.mock("@agent-native/core/client/use-action", async (importOriginal) => {
|
|
214
214
|
const actual =
|
|
215
|
-
await importOriginal<
|
|
215
|
+
await importOriginal<
|
|
216
|
+
typeof import("@agent-native/core/client/use-action")
|
|
217
|
+
>();
|
|
216
218
|
return { ...actual, ...actionMocks };
|
|
217
219
|
});
|
|
218
220
|
|
|
@@ -433,6 +435,8 @@ describe("MultiTabAssistantChat postMessage bridge", () => {
|
|
|
433
435
|
beforeEach(async () => {
|
|
434
436
|
vi.stubGlobal("IS_REACT_ACT_ENVIRONMENT", true);
|
|
435
437
|
resetThreadMocks();
|
|
438
|
+
actionMocks.callAction.mockReset();
|
|
439
|
+
actionMocks.callAction.mockResolvedValue(null as never);
|
|
436
440
|
ensureLocalStorage();
|
|
437
441
|
vi.stubGlobal(
|
|
438
442
|
"fetch",
|
|
@@ -3345,7 +3349,7 @@ describe("MultiTabAssistantChat page overlay", () => {
|
|
|
3345
3349
|
).not.toBeNull();
|
|
3346
3350
|
});
|
|
3347
3351
|
|
|
3348
|
-
it("reserves
|
|
3352
|
+
it("reserves one page-header height when its actions are temporarily empty", async () => {
|
|
3349
3353
|
await act(async () => {
|
|
3350
3354
|
root.render(
|
|
3351
3355
|
<MultiTabAssistantChat
|
|
@@ -3359,7 +3363,7 @@ describe("MultiTabAssistantChat page overlay", () => {
|
|
|
3359
3363
|
"[data-agent-page-chat-topbar]",
|
|
3360
3364
|
);
|
|
3361
3365
|
expect(topbar).not.toBeNull();
|
|
3362
|
-
expect(topbar?.className).toContain("pt-
|
|
3366
|
+
expect(topbar?.className).toContain("pt-12");
|
|
3363
3367
|
});
|
|
3364
3368
|
});
|
|
3365
3369
|
|