From 86e630bb8a31dd173c8bc405d9edc54553e2031a Mon Sep 17 00:00:00 2001 From: onevcat Date: Fri, 31 Jul 2026 14:39:49 +0900 Subject: [PATCH] Reset runtime-specific agent profile settings --- docs/components/agent-profiles.md | 4 ++++ .../Reducer/AgentProfileEditorFeature.swift | 12 ++++++++++++ .../Views/AgentProfileEditorView.swift | 8 +++++++- .../AgentProfileEditorFeatureTests.swift | 18 ++++++++++++++++++ 4 files changed, 41 insertions(+), 1 deletion(-) diff --git a/docs/components/agent-profiles.md b/docs/components/agent-profiles.md index afe0b4e1..fac24026 100644 --- a/docs/components/agent-profiles.md +++ b/docs/components/agent-profiles.md @@ -46,6 +46,10 @@ sidebar remains available. Adding a profile opens the same editor immediately. Changing another Settings sidebar section leaves the editor and opens that section's root. +Changing a profile's **Agent** resets its Model, Reasoning Effort, and Extra +Arguments to the new runtime defaults. Those values are runtime-specific; add +new values after choosing the destination agent. + **Recommended** resolves in three tiers: the repo's **Default Agent Profile** (Repo Settings) → the last profile explicitly launched in this repo → the first enabled profile in the Settings list order. Each tier only matches an diff --git a/supacode/Features/Settings/Reducer/AgentProfileEditorFeature.swift b/supacode/Features/Settings/Reducer/AgentProfileEditorFeature.swift index d7f2af37..cb858235 100644 --- a/supacode/Features/Settings/Reducer/AgentProfileEditorFeature.swift +++ b/supacode/Features/Settings/Reducer/AgentProfileEditorFeature.swift @@ -25,6 +25,7 @@ struct AgentProfileEditorFeature { enum Action: BindableAction { case task + case runtimeChanged(AgentProfileRuntime) case binding(BindingAction) case removeTapped case revealProfileFiles @@ -57,6 +58,17 @@ struct AgentProfileEditorFeature { refreshHomeStatus(&state) return .none + case .runtimeChanged(let runtime): + guard state.profile.runtime != runtime else { return .none } + // Model, effort, and literal CLI arguments belong to the selected + // runtime. Keep only cross-runtime profile settings on a switch. + state.profile.runtime = runtime + state.profile.model = nil + state.profile.reasoningEffort = nil + state.profile.extraArguments = "" + refreshHomeStatus(&state) + return .send(.delegate(.profileEdited(state.profile))) + case .binding: // `.unrestricted` is never applied silently: the change reverts until // the user explicitly confirms it (docs-ai 053). diff --git a/supacode/Features/Settings/Views/AgentProfileEditorView.swift b/supacode/Features/Settings/Views/AgentProfileEditorView.swift index 00b1266b..8f838152 100644 --- a/supacode/Features/Settings/Views/AgentProfileEditorView.swift +++ b/supacode/Features/Settings/Views/AgentProfileEditorView.swift @@ -22,7 +22,13 @@ struct AgentProfileEditorView: View { private var profileSection: some View { Section("Profile") { TextField("Name", text: $store.profile.name) - Picker("Agent", selection: $store.profile.runtime) { + Picker( + "Agent", + selection: Binding( + get: { store.profile.runtime }, + set: { store.send(.runtimeChanged($0)) } + ) + ) { ForEach(AgentProfileRuntime.allCases) { runtime in Text(AgentRuntimeAdapterRegistry.displayName(for: runtime.agent)).tag(runtime) } diff --git a/supacodeTests/AgentProfileEditorFeatureTests.swift b/supacodeTests/AgentProfileEditorFeatureTests.swift index dc98e483..d44bfd54 100644 --- a/supacodeTests/AgentProfileEditorFeatureTests.swift +++ b/supacodeTests/AgentProfileEditorFeatureTests.swift @@ -22,6 +22,24 @@ struct AgentProfileEditorFeatureTests { await store.receive(\.delegate.profileEdited) } + @Test(.dependencies) func changingRuntimeClearsRuntimeSpecificConfiguration() async { + var profile = AgentProfile(name: "Codex", runtime: .codex) + profile.model = "gpt-5.6-sol" + profile.reasoningEffort = "xhigh" + profile.extraArguments = "--search" + let store = TestStore(initialState: AgentProfileEditorFeature.State(profile: profile)) { + AgentProfileEditorFeature() + } + + await store.send(.runtimeChanged(.claude)) { + $0.profile.runtime = .claude + $0.profile.model = nil + $0.profile.reasoningEffort = nil + $0.profile.extraArguments = "" + } + await store.receive(\.delegate.profileEdited) + } + @Test(.dependencies) func unrestrictedRequiresExplicitConfirmation() async { let profile = AgentProfile(name: "Codex", runtime: .codex) let storage = SettingsTestStorage() -- 2.51.2