diff --git a/gui/src/pages/config/sections/ModelsSection.test.tsx b/gui/src/pages/config/sections/ModelsSection.test.tsx
new file mode 100644
index 00000000000..10f3aec1e7d
--- /dev/null
+++ b/gui/src/pages/config/sections/ModelsSection.test.tsx
@@ -0,0 +1,116 @@
+import { render, screen } from "@testing-library/react";
+import { Provider } from "react-redux";
+import type { ReactNode } from "react";
+import { describe, expect, it, vi } from "vitest";
+import { createMockStore } from "../../../util/test/mockStore";
+import { ModelsSection } from "./ModelsSection";
+
+vi.mock("../../../context/Auth", () => ({
+ useAuth: () => ({
+ selectedProfile: {
+ profileType: "local",
+ },
+ }),
+}));
+
+vi.mock("../../../components/mainInput/Lump/useEditBlock", () => ({
+ useEditModel: () => vi.fn(),
+}));
+
+vi.mock("../../../components/gui/Shortcut", () => ({
+ default: ({ children }: { children: ReactNode }) => <>{children}>,
+}));
+
+vi.mock("../../../components/ui", () => ({
+ Card: ({ children }: { children: ReactNode }) =>
{children}
,
+ Divider: () =>
,
+ Toggle: ({
+ children,
+ title,
+ subtitle,
+ }: {
+ children: ReactNode;
+ title: string;
+ subtitle?: string;
+ }) => (
+
+ {title}
+ {subtitle ? {subtitle}
: null}
+ {children}
+
+ ),
+}));
+
+vi.mock("../components/ConfigHeader", () => ({
+ ConfigHeader: ({ title }: { title: string }) => {title}
,
+}));
+
+vi.mock("../components/ModelRoleRow", () => ({
+ ModelRoleRow: ({
+ role,
+ description,
+ setupURL,
+ }: {
+ role: string;
+ description: ReactNode;
+ setupURL: string;
+ }) => (
+
+ ),
+}));
+
+vi.mock("../../../util", async () => {
+ const actual =
+ await vi.importActual("../../../util");
+
+ return {
+ ...actual,
+ getMetaKeyLabel: () => "cmd",
+ isJetBrains: () => false,
+ };
+});
+
+describe("ModelsSection docs links", () => {
+ function renderComponent() {
+ const { mockIdeMessenger, ...store } = createMockStore();
+
+ render(
+
+
+ ,
+ );
+
+ return { store, mockIdeMessenger };
+ }
+
+ it("uses current ide-extensions docs routes for learn more and setup links", () => {
+ renderComponent();
+
+ const learnMoreLinks = screen.getAllByRole("link", { name: "Learn more" });
+ const setupLinks = [
+ screen.getByRole("link", { name: "chat setup" }),
+ screen.getByRole("link", { name: "autocomplete setup" }),
+ screen.getByRole("link", { name: "edit setup" }),
+ ];
+
+ const hrefs = [...learnMoreLinks, ...setupLinks].map((link) =>
+ link.getAttribute("href"),
+ );
+
+ expect(hrefs).toEqual([
+ "https://docs.continue.dev/ide-extensions/chat/quick-start",
+ "https://docs.continue.dev/ide-extensions/autocomplete/quick-start",
+ "https://docs.continue.dev/ide-extensions/edit/quick-start",
+ "https://docs.continue.dev/ide-extensions/chat/model-setup",
+ "https://docs.continue.dev/ide-extensions/autocomplete/model-setup",
+ "https://docs.continue.dev/ide-extensions/edit/model-setup",
+ ]);
+
+ hrefs.forEach((href) => {
+ expect(href).not.toContain("/docs/");
+ });
+ });
+});
diff --git a/gui/src/pages/config/sections/ModelsSection.tsx b/gui/src/pages/config/sections/ModelsSection.tsx
index 316f463a88a..1ab9b5758a3 100644
--- a/gui/src/pages/config/sections/ModelsSection.tsx
+++ b/gui/src/pages/config/sections/ModelsSection.tsx
@@ -14,6 +14,22 @@ import { getMetaKeyLabel, isJetBrains } from "../../../util";
import { ConfigHeader } from "../components/ConfigHeader";
import { ModelRoleRow } from "../components/ModelRoleRow";
+const MODEL_DOCS_URLS = {
+ chat: {
+ learnMore: "https://docs.continue.dev/ide-extensions/chat/quick-start",
+ setup: "https://docs.continue.dev/ide-extensions/chat/model-setup",
+ },
+ autocomplete: {
+ learnMore:
+ "https://docs.continue.dev/ide-extensions/autocomplete/quick-start",
+ setup: "https://docs.continue.dev/ide-extensions/autocomplete/model-setup",
+ },
+ edit: {
+ learnMore: "https://docs.continue.dev/ide-extensions/edit/quick-start",
+ setup: "https://docs.continue.dev/ide-extensions/edit/model-setup",
+ },
+} as const;
+
export function ModelsSection() {
const { selectedProfile } = useAuth();
const dispatch = useAppDispatch();
@@ -83,7 +99,7 @@ export function ModelsSection() {
Used in Chat, Plan, Agent mode (
handleRoleUpdate("chat", model)}
onConfigure={handleConfigureModel}
- setupURL="https://docs.continue.dev/chat/model-setup"
+ setupURL={MODEL_DOCS_URLS.chat.setup}
/>
@@ -109,7 +125,7 @@ export function ModelsSection() {
Used in inline code completions as you type (
handleRoleUpdate("autocomplete", model)}
onConfigure={handleConfigureModel}
- setupURL="https://docs.continue.dev/autocomplete/model-setup"
+ setupURL={MODEL_DOCS_URLS.autocomplete.setup}
/>
{/* Jetbrains has a model selector inline */}
@@ -142,7 +158,7 @@ export function ModelsSection() {
Used to transform a selected section of code (
handleRoleUpdate("edit", model)}
onConfigure={handleConfigureModel}
- setupURL="https://docs.continue.dev/edit/model-setup"
+ setupURL={MODEL_DOCS_URLS.edit.setup}
/>
>
)}