diff --git a/lib/app/app_controller_desktop_thread_actions.dart b/lib/app/app_controller_desktop_thread_actions.dart index de51fd46..c41f7c18 100644 --- a/lib/app/app_controller_desktop_thread_actions.dart +++ b/lib/app/app_controller_desktop_thread_actions.dart @@ -231,6 +231,7 @@ extension AppControllerDesktopThreadActions on AppController { nextTarget, sessionKey: nextSessionKey, persistDefaultSelection: false, + preserveGatewayHistoryForSelectedThread: false, ); if (nextTarget == AssistantExecutionTarget.singleAgent) { await refreshSingleAgentSkillsForSession(nextSessionKey); diff --git a/lib/app/app_controller_desktop_workspace_execution.dart b/lib/app/app_controller_desktop_workspace_execution.dart index a142aa9a..1aeefafd 100644 --- a/lib/app/app_controller_desktop_workspace_execution.dart +++ b/lib/app/app_controller_desktop_workspace_execution.dart @@ -188,6 +188,7 @@ extension AppControllerDesktopWorkspaceExecution on AppController { AssistantExecutionTarget target, { required String sessionKey, required bool persistDefaultSelection, + bool preserveGatewayHistoryForSelectedThread = true, }) async { final resolvedTarget = sanitizePersistedExecutionTargetInternal(target); final normalizedSessionKey = normalizedAssistantSessionKeyInternal( @@ -215,7 +216,8 @@ extension AppControllerDesktopWorkspaceExecution on AppController { } if (resolvedTarget == AssistantExecutionTarget.singleAgent) { - if (runtimeInternal.isConnected) { + if (preserveGatewayHistoryForSelectedThread && + runtimeInternal.isConnected) { preserveGatewayHistoryForSessionInternal(normalizedSessionKey); } await ensureActiveAssistantThreadInternal(); diff --git a/test/runtime/app_controller_execution_target_switch_suite_thread.dart b/test/runtime/app_controller_execution_target_switch_suite_thread.dart index cae2633a..24fe1013 100644 --- a/test/runtime/app_controller_execution_target_switch_suite_thread.dart +++ b/test/runtime/app_controller_execution_target_switch_suite_thread.dart @@ -203,6 +203,76 @@ void registerExecutionTargetSwitchThreadTests() { }, ); + test( + 'AppController does not attach the previous desktop gateway history to a fresh single-agent task thread', + () async { + SharedPreferences.setMockInitialValues({}); + final tempDirectory = await Directory.systemTemp.createTemp( + 'xworkmate-thread-new-task-history-isolation-', + ); + addTearDown(() async { + await deleteDirectoryWithRetryInternal(tempDirectory); + }); + final store = SecureConfigStore( + enableSecureStorage: false, + databasePathResolver: () async => '${tempDirectory.path}/settings.db', + fallbackDirectoryPathResolver: () async => tempDirectory.path, + ); + final gateway = FakeGatewayRuntimeInternal(store: store); + final controller = AppController( + store: store, + runtimeCoordinator: RuntimeCoordinator( + gateway: gateway, + codex: FakeCodexRuntimeInternal(), + ), + ); + addTearDown(controller.dispose); + + await waitForInternal(() => !controller.initializing); + await controller.saveSettings( + controller.settings.copyWith( + workspacePath: tempDirectory.path, + assistantExecutionTarget: AssistantExecutionTarget.local, + ), + refreshAfterSave: false, + ); + + await controller.setAssistantExecutionTarget( + AssistantExecutionTarget.local, + ); + controller.chatControllerInternal.messagesInternal = [ + GatewayChatMessage( + id: 'gateway-old-message', + role: 'assistant', + text: 'previous desktop gateway history', + timestampMs: DateTime.now().millisecondsSinceEpoch.toDouble(), + toolCallId: null, + toolName: null, + stopReason: null, + pending: false, + error: false, + ), + ]; + + controller.initializeAssistantThreadContext( + 'draft:fresh-thread', + title: '新对话', + executionTarget: AssistantExecutionTarget.singleAgent, + ); + await controller.switchSession('draft:fresh-thread'); + + expect( + controller.gatewayHistoryCacheInternal['draft:fresh-thread'], + isNull, + ); + expect( + controller.assistantThreadMessagesInternal['draft:fresh-thread'] ?? + const [], + isEmpty, + ); + }, + ); + test('AppController persists markdown view mode per thread', () async { SharedPreferences.setMockInitialValues({}); final tempDirectory = await Directory.systemTemp.createTemp(