@agent-native/toolkit 0.205.0 → 0.206.0-nightly-20261009011246
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.map +1 -1
- package/dist/app/agentkit/react/components.js +17 -9
- package/dist/app/agentkit/react/components.js.map +1 -1
- package/dist/app/auth/AuthPage.d.ts.map +1 -1
- package/dist/app/auth/AuthPage.js +11 -0
- package/dist/app/auth/AuthPage.js.map +1 -1
- package/dist/app/chat/AgentKitAssistantChat.d.ts +2 -0
- package/dist/app/chat/AgentKitAssistantChat.d.ts.map +1 -1
- package/dist/app/chat/AgentKitAssistantChat.js +24 -14
- package/dist/app/chat/AgentKitAssistantChat.js.map +1 -1
- package/dist/app/chat/AgentPanel.d.ts.map +1 -1
- package/dist/app/chat/AgentPanel.js +3 -2
- package/dist/app/chat/AgentPanel.js.map +1 -1
- package/dist/app/chat/MultiTabAssistantChat.d.ts +4 -1
- package/dist/app/chat/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/app/chat/MultiTabAssistantChat.js +61 -3
- package/dist/app/chat/MultiTabAssistantChat.js.map +1 -1
- package/dist/app/chat/agentkit-chat/approval-card.d.ts.map +1 -1
- package/dist/app/chat/agentkit-chat/approval-card.js +2 -1
- package/dist/app/chat/agentkit-chat/approval-card.js.map +1 -1
- package/dist/app/chat/chat/run-recovery.d.ts.map +1 -1
- package/dist/app/chat/chat/run-recovery.js +74 -8
- package/dist/app/chat/chat/run-recovery.js.map +1 -1
- package/dist/app/chat/chat/tool-call-display.d.ts.map +1 -1
- package/dist/app/chat/chat/tool-call-display.js +6 -4
- package/dist/app/chat/chat/tool-call-display.js.map +1 -1
- package/dist/app/chat/chat-first/ChatFirstAgentActivityPanel.d.ts.map +1 -1
- package/dist/app/chat/chat-first/ChatFirstAgentActivityPanel.js +2 -1
- package/dist/app/chat/chat-first/ChatFirstAgentActivityPanel.js.map +1 -1
- package/dist/app/chat/conversation/AgentConversation.d.ts.map +1 -1
- package/dist/app/chat/conversation/AgentConversation.js +10 -7
- package/dist/app/chat/conversation/AgentConversation.js.map +1 -1
- package/dist/app/chat/fallback-chat-title.d.ts.map +1 -1
- package/dist/app/chat/fallback-chat-title.js +2 -4
- package/dist/app/chat/fallback-chat-title.js.map +1 -1
- package/dist/app/chat/mcp-apps/McpAppRenderer.d.ts.map +1 -1
- package/dist/app/chat/mcp-apps/McpAppRenderer.js +3 -2
- package/dist/app/chat/mcp-apps/McpAppRenderer.js.map +1 -1
- package/dist/app/chat/session-replay-privacy.d.ts +7 -0
- package/dist/app/chat/session-replay-privacy.d.ts.map +1 -0
- package/dist/app/chat/session-replay-privacy.js +6 -0
- package/dist/app/chat/session-replay-privacy.js.map +1 -0
- package/dist/app/extensions/ExtensionViewer.d.ts +4 -1
- package/dist/app/extensions/ExtensionViewer.d.ts.map +1 -1
- package/dist/app/extensions/ExtensionViewer.js +3 -3
- package/dist/app/extensions/ExtensionViewer.js.map +1 -1
- package/dist/app/extensions/ExtensionViewerPage.d.ts +4 -1
- package/dist/app/extensions/ExtensionViewerPage.d.ts.map +1 -1
- package/dist/app/extensions/ExtensionViewerPage.js +2 -2
- package/dist/app/extensions/ExtensionViewerPage.js.map +1 -1
- package/dist/app/onboarding/FirstRunOnboarding.d.ts.map +1 -1
- package/dist/app/onboarding/FirstRunOnboarding.js +53 -12
- package/dist/app/onboarding/FirstRunOnboarding.js.map +1 -1
- package/dist/app/onboarding/OnboardingPanel.d.ts.map +1 -1
- package/dist/app/onboarding/OnboardingPanel.js +14 -4
- package/dist/app/onboarding/OnboardingPanel.js.map +1 -1
- package/dist/app/resources/ResourceEditor.d.ts +4 -1
- package/dist/app/resources/ResourceEditor.d.ts.map +1 -1
- package/dist/app/resources/ResourceEditor.js +18 -7
- package/dist/app/resources/ResourceEditor.js.map +1 -1
- package/dist/app/resources/ResourcesPanel.d.ts +4 -1
- package/dist/app/resources/ResourcesPanel.d.ts.map +1 -1
- package/dist/app/resources/ResourcesPanel.js +18 -18
- package/dist/app/resources/ResourcesPanel.js.map +1 -1
- package/dist/app/resources/custom-agent-model-options.d.ts +16 -0
- package/dist/app/resources/custom-agent-model-options.d.ts.map +1 -0
- package/dist/app/resources/custom-agent-model-options.js +53 -0
- package/dist/app/resources/custom-agent-model-options.js.map +1 -0
- package/dist/app/settings/SettingsPanel.d.ts.map +1 -1
- package/dist/app/settings/SettingsPanel.js +34 -3
- package/dist/app/settings/SettingsPanel.js.map +1 -1
- package/dist/app/settings/SettingsTabsPage.d.ts.map +1 -1
- package/dist/app/settings/SettingsTabsPage.js +2 -0
- package/dist/app/settings/SettingsTabsPage.js.map +1 -1
- package/dist/app/settings/api-keys/ApiKeyDialogs.d.ts.map +1 -1
- package/dist/app/settings/api-keys/ApiKeyDialogs.js +49 -9
- package/dist/app/settings/api-keys/ApiKeyDialogs.js.map +1 -1
- package/dist/app/settings/api-keys/ApiKeysSettingsPage.js +2 -1
- package/dist/app/settings/api-keys/ApiKeysSettingsPage.js.map +1 -1
- package/dist/app/settings/model/ModelSettingsPage.d.ts.map +1 -1
- package/dist/app/settings/model/ModelSettingsPage.js +43 -9
- package/dist/app/settings/model/ModelSettingsPage.js.map +1 -1
- package/dist/app/settings/model/ProviderDialog.d.ts +4 -0
- package/dist/app/settings/model/ProviderDialog.d.ts.map +1 -1
- package/dist/app/settings/model/ProviderDialog.js +107 -11
- package/dist/app/settings/model/ProviderDialog.js.map +1 -1
- package/dist/app/settings/useBuilderStatus.d.ts.map +1 -1
- package/dist/app/settings/useBuilderStatus.js +13 -10
- package/dist/app/settings/useBuilderStatus.js.map +1 -1
- package/dist/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/composer/TiptapComposer.js +51 -13
- package/dist/composer/TiptapComposer.js.map +1 -1
- package/package.json +4 -4
- package/src/app/agentkit/react/components.interaction.spec.tsx +229 -1
- package/src/app/agentkit/react/components.spec.tsx +42 -1
- package/src/app/agentkit/react/components.tsx +46 -12
- package/src/app/auth/AuthPage.tsx +13 -0
- package/src/app/chat/AgentKitAssistantChat.spec.tsx +116 -5
- package/src/app/chat/AgentKitAssistantChat.tsx +41 -20
- package/src/app/chat/AgentPanel.tsx +5 -1
- package/src/app/chat/MultiTabAssistantChat.spec.tsx +152 -7
- package/src/app/chat/MultiTabAssistantChat.tsx +71 -4
- package/src/app/chat/agentkit-chat/approval-card.spec.tsx +17 -0
- package/src/app/chat/agentkit-chat/approval-card.tsx +2 -0
- package/src/app/chat/chat/run-recovery.spec.tsx +354 -9
- package/src/app/chat/chat/run-recovery.tsx +178 -10
- package/src/app/chat/chat/tool-call-display.spec.tsx +77 -0
- package/src/app/chat/chat/tool-call-display.tsx +23 -6
- package/src/app/chat/chat-first/ChatFirstAgentActivityPanel.tsx +2 -1
- package/src/app/chat/conversation/AgentConversation.spec.tsx +190 -1
- package/src/app/chat/conversation/AgentConversation.tsx +32 -8
- package/src/app/chat/fallback-chat-title.spec.ts +44 -0
- package/src/app/chat/fallback-chat-title.ts +3 -4
- package/src/app/chat/mcp-apps/McpAppRenderer.spec.ts +24 -0
- package/src/app/chat/mcp-apps/McpAppRenderer.tsx +10 -2
- package/src/app/chat/session-replay-privacy.spec.ts +14 -0
- package/src/app/chat/session-replay-privacy.ts +5 -0
- package/src/app/extensions/ExtensionViewer.tsx +15 -3
- package/src/app/extensions/ExtensionViewerPage.tsx +7 -3
- package/src/app/onboarding/FirstRunOnboarding.spec.tsx +252 -2
- package/src/app/onboarding/FirstRunOnboarding.tsx +56 -9
- package/src/app/onboarding/OnboardingPanel.save-scope.spec.tsx +1 -0
- package/src/app/onboarding/OnboardingPanel.tsx +15 -3
- package/src/app/resources/ResourceEditor.spec.tsx +240 -5
- package/src/app/resources/ResourceEditor.tsx +57 -10
- package/src/app/resources/ResourcesPanel.spec.ts +86 -4
- package/src/app/resources/ResourcesPanel.tsx +49 -16
- package/src/app/resources/custom-agent-model-options.ts +92 -0
- package/src/app/settings/SettingsPanel.model-defaults.spec.tsx +26 -13
- package/src/app/settings/SettingsPanel.tsx +35 -3
- package/src/app/settings/SettingsTabsPage.spec.tsx +97 -0
- package/src/app/settings/SettingsTabsPage.tsx +2 -0
- package/src/app/settings/api-keys/ApiKeyDialogs.tsx +84 -22
- package/src/app/settings/api-keys/ApiKeysSettingsPage.spec.tsx +229 -1
- package/src/app/settings/api-keys/ApiKeysSettingsPage.tsx +3 -2
- package/src/app/settings/model/ModelSettingsPage.spec.tsx +99 -9
- package/src/app/settings/model/ModelSettingsPage.tsx +79 -11
- package/src/app/settings/model/ProviderDialog.spec.tsx +192 -1
- package/src/app/settings/model/ProviderDialog.tsx +225 -29
- package/src/app/settings/useBuilderStatus.spec.tsx +49 -0
- package/src/app/settings/useBuilderStatus.ts +16 -10
- package/src/composer/TiptapComposer.spec.ts +97 -2
- package/src/composer/TiptapComposer.tsx +67 -13
|
@@ -2,12 +2,43 @@
|
|
|
2
2
|
|
|
3
3
|
import React, { act } from "react";
|
|
4
4
|
import { createRoot, type Root } from "react-dom/client";
|
|
5
|
-
import { createMemoryRouter, RouterProvider } from "react-router";
|
|
5
|
+
import { createMemoryRouter, RouterProvider, useLocation } from "react-router";
|
|
6
6
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
7
7
|
|
|
8
8
|
const clipboardMock = vi.hoisted(() => ({
|
|
9
9
|
writeClipboardText: vi.fn(),
|
|
10
10
|
}));
|
|
11
|
+
const setupTelemetryMock = vi.hoisted(() => vi.fn());
|
|
12
|
+
const builderConnectMock = vi.hoisted(() => ({
|
|
13
|
+
onConnect: undefined as ((provisionAccount: boolean) => void) | undefined,
|
|
14
|
+
}));
|
|
15
|
+
|
|
16
|
+
function SetupTrackingFlowProbe() {
|
|
17
|
+
const { state } = useLocation();
|
|
18
|
+
const trackingFlow = (state as { providerSetupTrackingFlow?: string } | null)
|
|
19
|
+
?.providerSetupTrackingFlow;
|
|
20
|
+
return <div data-testid="setup-tracking-flow">{trackingFlow}</div>;
|
|
21
|
+
}
|
|
22
|
+
const builderFlowMock = vi.hoisted(() => ({
|
|
23
|
+
onConnected: undefined as
|
|
24
|
+
| ((state: { orgName: string | null }) => void | Promise<void>)
|
|
25
|
+
| undefined,
|
|
26
|
+
state: {
|
|
27
|
+
configured: false,
|
|
28
|
+
connecting: false,
|
|
29
|
+
error: null as string | null,
|
|
30
|
+
errorKind: null as "status-read" | "connection" | "launch" | null,
|
|
31
|
+
terminalError: null as string | null,
|
|
32
|
+
statusUnavailable: false,
|
|
33
|
+
statusReadSettledCount: 0,
|
|
34
|
+
hasFetchedStatus: true,
|
|
35
|
+
},
|
|
36
|
+
start: vi.fn(),
|
|
37
|
+
}));
|
|
38
|
+
|
|
39
|
+
vi.mock("@agent-native/core/client/onboarding/use-onboarding", () => ({
|
|
40
|
+
trackOnboardingEvent: setupTelemetryMock,
|
|
41
|
+
}));
|
|
11
42
|
|
|
12
43
|
const referralInfoQueryMock = vi.hoisted(() => ({ data: null as unknown }));
|
|
13
44
|
|
|
@@ -155,19 +186,26 @@ vi.mock("@agent-native/core/client/i18n", () => ({
|
|
|
155
186
|
vi.mock("../../settings/BuilderConnectPopover.js", () => {
|
|
156
187
|
deferredUiModuleLoads.builderConnectPopover = true;
|
|
157
188
|
return {
|
|
158
|
-
BuilderConnectPopover: ({
|
|
189
|
+
BuilderConnectPopover: ({
|
|
159
190
|
children,
|
|
191
|
+
onConnect,
|
|
192
|
+
}: {
|
|
193
|
+
children: React.ReactNode;
|
|
194
|
+
onConnect?: (provisionAccount: boolean) => void;
|
|
195
|
+
}) => {
|
|
196
|
+
builderConnectMock.onConnect = onConnect;
|
|
197
|
+
return children;
|
|
198
|
+
},
|
|
160
199
|
};
|
|
161
200
|
});
|
|
162
201
|
|
|
163
202
|
vi.mock("../../settings/useBuilderStatus.js", () => ({
|
|
164
|
-
useBuilderConnectFlow: (
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
}),
|
|
203
|
+
useBuilderConnectFlow: (options?: {
|
|
204
|
+
onConnected?: (state: { orgName: string | null }) => void | Promise<void>;
|
|
205
|
+
}) => {
|
|
206
|
+
builderFlowMock.onConnected = options?.onConnected;
|
|
207
|
+
return { ...builderFlowMock.state, start: builderFlowMock.start };
|
|
208
|
+
},
|
|
171
209
|
}));
|
|
172
210
|
|
|
173
211
|
import { AgentNativeI18nProvider } from "@agent-native/core/client/i18n";
|
|
@@ -189,6 +227,20 @@ describe("run recovery surfaces", () => {
|
|
|
189
227
|
document.body.appendChild(container);
|
|
190
228
|
root = createRoot(container);
|
|
191
229
|
clipboardMock.writeClipboardText.mockReset();
|
|
230
|
+
setupTelemetryMock.mockReset();
|
|
231
|
+
builderConnectMock.onConnect = undefined;
|
|
232
|
+
builderFlowMock.onConnected = undefined;
|
|
233
|
+
builderFlowMock.start.mockReset();
|
|
234
|
+
Object.assign(builderFlowMock.state, {
|
|
235
|
+
configured: false,
|
|
236
|
+
connecting: false,
|
|
237
|
+
error: null,
|
|
238
|
+
errorKind: null,
|
|
239
|
+
terminalError: null,
|
|
240
|
+
statusUnavailable: false,
|
|
241
|
+
statusReadSettledCount: 0,
|
|
242
|
+
hasFetchedStatus: true,
|
|
243
|
+
});
|
|
192
244
|
referralInfoQueryMock.data = null;
|
|
193
245
|
});
|
|
194
246
|
|
|
@@ -201,6 +253,50 @@ describe("run recovery surfaces", () => {
|
|
|
201
253
|
window.history.replaceState(null, "", "/");
|
|
202
254
|
});
|
|
203
255
|
|
|
256
|
+
it.each(["message", "details"] as const)(
|
|
257
|
+
"masks run failure %s without masking recovery controls",
|
|
258
|
+
async (field) => {
|
|
259
|
+
const info = {
|
|
260
|
+
message: "Example Person's example notes are locked.",
|
|
261
|
+
details: "Example Document cannot be opened for Example Person.",
|
|
262
|
+
runId: "run-example",
|
|
263
|
+
errorCode: "runtime_error",
|
|
264
|
+
};
|
|
265
|
+
await act(async () => {
|
|
266
|
+
root.render(
|
|
267
|
+
<RunErrorRecoveryCard
|
|
268
|
+
info={info}
|
|
269
|
+
onContinue={vi.fn()}
|
|
270
|
+
onRetry={vi.fn()}
|
|
271
|
+
onDismiss={vi.fn()}
|
|
272
|
+
/>,
|
|
273
|
+
);
|
|
274
|
+
});
|
|
275
|
+
if (field === "details") {
|
|
276
|
+
await act(async () => {
|
|
277
|
+
Array.from(container.querySelectorAll("button"))
|
|
278
|
+
.find((button) => button.textContent === "Details")!
|
|
279
|
+
.click();
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
const message = Array.from(
|
|
283
|
+
container.querySelectorAll(field === "message" ? "p" : "pre"),
|
|
284
|
+
).find((element) => element.textContent === info[field]);
|
|
285
|
+
expect(message?.hasAttribute("data-an-mask")).toBe(true);
|
|
286
|
+
expect(container.firstElementChild?.hasAttribute("data-an-mask")).toBe(
|
|
287
|
+
false,
|
|
288
|
+
);
|
|
289
|
+
expect(
|
|
290
|
+
container
|
|
291
|
+
.querySelector(".font-medium.text-foreground")
|
|
292
|
+
?.closest("[data-an-mask]"),
|
|
293
|
+
).toBeNull();
|
|
294
|
+
for (const button of container.querySelectorAll("button")) {
|
|
295
|
+
expect(button.closest("[data-an-mask]")).toBeNull();
|
|
296
|
+
}
|
|
297
|
+
},
|
|
298
|
+
);
|
|
299
|
+
|
|
204
300
|
it("offers the Builder subscription link for credit limits only", async () => {
|
|
205
301
|
await act(async () => {
|
|
206
302
|
root.render(
|
|
@@ -630,6 +726,215 @@ describe("run recovery surfaces", () => {
|
|
|
630
726
|
expect(container.textContent).not.toContain("Choose a provider");
|
|
631
727
|
});
|
|
632
728
|
|
|
729
|
+
it("tracks setup card exposure once and the Builder and custom key choices", async () => {
|
|
730
|
+
const renderCard = () => (
|
|
731
|
+
<AgentNativeI18nProvider
|
|
732
|
+
initialLocale="en-US"
|
|
733
|
+
initialPreference="en-US"
|
|
734
|
+
persistPreference={false}
|
|
735
|
+
>
|
|
736
|
+
<BuilderSetupCard />
|
|
737
|
+
</AgentNativeI18nProvider>
|
|
738
|
+
);
|
|
739
|
+
|
|
740
|
+
await act(async () => {
|
|
741
|
+
root.render(renderCard());
|
|
742
|
+
});
|
|
743
|
+
await act(async () => {
|
|
744
|
+
root.render(renderCard());
|
|
745
|
+
});
|
|
746
|
+
|
|
747
|
+
expect(setupTelemetryMock).toHaveBeenCalledTimes(1);
|
|
748
|
+
expect(setupTelemetryMock).toHaveBeenCalledWith(
|
|
749
|
+
"integration_setup_exposed",
|
|
750
|
+
expect.objectContaining({
|
|
751
|
+
flow: "chat_setup",
|
|
752
|
+
app_name: expect.any(String),
|
|
753
|
+
step_id: "connect_ai",
|
|
754
|
+
method_id: "setup_card",
|
|
755
|
+
action: "view",
|
|
756
|
+
outcome: "exposed",
|
|
757
|
+
}),
|
|
758
|
+
);
|
|
759
|
+
|
|
760
|
+
await act(async () => {
|
|
761
|
+
container
|
|
762
|
+
.querySelector<HTMLButtonElement>(
|
|
763
|
+
".agent-builder-setup-card__builder-button",
|
|
764
|
+
)
|
|
765
|
+
?.click();
|
|
766
|
+
container
|
|
767
|
+
.querySelector<HTMLAnchorElement>('a[href="/settings/keys"]')
|
|
768
|
+
?.click();
|
|
769
|
+
});
|
|
770
|
+
|
|
771
|
+
expect(setupTelemetryMock).toHaveBeenCalledWith(
|
|
772
|
+
"integration_method_clicked",
|
|
773
|
+
expect.objectContaining({
|
|
774
|
+
method_id: "builder",
|
|
775
|
+
action: "click",
|
|
776
|
+
outcome: "started",
|
|
777
|
+
}),
|
|
778
|
+
);
|
|
779
|
+
expect(setupTelemetryMock).toHaveBeenCalledWith(
|
|
780
|
+
"integration_method_clicked",
|
|
781
|
+
expect.objectContaining({
|
|
782
|
+
method_id: "custom_keys",
|
|
783
|
+
action: "click",
|
|
784
|
+
outcome: "started",
|
|
785
|
+
}),
|
|
786
|
+
);
|
|
787
|
+
});
|
|
788
|
+
|
|
789
|
+
it("tracks Builder success only after a selected setup attempt is confirmed", async () => {
|
|
790
|
+
const card = (
|
|
791
|
+
<AgentNativeI18nProvider
|
|
792
|
+
initialLocale="en-US"
|
|
793
|
+
initialPreference="en-US"
|
|
794
|
+
persistPreference={false}
|
|
795
|
+
>
|
|
796
|
+
<BuilderSetupCard />
|
|
797
|
+
</AgentNativeI18nProvider>
|
|
798
|
+
);
|
|
799
|
+
await act(async () => {
|
|
800
|
+
root.render(card);
|
|
801
|
+
});
|
|
802
|
+
expect(
|
|
803
|
+
setupTelemetryMock.mock.calls.some(
|
|
804
|
+
([name]) => name === "integration_method_outcome",
|
|
805
|
+
),
|
|
806
|
+
).toBe(false);
|
|
807
|
+
|
|
808
|
+
await act(async () => {
|
|
809
|
+
container
|
|
810
|
+
.querySelector<HTMLButtonElement>(
|
|
811
|
+
".agent-builder-setup-card__builder-button",
|
|
812
|
+
)
|
|
813
|
+
?.click();
|
|
814
|
+
});
|
|
815
|
+
await vi.waitFor(() =>
|
|
816
|
+
expect(builderConnectMock.onConnect).toBeTypeOf("function"),
|
|
817
|
+
);
|
|
818
|
+
await act(async () => builderConnectMock.onConnect?.(true));
|
|
819
|
+
expect(builderFlowMock.start).toHaveBeenCalledWith({
|
|
820
|
+
provisionAccount: true,
|
|
821
|
+
});
|
|
822
|
+
|
|
823
|
+
await act(async () => {
|
|
824
|
+
await builderFlowMock.onConnected?.({ orgName: null });
|
|
825
|
+
});
|
|
826
|
+
expect(setupTelemetryMock).toHaveBeenCalledWith(
|
|
827
|
+
"integration_method_outcome",
|
|
828
|
+
expect.objectContaining({
|
|
829
|
+
method_id: "builder",
|
|
830
|
+
action: "connect",
|
|
831
|
+
outcome: "connected",
|
|
832
|
+
}),
|
|
833
|
+
);
|
|
834
|
+
});
|
|
835
|
+
|
|
836
|
+
it("records bounded Builder failure outcomes after a setup attempt", async () => {
|
|
837
|
+
const renderCard = () => (
|
|
838
|
+
<AgentNativeI18nProvider
|
|
839
|
+
initialLocale="en-US"
|
|
840
|
+
initialPreference="en-US"
|
|
841
|
+
persistPreference={false}
|
|
842
|
+
>
|
|
843
|
+
<BuilderSetupCard />
|
|
844
|
+
</AgentNativeI18nProvider>
|
|
845
|
+
);
|
|
846
|
+
await act(async () => {
|
|
847
|
+
root.render(renderCard());
|
|
848
|
+
});
|
|
849
|
+
await act(async () => {
|
|
850
|
+
container
|
|
851
|
+
.querySelector<HTMLButtonElement>(
|
|
852
|
+
".agent-builder-setup-card__builder-button",
|
|
853
|
+
)
|
|
854
|
+
?.click();
|
|
855
|
+
});
|
|
856
|
+
await vi.waitFor(() =>
|
|
857
|
+
expect(builderConnectMock.onConnect).toBeTypeOf("function"),
|
|
858
|
+
);
|
|
859
|
+
await act(async () => builderConnectMock.onConnect?.(true));
|
|
860
|
+
|
|
861
|
+
builderFlowMock.state.statusUnavailable = true;
|
|
862
|
+
builderFlowMock.state.errorKind = "status-read";
|
|
863
|
+
builderFlowMock.state.error = "Builder status unavailable: private text";
|
|
864
|
+
await act(async () => {
|
|
865
|
+
root.render(renderCard());
|
|
866
|
+
});
|
|
867
|
+
expect(setupTelemetryMock).toHaveBeenCalledWith(
|
|
868
|
+
"integration_method_outcome",
|
|
869
|
+
expect.objectContaining({
|
|
870
|
+
method_id: "builder",
|
|
871
|
+
action: "connect",
|
|
872
|
+
outcome: "status_read_failed",
|
|
873
|
+
}),
|
|
874
|
+
);
|
|
875
|
+
|
|
876
|
+
setupTelemetryMock.mockClear();
|
|
877
|
+
builderFlowMock.state.statusUnavailable = false;
|
|
878
|
+
builderFlowMock.state.errorKind = null;
|
|
879
|
+
builderFlowMock.state.error = null;
|
|
880
|
+
builderFlowMock.state.terminalError = null;
|
|
881
|
+
await act(async () => {
|
|
882
|
+
root.render(renderCard());
|
|
883
|
+
});
|
|
884
|
+
await act(async () => {
|
|
885
|
+
container
|
|
886
|
+
.querySelector<HTMLButtonElement>(
|
|
887
|
+
".agent-builder-setup-card__builder-button",
|
|
888
|
+
)
|
|
889
|
+
?.click();
|
|
890
|
+
});
|
|
891
|
+
await vi.waitFor(() =>
|
|
892
|
+
expect(builderConnectMock.onConnect).toBeTypeOf("function"),
|
|
893
|
+
);
|
|
894
|
+
await act(async () => builderConnectMock.onConnect?.(true));
|
|
895
|
+
builderFlowMock.state.terminalError = "Private connection error text";
|
|
896
|
+
builderFlowMock.state.errorKind = "connection";
|
|
897
|
+
builderFlowMock.state.error = "Private connection error text";
|
|
898
|
+
await act(async () => {
|
|
899
|
+
root.render(renderCard());
|
|
900
|
+
});
|
|
901
|
+
expect(setupTelemetryMock).toHaveBeenCalledWith(
|
|
902
|
+
"integration_method_outcome",
|
|
903
|
+
expect.objectContaining({
|
|
904
|
+
method_id: "builder",
|
|
905
|
+
action: "connect",
|
|
906
|
+
outcome: "connection_failed",
|
|
907
|
+
}),
|
|
908
|
+
);
|
|
909
|
+
expect(JSON.stringify(setupTelemetryMock.mock.calls)).not.toContain(
|
|
910
|
+
"Private connection error text",
|
|
911
|
+
);
|
|
912
|
+
});
|
|
913
|
+
|
|
914
|
+
it("does not report a configured or preexisting Builder error as an outcome", async () => {
|
|
915
|
+
builderFlowMock.state.configured = true;
|
|
916
|
+
builderFlowMock.state.terminalError = "Preexisting connection error";
|
|
917
|
+
builderFlowMock.state.errorKind = "connection";
|
|
918
|
+
const card = (
|
|
919
|
+
<AgentNativeI18nProvider
|
|
920
|
+
initialLocale="en-US"
|
|
921
|
+
initialPreference="en-US"
|
|
922
|
+
persistPreference={false}
|
|
923
|
+
>
|
|
924
|
+
<BuilderSetupCard />
|
|
925
|
+
</AgentNativeI18nProvider>
|
|
926
|
+
);
|
|
927
|
+
await act(async () => {
|
|
928
|
+
root.render(card);
|
|
929
|
+
});
|
|
930
|
+
|
|
931
|
+
expect(
|
|
932
|
+
setupTelemetryMock.mock.calls.some(
|
|
933
|
+
([name]) => name === "integration_method_outcome",
|
|
934
|
+
),
|
|
935
|
+
).toBe(false);
|
|
936
|
+
});
|
|
937
|
+
|
|
633
938
|
it("keeps the Custom keys link within a mounted workspace app", async () => {
|
|
634
939
|
const router = createMemoryRouter(
|
|
635
940
|
[
|
|
@@ -660,6 +965,46 @@ describe("run recovery surfaces", () => {
|
|
|
660
965
|
expect(container.querySelector('input[type="password"]')).toBeNull();
|
|
661
966
|
});
|
|
662
967
|
|
|
968
|
+
it("passes chat setup attribution through the Custom keys link", async () => {
|
|
969
|
+
featureFlagMock.state = { status: "ready", enabled: false };
|
|
970
|
+
const router = createMemoryRouter(
|
|
971
|
+
[
|
|
972
|
+
{
|
|
973
|
+
path: "/ask",
|
|
974
|
+
element: (
|
|
975
|
+
<AgentNativeI18nProvider
|
|
976
|
+
initialLocale="en-US"
|
|
977
|
+
initialPreference="en-US"
|
|
978
|
+
persistPreference={false}
|
|
979
|
+
>
|
|
980
|
+
<BuilderSetupContent />
|
|
981
|
+
</AgentNativeI18nProvider>
|
|
982
|
+
),
|
|
983
|
+
},
|
|
984
|
+
{ path: "/settings/keys", element: <SetupTrackingFlowProbe /> },
|
|
985
|
+
],
|
|
986
|
+
{ initialEntries: ["/ask"] },
|
|
987
|
+
);
|
|
988
|
+
|
|
989
|
+
await act(async () => {
|
|
990
|
+
root.render(<RouterProvider router={router} />);
|
|
991
|
+
});
|
|
992
|
+
const customKeysLink = container.querySelector<HTMLAnchorElement>(
|
|
993
|
+
'a[href="/settings/keys"]',
|
|
994
|
+
);
|
|
995
|
+
expect(customKeysLink).not.toBeNull();
|
|
996
|
+
|
|
997
|
+
await act(async () => {
|
|
998
|
+
customKeysLink?.click();
|
|
999
|
+
await Promise.resolve();
|
|
1000
|
+
});
|
|
1001
|
+
|
|
1002
|
+
expect(
|
|
1003
|
+
container.querySelector('[data-testid="setup-tracking-flow"]')
|
|
1004
|
+
?.textContent,
|
|
1005
|
+
).toBe("chat_setup");
|
|
1006
|
+
});
|
|
1007
|
+
|
|
663
1008
|
it("links custom keys to the Model page with the settings redesign on", async () => {
|
|
664
1009
|
featureFlagMock.state = { status: "ready", enabled: true };
|
|
665
1010
|
try {
|