@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.
Files changed (144) hide show
  1. package/dist/app/agentkit/react/components.d.ts +4 -1
  2. package/dist/app/agentkit/react/components.d.ts.map +1 -1
  3. package/dist/app/agentkit/react/components.js +12 -4
  4. package/dist/app/agentkit/react/components.js.map +1 -1
  5. package/dist/app/chat/AgentKitAssistantChat.d.ts.map +1 -1
  6. package/dist/app/chat/AgentKitAssistantChat.js +43 -21
  7. package/dist/app/chat/AgentKitAssistantChat.js.map +1 -1
  8. package/dist/app/chat/AgentSidebar.d.ts.map +1 -1
  9. package/dist/app/chat/AgentSidebar.js +2 -0
  10. package/dist/app/chat/AgentSidebar.js.map +1 -1
  11. package/dist/app/chat/FileStorageSetupPopover.js +2 -2
  12. package/dist/app/chat/FileStorageSetupPopover.js.map +1 -1
  13. package/dist/app/chat/MultiTabAssistantChat.js +1 -1
  14. package/dist/app/chat/agentkit-chat/connections.d.ts +1 -4
  15. package/dist/app/chat/agentkit-chat/connections.d.ts.map +1 -1
  16. package/dist/app/chat/agentkit-chat/connections.js +1 -26
  17. package/dist/app/chat/agentkit-chat/connections.js.map +1 -1
  18. package/dist/app/chat/agentkit-chat/history.d.ts +4 -1
  19. package/dist/app/chat/agentkit-chat/history.d.ts.map +1 -1
  20. package/dist/app/chat/agentkit-chat/history.js +17 -5
  21. package/dist/app/chat/agentkit-chat/history.js.map +1 -1
  22. package/dist/app/chat/chat/history-types.d.ts +1 -1
  23. package/dist/app/chat/chat/history-types.d.ts.map +1 -1
  24. package/dist/app/chat/chat-first/copy.d.ts +1 -2
  25. package/dist/app/chat/chat-first/copy.d.ts.map +1 -1
  26. package/dist/app/chat/chat-first/copy.js +1 -121
  27. package/dist/app/chat/chat-first/copy.js.map +1 -1
  28. package/dist/app/chat/chat-first-copy.d.ts +3 -0
  29. package/dist/app/chat/chat-first-copy.d.ts.map +1 -0
  30. package/dist/app/chat/chat-first-copy.js +122 -0
  31. package/dist/app/chat/chat-first-copy.js.map +1 -0
  32. package/dist/app/feature-flags/FeatureFlagsPanel.d.ts.map +1 -1
  33. package/dist/app/feature-flags/FeatureFlagsPanel.js +1 -0
  34. package/dist/app/feature-flags/FeatureFlagsPanel.js.map +1 -1
  35. package/dist/app/i18n/catalogs/ar-SA.d.ts.map +1 -1
  36. package/dist/app/i18n/catalogs/ar-SA.js +2 -1
  37. package/dist/app/i18n/catalogs/ar-SA.js.map +1 -1
  38. package/dist/app/i18n/catalogs/de-DE.d.ts.map +1 -1
  39. package/dist/app/i18n/catalogs/de-DE.js +2 -1
  40. package/dist/app/i18n/catalogs/de-DE.js.map +1 -1
  41. package/dist/app/i18n/catalogs/en-US.d.ts +2 -1
  42. package/dist/app/i18n/catalogs/en-US.d.ts.map +1 -1
  43. package/dist/app/i18n/catalogs/en-US.js +2 -1
  44. package/dist/app/i18n/catalogs/en-US.js.map +1 -1
  45. package/dist/app/i18n/catalogs/es-ES.d.ts.map +1 -1
  46. package/dist/app/i18n/catalogs/es-ES.js +2 -1
  47. package/dist/app/i18n/catalogs/es-ES.js.map +1 -1
  48. package/dist/app/i18n/catalogs/fr-FR.d.ts.map +1 -1
  49. package/dist/app/i18n/catalogs/fr-FR.js +2 -1
  50. package/dist/app/i18n/catalogs/fr-FR.js.map +1 -1
  51. package/dist/app/i18n/catalogs/hi-IN.d.ts.map +1 -1
  52. package/dist/app/i18n/catalogs/hi-IN.js +2 -1
  53. package/dist/app/i18n/catalogs/hi-IN.js.map +1 -1
  54. package/dist/app/i18n/catalogs/ja-JP.d.ts.map +1 -1
  55. package/dist/app/i18n/catalogs/ja-JP.js +2 -1
  56. package/dist/app/i18n/catalogs/ja-JP.js.map +1 -1
  57. package/dist/app/i18n/catalogs/ko-KR.d.ts.map +1 -1
  58. package/dist/app/i18n/catalogs/ko-KR.js +2 -1
  59. package/dist/app/i18n/catalogs/ko-KR.js.map +1 -1
  60. package/dist/app/i18n/catalogs/pt-BR.d.ts.map +1 -1
  61. package/dist/app/i18n/catalogs/pt-BR.js +2 -1
  62. package/dist/app/i18n/catalogs/pt-BR.js.map +1 -1
  63. package/dist/app/i18n/catalogs/zh-CN.d.ts.map +1 -1
  64. package/dist/app/i18n/catalogs/zh-CN.js +2 -1
  65. package/dist/app/i18n/catalogs/zh-CN.js.map +1 -1
  66. package/dist/app/i18n/catalogs/zh-TW.d.ts.map +1 -1
  67. package/dist/app/i18n/catalogs/zh-TW.js +2 -1
  68. package/dist/app/i18n/catalogs/zh-TW.js.map +1 -1
  69. package/dist/app/labs/LabsSettings.d.ts.map +1 -1
  70. package/dist/app/labs/LabsSettings.js +7 -3
  71. package/dist/app/labs/LabsSettings.js.map +1 -1
  72. package/dist/app/org/OrgGeneralSection.d.ts.map +1 -1
  73. package/dist/app/org/OrgGeneralSection.js +21 -18
  74. package/dist/app/org/OrgGeneralSection.js.map +1 -1
  75. package/dist/app/org/OrgSwitcher.d.ts.map +1 -1
  76. package/dist/app/org/OrgSwitcher.js +3 -2
  77. package/dist/app/org/OrgSwitcher.js.map +1 -1
  78. package/dist/app/org/workspace-app-links.d.ts +1 -0
  79. package/dist/app/org/workspace-app-links.d.ts.map +1 -1
  80. package/dist/app/org/workspace-app-links.js +3 -0
  81. package/dist/app/org/workspace-app-links.js.map +1 -1
  82. package/dist/app/resources/McpAgentKitConnectionRequest.d.ts +7 -2
  83. package/dist/app/resources/McpAgentKitConnectionRequest.d.ts.map +1 -1
  84. package/dist/app/resources/McpAgentKitConnectionRequest.js +132 -13
  85. package/dist/app/resources/McpAgentKitConnectionRequest.js.map +1 -1
  86. package/dist/icons/ResourceIconPicker.d.ts +6 -1
  87. package/dist/icons/ResourceIconPicker.d.ts.map +1 -1
  88. package/dist/icons/ResourceIconPicker.js +45 -6
  89. package/dist/icons/ResourceIconPicker.js.map +1 -1
  90. package/package.json +6 -4
  91. package/src/app/agentkit/react/components.spec.tsx +3 -3
  92. package/src/app/agentkit/react/components.tsx +22 -4
  93. package/src/app/agentkit/react/lifecycle.spec.tsx +42 -0
  94. package/src/app/chat/AgentKitAssistantChat.spec.tsx +114 -11
  95. package/src/app/chat/AgentKitAssistantChat.tsx +78 -17
  96. package/src/app/chat/AgentPanel.header.spec.ts +59 -22
  97. package/src/app/chat/AgentSidebar.tsx +2 -0
  98. package/src/app/chat/FileStorageSetupPopover.tsx +2 -2
  99. package/src/app/chat/MultiTabAssistantChat.messageCount.spec.tsx +3 -1
  100. package/src/app/chat/MultiTabAssistantChat.spec.tsx +8 -4
  101. package/src/app/chat/MultiTabAssistantChat.tsx +1 -1
  102. package/src/app/chat/agentkit-chat/action-widget.spec.tsx +5 -17
  103. package/src/app/chat/agentkit-chat/connections.spec.tsx +137 -0
  104. package/src/app/chat/agentkit-chat/connections.ts +2 -37
  105. package/src/app/chat/agentkit-chat/history.tsx +23 -8
  106. package/src/app/chat/chat/history-types.ts +1 -1
  107. package/src/app/chat/chat/tool-call-display.spec.tsx +2 -2
  108. package/src/app/chat/chat/widgets/record-change-widget.spec.tsx +20 -29
  109. package/src/app/chat/chat-first/copy.ts +1 -133
  110. package/src/app/chat/chat-first-copy.ts +133 -0
  111. package/src/app/chat/composer/use-agentkit-capabilities.hardening.spec.tsx +3 -2
  112. package/src/app/feature-flags/FeatureFlagsPanel.tsx +1 -0
  113. package/src/app/i18n/catalogs/ar-SA.ts +2 -1
  114. package/src/app/i18n/catalogs/de-DE.ts +3 -1
  115. package/src/app/i18n/catalogs/en-US.ts +2 -1
  116. package/src/app/i18n/catalogs/es-ES.ts +2 -1
  117. package/src/app/i18n/catalogs/fr-FR.ts +3 -1
  118. package/src/app/i18n/catalogs/hi-IN.ts +2 -1
  119. package/src/app/i18n/catalogs/ja-JP.ts +2 -1
  120. package/src/app/i18n/catalogs/ko-KR.ts +2 -1
  121. package/src/app/i18n/catalogs/pt-BR.ts +3 -1
  122. package/src/app/i18n/catalogs/zh-CN.ts +2 -1
  123. package/src/app/i18n/catalogs/zh-TW.ts +2 -1
  124. package/src/app/integrations/IntegrationDetailPage.spec.tsx +1 -1
  125. package/src/app/labs/LabsSettings.tsx +46 -10
  126. package/src/app/observability/ThumbsFeedback.spec.tsx +15 -0
  127. package/src/app/onboarding/FirstRunOnboarding.spec.tsx +4 -0
  128. package/src/app/org/OrgGeneralSection.tsx +32 -22
  129. package/src/app/org/OrgSwitcher.tsx +3 -2
  130. package/src/app/org/workspace-app-links.spec.ts +4 -0
  131. package/src/app/org/workspace-app-links.ts +8 -1
  132. package/src/app/resources/McpAgentKitConnectionRequest.spec.tsx +371 -2
  133. package/src/app/resources/McpAgentKitConnectionRequest.tsx +171 -11
  134. package/src/app/settings/SettingsTabsPage.spec.tsx +4 -2
  135. package/src/app/settings/shell/SettingsShell.spec.tsx +14 -8
  136. package/src/app/settings/shell/pages/app-group-pages.spec.tsx +35 -5
  137. package/src/app/settings/shell/pages/resource-pages.spec.tsx +3 -0
  138. package/src/app/settings/usage/UsagePage.spec.tsx +3 -3
  139. package/src/app/shared/lazy-chunk-error-boundary.spec.tsx +2 -0
  140. package/src/app-shell/sidebar-overflow.spec.tsx +4 -1
  141. package/src/design-tweaks/visual-style-controls.spec.tsx +38 -0
  142. package/src/editor/useCollabReconcile.concurrent.spec.ts +2 -1
  143. package/src/icons/ResourceIconPicker.spec.tsx +270 -0
  144. package/src/icons/ResourceIconPicker.tsx +72 -4
@@ -0,0 +1,133 @@
1
+ import type { ChatFirstSurfaceKind } from "@agent-native/core/client/agent-chat";
2
+
3
+ import type { ChatFirstCopy } from "./chat-first/types.js";
4
+
5
+ const DEFAULT_COPY: Record<string, string> = {
6
+ newChat: "New chat",
7
+ search: "Search",
8
+ workspaceApps: "Apps",
9
+ allApps: "All apps",
10
+ integrations: "Integrations",
11
+ scheduled: "Scheduled",
12
+ createWorkspaceApp: "Create app",
13
+ openApp: "Open {name}",
14
+ appsLoadError: "Apps could not be loaded",
15
+ noWorkspaceApps: "No apps yet",
16
+ createApp: "Create app",
17
+ retry: "Retry",
18
+ dismiss: "Dismiss",
19
+ unpinApp: "Unpin this app",
20
+ pinApp: "Pin this app",
21
+ reloadApp: "Reload app",
22
+ removePinned: "Remove from pinned apps",
23
+ pinTop: "Pin app to the top",
24
+ moveUp: "Move up",
25
+ moveDown: "Move down",
26
+ removeApp: "Remove app from workspace",
27
+ showMore: "Show more",
28
+ showLess: "Show less",
29
+ appOrderUnavailable: "App order could not be saved on this device.",
30
+ openSideSurfaces: "Open side surfaces",
31
+ sideSurfaces: "Side surfaces",
32
+ resizeSideSurface: "Resize side surface",
33
+ closeTab: "Close {name}",
34
+ close: "Close",
35
+ closeOthers: "Close others",
36
+ closeToRight: "Close to the right",
37
+ closeAll: "Close all",
38
+ deferred: "Deferred",
39
+ openActivity: "Open activity",
40
+ unavailable: "This surface is not available here.",
41
+ browserBack: "Back",
42
+ browserForward: "Forward",
43
+ browserReload: "Reload page",
44
+ browserAddress: "Browser address",
45
+ browserOpenExternal: "Open in external browser",
46
+ browserClose: "Close browser",
47
+ browserPage: "Browser page",
48
+ browserInvalidUrl: "Enter a full http(s) URL to navigate.",
49
+ browserPreviewStarting: "Starting preview…",
50
+ browserPreviewError: "Preview unavailable",
51
+ appUnavailable: "This workspace app is no longer available.",
52
+ appLoadError: "This app could not be loaded",
53
+ appLoading: "Loading app",
54
+ agentActivityEyebrow: "Workspace",
55
+ agentActivityTitle: "Agent activity",
56
+ agentActivityDescription:
57
+ "Follow runs and open a second session beside this chat.",
58
+ refreshAgentActivity: "Refresh agent activity",
59
+ noAgentSessions: "No agent sessions yet",
60
+ startAgentSession: "Start an agent run and it will appear here.",
61
+ watchSession: "Watch",
62
+ copySessionId: "Copy session ID",
63
+ copySessionIdFor: "Copy session ID for {name}",
64
+ sessionIdCopied: "Session ID copied",
65
+ sessionIdShort: "ID",
66
+ copied: "Copied",
67
+ agentActivityStatusQueued: "Queued",
68
+ agentActivityStatusRunning: "Running",
69
+ agentActivityStatusPaused: "Paused",
70
+ agentActivityStatusNeedsApproval: "Needs approval",
71
+ agentActivityStatusCompleted: "Completed",
72
+ agentActivityStatusErrored: "Needs attention",
73
+ agentActivityStatusRecent: "Recent",
74
+ agentActivityStatusUnknown: "Unknown",
75
+ watchingSession: "Watching {name}",
76
+ session: "session",
77
+ stopWatchingSession: "Stop watching session",
78
+ stopWatching: "Stop watching",
79
+ watchedSession: "Watched session",
80
+ agentsTitle: "Subagents",
81
+ };
82
+
83
+ const SURFACE_COPY: Record<
84
+ ChatFirstSurfaceKind,
85
+ { label: string; reason: string }
86
+ > = {
87
+ app: {
88
+ label: "App",
89
+ reason: "Open a workspace app beside the conversation.",
90
+ },
91
+ browser: {
92
+ label: "Browser",
93
+ reason: "Ask the agent to open a web URL.",
94
+ },
95
+ terminal: {
96
+ label: "Terminal",
97
+ reason:
98
+ "Deferred: an embedded PTY lifecycle is not connected in this release.",
99
+ },
100
+ files: {
101
+ label: "Files",
102
+ reason:
103
+ "Deferred: a bounded workspace tree is not connected in this release.",
104
+ },
105
+ diff: {
106
+ label: "Diff",
107
+ reason: "Deferred: changed-file data is not connected in this release.",
108
+ },
109
+ "side-chat": {
110
+ label: "Side chat",
111
+ reason: "Choose Watch and message from any chat row.",
112
+ },
113
+ agents: {
114
+ label: "Agents",
115
+ reason: "Review recent runs or watch one beside this conversation.",
116
+ },
117
+ };
118
+
119
+ function interpolate(value: string, values?: Record<string, string>): string {
120
+ if (!values) return value;
121
+ return value.replace(/\{(\w+)\}/g, (_, key: string) => values[key] ?? "");
122
+ }
123
+
124
+ export const defaultChatFirstCopy: ChatFirstCopy = (key, values) => {
125
+ if (key.startsWith("surface.")) {
126
+ const [, kind, field] = key.split(".");
127
+ const surface = SURFACE_COPY[kind as ChatFirstSurfaceKind];
128
+ if (surface && (field === "label" || field === "reason")) {
129
+ return surface[field];
130
+ }
131
+ }
132
+ return interpolate(DEFAULT_COPY[key] ?? key, values);
133
+ };
@@ -132,8 +132,9 @@ describe("AgentKit capability lifecycle", () => {
132
132
  await settle();
133
133
  expect(result.data).toBeUndefined();
134
134
  next.resolve(empty);
135
- await settle();
136
- expect(result.data).toEqual(empty);
135
+ await act(async () => {
136
+ await vi.waitFor(() => expect(result.data).toEqual(empty));
137
+ });
137
138
  },
138
139
  );
139
140
 
@@ -473,6 +473,7 @@ export function FeatureFlagsEditor({
473
473
  const sortedFlags = useMemo(
474
474
  () =>
475
475
  flags
476
+ .filter((flag) => flag.canManage !== false)
476
477
  .map((flag) => ({
477
478
  ...flag,
478
479
  rules: normalizeFeatureFlagRules(flag.rules),
@@ -789,7 +789,7 @@ const messages: ToolkitAgentChatTranslation = {
789
789
  "mcpIntegrations.catalog.gong.useCase":
790
790
  "مكالمات المبيعات، والنصوص المفرّغة، ورؤى الصفقات، وملخصات الحسابات",
791
791
  "mcpIntegrations.catalog.gong.setupNote":
792
- "يتطلب Gong أن ينشئ مسؤول تقني تكامل MCP ويختار تفويضًا شخصيًا أو مشتركًا. يجب إعداد معرّف العميل والسر الناتجين قبل الربط.",
792
+ "يجب أن ينشئ المسؤول التقني في Gong تكامل MCP مع تفويض شخصي أو مشترك. للتسجيل اليدوي، احفظ معرّف العميل والسر الناتجين كسرّي مساحة العمل `GONG_MCP_CLIENT_ID` و`GONG_MCP_CLIENT_SECRET`؛ أما التسجيل التلقائي فلا يحتاج إلى بيانات اعتماد للعميل.",
793
793
  "mcpIntegrations.catalog.semgrep.description":
794
794
  "فحص التعليمات البرمجية بحثًا عن مشكلات أمنية.",
795
795
  "mcpIntegrations.catalog.semgrep.useCase":
@@ -1007,6 +1007,7 @@ const messages: ToolkitAgentChatTranslation = {
1007
1007
  "message.revertQuestion":
1008
1008
  "هل تريد الرجوع إلى هذه النقطة؟ ستفقد التغييرات التي أُجريت بعدها.",
1009
1009
  "message.restoreRequestFailed": "فشل طلب الاستعادة.",
1010
+ "message.historyUnavailable": "تعذر تحميل سجل التغييرات.",
1010
1011
  "message.threadNotFound":
1011
1012
  "لم تعد سلسلة الدردشة هذه متاحة. ابدأ دردشة جديدة أو أعد المحاولة إذا كان ذلك غير متوقع.",
1012
1013
  "message.restoring": "جارٍ الاستعادة...",
@@ -544,7 +544,7 @@ const messages: ToolkitAgentChatTranslation = {
544
544
  "mcpIntegrations.catalog.gong.useCase":
545
545
  "Verkaufsgespräche, Transkripte, Deal-Erkenntnisse, Account-Zusammenfassungen",
546
546
  "mcpIntegrations.catalog.gong.setupNote":
547
- "In Gong muss ein technischer Admin eine MCP-Integration erstellen und persönliche oder geteilte Autorisierung wählen. Die generierte Client-ID und das Secret müssen vor dem Verbinden konfiguriert werden.",
547
+ "Ein technischer Gong-Admin muss eine MCP-Integration mit persönlicher oder geteilter Autorisierung erstellen. Bei manueller Registrierung speicherst du die generierte Client-ID und das Secret als Workspace-Secrets `GONG_MCP_CLIENT_ID` und `GONG_MCP_CLIENT_SECRET`; die automatische Registrierung benötigt keine Client-Zugangsdaten.",
548
548
  "mcpIntegrations.catalog.semgrep.description":
549
549
  "Code auf Sicherheitsbefunde scannen.",
550
550
  "mcpIntegrations.catalog.semgrep.useCase":
@@ -756,6 +756,8 @@ const messages: ToolkitAgentChatTranslation = {
756
756
  "message.revertQuestion":
757
757
  "Zu diesem Punkt zurückkehren? Änderungen danach gehen verloren.",
758
758
  "message.restoreRequestFailed": "Wiederherstellungsanfrage fehlgeschlagen.",
759
+ "message.historyUnavailable":
760
+ "Der Änderungsverlauf konnte nicht geladen werden.",
759
761
  "message.threadNotFound":
760
762
  "Dieser Chat-Thread ist nicht mehr verfügbar. Starte einen neuen Chat oder versuche es erneut, falls das unerwartet war.",
761
763
  "message.restoring": "Wird wiederhergestellt...",
@@ -785,7 +785,7 @@ const messages = {
785
785
  "mcpIntegrations.catalog.gong.useCase":
786
786
  "Sales calls, transcripts, deal insights, account summaries",
787
787
  "mcpIntegrations.catalog.gong.setupNote":
788
- "Gong requires a tech admin to create an MCP integration and choose personal or shared authorization. The generated client ID and secret must be configured before connecting.",
788
+ "A Gong tech admin must create an MCP integration with personal or shared authorization. For Manual registration, save the generated client ID and secret as workspace secrets `GONG_MCP_CLIENT_ID` and `GONG_MCP_CLIENT_SECRET`; Automatic registration needs no client credentials.",
789
789
  "mcpIntegrations.catalog.semgrep.description":
790
790
  "Scan code for security findings.",
791
791
  "mcpIntegrations.catalog.semgrep.useCase":
@@ -997,6 +997,7 @@ const messages = {
997
997
  "message.revertQuestion":
998
998
  "Revert to this point? Changes made after this point will be lost.",
999
999
  "message.restoreRequestFailed": "Restore request failed.",
1000
+ "message.historyUnavailable": "Could not load change history.",
1000
1001
  "message.threadNotFound":
1001
1002
  "This chat thread is no longer available. Start a new chat or retry if this was unexpected.",
1002
1003
  "message.restoring": "Restoring...",
@@ -542,7 +542,7 @@ const messages: ToolkitAgentChatTranslation = {
542
542
  "mcpIntegrations.catalog.gong.useCase":
543
543
  "Llamadas de ventas, transcripciones, información sobre oportunidades, resúmenes de cuentas",
544
544
  "mcpIntegrations.catalog.gong.setupNote":
545
- "Gong requiere que un administrador técnico cree una integración MCP y elija una autorización personal o compartida. El ID de cliente y el secreto generados deben configurarse antes de conectar.",
545
+ "Un administrador técnico de Gong debe crear una integración MCP con autorización personal o compartida. Para el registro Manual, guarda el ID y el secreto de cliente generados como secretos del espacio de trabajo `GONG_MCP_CLIENT_ID` y `GONG_MCP_CLIENT_SECRET`; el registro Automático no requiere credenciales de cliente.",
546
546
  "mcpIntegrations.catalog.semgrep.description":
547
547
  "Analiza el código en busca de problemas de seguridad.",
548
548
  "mcpIntegrations.catalog.semgrep.useCase":
@@ -754,6 +754,7 @@ const messages: ToolkitAgentChatTranslation = {
754
754
  "message.revertQuestion":
755
755
  "¿Volver a este punto? Se perderán los cambios posteriores.",
756
756
  "message.restoreRequestFailed": "Error en la solicitud de restauración.",
757
+ "message.historyUnavailable": "No se pudo cargar el historial de cambios.",
757
758
  "message.threadNotFound":
758
759
  "Este hilo de chat ya no está disponible. Inicia un chat nuevo o inténtalo de nuevo si esto no era esperado.",
759
760
  "message.restoring": "Restaurando...",
@@ -549,7 +549,7 @@ const messages: ToolkitAgentChatTranslation = {
549
549
  "mcpIntegrations.catalog.gong.useCase":
550
550
  "Appels commerciaux, transcriptions, insights sur les opportunités, résumés de comptes",
551
551
  "mcpIntegrations.catalog.gong.setupNote":
552
- "Gong exige qu’un administrateur technique crée une intégration MCP et choisisse une autorisation personnelle ou partagée. L’ID client et le secret générés doivent être configurés avant la connexion.",
552
+ "Un administrateur technique Gong doit créer une intégration MCP avec une autorisation personnelle ou partagée. Pour l’inscription manuelle, enregistrez l’ID client et le secret générés dans les secrets de l’espace de travail `GONG_MCP_CLIENT_ID` et `GONG_MCP_CLIENT_SECRET` ; l’inscription automatique ne nécessite pas d’identifiants client.",
553
553
  "mcpIntegrations.catalog.semgrep.description":
554
554
  "Analysez le code pour détecter des problèmes de sécurité.",
555
555
  "mcpIntegrations.catalog.semgrep.useCase":
@@ -760,6 +760,8 @@ const messages: ToolkitAgentChatTranslation = {
760
760
  "message.revertQuestion":
761
761
  "Revenir à ce point ? Les modifications ultérieures seront perdues.",
762
762
  "message.restoreRequestFailed": "Échec de la demande de restauration.",
763
+ "message.historyUnavailable":
764
+ "Impossible de charger l’historique des modifications.",
763
765
  "message.threadNotFound":
764
766
  "Ce fil de discussion n’est plus disponible. Démarrez une nouvelle discussion ou réessayez si cela est inattendu.",
765
767
  "message.restoring": "Restauration...",
@@ -775,7 +775,7 @@ const messages: ToolkitAgentChatTranslation = {
775
775
  "mcpIntegrations.catalog.gong.useCase":
776
776
  "सेल्स कॉल, ट्रांसक्रिप्ट, डील इनसाइट, खाते का सारांश",
777
777
  "mcpIntegrations.catalog.gong.setupNote":
778
- "Gong में एक टेक एडमिन को MCP इंटीग्रेशन बनाना होगा और व्यक्तिगत या साझा ऑथराइज़ेशन चुनना होगा। कनेक्ट करने से पहले जनरेट किए गए क्लाइंट ID और सीक्रेट को कॉन्फ़िगर करना ज़रूरी है।",
778
+ "Gong के टेक एडमिन को व्यक्तिगत या साझा ऑथराइज़ेशन वाला MCP इंटीग्रेशन बनाना होगा। मैन्युअल रजिस्ट्रेशन के लिए जनरेट किया गया क्लाइंट ID और सीक्रेट वर्कस्पेस सीक्रेट `GONG_MCP_CLIENT_ID` और `GONG_MCP_CLIENT_SECRET` के रूप में सेव करें; ऑटोमैटिक रजिस्ट्रेशन के लिए क्लाइंट क्रेडेंशियल की ज़रूरत नहीं है।",
779
779
  "mcpIntegrations.catalog.semgrep.description":
780
780
  "सुरक्षा से जुड़ी समस्याओं के लिए कोड स्कैन करें।",
781
781
  "mcpIntegrations.catalog.semgrep.useCase":
@@ -980,6 +980,7 @@ const messages: ToolkitAgentChatTranslation = {
980
980
  "message.restoreQuestion": "यहाँ तक पुनर्स्थापित करें?",
981
981
  "message.revertQuestion": "इस बिंदु पर वापस जाएँ? इसके बाद किए गए बदलाव खो जाएँगे।",
982
982
  "message.restoreRequestFailed": "पुनर्स्थापना अनुरोध विफल रहा।",
983
+ "message.historyUnavailable": "बदलावों का इतिहास लोड नहीं हो सका।",
983
984
  "message.threadNotFound":
984
985
  "यह चैट थ्रेड अब उपलब्ध नहीं है। नई चैट शुरू करें या यदि यह अप्रत्याशित है तो फिर कोशिश करें।",
985
986
  "message.restoring": "पुनर्स्थापित किया जा रहा है...",
@@ -804,7 +804,7 @@ const messages: ToolkitAgentChatTranslation = {
804
804
  "mcpIntegrations.catalog.gong.useCase":
805
805
  "営業通話、文字起こし、商談のインサイト、アカウントの概要",
806
806
  "mcpIntegrations.catalog.gong.setupNote":
807
- "Gong では、技術管理者が MCP 連携を作成し、個人または共有の認証を選択する必要があります。接続する前に、生成されたクライアント ID とシークレットを設定してください。",
807
+ "Gong の技術管理者が、個人または共有の認証を選んで MCP 連携を作成する必要があります。手動登録では、生成されたクライアント ID とシークレットをワークスペースのシークレット `GONG_MCP_CLIENT_ID` と `GONG_MCP_CLIENT_SECRET` として保存してください。自動登録ではクライアント認証情報は不要です。",
808
808
  "mcpIntegrations.catalog.semgrep.description":
809
809
  "コードをスキャンしてセキュリティ上の問題を検出します。",
810
810
  "mcpIntegrations.catalog.semgrep.useCase":
@@ -1013,6 +1013,7 @@ const messages: ToolkitAgentChatTranslation = {
1013
1013
  "message.restoreQuestion": "ここまで復元しますか?",
1014
1014
  "message.revertQuestion": "この時点に戻しますか?この後の変更は失われます。",
1015
1015
  "message.restoreRequestFailed": "復元リクエストに失敗しました。",
1016
+ "message.historyUnavailable": "変更履歴を読み込めませんでした。",
1016
1017
  "message.threadNotFound":
1017
1018
  "このチャットスレッドは利用できなくなりました。新しいチャットを開始するか、想定外の場合は再試行してください。",
1018
1019
  "message.restoring": "復元中...",
@@ -781,7 +781,7 @@ const messages: ToolkitAgentChatTranslation = {
781
781
  "mcpIntegrations.catalog.gong.useCase":
782
782
  "영업 통화, 스크립트, 거래 인사이트, 계정 요약",
783
783
  "mcpIntegrations.catalog.gong.setupNote":
784
- "Gong에서는 기술 관리자가 MCP 연동을 만들고 개인 또는 공유 승인 방식을 선택해야 합니다. 연결하기 전에 생성된 클라이언트 ID와 시크릿을 구성해야 합니다.",
784
+ "Gong 기술 관리자가 개인 또는 공유 승인을 선택해 MCP 연동을 만들어야 합니다. 수동 등록에서는 생성된 클라이언트 ID와 시크릿을 워크스페이스 시크릿 `GONG_MCP_CLIENT_ID` 및 `GONG_MCP_CLIENT_SECRET`으로 저장하세요. 자동 등록에는 클라이언트 인증 정보가 필요하지 않습니다.",
785
785
  "mcpIntegrations.catalog.semgrep.description":
786
786
  "코드에서 보안 문제를 스캔합니다.",
787
787
  "mcpIntegrations.catalog.semgrep.useCase":
@@ -991,6 +991,7 @@ const messages: ToolkitAgentChatTranslation = {
991
991
  "message.revertQuestion":
992
992
  "이 지점으로 되돌릴까요? 이후 변경 사항은 사라집니다.",
993
993
  "message.restoreRequestFailed": "복원 요청에 실패했습니다.",
994
+ "message.historyUnavailable": "변경 기록을 불러올 수 없습니다.",
994
995
  "message.threadNotFound":
995
996
  "이 채팅 스레드는 더 이상 사용할 수 없습니다. 새 채팅을 시작하거나 예상치 못한 문제라면 다시 시도하세요.",
996
997
  "message.restoring": "복원 중...",
@@ -537,7 +537,7 @@ const messages: ToolkitAgentChatTranslation = {
537
537
  "mcpIntegrations.catalog.gong.useCase":
538
538
  "Chamadas de vendas, transcrições, insights de negócios, resumos de contas",
539
539
  "mcpIntegrations.catalog.gong.setupNote":
540
- "O Gong exige que um administrador técnico crie uma integração MCP e escolha a autorização pessoal ou compartilhada. O ID e o segredo do cliente gerados precisam ser configurados antes de conectar.",
540
+ "Um administrador técnico do Gong precisa criar uma integração MCP com autorização pessoal ou compartilhada. No registro Manual, salve o ID e o segredo do cliente gerados como segredos do espaço de trabalho `GONG_MCP_CLIENT_ID` e `GONG_MCP_CLIENT_SECRET`; o registro Automático não precisa de credenciais de cliente.",
541
541
  "mcpIntegrations.catalog.semgrep.description":
542
542
  "Analise o código em busca de problemas de segurança.",
543
543
  "mcpIntegrations.catalog.semgrep.useCase":
@@ -747,6 +747,8 @@ const messages: ToolkitAgentChatTranslation = {
747
747
  "message.revertQuestion":
748
748
  "Reverter para este ponto? As alterações feitas depois serão perdidas.",
749
749
  "message.restoreRequestFailed": "Falha na solicitação de restauração.",
750
+ "message.historyUnavailable":
751
+ "Não foi possível carregar o histórico de alterações.",
750
752
  "message.threadNotFound":
751
753
  "Esta conversa não está mais disponível. Inicie uma nova conversa ou tente novamente se isso for inesperado.",
752
754
  "message.restoring": "Restaurando...",
@@ -744,7 +744,7 @@ const messages: ToolkitAgentChatTranslation = {
744
744
  "mcpIntegrations.catalog.gong.useCase":
745
745
  "销售通话、转录文本、交易洞察、客户摘要",
746
746
  "mcpIntegrations.catalog.gong.setupNote":
747
- "Gong 需要技术管理员创建 MCP 集成,并选择个人授权或共享授权。连接前必须配置生成的客户端 ID 和密钥。",
747
+ "Gong 技术管理员需要创建 MCP 集成并选择个人或共享授权。使用手动注册时,请将生成的客户端 ID 和密钥保存为工作区密钥 `GONG_MCP_CLIENT_ID` 和 `GONG_MCP_CLIENT_SECRET`;自动注册无需客户端凭据。",
748
748
  "mcpIntegrations.catalog.semgrep.description": "扫描代码中的安全问题。",
749
749
  "mcpIntegrations.catalog.semgrep.useCase": "安全扫描、漏洞检测、代码分析",
750
750
  "mcpIntegrations.catalog.linear.description": "读取和写入 Linear 议题。",
@@ -934,6 +934,7 @@ const messages: ToolkitAgentChatTranslation = {
934
934
  "message.restoreQuestion": "恢复到此处?",
935
935
  "message.revertQuestion": "还原到此处?此后所做的更改将会丢失。",
936
936
  "message.restoreRequestFailed": "恢复请求失败。",
937
+ "message.historyUnavailable": "无法加载更改历史。",
937
938
  "message.threadNotFound":
938
939
  "此聊天线程已不可用。请开始新聊天;如果这是意外情况,也可以重试。",
939
940
  "message.restoring": "正在恢复...",
@@ -745,7 +745,7 @@ const messages: ToolkitAgentChatTranslation = {
745
745
  "mcpIntegrations.catalog.gong.useCase":
746
746
  "銷售通話、逐字稿、交易洞察、客戶摘要",
747
747
  "mcpIntegrations.catalog.gong.setupNote":
748
- "Gong 需要技術管理員建立 MCP 整合,並選擇個人或共用授權。連線前必須先設定產生的用戶端 ID 和密鑰。",
748
+ "Gong 技術管理員需要建立 MCP 整合並選擇個人或共用授權。使用手動註冊時,請將產生的用戶端 ID 和密鑰儲存為工作區密鑰 `GONG_MCP_CLIENT_ID` 和 `GONG_MCP_CLIENT_SECRET`;自動註冊不需要用戶端憑證。",
749
749
  "mcpIntegrations.catalog.semgrep.description": "掃描程式碼中的安全性問題。",
750
750
  "mcpIntegrations.catalog.semgrep.useCase": "安全性掃描、漏洞偵測、程式碼分析",
751
751
  "mcpIntegrations.catalog.linear.description": "讀取及撰寫 Linear 議題。",
@@ -937,6 +937,7 @@ const messages: ToolkitAgentChatTranslation = {
937
937
  "message.restoreQuestion": "要還原到這裡嗎?",
938
938
  "message.revertQuestion": "要還原到這裡嗎?之後所做的變更將會遺失。",
939
939
  "message.restoreRequestFailed": "還原要求失敗。",
940
+ "message.historyUnavailable": "無法載入變更歷史。",
940
941
  "message.threadNotFound":
941
942
  "此聊天串已無法使用。請開始新的聊天;如果這是意外情況,也可以重試。",
942
943
  "message.restoring": "正在還原...",
@@ -36,7 +36,7 @@ vi.mock("../settings/api-keys/api-keys-client.js", () => keys);
36
36
  vi.mock("@agent-native/core/client/org/hooks", () => ({
37
37
  useOrg: () => ({ data: { orgName: "Acme" } }),
38
38
  }));
39
- vi.mock("./useIntegrationStatus.js", () => ({
39
+ vi.mock("@agent-native/core/client/integrations/useIntegrationStatus", () => ({
40
40
  useIntegrationStatus: () => ({ statuses: [], loading: false, refetch() {} }),
41
41
  }));
42
42
  vi.mock("sonner", () => ({ toast: { success: vi.fn(), error: vi.fn() } }));
@@ -1,5 +1,8 @@
1
1
  import { useT } from "@agent-native/core/client/i18n";
2
- import type { LabValues } from "@agent-native/core/client/labs/use-lab";
2
+ import type {
3
+ LabStates,
4
+ LabValues,
5
+ } from "@agent-native/core/client/labs/use-lab";
3
6
  import {
4
7
  useActionMutation,
5
8
  useActionQuery,
@@ -21,6 +24,7 @@ interface LabsSettingsState {
21
24
  /** The labs to list: every one passed until the server answers, then the ones it registered. */
22
25
  labs: readonly LabDefinition[];
23
26
  enabled: (lab: LabDefinition) => boolean;
27
+ mixed: (lab: LabDefinition) => boolean;
24
28
  toggle: (lab: LabDefinition, enabled: boolean) => void;
25
29
  /** Switches wait for the server's answer; they can't save before it. */
26
30
  disabled: boolean;
@@ -30,7 +34,7 @@ interface LabsSettingsState {
30
34
  failedLab: LabDefinition | null;
31
35
  }
32
36
 
33
- function hasOwn(values: LabValues, key: string): boolean {
37
+ function hasOwn(values: LabStates, key: string): boolean {
34
38
  return Object.prototype.hasOwnProperty.call(values, key);
35
39
  }
36
40
 
@@ -43,7 +47,7 @@ function hasOwn(values: LabValues, key: string): boolean {
43
47
  function useLabsSettingsState(
44
48
  labs: readonly LabDefinition[],
45
49
  ): LabsSettingsState {
46
- const valuesQuery = useActionQuery<LabValues>("get-labs" as never);
50
+ const valuesQuery = useActionQuery<LabStates>("get-lab-states" as never);
47
51
  const setLab = useActionMutation<
48
52
  { key: string; enabled: boolean; values: LabValues },
49
53
  { key: string; enabled: boolean }
@@ -80,7 +84,11 @@ function useLabsSettingsState(
80
84
  labs: visible,
81
85
  enabled: (lab) =>
82
86
  overrides[lab.key] ??
83
- (values ? values[lab.key] === true : lab.defaultEnabled === true),
87
+ (values
88
+ ? values[lab.key]?.enabled === true
89
+ : lab.defaultEnabled === true),
90
+ mixed: (lab) =>
91
+ overrides[lab.key] === undefined && values?.[lab.key]?.mixed === true,
84
92
  toggle,
85
93
  disabled: !values || setLab.isPending,
86
94
  loadFailed: !values && valuesQuery.isError,
@@ -111,6 +119,7 @@ function LabRows({ state }: { state: LabsSettingsState }) {
111
119
  {state.labs.map((lab) => {
112
120
  const label = lab.displayName ?? lab.key;
113
121
  const failed = state.failedLab?.key === lab.key;
122
+ const mixed = state.mixed(lab);
114
123
  return (
115
124
  <SettingsRow
116
125
  key={lab.key}
@@ -123,17 +132,44 @@ function LabRows({ state }: { state: LabsSettingsState }) {
123
132
  lab: label,
124
133
  })}
125
134
  </span>
135
+ ) : mixed ? (
136
+ (lab.inheritedMixedDescription ?? lab.description)
126
137
  ) : (
127
138
  lab.description
128
139
  )
129
140
  }
130
141
  control={
131
- <Switch
132
- checked={state.enabled(lab)}
133
- onChange={(next) => state.toggle(lab, next)}
134
- disabled={state.disabled}
135
- aria-label={label}
136
- />
142
+ mixed ? (
143
+ <div className="flex gap-2">
144
+ <Button
145
+ type="button"
146
+ variant="outline"
147
+ size="sm"
148
+ disabled={state.disabled}
149
+ onClick={() => state.toggle(lab, true)}
150
+ aria-label={`${label}: ${t("agentChat.settingsShell.channels.state.on")}`}
151
+ >
152
+ {t("agentChat.settingsShell.channels.state.on")}
153
+ </Button>
154
+ <Button
155
+ type="button"
156
+ variant="outline"
157
+ size="sm"
158
+ disabled={state.disabled}
159
+ onClick={() => state.toggle(lab, false)}
160
+ aria-label={`${label}: ${t("agentChat.settingsShell.channels.state.off")}`}
161
+ >
162
+ {t("agentChat.settingsShell.channels.state.off")}
163
+ </Button>
164
+ </div>
165
+ ) : (
166
+ <Switch
167
+ checked={state.enabled(lab)}
168
+ onChange={(next) => state.toggle(lab, next)}
169
+ disabled={state.disabled}
170
+ aria-label={label}
171
+ />
172
+ )
137
173
  }
138
174
  />
139
175
  );
@@ -52,11 +52,14 @@ afterEach(() => {
52
52
  vi.unstubAllEnvs();
53
53
  });
54
54
 
55
+ const catalog = createToolkitI18nCatalog({ messages: {} });
56
+
55
57
  describe("ThumbsFeedback localization", () => {
56
58
  it("renders localized accessible labels and explanation copy", async () => {
57
59
  act(() => {
58
60
  root.render(
59
61
  <AgentNativeI18nProvider
62
+ catalog={catalog}
60
63
  initialLocale="de-DE"
61
64
  initialPreference="de-DE"
62
65
  persistPreference={false}
@@ -87,6 +90,7 @@ describe("ThumbsFeedback localization", () => {
87
90
  act(() => {
88
91
  root.render(
89
92
  <AgentNativeI18nProvider
93
+ catalog={catalog}
90
94
  initialLocale="en-US"
91
95
  initialPreference="en-US"
92
96
  persistPreference={false}
@@ -181,6 +185,7 @@ describe("ThumbsFeedback localization", () => {
181
185
  act(() => {
182
186
  root.render(
183
187
  <AgentNativeI18nProvider
188
+ catalog={catalog}
184
189
  initialLocale="en-US"
185
190
  initialPreference="en-US"
186
191
  persistPreference={false}
@@ -295,6 +300,7 @@ describe("ThumbsFeedback localization", () => {
295
300
  act(() => {
296
301
  root.render(
297
302
  <AgentNativeI18nProvider
303
+ catalog={catalog}
298
304
  initialLocale="en-US"
299
305
  initialPreference="en-US"
300
306
  persistPreference={false}
@@ -421,6 +427,7 @@ describe("ThumbsFeedback localization", () => {
421
427
  act(() => {
422
428
  root.render(
423
429
  <AgentNativeI18nProvider
430
+ catalog={catalog}
424
431
  initialLocale="en-US"
425
432
  initialPreference="en-US"
426
433
  persistPreference={false}
@@ -511,6 +518,7 @@ describe("ThumbsFeedback localization", () => {
511
518
  act(() => {
512
519
  root.render(
513
520
  <AgentNativeI18nProvider
521
+ catalog={catalog}
514
522
  initialLocale="en-US"
515
523
  initialPreference="en-US"
516
524
  persistPreference={false}
@@ -558,6 +566,7 @@ describe("ThumbsFeedback localization", () => {
558
566
  act(() => {
559
567
  root.render(
560
568
  <AgentNativeI18nProvider
569
+ catalog={catalog}
561
570
  initialLocale="en-US"
562
571
  initialPreference="en-US"
563
572
  persistPreference={false}
@@ -596,6 +605,7 @@ describe("ThumbsFeedback localization", () => {
596
605
  act(() => {
597
606
  root.render(
598
607
  <AgentNativeI18nProvider
608
+ catalog={catalog}
599
609
  initialLocale="en-US"
600
610
  initialPreference="en-US"
601
611
  persistPreference={false}
@@ -639,6 +649,7 @@ describe("ThumbsFeedback localization", () => {
639
649
  act(() => {
640
650
  root.render(
641
651
  <AgentNativeI18nProvider
652
+ catalog={catalog}
642
653
  initialLocale="en-US"
643
654
  initialPreference="en-US"
644
655
  persistPreference={false}
@@ -674,6 +685,7 @@ describe("ThumbsFeedback localization", () => {
674
685
  act(() => {
675
686
  root.render(
676
687
  <AgentNativeI18nProvider
688
+ catalog={catalog}
677
689
  initialLocale="en-US"
678
690
  initialPreference="en-US"
679
691
  persistPreference={false}
@@ -709,6 +721,7 @@ describe("ThumbsFeedback localization", () => {
709
721
  act(() => {
710
722
  root.render(
711
723
  <AgentNativeI18nProvider
724
+ catalog={catalog}
712
725
  initialLocale="en-US"
713
726
  initialPreference="en-US"
714
727
  persistPreference={false}
@@ -746,6 +759,7 @@ describe("ThumbsFeedback localization", () => {
746
759
  act(() => {
747
760
  root.render(
748
761
  <AgentNativeI18nProvider
762
+ catalog={catalog}
749
763
  initialLocale="en-US"
750
764
  initialPreference="en-US"
751
765
  persistPreference={false}
@@ -797,6 +811,7 @@ describe("ThumbsFeedback localization", () => {
797
811
  act(() => {
798
812
  root.render(
799
813
  <AgentNativeI18nProvider
814
+ catalog={catalog}
800
815
  initialLocale="en-US"
801
816
  initialPreference="en-US"
802
817
  persistPreference={false}
@@ -45,6 +45,10 @@ vi.mock("react-router", async (importOriginal) => {
45
45
  };
46
46
  });
47
47
 
48
+ vi.mock("@agent-native/core/client/feature-flags/use-feature-flag", () => ({
49
+ useFeatureFlagState: () => ({ status: "ready", enabled: true }),
50
+ }));
51
+
48
52
  vi.mock("@agent-native/core/client/onboarding/use-onboarding", () => ({
49
53
  trackOnboardingEvent: mocks.trackOnboardingEvent,
50
54
  useOnboarding: mocks.useOnboarding,