@agent-native/toolkit 0.216.0 → 0.218.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 +26 -0
- package/dist/app/agent-page/AgentContextTab.d.ts.map +1 -1
- package/dist/app/agent-page/AgentContextTab.js +1 -0
- package/dist/app/agent-page/AgentContextTab.js.map +1 -1
- package/dist/app/agentkit/react/components.d.ts.map +1 -1
- package/dist/app/agentkit/react/components.js +1 -1
- package/dist/app/agentkit/react/components.js.map +1 -1
- package/dist/app/agentkit/react/context.d.ts +4 -1
- package/dist/app/agentkit/react/context.d.ts.map +1 -1
- package/dist/app/agentkit/react/context.js +3 -1
- package/dist/app/agentkit/react/context.js.map +1 -1
- package/dist/app/agentkit/react/data-chart-layout.d.ts +30 -0
- package/dist/app/agentkit/react/data-chart-layout.d.ts.map +1 -0
- package/dist/app/agentkit/react/data-chart-layout.js +2 -0
- package/dist/app/agentkit/react/data-chart-layout.js.map +1 -0
- 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 +3 -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 +18 -0
- package/dist/app/agentkit/react/transcript-layout.d.ts +2 -0
- package/dist/app/agentkit/react/transcript-layout.d.ts.map +1 -1
- package/dist/app/agentkit/react/transcript-layout.js.map +1 -1
- 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 +2 -2
- package/dist/app/chat/AgentKitAssistantChat.js.map +1 -1
- package/dist/app/chat/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/app/chat/MultiTabAssistantChat.js +51 -93
- package/dist/app/chat/MultiTabAssistantChat.js.map +1 -1
- package/dist/app/chat/agentkit-chat/action-widget.d.ts.map +1 -1
- package/dist/app/chat/agentkit-chat/action-widget.js +3 -1
- package/dist/app/chat/agentkit-chat/action-widget.js.map +1 -1
- package/dist/app/chat/agentkit-chat/rail.d.ts +1 -1
- package/dist/app/chat/agentkit-chat/rail.d.ts.map +1 -1
- package/dist/app/chat/agentkit-chat/rail.js +1 -1
- package/dist/app/chat/agentkit-chat/rail.js.map +1 -1
- package/dist/app/chat/chat/index.d.ts +2 -1
- package/dist/app/chat/chat/index.d.ts.map +1 -1
- package/dist/app/chat/chat/index.js +1 -1
- package/dist/app/chat/chat/index.js.map +1 -1
- package/dist/app/chat/chat/surface-types.d.ts +3 -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 +3 -1
- package/dist/app/chat/chat/tool-call-display.d.ts.map +1 -1
- package/dist/app/chat/chat/tool-call-display.js +4 -3
- package/dist/app/chat/chat/tool-call-display.js.map +1 -1
- package/dist/app/chat/chat/tool-render-registry.d.ts +2 -0
- package/dist/app/chat/chat/tool-render-registry.d.ts.map +1 -1
- package/dist/app/chat/chat/tool-render-registry.js.map +1 -1
- package/dist/app/chat/chat/widgets/DataChartRenderer.d.ts +3 -1
- package/dist/app/chat/chat/widgets/DataChartRenderer.d.ts.map +1 -1
- package/dist/app/chat/chat/widgets/DataChartRenderer.js +116 -26
- package/dist/app/chat/chat/widgets/DataChartRenderer.js.map +1 -1
- package/dist/app/chat/chat/widgets/DataChartWidget.d.ts +3 -1
- package/dist/app/chat/chat/widgets/DataChartWidget.d.ts.map +1 -1
- package/dist/app/chat/chat/widgets/DataChartWidget.js +21 -2
- package/dist/app/chat/chat/widgets/DataChartWidget.js.map +1 -1
- package/dist/app/chat/chat/widgets/DataInsightsWidget.d.ts +3 -1
- package/dist/app/chat/chat/widgets/DataInsightsWidget.d.ts.map +1 -1
- package/dist/app/chat/chat/widgets/DataInsightsWidget.js +2 -2
- package/dist/app/chat/chat/widgets/DataInsightsWidget.js.map +1 -1
- package/dist/app/chat/chat/widgets/DataWidgetDisplayControls.d.ts +1 -1
- package/dist/app/chat/chat/widgets/DataWidgetDisplayControls.d.ts.map +1 -1
- package/dist/app/chat/chat/widgets/DataWidgetDisplayControls.js +3 -1
- package/dist/app/chat/chat/widgets/DataWidgetDisplayControls.js.map +1 -1
- package/dist/app/chat/chat/widgets/builtin-tool-renderers.d.ts.map +1 -1
- package/dist/app/chat/chat/widgets/builtin-tool-renderers.js +2 -2
- package/dist/app/chat/chat/widgets/builtin-tool-renderers.js.map +1 -1
- package/dist/app/chat/chat-first/chat-history.d.ts +13 -2
- package/dist/app/chat/chat-first/chat-history.d.ts.map +1 -1
- package/dist/app/chat/chat-first/chat-history.js +24 -3
- package/dist/app/chat/chat-first/chat-history.js.map +1 -1
- package/dist/app/chat/ownership-history/ChatOwnerAvatar.d.ts +6 -0
- package/dist/app/chat/ownership-history/ChatOwnerAvatar.d.ts.map +1 -0
- package/dist/app/chat/ownership-history/ChatOwnerAvatar.js +9 -0
- package/dist/app/chat/ownership-history/ChatOwnerAvatar.js.map +1 -0
- package/dist/app/chat/ownership-history/index.d.ts +11 -0
- package/dist/app/chat/ownership-history/index.d.ts.map +1 -0
- package/dist/app/chat/ownership-history/index.js +22 -0
- package/dist/app/chat/ownership-history/index.js.map +1 -0
- package/dist/app/chat/ownership-history/rows.d.ts +27 -0
- package/dist/app/chat/ownership-history/rows.d.ts.map +1 -0
- package/dist/app/chat/ownership-history/rows.js +101 -0
- package/dist/app/chat/ownership-history/rows.js.map +1 -0
- package/dist/app/chat/ownership-history/useOwnershipChatHistory.d.ts +52 -0
- package/dist/app/chat/ownership-history/useOwnershipChatHistory.d.ts.map +1 -0
- package/dist/app/chat/ownership-history/useOwnershipChatHistory.js +497 -0
- package/dist/app/chat/ownership-history/useOwnershipChatHistory.js.map +1 -0
- package/dist/app/i18n/catalogs/ar-SA.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/ar-SA.js +3 -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 +3 -0
- package/dist/app/i18n/catalogs/de-DE.js.map +1 -1
- package/dist/app/i18n/catalogs/en-US.d.ts +3 -0
- package/dist/app/i18n/catalogs/en-US.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/en-US.js +3 -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 +3 -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 +3 -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 +3 -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 +3 -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 +3 -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 +3 -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 +3 -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 +3 -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/app/sharing/ShareButton.d.ts.map +1 -1
- package/dist/app/sharing/ShareButton.js +9 -8
- package/dist/app/sharing/ShareButton.js.map +1 -1
- package/dist/chat-history/ChatHistoryList.d.ts +16 -3
- package/dist/chat-history/ChatHistoryList.d.ts.map +1 -1
- package/dist/chat-history/ChatHistoryList.js +25 -15
- package/dist/chat-history/ChatHistoryList.js.map +1 -1
- package/dist/chat-history.css +109 -9
- 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 +10 -3
- package/src/app/agent-page/AgentContextTab.spec.ts +50 -2
- package/src/app/agent-page/AgentContextTab.tsx +1 -0
- package/src/app/agentkit/react/components.interaction.spec.tsx +2 -0
- package/src/app/agentkit/react/components.spec.tsx +4 -1
- package/src/app/agentkit/react/components.tsx +3 -0
- package/src/app/agentkit/react/context.tsx +6 -0
- package/src/app/agentkit/react/data-chart-layout.ts +25 -0
- package/src/app/agentkit/react/index.ts +1 -0
- package/src/app/agentkit/react/root.tsx +4 -0
- package/src/app/agentkit/react/styles.css +18 -0
- package/src/app/agentkit/react/transcript-layout.ts +2 -0
- package/src/app/auth/AuthPage.interaction.spec.tsx +74 -0
- package/src/app/auth/AuthPage.tsx +32 -39
- package/src/app/chat/AgentKitAssistantChat.tsx +2 -0
- package/src/app/chat/MultiTabAssistantChat.spec.tsx +270 -3
- package/src/app/chat/MultiTabAssistantChat.tsx +79 -156
- package/src/app/chat/agentkit-chat/action-widget.tsx +3 -0
- package/src/app/chat/agentkit-chat/rail.ts +11 -0
- package/src/app/chat/chat/index.ts +10 -0
- package/src/app/chat/chat/surface-types.ts +3 -0
- package/src/app/chat/chat/tool-call-display.spec.tsx +29 -0
- package/src/app/chat/chat/tool-call-display.tsx +7 -0
- package/src/app/chat/chat/tool-render-registry.tsx +3 -0
- package/src/app/chat/chat/widgets/DataChartRenderer.spec.tsx +377 -17
- package/src/app/chat/chat/widgets/DataChartRenderer.tsx +232 -63
- package/src/app/chat/chat/widgets/DataChartWidget.spec.tsx +67 -0
- package/src/app/chat/chat/widgets/DataChartWidget.tsx +39 -5
- package/src/app/chat/chat/widgets/DataInsightsWidget.tsx +13 -2
- package/src/app/chat/chat/widgets/DataWidgetDisplayControls.tsx +6 -4
- package/src/app/chat/chat/widgets/builtin-tool-renderers.tsx +5 -1
- package/src/app/chat/chat-first/chat-history.spec.tsx +79 -0
- package/src/app/chat/chat-first/chat-history.tsx +75 -22
- package/src/app/chat/ownership-history/ChatOwnerAvatar.tsx +27 -0
- package/src/app/chat/ownership-history/index.tsx +67 -0
- package/src/app/chat/ownership-history/ownership-history.spec.tsx +3146 -0
- package/src/app/chat/ownership-history/rows.ts +156 -0
- package/src/app/chat/ownership-history/useOwnershipChatHistory.ts +709 -0
- package/src/app/i18n/catalogs/ar-SA.ts +3 -0
- package/src/app/i18n/catalogs/de-DE.ts +3 -0
- package/src/app/i18n/catalogs/en-US.ts +3 -0
- package/src/app/i18n/catalogs/es-ES.ts +3 -0
- package/src/app/i18n/catalogs/fr-FR.ts +3 -0
- package/src/app/i18n/catalogs/hi-IN.ts +3 -0
- package/src/app/i18n/catalogs/ja-JP.ts +3 -0
- package/src/app/i18n/catalogs/ko-KR.ts +3 -0
- package/src/app/i18n/catalogs/pt-BR.ts +3 -0
- package/src/app/i18n/catalogs/zh-CN.ts +3 -0
- package/src/app/i18n/catalogs/zh-TW.ts +3 -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/app/sharing/ShareButton.tsx +12 -10
- package/src/chat-history/ChatHistoryList.spec.tsx +51 -0
- package/src/chat-history/ChatHistoryList.tsx +87 -26
- package/src/chat-history/ChatHistoryRailSections.spec.tsx +12 -4
- package/src/chat-history.css +109 -9
- package/src/ui/sonner.spec.ts +10 -0
- package/src/ui/sonner.tsx +2 -2
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
captureAttribution,
|
|
5
|
+
getAnalyticsAnonymousId,
|
|
5
6
|
getAnalyticsSessionId,
|
|
6
7
|
} from "@agent-native/core/client/analytics";
|
|
7
8
|
import { frameworkRoutePrefix } from "@agent-native/core/client/api-path";
|
|
@@ -12,6 +13,7 @@ import {
|
|
|
12
13
|
normalizeOAuthReturnPath,
|
|
13
14
|
shouldRetryAuthSessionProbe,
|
|
14
15
|
} from "@agent-native/core/client/auth/auth-page-helpers";
|
|
16
|
+
import { whenConsentDecided } from "@agent-native/core/client/consent";
|
|
15
17
|
import { openOAuthPopup } from "@agent-native/core/client/oauth-popup";
|
|
16
18
|
import { navigateForSession } from "@agent-native/core/client/use-session";
|
|
17
19
|
import { normalizeLocaleCode } from "@agent-native/core/localization/shared";
|
|
@@ -65,7 +67,6 @@ type AuthRequestResult = {
|
|
|
65
67
|
const EMAIL_PATTERN = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
66
68
|
const TAB_STORAGE_KEY = "an.onboarding.tab";
|
|
67
69
|
const PENDING_SIGNUP_EMAIL_STORAGE_KEY = "an.onboarding.pendingSignupEmail";
|
|
68
|
-
const ANALYTICS_ANONYMOUS_ID_KEY = "agent-native.anonymous_id";
|
|
69
70
|
const GOOGLE_AUTH_URL_PATH = "/_agent-native/google/auth-url";
|
|
70
71
|
const BUILDER_DESKTOP_RETURN_ORIGIN = "http://127.0.0.1:8080";
|
|
71
72
|
const useIsomorphicLayoutEffect =
|
|
@@ -261,15 +262,6 @@ async function requestJson(
|
|
|
261
262
|
return { response, data, readable };
|
|
262
263
|
}
|
|
263
264
|
|
|
264
|
-
function generateAnonymousId(): string {
|
|
265
|
-
try {
|
|
266
|
-
if (typeof crypto.randomUUID === "function") return crypto.randomUUID();
|
|
267
|
-
} catch {
|
|
268
|
-
// coercion-ok: the browser fallback remains usable when crypto is unavailable.
|
|
269
|
-
}
|
|
270
|
-
return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
|
|
271
|
-
}
|
|
272
|
-
|
|
273
265
|
function trackAuth(
|
|
274
266
|
app: string,
|
|
275
267
|
name: string,
|
|
@@ -298,9 +290,8 @@ function trackAuth(
|
|
|
298
290
|
}
|
|
299
291
|
).__AGENT_NATIVE_CONFIG__;
|
|
300
292
|
if (!config?.agentNativeAnalyticsPublicKey) return;
|
|
301
|
-
const anonymousId = readStorage(ANALYTICS_ANONYMOUS_ID_KEY);
|
|
302
|
-
if (!anonymousId) return;
|
|
303
293
|
const sessionId = getAnalyticsSessionId();
|
|
294
|
+
const timestamp = new Date().toISOString();
|
|
304
295
|
const endpoint = resolveLaneEndpoint(
|
|
305
296
|
config.agentNativeAnalyticsEndpoint ??
|
|
306
297
|
"https://analytics.agent-native.com/track",
|
|
@@ -313,23 +304,33 @@ function trackAuth(
|
|
|
313
304
|
}> = [{ name, properties: legacyProperties }];
|
|
314
305
|
const canonical = canonicalTrackingEvent(name, legacyProperties);
|
|
315
306
|
if (canonical) events.push(canonical);
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
307
|
+
const publicKey = config.agentNativeAnalyticsPublicKey;
|
|
308
|
+
// The visitor id waits for analytics consent, as in the app bundle.
|
|
309
|
+
whenConsentDecided((decided) => {
|
|
310
|
+
const anonymousId = decided ? getAnalyticsAnonymousId() : undefined;
|
|
311
|
+
for (const event of events) {
|
|
312
|
+
const body = JSON.stringify({
|
|
313
|
+
publicKey,
|
|
314
|
+
event: event.name,
|
|
315
|
+
properties: anonymousId
|
|
316
|
+
? event.properties
|
|
317
|
+
: {
|
|
318
|
+
...event.properties,
|
|
319
|
+
analytics_consent: decided ? "withheld" : "unknown",
|
|
320
|
+
},
|
|
321
|
+
anonymousId,
|
|
322
|
+
sessionId,
|
|
323
|
+
timestamp,
|
|
324
|
+
});
|
|
325
|
+
if (navigator.sendBeacon?.(endpoint, body)) continue;
|
|
326
|
+
void fetch(endpoint, {
|
|
327
|
+
method: "POST",
|
|
328
|
+
body,
|
|
329
|
+
keepalive: true,
|
|
330
|
+
headers: { "Content-Type": "text/plain;charset=UTF-8" },
|
|
331
|
+
}).catch(() => undefined);
|
|
332
|
+
}
|
|
333
|
+
});
|
|
333
334
|
} catch {
|
|
334
335
|
// coercion-ok: analytics is best effort and cannot block authentication.
|
|
335
336
|
}
|
|
@@ -1036,16 +1037,8 @@ export function AuthPage(props: AuthPageProps) {
|
|
|
1036
1037
|
}, [apiPath, redirectToSignedInApp, runtimeBasePathResolved, view]);
|
|
1037
1038
|
|
|
1038
1039
|
React.useEffect(() => {
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
anonymousId = generateAnonymousId();
|
|
1042
|
-
writeStorage(ANALYTICS_ANONYMOUS_ID_KEY, anonymousId);
|
|
1043
|
-
}
|
|
1044
|
-
try {
|
|
1045
|
-
document.cookie = `an_aid=${encodeURIComponent(anonymousId)}; path=/; max-age=2592000; SameSite=Lax`;
|
|
1046
|
-
} catch {
|
|
1047
|
-
// coercion-ok: attribution cookies are optional for authentication.
|
|
1048
|
-
}
|
|
1040
|
+
// Stores `an_aid` only with analytics consent, and asks for the region.
|
|
1041
|
+
getAnalyticsAnonymousId();
|
|
1049
1042
|
// Capture is once per page load, so it must wait for a workspace's
|
|
1050
1043
|
// inferred base path or `landing_path` falls back to the wrong home.
|
|
1051
1044
|
if (runtimeBasePathResolved) {
|
|
@@ -2108,6 +2108,7 @@ export const AgentKitAssistantChat = forwardRef<
|
|
|
2108
2108
|
loadRunUsage={loadRunUsage}
|
|
2109
2109
|
buildFeedbackReport={formatFeedbackReport}
|
|
2110
2110
|
workedForRowLayout={props.workedForRowLayout}
|
|
2111
|
+
dataChartLayout={props.dataChartLayout}
|
|
2111
2112
|
formatWorkedForDuration={props.formatWorkedForDuration}
|
|
2112
2113
|
onThreadForked={(thread) => props.onForkedThread?.(thread.id)}
|
|
2113
2114
|
onCopyMessage={({ text }) => {
|
|
@@ -6474,6 +6475,7 @@ function AgentKitTool({ value, active }: AgentKitRenderProps<AgentToolCall>) {
|
|
|
6474
6475
|
activity={metadata.activity === true}
|
|
6475
6476
|
isActiveTail={active === true}
|
|
6476
6477
|
workedForRowLayout={surface.props.workedForRowLayout}
|
|
6478
|
+
dataChartLayout={surface.props.dataChartLayout}
|
|
6477
6479
|
formatWorkedForDuration={surface.props.formatWorkedForDuration}
|
|
6478
6480
|
/>
|
|
6479
6481
|
</SuppressInlineOpenAppContext.Provider>
|
|
@@ -34,6 +34,7 @@ import React, { act } from "react";
|
|
|
34
34
|
import { flushSync } from "react-dom";
|
|
35
35
|
import { createRoot, type Root } from "react-dom/client";
|
|
36
36
|
import { MemoryRouter } from "react-router";
|
|
37
|
+
import { toast } from "sonner";
|
|
37
38
|
import {
|
|
38
39
|
afterEach,
|
|
39
40
|
beforeEach,
|
|
@@ -7874,6 +7875,8 @@ describe("MultiTabAssistantChat page overlay", () => {
|
|
|
7874
7875
|
describe("MultiTabAssistantChat history popover", () => {
|
|
7875
7876
|
let container: HTMLDivElement;
|
|
7876
7877
|
let root: Root;
|
|
7878
|
+
let sharedHistoryRows: ChatThreadSummary[];
|
|
7879
|
+
let mineHistoryRows: ChatThreadSummary[] | undefined;
|
|
7877
7880
|
|
|
7878
7881
|
beforeEach(() => {
|
|
7879
7882
|
vi.stubGlobal("IS_REACT_ACT_ENVIRONMENT", true);
|
|
@@ -7882,6 +7885,8 @@ describe("MultiTabAssistantChat history popover", () => {
|
|
|
7882
7885
|
return 0;
|
|
7883
7886
|
});
|
|
7884
7887
|
resetThreadMocks();
|
|
7888
|
+
sharedHistoryRows = [];
|
|
7889
|
+
mineHistoryRows = undefined;
|
|
7885
7890
|
const now = Date.now();
|
|
7886
7891
|
threadMocks.activeThreadId = "thread-1";
|
|
7887
7892
|
const historyThreads: ChatThreadSummary[] = [
|
|
@@ -7917,7 +7922,32 @@ describe("MultiTabAssistantChat history popover", () => {
|
|
|
7917
7922
|
threadMocks.threads = historyThreads;
|
|
7918
7923
|
vi.stubGlobal(
|
|
7919
7924
|
"fetch",
|
|
7920
|
-
vi.fn(async () =>
|
|
7925
|
+
vi.fn(async (input: RequestInfo | URL) => {
|
|
7926
|
+
const url = new URL(String(input), "http://test.local");
|
|
7927
|
+
const ownership = url.searchParams.get("ownership");
|
|
7928
|
+
if (ownership) {
|
|
7929
|
+
const source =
|
|
7930
|
+
ownership === "mine"
|
|
7931
|
+
? (mineHistoryRows ?? threadMocks.threads).map((thread) => ({
|
|
7932
|
+
...thread,
|
|
7933
|
+
ownerEmail: "me@example.com",
|
|
7934
|
+
accessBasis: "owner",
|
|
7935
|
+
visibility: "private",
|
|
7936
|
+
}))
|
|
7937
|
+
: sharedHistoryRows;
|
|
7938
|
+
const query = url.searchParams.get("q") ?? "";
|
|
7939
|
+
const matching = source.filter((row) =>
|
|
7940
|
+
row.title.toLowerCase().includes(query.toLowerCase()),
|
|
7941
|
+
);
|
|
7942
|
+
const offset = Number(url.searchParams.get("offset") ?? 0);
|
|
7943
|
+
const limit = Number(url.searchParams.get("limit") ?? 50);
|
|
7944
|
+
return Response.json({
|
|
7945
|
+
threads: matching.slice(offset, offset + limit),
|
|
7946
|
+
hasMore: matching.length > offset + limit,
|
|
7947
|
+
});
|
|
7948
|
+
}
|
|
7949
|
+
return Response.json({ value: null });
|
|
7950
|
+
}),
|
|
7921
7951
|
);
|
|
7922
7952
|
window.localStorage.clear();
|
|
7923
7953
|
window.localStorage.setItem(
|
|
@@ -7947,7 +7977,7 @@ describe("MultiTabAssistantChat history popover", () => {
|
|
|
7947
7977
|
'button[aria-label="All chats"]',
|
|
7948
7978
|
);
|
|
7949
7979
|
expect(historyButton).not.toBeNull();
|
|
7950
|
-
act(() => {
|
|
7980
|
+
await act(async () => {
|
|
7951
7981
|
historyButton!.click();
|
|
7952
7982
|
});
|
|
7953
7983
|
}
|
|
@@ -7965,13 +7995,224 @@ describe("MultiTabAssistantChat history popover", () => {
|
|
|
7965
7995
|
});
|
|
7966
7996
|
}
|
|
7967
7997
|
|
|
7998
|
+
it.each(["local", "owner"] as const)(
|
|
7999
|
+
"keeps the active proven-%s empty chat before persistence and hides inactive blanks",
|
|
8000
|
+
async (proof) => {
|
|
8001
|
+
mineHistoryRows = [];
|
|
8002
|
+
threadMocks.isNewThread.mockImplementation(() => proof === "local");
|
|
8003
|
+
threadMocks.threads = threadMocks.threads.slice(0, 2).map((thread) => ({
|
|
8004
|
+
...thread,
|
|
8005
|
+
messageCount: 0,
|
|
8006
|
+
...(proof === "owner"
|
|
8007
|
+
? {
|
|
8008
|
+
accessBasis: "owner" as const,
|
|
8009
|
+
ownerEmail: "me@example.com",
|
|
8010
|
+
visibility: "private" as const,
|
|
8011
|
+
}
|
|
8012
|
+
: {}),
|
|
8013
|
+
}));
|
|
8014
|
+
await openHistory();
|
|
8015
|
+
|
|
8016
|
+
const mine = container.querySelector(
|
|
8017
|
+
'.an-chat-history__section[data-section-id="mine"]',
|
|
8018
|
+
)!;
|
|
8019
|
+
expect(
|
|
8020
|
+
Array.from(mine.querySelectorAll(".an-chat-history-row__title")).map(
|
|
8021
|
+
(element) => element.textContent,
|
|
8022
|
+
),
|
|
8023
|
+
).toEqual(["Active chat"]);
|
|
8024
|
+
expect(mine.querySelector(".an-chat-history-row--active")).not.toBeNull();
|
|
8025
|
+
expect(
|
|
8026
|
+
mine.querySelector(".an-chat-history-row__timestamp")?.textContent,
|
|
8027
|
+
).toBe("Active");
|
|
8028
|
+
expect(threadMocks.saveThreadData).not.toHaveBeenCalled();
|
|
8029
|
+
},
|
|
8030
|
+
);
|
|
8031
|
+
|
|
8032
|
+
it.each([false, true])(
|
|
8033
|
+
"never recasts an active shared empty chat as Mine (server row loaded: %s)",
|
|
8034
|
+
async (loaded) => {
|
|
8035
|
+
mineHistoryRows = [];
|
|
8036
|
+
threadMocks.isNewThread.mockReturnValue(true);
|
|
8037
|
+
const shared: ChatThreadSummary = {
|
|
8038
|
+
...threadMocks.threads[0],
|
|
8039
|
+
messageCount: 0,
|
|
8040
|
+
accessBasis: "direct",
|
|
8041
|
+
ownerEmail: "pat@example.com",
|
|
8042
|
+
visibility: "private",
|
|
8043
|
+
};
|
|
8044
|
+
threadMocks.threads = [shared];
|
|
8045
|
+
sharedHistoryRows = loaded ? [shared] : [];
|
|
8046
|
+
await openHistory();
|
|
8047
|
+
|
|
8048
|
+
expect(
|
|
8049
|
+
container.querySelector(
|
|
8050
|
+
'.an-chat-history__section[data-section-id="mine"] .an-chat-history-row',
|
|
8051
|
+
),
|
|
8052
|
+
).toBeNull();
|
|
8053
|
+
const sharedSection = container.querySelector(
|
|
8054
|
+
'.an-chat-history__section[data-section-id="shared"]',
|
|
8055
|
+
);
|
|
8056
|
+
expect(
|
|
8057
|
+
sharedSection?.querySelectorAll(".an-chat-history-row").length ?? 0,
|
|
8058
|
+
).toBe(loaded ? 1 : 0);
|
|
8059
|
+
const trigger =
|
|
8060
|
+
sharedSection?.querySelector<HTMLButtonElement>(
|
|
8061
|
+
".an-chat-history-row__menu-trigger",
|
|
8062
|
+
) ?? null;
|
|
8063
|
+
if (!loaded) {
|
|
8064
|
+
expect(trigger).toBeNull();
|
|
8065
|
+
return;
|
|
8066
|
+
}
|
|
8067
|
+
await openRowMenu(trigger!);
|
|
8068
|
+
expect(
|
|
8069
|
+
Array.from(
|
|
8070
|
+
document.body.querySelectorAll(".an-chat-history-row__menu-item"),
|
|
8071
|
+
(element) => element.textContent,
|
|
8072
|
+
),
|
|
8073
|
+
).toEqual(["Copy link"]);
|
|
8074
|
+
},
|
|
8075
|
+
);
|
|
8076
|
+
|
|
8077
|
+
it("loads both ownership lists only while open and debounces search to both", async () => {
|
|
8078
|
+
await act(async () => {
|
|
8079
|
+
root.render(<MultiTabAssistantChat storageKey="history-test" />);
|
|
8080
|
+
});
|
|
8081
|
+
const fetchMock = vi.mocked(fetch);
|
|
8082
|
+
const ownershipRequests = () =>
|
|
8083
|
+
fetchMock.mock.calls
|
|
8084
|
+
.map(([input]) => new URL(String(input), "http://test.local"))
|
|
8085
|
+
.filter((url) => url.searchParams.has("ownership"));
|
|
8086
|
+
expect(ownershipRequests()).toHaveLength(0);
|
|
8087
|
+
await openHistory();
|
|
8088
|
+
expect(
|
|
8089
|
+
ownershipRequests().map((url) => url.searchParams.get("ownership")),
|
|
8090
|
+
).toEqual(["mine", "shared"]);
|
|
8091
|
+
vi.useFakeTimers();
|
|
8092
|
+
try {
|
|
8093
|
+
const input = container.querySelector<HTMLInputElement>(
|
|
8094
|
+
".an-chat-history__search-input",
|
|
8095
|
+
)!;
|
|
8096
|
+
act(() => {
|
|
8097
|
+
Object.getOwnPropertyDescriptor(
|
|
8098
|
+
window.HTMLInputElement.prototype,
|
|
8099
|
+
"value",
|
|
8100
|
+
)!.set!.call(input, "Other");
|
|
8101
|
+
input.dispatchEvent(new Event("input", { bubbles: true }));
|
|
8102
|
+
});
|
|
8103
|
+
expect(ownershipRequests()).toHaveLength(2);
|
|
8104
|
+
await act(async () => {
|
|
8105
|
+
await vi.advanceTimersByTimeAsync(250);
|
|
8106
|
+
});
|
|
8107
|
+
expect(
|
|
8108
|
+
ownershipRequests()
|
|
8109
|
+
.slice(-2)
|
|
8110
|
+
.map((url) => [
|
|
8111
|
+
url.searchParams.get("ownership"),
|
|
8112
|
+
url.searchParams.get("q"),
|
|
8113
|
+
]),
|
|
8114
|
+
).toEqual([
|
|
8115
|
+
["mine", "Other"],
|
|
8116
|
+
["shared", "Other"],
|
|
8117
|
+
]);
|
|
8118
|
+
expect(threadMocks.searchThreads).not.toHaveBeenCalled();
|
|
8119
|
+
} finally {
|
|
8120
|
+
vi.useRealTimers();
|
|
8121
|
+
}
|
|
8122
|
+
});
|
|
8123
|
+
|
|
8124
|
+
it("previews five shared rows without owner pins or actions and switches through history", async () => {
|
|
8125
|
+
sharedHistoryRows = Array.from({ length: 51 }, (_, index) => ({
|
|
8126
|
+
id: `shared-${index}`,
|
|
8127
|
+
title: `Shared ${index}`,
|
|
8128
|
+
preview: "",
|
|
8129
|
+
messageCount: 1,
|
|
8130
|
+
createdAt: 1,
|
|
8131
|
+
updatedAt: 1,
|
|
8132
|
+
scope: null,
|
|
8133
|
+
accessBasis: index === 0 ? "organization" : "direct",
|
|
8134
|
+
ownerEmail: "pat@example.com",
|
|
8135
|
+
visibility: "org",
|
|
8136
|
+
pinnedAt: 10,
|
|
8137
|
+
}));
|
|
8138
|
+
await openHistory();
|
|
8139
|
+
const sharedSection = container.querySelector(
|
|
8140
|
+
'.an-chat-history__section[data-section-id="shared"]',
|
|
8141
|
+
)!;
|
|
8142
|
+
expect(sharedSection.querySelectorAll(".an-chat-history-row")).toHaveLength(
|
|
8143
|
+
5,
|
|
8144
|
+
);
|
|
8145
|
+
expect(sharedSection.textContent).toContain("pat@example.com");
|
|
8146
|
+
expect(sharedSection.textContent).toContain(
|
|
8147
|
+
"Shared with your organization",
|
|
8148
|
+
);
|
|
8149
|
+
await openRowMenu(
|
|
8150
|
+
sharedSection.querySelector<HTMLButtonElement>(
|
|
8151
|
+
".an-chat-history-row__menu-trigger",
|
|
8152
|
+
)!,
|
|
8153
|
+
);
|
|
8154
|
+
expect(
|
|
8155
|
+
Array.from(
|
|
8156
|
+
document.body.querySelectorAll(".an-chat-history-row__menu-item"),
|
|
8157
|
+
(element) => element.textContent,
|
|
8158
|
+
),
|
|
8159
|
+
).toEqual(["Copy link"]);
|
|
8160
|
+
await act(async () => {
|
|
8161
|
+
document.dispatchEvent(
|
|
8162
|
+
new KeyboardEvent("keydown", { key: "Escape", bubbles: true }),
|
|
8163
|
+
);
|
|
8164
|
+
});
|
|
8165
|
+
expect(
|
|
8166
|
+
sharedSection.querySelector(".an-chat-history-row--pinned"),
|
|
8167
|
+
).toBeNull();
|
|
8168
|
+
expect(container.querySelector(".an-chat-history-rail__footer")).toBeNull();
|
|
8169
|
+
await act(async () => {
|
|
8170
|
+
sharedSection
|
|
8171
|
+
.querySelector<HTMLButtonElement>(
|
|
8172
|
+
".an-chat-history-rail__section-toggle",
|
|
8173
|
+
)!
|
|
8174
|
+
.click();
|
|
8175
|
+
});
|
|
8176
|
+
expect(sharedSection.querySelectorAll(".an-chat-history-row")).toHaveLength(
|
|
8177
|
+
50,
|
|
8178
|
+
);
|
|
8179
|
+
await act(async () => {
|
|
8180
|
+
sharedSection
|
|
8181
|
+
.querySelector<HTMLButtonElement>(".an-chat-history-rail__load-more")!
|
|
8182
|
+
.click();
|
|
8183
|
+
});
|
|
8184
|
+
expect(sharedSection.querySelectorAll(".an-chat-history-row")).toHaveLength(
|
|
8185
|
+
51,
|
|
8186
|
+
);
|
|
8187
|
+
await act(async () => {
|
|
8188
|
+
sharedSection
|
|
8189
|
+
.querySelector<HTMLButtonElement>(
|
|
8190
|
+
".an-chat-history-rail__section-toggle",
|
|
8191
|
+
)!
|
|
8192
|
+
.click();
|
|
8193
|
+
});
|
|
8194
|
+
expect(sharedSection.querySelectorAll(".an-chat-history-row")).toHaveLength(
|
|
8195
|
+
5,
|
|
8196
|
+
);
|
|
8197
|
+
await act(async () => {
|
|
8198
|
+
sharedSection
|
|
8199
|
+
.querySelector<HTMLButtonElement>(".an-chat-history-row__button")!
|
|
8200
|
+
.click();
|
|
8201
|
+
});
|
|
8202
|
+
expect(threadMocks.switchThread).toHaveBeenCalledWith("shared-0");
|
|
8203
|
+
expect(container.querySelector(".an-chat-history")).toBeNull();
|
|
8204
|
+
expect(
|
|
8205
|
+
chatThreadHookMocks.useChatThreads.mock.calls.at(-1)?.[3]?.ownership,
|
|
8206
|
+
).toBeUndefined();
|
|
8207
|
+
});
|
|
8208
|
+
|
|
7968
8209
|
it("groups pinned threads into a dedicated section, sorted ahead of the rest", async () => {
|
|
7969
8210
|
await openHistory();
|
|
7970
8211
|
|
|
7971
8212
|
const labels = Array.from(
|
|
7972
8213
|
container.querySelectorAll(".an-chat-history__section-label"),
|
|
7973
8214
|
).map((el) => el.textContent);
|
|
7974
|
-
expect(labels).toEqual(["Pinned"]);
|
|
8215
|
+
expect(labels).toEqual(["Pinned", "My chats"]);
|
|
7975
8216
|
|
|
7976
8217
|
const titles = Array.from(
|
|
7977
8218
|
container.querySelectorAll(".an-chat-history-row__title"),
|
|
@@ -8055,6 +8296,32 @@ describe("MultiTabAssistantChat history popover", () => {
|
|
|
8055
8296
|
expect(threadMocks.pinThread).toHaveBeenCalledWith("thread-3", true);
|
|
8056
8297
|
});
|
|
8057
8298
|
|
|
8299
|
+
it("shows the localized save failure when a history pin fails", async () => {
|
|
8300
|
+
const toastError = vi
|
|
8301
|
+
.spyOn(toast, "error")
|
|
8302
|
+
.mockReturnValue("failure-toast");
|
|
8303
|
+
threadMocks.pinThread.mockResolvedValue(false);
|
|
8304
|
+
try {
|
|
8305
|
+
await openHistory();
|
|
8306
|
+
const row = container.querySelectorAll(".an-chat-history-row")[2];
|
|
8307
|
+
await openRowMenu(
|
|
8308
|
+
row.querySelector<HTMLButtonElement>(
|
|
8309
|
+
".an-chat-history-row__menu-trigger",
|
|
8310
|
+
)!,
|
|
8311
|
+
);
|
|
8312
|
+
const pinItem = Array.from(
|
|
8313
|
+
document.body.querySelectorAll<HTMLButtonElement>(
|
|
8314
|
+
".an-chat-history-row__menu-item",
|
|
8315
|
+
),
|
|
8316
|
+
).find((element) => element.textContent?.includes("Pin to top"))!;
|
|
8317
|
+
await act(async () => pinItem.click());
|
|
8318
|
+
expect(threadMocks.pinThread).toHaveBeenCalledWith("thread-3", true);
|
|
8319
|
+
expect(toastError).toHaveBeenCalledExactlyOnceWith("Save failed");
|
|
8320
|
+
} finally {
|
|
8321
|
+
toastError.mockRestore();
|
|
8322
|
+
}
|
|
8323
|
+
});
|
|
8324
|
+
|
|
8058
8325
|
it("unpins an already-pinned thread via the row action menu", async () => {
|
|
8059
8326
|
await openHistory();
|
|
8060
8327
|
|