@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.
Files changed (143) hide show
  1. package/dist/app/agentkit/react/components.d.ts.map +1 -1
  2. package/dist/app/agentkit/react/components.js +17 -9
  3. package/dist/app/agentkit/react/components.js.map +1 -1
  4. package/dist/app/auth/AuthPage.d.ts.map +1 -1
  5. package/dist/app/auth/AuthPage.js +11 -0
  6. package/dist/app/auth/AuthPage.js.map +1 -1
  7. package/dist/app/chat/AgentKitAssistantChat.d.ts +2 -0
  8. package/dist/app/chat/AgentKitAssistantChat.d.ts.map +1 -1
  9. package/dist/app/chat/AgentKitAssistantChat.js +24 -14
  10. package/dist/app/chat/AgentKitAssistantChat.js.map +1 -1
  11. package/dist/app/chat/AgentPanel.d.ts.map +1 -1
  12. package/dist/app/chat/AgentPanel.js +3 -2
  13. package/dist/app/chat/AgentPanel.js.map +1 -1
  14. package/dist/app/chat/MultiTabAssistantChat.d.ts +4 -1
  15. package/dist/app/chat/MultiTabAssistantChat.d.ts.map +1 -1
  16. package/dist/app/chat/MultiTabAssistantChat.js +61 -3
  17. package/dist/app/chat/MultiTabAssistantChat.js.map +1 -1
  18. package/dist/app/chat/agentkit-chat/approval-card.d.ts.map +1 -1
  19. package/dist/app/chat/agentkit-chat/approval-card.js +2 -1
  20. package/dist/app/chat/agentkit-chat/approval-card.js.map +1 -1
  21. package/dist/app/chat/chat/run-recovery.d.ts.map +1 -1
  22. package/dist/app/chat/chat/run-recovery.js +74 -8
  23. package/dist/app/chat/chat/run-recovery.js.map +1 -1
  24. package/dist/app/chat/chat/tool-call-display.d.ts.map +1 -1
  25. package/dist/app/chat/chat/tool-call-display.js +6 -4
  26. package/dist/app/chat/chat/tool-call-display.js.map +1 -1
  27. package/dist/app/chat/chat-first/ChatFirstAgentActivityPanel.d.ts.map +1 -1
  28. package/dist/app/chat/chat-first/ChatFirstAgentActivityPanel.js +2 -1
  29. package/dist/app/chat/chat-first/ChatFirstAgentActivityPanel.js.map +1 -1
  30. package/dist/app/chat/conversation/AgentConversation.d.ts.map +1 -1
  31. package/dist/app/chat/conversation/AgentConversation.js +10 -7
  32. package/dist/app/chat/conversation/AgentConversation.js.map +1 -1
  33. package/dist/app/chat/fallback-chat-title.d.ts.map +1 -1
  34. package/dist/app/chat/fallback-chat-title.js +2 -4
  35. package/dist/app/chat/fallback-chat-title.js.map +1 -1
  36. package/dist/app/chat/mcp-apps/McpAppRenderer.d.ts.map +1 -1
  37. package/dist/app/chat/mcp-apps/McpAppRenderer.js +3 -2
  38. package/dist/app/chat/mcp-apps/McpAppRenderer.js.map +1 -1
  39. package/dist/app/chat/session-replay-privacy.d.ts +7 -0
  40. package/dist/app/chat/session-replay-privacy.d.ts.map +1 -0
  41. package/dist/app/chat/session-replay-privacy.js +6 -0
  42. package/dist/app/chat/session-replay-privacy.js.map +1 -0
  43. package/dist/app/extensions/ExtensionViewer.d.ts +4 -1
  44. package/dist/app/extensions/ExtensionViewer.d.ts.map +1 -1
  45. package/dist/app/extensions/ExtensionViewer.js +3 -3
  46. package/dist/app/extensions/ExtensionViewer.js.map +1 -1
  47. package/dist/app/extensions/ExtensionViewerPage.d.ts +4 -1
  48. package/dist/app/extensions/ExtensionViewerPage.d.ts.map +1 -1
  49. package/dist/app/extensions/ExtensionViewerPage.js +2 -2
  50. package/dist/app/extensions/ExtensionViewerPage.js.map +1 -1
  51. package/dist/app/onboarding/FirstRunOnboarding.d.ts.map +1 -1
  52. package/dist/app/onboarding/FirstRunOnboarding.js +53 -12
  53. package/dist/app/onboarding/FirstRunOnboarding.js.map +1 -1
  54. package/dist/app/onboarding/OnboardingPanel.d.ts.map +1 -1
  55. package/dist/app/onboarding/OnboardingPanel.js +14 -4
  56. package/dist/app/onboarding/OnboardingPanel.js.map +1 -1
  57. package/dist/app/resources/ResourceEditor.d.ts +4 -1
  58. package/dist/app/resources/ResourceEditor.d.ts.map +1 -1
  59. package/dist/app/resources/ResourceEditor.js +18 -7
  60. package/dist/app/resources/ResourceEditor.js.map +1 -1
  61. package/dist/app/resources/ResourcesPanel.d.ts +4 -1
  62. package/dist/app/resources/ResourcesPanel.d.ts.map +1 -1
  63. package/dist/app/resources/ResourcesPanel.js +18 -18
  64. package/dist/app/resources/ResourcesPanel.js.map +1 -1
  65. package/dist/app/resources/custom-agent-model-options.d.ts +16 -0
  66. package/dist/app/resources/custom-agent-model-options.d.ts.map +1 -0
  67. package/dist/app/resources/custom-agent-model-options.js +53 -0
  68. package/dist/app/resources/custom-agent-model-options.js.map +1 -0
  69. package/dist/app/settings/SettingsPanel.d.ts.map +1 -1
  70. package/dist/app/settings/SettingsPanel.js +34 -3
  71. package/dist/app/settings/SettingsPanel.js.map +1 -1
  72. package/dist/app/settings/SettingsTabsPage.d.ts.map +1 -1
  73. package/dist/app/settings/SettingsTabsPage.js +2 -0
  74. package/dist/app/settings/SettingsTabsPage.js.map +1 -1
  75. package/dist/app/settings/api-keys/ApiKeyDialogs.d.ts.map +1 -1
  76. package/dist/app/settings/api-keys/ApiKeyDialogs.js +49 -9
  77. package/dist/app/settings/api-keys/ApiKeyDialogs.js.map +1 -1
  78. package/dist/app/settings/api-keys/ApiKeysSettingsPage.js +2 -1
  79. package/dist/app/settings/api-keys/ApiKeysSettingsPage.js.map +1 -1
  80. package/dist/app/settings/model/ModelSettingsPage.d.ts.map +1 -1
  81. package/dist/app/settings/model/ModelSettingsPage.js +43 -9
  82. package/dist/app/settings/model/ModelSettingsPage.js.map +1 -1
  83. package/dist/app/settings/model/ProviderDialog.d.ts +4 -0
  84. package/dist/app/settings/model/ProviderDialog.d.ts.map +1 -1
  85. package/dist/app/settings/model/ProviderDialog.js +107 -11
  86. package/dist/app/settings/model/ProviderDialog.js.map +1 -1
  87. package/dist/app/settings/useBuilderStatus.d.ts.map +1 -1
  88. package/dist/app/settings/useBuilderStatus.js +13 -10
  89. package/dist/app/settings/useBuilderStatus.js.map +1 -1
  90. package/dist/composer/TiptapComposer.d.ts.map +1 -1
  91. package/dist/composer/TiptapComposer.js +51 -13
  92. package/dist/composer/TiptapComposer.js.map +1 -1
  93. package/package.json +4 -4
  94. package/src/app/agentkit/react/components.interaction.spec.tsx +229 -1
  95. package/src/app/agentkit/react/components.spec.tsx +42 -1
  96. package/src/app/agentkit/react/components.tsx +46 -12
  97. package/src/app/auth/AuthPage.tsx +13 -0
  98. package/src/app/chat/AgentKitAssistantChat.spec.tsx +116 -5
  99. package/src/app/chat/AgentKitAssistantChat.tsx +41 -20
  100. package/src/app/chat/AgentPanel.tsx +5 -1
  101. package/src/app/chat/MultiTabAssistantChat.spec.tsx +152 -7
  102. package/src/app/chat/MultiTabAssistantChat.tsx +71 -4
  103. package/src/app/chat/agentkit-chat/approval-card.spec.tsx +17 -0
  104. package/src/app/chat/agentkit-chat/approval-card.tsx +2 -0
  105. package/src/app/chat/chat/run-recovery.spec.tsx +354 -9
  106. package/src/app/chat/chat/run-recovery.tsx +178 -10
  107. package/src/app/chat/chat/tool-call-display.spec.tsx +77 -0
  108. package/src/app/chat/chat/tool-call-display.tsx +23 -6
  109. package/src/app/chat/chat-first/ChatFirstAgentActivityPanel.tsx +2 -1
  110. package/src/app/chat/conversation/AgentConversation.spec.tsx +190 -1
  111. package/src/app/chat/conversation/AgentConversation.tsx +32 -8
  112. package/src/app/chat/fallback-chat-title.spec.ts +44 -0
  113. package/src/app/chat/fallback-chat-title.ts +3 -4
  114. package/src/app/chat/mcp-apps/McpAppRenderer.spec.ts +24 -0
  115. package/src/app/chat/mcp-apps/McpAppRenderer.tsx +10 -2
  116. package/src/app/chat/session-replay-privacy.spec.ts +14 -0
  117. package/src/app/chat/session-replay-privacy.ts +5 -0
  118. package/src/app/extensions/ExtensionViewer.tsx +15 -3
  119. package/src/app/extensions/ExtensionViewerPage.tsx +7 -3
  120. package/src/app/onboarding/FirstRunOnboarding.spec.tsx +252 -2
  121. package/src/app/onboarding/FirstRunOnboarding.tsx +56 -9
  122. package/src/app/onboarding/OnboardingPanel.save-scope.spec.tsx +1 -0
  123. package/src/app/onboarding/OnboardingPanel.tsx +15 -3
  124. package/src/app/resources/ResourceEditor.spec.tsx +240 -5
  125. package/src/app/resources/ResourceEditor.tsx +57 -10
  126. package/src/app/resources/ResourcesPanel.spec.ts +86 -4
  127. package/src/app/resources/ResourcesPanel.tsx +49 -16
  128. package/src/app/resources/custom-agent-model-options.ts +92 -0
  129. package/src/app/settings/SettingsPanel.model-defaults.spec.tsx +26 -13
  130. package/src/app/settings/SettingsPanel.tsx +35 -3
  131. package/src/app/settings/SettingsTabsPage.spec.tsx +97 -0
  132. package/src/app/settings/SettingsTabsPage.tsx +2 -0
  133. package/src/app/settings/api-keys/ApiKeyDialogs.tsx +84 -22
  134. package/src/app/settings/api-keys/ApiKeysSettingsPage.spec.tsx +229 -1
  135. package/src/app/settings/api-keys/ApiKeysSettingsPage.tsx +3 -2
  136. package/src/app/settings/model/ModelSettingsPage.spec.tsx +99 -9
  137. package/src/app/settings/model/ModelSettingsPage.tsx +79 -11
  138. package/src/app/settings/model/ProviderDialog.spec.tsx +192 -1
  139. package/src/app/settings/model/ProviderDialog.tsx +225 -29
  140. package/src/app/settings/useBuilderStatus.spec.tsx +49 -0
  141. package/src/app/settings/useBuilderStatus.ts +16 -10
  142. package/src/composer/TiptapComposer.spec.ts +97 -2
  143. package/src/composer/TiptapComposer.tsx +67 -13
@@ -137,6 +137,8 @@ describe("createTiptapComposerExtensions", () => {
137
137
  );
138
138
  expect(compactComposerModelName("google/gemini-3.8-flash")).toBe("Flash");
139
139
  expect(compactComposerModelName("qwen/qwen3.8-max-0902")).toBe("Max");
140
+ expect(compactComposerModelName("qwen3-coder")).toBe("Coder");
141
+ expect(compactComposerModelName("constructor")).toBe("constructor");
140
142
  expect(compactComposerModelName("claude-sonnet-5")).toBe("Sonnet");
141
143
  expect(compactComposerModelName("claude-sonnet-5-5")).toBe("Sonnet");
142
144
  expect(compactComposerModelName("anthropic/claude-opus-5.5")).toBe("Opus");
@@ -144,9 +146,10 @@ describe("createTiptapComposerExtensions", () => {
144
146
  "Flash-Lite",
145
147
  );
146
148
  expect(compactComposerModelName("grok-code-fast")).toBe("Code Fast");
147
- expect(compactComposerModelName("deepseek-v3-1")).toBe("DeepSeek");
149
+ expect(compactComposerModelName("x-ai/grok-build-0.1")).toBe("Build");
150
+ expect(compactComposerModelName("deepseek-v3-1")).toBe("DeepSeek v3.1");
148
151
  expect(compactComposerModelName("deepseek-v4-1-flash")).toBe(
149
- "DeepSeek Flash",
152
+ "DeepSeek V4.1 Flash",
150
153
  );
151
154
  expect(compactComposerModelName("z-ai-glm-5-3-flash")).toBe(
152
155
  "GLM 5.3 Flash",
@@ -2789,6 +2792,98 @@ describe("createTiptapComposerExtensions", () => {
2789
2792
  expect(picker?.textContent).not.toContain("Builder.io");
2790
2793
  });
2791
2794
 
2795
+ it("keeps the selected model visible when the picker hides older versions", () => {
2796
+ function Harness() {
2797
+ const runtime = useLocalRuntime(emptyChatModelAdapter);
2798
+ return React.createElement(
2799
+ AssistantRuntimeProvider,
2800
+ { runtime },
2801
+ React.createElement(
2802
+ TooltipProvider,
2803
+ null,
2804
+ React.createElement(TiptapComposer, {
2805
+ availableModels: [
2806
+ {
2807
+ engine: "openai",
2808
+ label: "OpenAI",
2809
+ models: ["gpt-5.6-luna", "gpt-6-luna"],
2810
+ configured: true,
2811
+ },
2812
+ ],
2813
+ selectedModel: "gpt-5.6-luna",
2814
+ selectedEngine: "openai",
2815
+ onModelChange: vi.fn(),
2816
+ includeDefaultSlashSkills: false,
2817
+ plusMenuMode: "hidden",
2818
+ providerConnectStatusEnabled: false,
2819
+ voiceEnabled: false,
2820
+ }),
2821
+ ),
2822
+ );
2823
+ }
2824
+
2825
+ act(() => root.render(React.createElement(Harness)));
2826
+ const modelButton = container.querySelector<HTMLButtonElement>(
2827
+ '[data-agent-composer-slot="model-button"]',
2828
+ );
2829
+ act(() => modelButton?.click());
2830
+ const modelTab = Array.from(document.querySelectorAll('[role="tab"]')).find(
2831
+ (tab) => tab.textContent?.includes("Model"),
2832
+ );
2833
+ act(() => (modelTab as HTMLElement | undefined)?.click());
2834
+ const picker = document.querySelector(
2835
+ '[role="tabpanel"][aria-label="model"]',
2836
+ );
2837
+ expect(picker?.textContent).toContain("GPT-5.6 Luna");
2838
+ expect(picker?.textContent).toContain("GPT-6 Luna");
2839
+ });
2840
+
2841
+ it("disambiguates the selected model when providers expose the same model", () => {
2842
+ function Harness() {
2843
+ const runtime = useLocalRuntime(emptyChatModelAdapter);
2844
+ return React.createElement(
2845
+ AssistantRuntimeProvider,
2846
+ { runtime },
2847
+ React.createElement(
2848
+ TooltipProvider,
2849
+ null,
2850
+ React.createElement(TiptapComposer, {
2851
+ availableModels: [
2852
+ {
2853
+ engine: "builder",
2854
+ label: "Builder · Builder.io",
2855
+ models: ["deepseek-v4-pro"],
2856
+ configured: true,
2857
+ },
2858
+ {
2859
+ engine: "ai-sdk:openrouter",
2860
+ label: "OpenRouter",
2861
+ models: ["deepseek/deepseek-v4-pro"],
2862
+ configured: true,
2863
+ },
2864
+ ],
2865
+ selectedModel: "deepseek-v4-pro",
2866
+ selectedEngine: "builder",
2867
+ onModelChange: vi.fn(),
2868
+ includeDefaultSlashSkills: false,
2869
+ plusMenuMode: "hidden",
2870
+ providerConnectStatusEnabled: false,
2871
+ voiceEnabled: false,
2872
+ }),
2873
+ ),
2874
+ );
2875
+ }
2876
+
2877
+ act(() => root.render(React.createElement(Harness)));
2878
+ const modelButton = container.querySelector<HTMLButtonElement>(
2879
+ '[data-agent-composer-slot="model-button"]',
2880
+ );
2881
+ expect(modelButton?.textContent).toContain("DeepSeek V4 Pro · Builder");
2882
+ expect(modelButton?.getAttribute("aria-label")).toContain(
2883
+ "DeepSeek V4 Pro · Builder",
2884
+ );
2885
+ });
2886
+
2792
2887
  it("chooses the newest tier version regardless of catalog order", () => {
2793
2888
  const models = [
2794
2889
  "openai/gpt-5.6-sol",
@@ -1401,8 +1401,33 @@ const FRIENDLY_MODEL_NAMES: Record<string, string> = {
1401
1401
  "pi-cli": "Pi",
1402
1402
  "opencode-cli": "OpenCode",
1403
1403
  "claude-fable-5": "Claude Fable 5",
1404
+ "claude-fable-5-1": "Claude Fable 5.1",
1405
+ "qwen3-coder": "Qwen3 Coder",
1404
1406
  "kimi-k2-5": "Kimi K2.5",
1405
1407
  "deepseek-v4-pro": "DeepSeek V4 Pro",
1408
+ "deepseek-v4-1-flash": "DeepSeek V4.1 Flash",
1409
+ "deepseek-v3-1": "DeepSeek v3.1",
1410
+ "z-ai-glm-4-5": "Z-AI GLM 4.5",
1411
+ "z-ai-glm-5-1": "Z-AI GLM 5.1",
1412
+ "z-ai-glm-5-3-flash": "Z-AI GLM 5.3 Flash",
1413
+ "grok-code-fast": "Grok Code Fast",
1414
+ "x-ai/grok-build-0.1": "Grok Build 0.1",
1415
+ "gpt-6-1-sol": "GPT-6.1 Sol",
1416
+ "gemini-3-1-pro": "Gemini 3.1 Pro",
1417
+ "gemini-3-8-flash": "Gemini 3.8 Flash",
1418
+ "google/gemini-3.1-pro-preview": "Gemini 3.1 Pro",
1419
+ "google/gemini-3.5-flash-lite": "Gemini 3.5 Flash-Lite",
1420
+ "google/gemini-3.1-flash-lite": "Gemini 3.1 Flash-Lite",
1421
+ "anthropic/claude-haiku-5.5": "Claude Haiku 5.5",
1422
+ "deepseek/deepseek-v4-pro": "DeepSeek V4 Pro",
1423
+ "deepseek/deepseek-v4.1-flash": "DeepSeek V4.1 Flash",
1424
+ "deepseek/deepseek-chat-v3.1": "DeepSeek v3.1",
1425
+ "z-ai/glm-4.5": "Z-AI GLM 4.5",
1426
+ "z-ai/glm-5.1": "Z-AI GLM 5.1",
1427
+ "z-ai/glm-5.3-flash": "Z-AI GLM 5.3 Flash",
1428
+ "x-ai/grok-4.7": "Grok 4.7",
1429
+ "qwen/qwen3-coder": "Qwen3 Coder",
1430
+ "moonshotai/kimi-k2.5": "Kimi K2.5",
1406
1431
  "z-ai/glm-5.2": "GLM 5.2",
1407
1432
  "openai/gpt-6-astra": "GPT-6 Astra",
1408
1433
  "openai/gpt-6-astra-pro": "GPT-6 Astra Pro",
@@ -1428,13 +1453,6 @@ const FRIENDLY_MODEL_NAMES: Record<string, string> = {
1428
1453
  "claude-haiku-4-5": "Claude Haiku 4.5",
1429
1454
  "gemini-3-5-flash-lite": "Gemini 3.5 Flash-Lite",
1430
1455
  "gemini-3-1-flash-lite": "Gemini 3.1 Flash-Lite",
1431
- "grok-code-fast": "Grok Code Fast",
1432
- "qwen3-coder": "Qwen3 Coder",
1433
- "deepseek-v3-1": "DeepSeek v3.1",
1434
- "deepseek-v4-1-flash": "DeepSeek V4.1 Flash",
1435
- "z-ai-glm-4-5": "Z-AI GLM 4.5",
1436
- "z-ai-glm-5-1": "Z-AI GLM 5.1",
1437
- "z-ai-glm-5-3-flash": "Z-AI GLM 5.3 Flash",
1438
1456
  };
1439
1457
 
1440
1458
  const LOCAL_RUNTIME_ENGINES = new Set([
@@ -1531,11 +1549,15 @@ function friendlyModelName(model: string, t?: ComposerTranslate): string {
1531
1549
  }) ?? "Default model"
1532
1550
  );
1533
1551
  }
1534
- if (FRIENDLY_MODEL_NAMES[model]) return FRIENDLY_MODEL_NAMES[model];
1552
+ const friendlyName = Object.hasOwn(FRIENDLY_MODEL_NAMES, model)
1553
+ ? FRIENDLY_MODEL_NAMES[model]
1554
+ : undefined;
1555
+ if (friendlyName !== undefined) return friendlyName;
1535
1556
  const normalizedModel = model.replace(/^(?:anthropic|openai|google)\//, "");
1536
1557
  // Claude: claude-{tier}-{major}[-minor][-dateYYYYMMDD].
1537
- const claude = normalizedModel.match(
1538
- /^claude-(opus|sonnet|haiku|fable)-(\d+)(?:[-.](\d+))?(?:-\d{8,})?$/,
1558
+ const undatedModel = normalizedModel.replace(/-\d{8,}$/, "");
1559
+ const claude = undatedModel.match(
1560
+ /^claude-(opus|sonnet|haiku|fable)-(\d+)(?:[-.](\d+))?$/,
1539
1561
  );
1540
1562
  if (claude) {
1541
1563
  const tier = claude[1][0].toUpperCase() + claude[1].slice(1);
@@ -1582,6 +1604,7 @@ export function compactComposerModelName(
1582
1604
  ): string {
1583
1605
  const fullName = friendlyModelName(model, t);
1584
1606
  if (model === "auto" || LOCAL_RUNTIME_ENGINES.has(model)) return fullName;
1607
+ if (/^DeepSeek\b/i.test(fullName)) return fullName;
1585
1608
  const shortName = fullName
1586
1609
  .replace(/^GPT-\d+(?:\.\d+)?\s*/i, "")
1587
1610
  .replace(/^Gemini\s+\d+(?:\.\d+)?\s*/i, "")
@@ -1993,6 +2016,30 @@ function ModelSelector({
1993
2016
  const selectedModelDisplayName = selectedModelProviderGroups
1994
2017
  .map((group) => group.modelDisplayNames?.[model])
1995
2018
  .find((displayName) => typeof displayName === "string");
2019
+ const selectedModelProviderGroup =
2020
+ selectedModelProviderGroups.find(
2021
+ (group) => group.engine === selectedEngine,
2022
+ ) ?? selectedModelProviderGroups[0];
2023
+ const selectedModelFriendlyName =
2024
+ selectedModelDisplayName ?? friendlyModelName(model, t);
2025
+ const selectedModelHasDuplicateName =
2026
+ selectedModelProviderGroup !== undefined &&
2027
+ modelProviderGroups.some(
2028
+ (group) =>
2029
+ group.engine !== selectedModelProviderGroup.engine &&
2030
+ group.models.some(
2031
+ (candidate) =>
2032
+ (group.modelDisplayNames?.[candidate] ??
2033
+ friendlyModelName(candidate, t)) === selectedModelFriendlyName,
2034
+ ),
2035
+ );
2036
+ const selectedModelProviderLabel = selectedModelProviderGroup?.label.replace(
2037
+ / · Builder\.io$/i,
2038
+ "",
2039
+ );
2040
+ const selectedModelDisplayLabel = selectedModelHasDuplicateName
2041
+ ? `${selectedModelFriendlyName} · ${selectedModelProviderLabel}`
2042
+ : selectedModelFriendlyName;
1996
2043
  const selectedModelNeedsConnection =
1997
2044
  onlyConnectPathAvailable ||
1998
2045
  (selectedModelProviderGroups.length > 0 &&
@@ -2001,11 +2048,13 @@ function ModelSelector({
2001
2048
  ? showBuilderAction
2002
2049
  ? t("agentChat.composer.connectAgent", { defaultValue: "Connect agent" })
2003
2050
  : t("agentChat.composer.connectKeys", { defaultValue: "Connect keys" })
2004
- : (selectedModelDisplayName ?? friendlyModelName(model, t));
2051
+ : selectedModelDisplayLabel;
2005
2052
  const selectedModelLabel = selectedModelName;
2006
2053
  const selectedModelButtonLabel = selectedModelNeedsConnection
2007
2054
  ? selectedModelLabel
2008
- : (selectedModelDisplayName ?? compactComposerModelName(model, t));
2055
+ : selectedModelHasDuplicateName
2056
+ ? selectedModelDisplayLabel
2057
+ : (selectedModelDisplayName ?? compactComposerModelName(model, t));
2009
2058
  const openLlmSettings = useCallback(() => {
2010
2059
  try {
2011
2060
  window.location.hash = "llm";
@@ -2498,10 +2547,15 @@ function ModelSelector({
2498
2547
  {hasConfiguredProvider &&
2499
2548
  !onlyConnectPathAvailable &&
2500
2549
  visibleProviderGroups.map((group, groupIndex) => {
2501
- const models =
2550
+ const latestModels =
2502
2551
  group.engine === "chatgpt-subscription"
2503
2552
  ? group.models
2504
2553
  : latestModelsOnly(group.models);
2554
+ const models = group.models.filter(
2555
+ (candidate) =>
2556
+ latestModels.includes(candidate) ||
2557
+ candidate === model,
2558
+ );
2505
2559
  const showProviderLabels =
2506
2560
  visibleProviderGroups.length > 1;
2507
2561
  const isLocalRuntime =