fix: align channel runtime and settings UI
This commit is contained in:
@@ -2,7 +2,8 @@ import type { ResolvedRuntimeSettings } from '../runtime-settings-store'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import {
|
||||
applyRuntimeSelection,
|
||||
getConfiguredRuntimeTarget
|
||||
getConfiguredRuntimeTarget,
|
||||
resolveConfiguredAgentRuntimeSelection
|
||||
} from './runtime-selection'
|
||||
|
||||
const defaultProfileId = '00000000-0000-4000-8000-000000000001'
|
||||
@@ -148,6 +149,41 @@ describe('runtime selection', () => {
|
||||
).toThrow('自动启动')
|
||||
})
|
||||
|
||||
it('resolves Agent Runtime backends from the global Runtime configuration', () => {
|
||||
const base = settings()
|
||||
const configured = settings({
|
||||
opencodeModelProfile: base.modelProfiles[1],
|
||||
continueModelProfile: base.modelProfiles[2]
|
||||
})
|
||||
|
||||
expect(
|
||||
resolveConfiguredAgentRuntimeSelection(configured, {
|
||||
provider: 'opencode',
|
||||
profileId: defaultProfileId
|
||||
})
|
||||
).toEqual({
|
||||
provider: 'opencode',
|
||||
profileId: secondProfileId
|
||||
})
|
||||
expect(
|
||||
resolveConfiguredAgentRuntimeSelection(configured, {
|
||||
provider: 'continue'
|
||||
})
|
||||
).toEqual({
|
||||
provider: 'continue',
|
||||
profileId: responsesProfileId
|
||||
})
|
||||
expect(
|
||||
resolveConfiguredAgentRuntimeSelection(configured, {
|
||||
provider: 'model',
|
||||
profileId: defaultProfileId
|
||||
})
|
||||
).toEqual({
|
||||
provider: 'model',
|
||||
profileId: defaultProfileId
|
||||
})
|
||||
})
|
||||
|
||||
it('routes legacy automatic settings through local OpenCode when the Server is blank', () => {
|
||||
expect(getConfiguredRuntimeTarget(settings())).toBe('opencode')
|
||||
expect(
|
||||
|
||||
@@ -35,6 +35,26 @@ export function getConfiguredRuntimeTarget(
|
||||
return 'model'
|
||||
}
|
||||
|
||||
export function resolveConfiguredAgentRuntimeSelection(
|
||||
settings: ResolvedRuntimeSettings,
|
||||
selection: AgentRuntimeSelection
|
||||
): AgentRuntimeSelection {
|
||||
if (
|
||||
selection.provider !== 'opencode' &&
|
||||
selection.provider !== 'continue'
|
||||
) {
|
||||
return selection
|
||||
}
|
||||
const profile =
|
||||
selection.provider === 'opencode'
|
||||
? settings.opencodeModelProfile
|
||||
: settings.continueModelProfile
|
||||
return {
|
||||
provider: selection.provider,
|
||||
...(profile ? { profileId: profile.id } : {})
|
||||
}
|
||||
}
|
||||
|
||||
export function applyRuntimeSelection(
|
||||
settings: ResolvedRuntimeSettings,
|
||||
selection: AgentRuntimeSelection
|
||||
|
||||
@@ -1185,8 +1185,8 @@ describe('AssistantDatabase', () => {
|
||||
rootPath: channelProject.rootPath,
|
||||
defaultWorkMode: channelProject.defaultWorkMode,
|
||||
runtimeSelection: {
|
||||
provider: 'model',
|
||||
profileId: removedProfileId
|
||||
provider: 'opencode',
|
||||
profileId: runtimeProfileId
|
||||
}
|
||||
})
|
||||
const imageChannelProject = database.ensureChannelProjects(
|
||||
@@ -1257,8 +1257,7 @@ describe('AssistantDatabase', () => {
|
||||
{ provider: 'model', profileId: runtimeProfileId }
|
||||
])
|
||||
expect(database.getProject(channelProject.id).runtimeSelection).toEqual({
|
||||
provider: 'model',
|
||||
profileId: defaultProfileId
|
||||
provider: 'opencode'
|
||||
})
|
||||
expect(
|
||||
database.getProject(imageChannelProject.id).runtimeSelection
|
||||
|
||||
+23
-5
@@ -973,15 +973,18 @@ describe('registerIpcHandlers agent terminal state', () => {
|
||||
respond: vi.fn(),
|
||||
clear: vi.fn()
|
||||
}
|
||||
const getResolvedSettings = vi.fn(
|
||||
async (): Promise<Record<string, unknown>> => ({
|
||||
toolApproval,
|
||||
subagentSmartRoutingEnabled: smartRoutingEnabled
|
||||
})
|
||||
)
|
||||
const dispose = registerIpcHandlers(
|
||||
window as never,
|
||||
runtime as never,
|
||||
'CommandOrControl+Shift+Space',
|
||||
{
|
||||
getResolvedSettings: vi.fn(async () => ({
|
||||
toolApproval,
|
||||
subagentSmartRoutingEnabled: smartRoutingEnabled
|
||||
}))
|
||||
getResolvedSettings
|
||||
} as never,
|
||||
{} as never,
|
||||
contextManager as never,
|
||||
@@ -1009,6 +1012,7 @@ describe('registerIpcHandlers agent terminal state', () => {
|
||||
assistantDatabase,
|
||||
contextManager,
|
||||
dispose,
|
||||
getResolvedSettings,
|
||||
clearHandler: electronMocks.handlers.get(
|
||||
ipcChannels.appClearLocalData
|
||||
),
|
||||
@@ -2240,6 +2244,8 @@ describe('registerIpcHandlers agent terminal state', () => {
|
||||
|
||||
it('routes remote Execute to a configured Agent Runtime without a GoodBuddy approval callback', async () => {
|
||||
let receivedAuthorize: unknown = 'not-called'
|
||||
const configuredProfileId =
|
||||
'00000000-0000-4000-8000-000000000019'
|
||||
const selectedRuntime = {
|
||||
runtimeId: 'continue',
|
||||
capability: 'chat',
|
||||
@@ -2282,6 +2288,11 @@ describe('registerIpcHandlers agent terminal state', () => {
|
||||
false,
|
||||
selectedRuntimes
|
||||
)
|
||||
harness.getResolvedSettings.mockResolvedValue({
|
||||
toolApproval: 'always',
|
||||
subagentSmartRoutingEnabled: false,
|
||||
continueModelProfile: { id: configuredProfileId }
|
||||
})
|
||||
vi.mocked(
|
||||
harness.assistantDatabase.listProjects
|
||||
).mockReturnValue([
|
||||
@@ -2323,9 +2334,16 @@ describe('registerIpcHandlers agent terminal state', () => {
|
||||
output: 'Continue 已执行'
|
||||
})
|
||||
expect(selectedRuntimes.getRuntime).toHaveBeenCalledWith(
|
||||
{ provider: 'continue' },
|
||||
{ provider: 'continue', profileId: configuredProfileId },
|
||||
'C:\\ProjectWorkspace'
|
||||
)
|
||||
expect(
|
||||
harness.assistantDatabase.getOrCreateRemoteConversation
|
||||
).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
runtimeSelection: { provider: 'continue' }
|
||||
})
|
||||
)
|
||||
expect(receivedAuthorize).toBeUndefined()
|
||||
expect(harness.approvalBroker.request).not.toHaveBeenCalled()
|
||||
await harness.dispose()
|
||||
|
||||
+16
-3
@@ -121,6 +121,7 @@ import {
|
||||
createDefaultModelRuntime,
|
||||
createModelProfileRuntime
|
||||
} from './agent/create-runtime'
|
||||
import { resolveConfiguredAgentRuntimeSelection } from './agent/runtime-selection'
|
||||
import { safeToolErrorDetail } from './agent/approval-summary'
|
||||
import { ReasoningTagStreamParser } from './agent/reasoning-stream'
|
||||
import type { BundledRuntimePaths } from './agent/bundled-runtimes'
|
||||
@@ -576,6 +577,7 @@ export function registerIpcHandlers(
|
||||
const resolveRequestRuntime = async (
|
||||
request: Pick<AgentRequest, 'projectId' | 'runtimeSelection'> & {
|
||||
workspaceOverride?: string
|
||||
followConfiguredAgentRuntime?: boolean
|
||||
}
|
||||
): Promise<AgentRuntime> => {
|
||||
const projectWorkspace =
|
||||
@@ -586,8 +588,14 @@ export function registerIpcHandlers(
|
||||
if (!selectedRuntimes || (!request.runtimeSelection && !projectWorkspace)) {
|
||||
return runtime
|
||||
}
|
||||
const selection =
|
||||
let selection =
|
||||
request.runtimeSelection ?? ({ provider: 'auto' } as const)
|
||||
if (request.followConfiguredAgentRuntime) {
|
||||
selection = resolveConfiguredAgentRuntimeSelection(
|
||||
await settingsStore.getResolvedSettings(),
|
||||
selection
|
||||
)
|
||||
}
|
||||
return projectWorkspace
|
||||
? selectedRuntimes.getRuntime(selection, projectWorkspace)
|
||||
: selectedRuntimes.getRuntime(selection)
|
||||
@@ -830,6 +838,7 @@ export function registerIpcHandlers(
|
||||
rootPath: string
|
||||
conversationId: string
|
||||
runtimeSelection: AgentRuntimeSelection
|
||||
followConfiguredAgentRuntime?: boolean
|
||||
runtime?: AgentRuntime
|
||||
taskId?: string
|
||||
contextIds?: string[]
|
||||
@@ -888,7 +897,9 @@ export function registerIpcHandlers(
|
||||
(await resolveRequestRuntime({
|
||||
projectId: schedule.projectId,
|
||||
runtimeSelection: remoteContext?.runtimeSelection,
|
||||
workspaceOverride: remoteContext?.rootPath
|
||||
workspaceOverride: remoteContext?.rootPath,
|
||||
followConfiguredAgentRuntime:
|
||||
remoteContext?.followConfiguredAgentRuntime
|
||||
}))
|
||||
const agentRuntimeSelected = isAgentRuntime(requestRuntime)
|
||||
const channelToolPolicy =
|
||||
@@ -1455,7 +1466,8 @@ export function registerIpcHandlers(
|
||||
executionRuntime = await resolveRequestRuntime({
|
||||
projectId: project.id,
|
||||
runtimeSelection,
|
||||
workspaceOverride: project.rootPath
|
||||
workspaceOverride: project.rootPath,
|
||||
followConfiguredAgentRuntime: true
|
||||
})
|
||||
executionStatus = await executionRuntime.getStatus()
|
||||
} catch (error) {
|
||||
@@ -1546,6 +1558,7 @@ export function registerIpcHandlers(
|
||||
rootPath: project.rootPath,
|
||||
conversationId: remoteConversation.id,
|
||||
runtimeSelection,
|
||||
followConfiguredAgentRuntime: true,
|
||||
runtime: executionRuntime,
|
||||
taskId: remoteTaskId,
|
||||
contextIds,
|
||||
|
||||
Reference in New Issue
Block a user