diff --git a/src/renderer/src/App.test.tsx b/src/renderer/src/App.test.tsx index 7c00b55c..787f419f 100644 --- a/src/renderer/src/App.test.tsx +++ b/src/renderer/src/App.test.tsx @@ -6351,7 +6351,7 @@ describe("App", () => { name: /^OpenCode · 默认模型.*sonnet-5$/u, }), ).toBeInTheDocument(); - expect(within(runtimeMenu).getAllByRole("menuitemradio")).toHaveLength(2); + expect(within(runtimeMenu).getAllByRole("menuitemradio")).toHaveLength(1); expect(within(runtimeMenu).queryByText("直连模型")).not.toBeInTheDocument(); expect( within(runtimeMenu).queryByText("Continue Runtime"), @@ -8539,7 +8539,7 @@ describe("App", () => { expect(openCodeModel).toBeEnabled(); expect(continueModel).toBeEnabled(); expect(deepseekHarness).toBeEnabled(); - expect(screen.getAllByRole("menuitemradio")).toHaveLength(10); + expect(screen.getAllByRole("menuitemradio")).toHaveLength(6); expect(within(runtimeMenu).getAllByRole("separator")).toHaveLength(4); expect(within(runtimeMenu).queryByRole("menu")).not.toBeInTheDocument(); expect( diff --git a/src/renderer/src/App.tsx b/src/renderer/src/App.tsx index 307cf687..fcee3ccb 100644 --- a/src/renderer/src/App.tsx +++ b/src/renderer/src/App.tsx @@ -76,8 +76,6 @@ import type { } from "../../shared/contracts"; import { defaultContextCompressionSettings, - isAgentRuntimeModelProtocol, - isDeepSeekHarnessModelProfile, maximumPastedImageBytes, } from "../../shared/contracts"; import { @@ -9802,26 +9800,6 @@ function App(): React.JSX.Element { > {t("runtime.manage")} - {runtimeSettings && ( - <> - {t("runtime.fixedRuntimeModel")} - {(["opencode", "continue", "deepseek-harness"] as const).flatMap((provider) => - runtimeSettings.modelProfiles.filter((profile) => - (!activeProjectUsesManagedSsh || provider === "opencode") && - (provider === "deepseek-harness" ? isDeepSeekHarnessModelProfile(profile) : isAgentRuntimeModelProtocol(profile.protocol)) - ).map((profile) => { - const selection = { provider, profileId: profile.id }; - const selected = activeRuntimeSelectionKey === agentRuntimeSelectionKey(selection); - return ; - }) - )} - - )} )} diff --git a/src/renderer/src/ProjectRuntimeSelector.test.tsx b/src/renderer/src/ProjectRuntimeSelector.test.tsx deleted file mode 100644 index d2d07898..00000000 --- a/src/renderer/src/ProjectRuntimeSelector.test.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import { cleanup, fireEvent, render, screen } from '@testing-library/react' -import { afterEach, describe, expect, it, vi } from 'vitest' -import { defaultRuntimeSettings, type RuntimeSettings } from '../../shared/contracts' -import { ProjectRuntimeSelector } from './ProjectRuntimeSelector' -import i18n from './i18n' - -afterEach(cleanup) - -describe('ProjectRuntimeSelector rules', () => { - it('allows fixed Runtime models and switching back to a profile-free reference', async () => { - await i18n.changeLanguage('zh-CN') - const profileId = '00000000-0000-4000-8000-000000000011' - const settings = { - ...defaultRuntimeSettings, - defaultModelProfileId: profileId, - modelProfiles: [{ - id: profileId, name: 'Model A', modelName: 'model-a', - baseUrl: 'https://example.com/v1', protocol: 'openai-chat-completions', - authentication: 'api-key', apiKeyConfigured: true - }] - } as RuntimeSettings - const onChange = vi.fn() - const props = { - ariaLabel: 'Project Runtime', label: 'Runtime', onChange, - runtimeSettings: settings - } - const view = render() - const select = screen.getByRole('combobox') - for (const provider of ['opencode', 'continue', 'deepseek-harness'] as const) { - expect(screen.getByRole('option', { - name: `${provider === 'opencode' ? 'OpenCode' : provider === 'continue' ? 'Continue' : 'DeepSeek Harness'} · Model A` - })).toHaveValue(`${provider}:${profileId}`) - fireEvent.change(select, { target: { value: `${provider}:${profileId}` } }) - expect(onChange).toHaveBeenLastCalledWith({ provider, profileId }) - } - view.rerender() - expect(screen.getByText('通过 OpenCode 运行,固定使用 Model A。')).toBeInTheDocument() - fireEvent.change(select, { target: { value: 'opencode:default' } }) - expect(onChange).toHaveBeenLastCalledWith({ provider: 'opencode' }) - fireEvent.change(select, { target: { value: 'model:default' } }) - expect(onChange).toHaveBeenLastCalledWith({ provider: 'model' }) - }) -}) diff --git a/src/renderer/src/ProjectRuntimeSelector.tsx b/src/renderer/src/ProjectRuntimeSelector.tsx index d944580f..ddb92766 100644 --- a/src/renderer/src/ProjectRuntimeSelector.tsx +++ b/src/renderer/src/ProjectRuntimeSelector.tsx @@ -1,10 +1,6 @@ -import type { TFunction } from 'i18next' +import type { TFunction } from 'i18next' import { useTranslation } from 'react-i18next' -import { - isAgentRuntimeModelProtocol, - isDeepSeekHarnessModelProfile, - type RuntimeSettings -} from '../../shared/contracts' +import type { RuntimeSettings } from '../../shared/contracts' import { agentRuntimeSelectionKey, getRuntimeSelectionForProvider, @@ -58,15 +54,6 @@ function runtimeSelectionDescription( : selection.provider === 'continue' ? 'Continue' : 'DeepSeek Harness' - if (selection.profileId) { - const profile = settings.modelProfiles.find( - (candidate) => candidate.id === selection.profileId - ) - return t('channels.project.fixedRuntimeDescription', { - runtime: runtimeLabel, - name: profile?.name ?? t('channels.project.missingProfile') - }) - } return t('channels.project.runtimeDescription', { runtime: runtimeLabel }) @@ -121,22 +108,9 @@ export function ProjectRuntimeSelector({ ...(selectionMode === 'configured' ? [{ provider: 'auto' as const }] : []), { provider: 'model' } ] - const fixedRuntimeSelections = selectionMode === 'configured' - ? runtimeProviders.flatMap((provider) => - directProfiles.filter((profile) => - provider === 'deepseek-harness' - ? isDeepSeekHarnessModelProfile(profile) - : isAgentRuntimeModelProtocol(profile.protocol) - ).map((profile) => ({ provider, profileId: profile.id })) - ) - : [] const fixedRuntimeSelection = runtimeSelection.provider !== 'model' && - 'profileId' in runtimeSelection && runtimeSelection.profileId && - !fixedRuntimeSelections.some((candidate) => - agentRuntimeSelectionKey(candidate) === agentRuntimeSelectionKey(runtimeSelection) - ) ? runtimeSelection : undefined + 'profileId' in runtimeSelection && runtimeSelection.profileId ? runtimeSelection : undefined const selections = [...inheritedSelections, ...directSelections, ...runtimeSelections, - ...fixedRuntimeSelections, ...(fixedRuntimeSelection ? [fixedRuntimeSelection] : [])] const selectionByKey = new Map( selections.map((candidate) => [ @@ -216,19 +190,6 @@ export function ProjectRuntimeSelector({ ))} - {fixedRuntimeSelections.length > 0 && ( - - {fixedRuntimeSelections.map((candidate) => ( - - ))} - - )} {runtimeSelectionDescription( diff --git a/src/renderer/src/i18n/locales/en-US/app.ts b/src/renderer/src/i18n/locales/en-US/app.ts index 4a30b60e..8384a031 100644 --- a/src/renderer/src/i18n/locales/en-US/app.ts +++ b/src/renderer/src/i18n/locales/en-US/app.ts @@ -210,8 +210,6 @@ export const app = { picker: 'Runtime and model', directModels: 'Direct models', defaultDirect: 'Direct · Follow the global default model', - fixedRuntimeModel: 'Fixed Runtime model', - fixedModel: 'Fixed', deepseekHarnessGroup: 'DeepSeek Harness (Developer preview · OpenAI-compatible)', manage: 'Manage Runtime and model connections', diff --git a/src/renderer/src/i18n/locales/en-US/integrations.ts b/src/renderer/src/i18n/locales/en-US/integrations.ts index dd3564dc..cbad87e2 100644 --- a/src/renderer/src/i18n/locales/en-US/integrations.ts +++ b/src/renderer/src/i18n/locales/en-US/integrations.ts @@ -46,8 +46,6 @@ export const integrations = { directDescription: 'Process messages directly with {{name}} ({{modelName}}).', defaultDirect: 'Direct · Follow the global default model', - fixedRuntimeModels: 'Agent Runtime · Fixed model', - fixedRuntimeDescription: 'Run through {{runtime}} with the fixed model {{name}}.', automaticDescription: 'Follow the global default Runtime setting.', runtimeDescription: diff --git a/src/renderer/src/i18n/locales/zh-CN/app.ts b/src/renderer/src/i18n/locales/zh-CN/app.ts index 344e62d7..dce86666 100644 --- a/src/renderer/src/i18n/locales/zh-CN/app.ts +++ b/src/renderer/src/i18n/locales/zh-CN/app.ts @@ -197,8 +197,6 @@ export const app = { picker: 'Runtime 和模型', directModels: '直连模型', defaultDirect: '直连 · 跟随全局默认模型', - fixedRuntimeModel: '固定 Runtime 模型', - fixedModel: '固定', deepseekHarnessGroup: 'DeepSeek Harness(开发者预览 · OpenAI 兼容)', manage: '管理 Runtime 和模型连接', diff --git a/src/renderer/src/i18n/locales/zh-CN/integrations.ts b/src/renderer/src/i18n/locales/zh-CN/integrations.ts index c8242960..b82d1e34 100644 --- a/src/renderer/src/i18n/locales/zh-CN/integrations.ts +++ b/src/renderer/src/i18n/locales/zh-CN/integrations.ts @@ -40,8 +40,6 @@ export const integrations = { '直接使用 {{name}}({{modelName}})处理消息。', automaticDescription: '跟随全局 Runtime 默认设置', defaultDirect: '直连 · 跟随全局默认模型', - fixedRuntimeModels: 'Agent Runtime · 固定模型', - fixedRuntimeDescription: '通过 {{runtime}} 运行,固定使用 {{name}}。', runtimeDescription: '通过 {{runtime}} Agent Runtime 运行,并跟随“Agent Runtime”设置中的全局 {{runtime}} 配置。', defaultMode: '默认模式',