Skip to content

[fix]: Fix live runtime settings refresh#27

Draft
zzj3720 wants to merge 1 commit into
mainfrom
codex/runtime-settings-hot-reload
Draft

[fix]: Fix live runtime settings refresh#27
zzj3720 wants to merge 1 commit into
mainfrom
codex/runtime-settings-hot-reload

Conversation

@zzj3720
Copy link
Copy Markdown

@zzj3720 zzj3720 commented May 15, 2026

Summary

  • lazy-load restored local agent sessions so clicking an interrupted conversation after restart does not recreate the runtime agent immediately
  • hot-reload local permission mode into active connector/session state, including auto-approving pending host-access requests when switching to Full Access
  • broadcast AI provider setting changes so the chat composer and settings list reload providers/models without restarting the app

Validation

  • swiftformat on modified Swift files
  • swiftlint lint on modified Swift files
  • git diff --check
  • macOS mini-machine: BUILD_CONFIGURATION=UnsignedDebug bash DevKit/Scripts/workspace_build_debug.sh (BUILD SUCCEEDED)
  • macOS mini-machine manual smoke:
    • saved an OpenAI API-token configuration in Settings and verified the chat composer changed from “Set up AI provider” to the GPT-5 (OpenAI) selector without restarting
    • changed the composer permission selector from Default permission to Full Access and verified the active UI updated immediately
    • restarted the app, opened a seeded interrupted conversation containing a pending permission request, and verified the conversation rendered and the app stayed responsive instead of freezing

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes three live runtime configuration refresh issues: restored local agent sessions are now lazy-loaded (no premature Agent creation when reopening interrupted conversations), the local permission mode hot-reloads into the active connector/session (auto-approving pending host-access requests when switching to Full Access), and AI provider settings changes are broadcast so the chat composer and settings list refresh without an app restart.

Changes:

  • Lazy-load the local KWWK Agent by removing ensureLocalAgent() from LocalAgentSession.setup() and adding refreshRuntimeConfiguration() to update model/system prompt of an already-instantiated agent.
  • Hot-apply local permission mode via new LocalRuntimeConnector.applyPermissionModeChange plus a respondsToPermissionMode flag on PendingConfirmation to auto-approve host-access prompts (excluding ComputerUse start) when switching to Full Access; clear grants when reverting to Default.
  • Add aiProviderSettingsDidChange notification posted by AIProviderDetailView after every save/sign-in/reset; AIProvidersSettingsView and ChatEditorViewModel subscribe to reload providers/models, and BridgeAIProviderRegistry.selectedModel(settings:) now falls back to the default model when the selected provider is disabled.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
macos/OpenBridge/Notifications/NotificationNames.swift Adds aiProviderSettingsDidChange notification name.
macos/OpenBridge/Interface/Settings/AIProviders/AIProvidersSettingsView.swift Reloads provider list on the new notification.
macos/OpenBridge/Interface/Settings/AIProviders/AIProviderDetailView.swift Posts the notification and reloads provider configuration after save/sign-in/reset.
macos/OpenBridge/Interface/Chat/ChatEditorViewModel+ComposerEditing.swift Calls applyLocalEnvironmentPermissionModeChange when the composer toggles permission mode.
macos/OpenBridge/Interface/Chat/ChatEditorViewModel.swift Subscribes to provider-settings notifications to refresh selected model.
macos/OpenBridge/Agent/LocalRuntime/OpenBridgeSystemPromptBuilder.swift Injects mode-specific permission instructions into the system prompt.
macos/OpenBridge/Agent/LocalRuntime/LocalRuntimeConnector.swift Adds permission-mode hot-apply and per-pending respondsToPermissionMode flag.
macos/OpenBridge/Agent/LocalRuntime/LocalAgentSession.swift Removes eager ensureLocalAgent() from setup and adds refreshRuntimeConfiguration plus extracted system-prompt builder.
macos/OpenBridge/Agent/BridgeAIProviderRegistry.swift Adds selectedModel(settings:) that falls back to default if the selected provider is disabled.
macos/OpenBridge/Agent/AgentSessionManager.swift Reworks refreshConnectorConfiguration to ensure runtime; adds applyLocalEnvironmentPermissionModeChange and reloadAIProviderConfiguration.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +153 to +162
func applyPermissionModeChange(_ mode: LocalEnvironmentPermissionMode) {
guard environmentKind == .localMacOS else { return }

switch mode {
case .default:
clearAllGrantedPermissions()
case .fullAccess:
approvePendingHostAccessPermissions()
}
}
Comment on lines 160 to 171
func refreshConnectorConfiguration() {
isVMReady = true
Task { [weak self] in
guard let self else { return }
do {
_ = try await ensureRuntimeReady()
await refreshLoadedSessionRuntimeConfiguration()
} catch {
vmLoadError = error
logger.warning("Failed to refresh local connector configuration: \(error.localizedDescription)")
}
}
}
Comment on lines +324 to +326
guard let localAgent else { return }
localAgent.state.model = await BridgeAIProviderRegistry.selectedModel()
localAgent.state.systemPrompt = await makeLocalAgentSystemPrompt()
Comment on lines +57 to 69
static func selectedModel(settings: BridgeAIProviderSettings) -> Model {
let selected = runtimeModel(
provider: settings.selectedModelProvider,
id: settings.selectedModelID,
settings: settings
) ?? defaultModel(settings: settings)
)
.flatMap { model in
BridgeAIProvider.provider(for: model).flatMap { provider in
settings[provider].isEnabled ? model : nil
}
}
return selected ?? defaultModel(settings: settings)
}
Comment on lines 42 to +79
@@ -59,6 +60,24 @@ enum OpenBridgeSystemPromptBuilder {
"""
}

private static func localPermissionModeInstruction() -> String {
switch SettingsManager.shared.localEnvironmentPermissionMode {
case .default:
"- Current local permission mode: Default. Host writes, host commands, and sensitive host paths require request_permission before use."
case .fullAccess:
"- Current local permission mode: Full Access. Host writes, host commands, and sensitive host paths are already approved for this app session; do not call request_permission solely for local permission, but still prefer sandbox unless local access is required."
}
}

private static func localPermissionRequestInstruction() -> String {
switch SettingsManager.shared.localEnvironmentPermissionMode {
case .default:
"- Before using bash, write, or edit in environment=\"local\", call request_permission(environment=\"local\", description=\"...\") with a clear, specific description of what you plan to do so the user can make an informed decision."
case .fullAccess:
"- Before using bash, write, or edit in environment=\"local\", confirm local access is truly required; request_permission is not needed while Full Access is active."
}
}
Comment on lines +659 to +664
private func applyProviderConfigurationChange() async {
await AgentSessionManager.shared.reloadAIProviderConfiguration()
await MainActor.run {
NotificationCenter.default.post(name: .aiProviderSettingsDidChange, object: nil)
}
}
@zanwei zanwei changed the title Fix live runtime settings refresh [fix]: Fix live runtime settings refresh May 15, 2026
@zzj3720 zzj3720 force-pushed the codex/runtime-settings-hot-reload branch from f006b29 to 2463712 Compare May 15, 2026 09:00
@zzj3720
Copy link
Copy Markdown
Author

zzj3720 commented May 15, 2026

Addressed Copilot review comments in 2463712:

  • Switching back to Default now only revokes cached local grants; it no longer expires unrelated pending confirmations.
  • Restored the immediate isVMReady = true/error-clear signal before async connector refresh.
  • Runtime model/system-prompt refreshes are deferred while a local run is active and applied after finish/cancel.
  • Moved selected-model fallback into shared registry helpers and routed composer loading through them.
  • Made Full Access prompt wording non-contradictory with the temporary-permission rule.
  • Provider save/sign-in/reset now reloads/broadcasts only when settings or auth secrets actually changed.

Validation after the follow-up:

  • local swiftformat / swiftlint on changed files (existing type-body-length warning only) and git diff --check
  • macOS mini-machine UnsignedDebug build succeeded after embedded web assets were rebuilt
  • manual UI smoke on mini-machine: app launched, provider save hot-loaded the GPT-5 (OpenAI) selector without restart, and permission selector toggled Full Access → Default without freezing/crashing
  • PR checks are green (Repository Hygiene, Sandbox VM Go Tests, Web)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants