From eeaaec0458861cd3c91cf7d4271dee00da1896ca Mon Sep 17 00:00:00 2001 From: Haitao Pan Date: Wed, 22 Apr 2026 10:17:51 +0800 Subject: [PATCH] fix bridge readiness checks --- ...pp_controller_desktop_runtime_helpers.dart | 12 +++- ...app_controller_desktop_thread_actions.dart | 8 +-- .../assistant_connection_state_test.dart | 18 ++++++ .../assistant_execution_target_test.dart | 58 ++++++++++++++++--- 4 files changed, 83 insertions(+), 13 deletions(-) diff --git a/lib/app/app_controller_desktop_runtime_helpers.dart b/lib/app/app_controller_desktop_runtime_helpers.dart index 62b14346..89349967 100644 --- a/lib/app/app_controller_desktop_runtime_helpers.dart +++ b/lib/app/app_controller_desktop_runtime_helpers.dart @@ -645,7 +645,17 @@ extension AppControllerDesktopRuntimeHelpers on AppController { } bool isBridgeAcpRuntimeConfiguredInternal() { - return true; + final bridgeEndpoint = resolveBridgeAcpEndpointInternal(); + if (bridgeEndpoint == null) { + return false; + } + final accountSyncState = settingsControllerInternal.accountSyncState; + if (settingsControllerInternal.accountSignedIn && + accountSyncState?.tokenConfigured.bridge == true) { + return true; + } + final envToken = runtimeEnvironmentValueInternal('BRIDGE_AUTH_TOKEN'); + return envToken != null && envToken.isNotEmpty; } Uri? resolveExternalAcpEndpointForRequestInternal( diff --git a/lib/app/app_controller_desktop_thread_actions.dart b/lib/app/app_controller_desktop_thread_actions.dart index 0857b6c4..0ea1a8b9 100644 --- a/lib/app/app_controller_desktop_thread_actions.dart +++ b/lib/app/app_controller_desktop_thread_actions.dart @@ -233,12 +233,10 @@ extension AppControllerDesktopThreadActions on AppController { }) async { final currentSessionKey = sessionsControllerInternal.currentSessionKey; final currentTarget = assistantExecutionTargetForSession(currentSessionKey); - if (!isBridgeAcpRuntimeConfiguredInternal()) { + final connectionState = currentAssistantConnectionState; + if (!connectionState.connected) { final error = StateError( - appText( - 'xworkmate-bridge 未连接。请先登录 svc.plus 同步 Bridge 访问,或保存手动 Bridge 配置。', - 'xworkmate-bridge is not connected. Sign in to svc.plus and sync Bridge access, or save a manual Bridge configuration first.', - ), + connectionState.detailLabel, ); appendAssistantThreadMessageInternal( currentSessionKey, diff --git a/test/runtime/assistant_connection_state_test.dart b/test/runtime/assistant_connection_state_test.dart index cb5738c6..36f80779 100644 --- a/test/runtime/assistant_connection_state_test.dart +++ b/test/runtime/assistant_connection_state_test.dart @@ -7,6 +7,24 @@ import 'package:xworkmate/runtime/secure_config_store.dart'; void main() { group('Assistant connection state', () { + test('does not report bridge runtime configured by default', () async { + final controller = await _isolatedController( + initialBridgeProviderCatalog: const [ + SingleAgentProvider.codex, + ], + initialGatewayProviderCatalog: const [ + SingleAgentProvider.openclaw, + ], + initialAvailableExecutionTargets: const [ + AssistantExecutionTarget.agent, + AssistantExecutionTarget.gateway, + ], + ); + addTearDown(controller.dispose); + + expect(controller.isBridgeAcpRuntimeConfiguredInternal(), isFalse); + }); + test( 'keeps signed-out sessions disconnected even when provider catalogs exist', () async { diff --git a/test/runtime/assistant_execution_target_test.dart b/test/runtime/assistant_execution_target_test.dart index 9e9712cc..fb5141c2 100644 --- a/test/runtime/assistant_execution_target_test.dart +++ b/test/runtime/assistant_execution_target_test.dart @@ -267,6 +267,16 @@ void main() { enableSecureStorage: false, ); await store.initialize(); + await store.saveAccountSessionToken('session-token'); + await store.saveAccountSessionSummary( + const AccountSessionSummary( + userId: 'user-1', + email: 'review@svc.plus', + name: 'Review User', + role: 'reviewer', + mfaEnabled: true, + ), + ); await store.saveAccountSyncState( AccountSyncState.defaults().copyWith( syncedDefaults: AccountRemoteProfile.defaults().copyWith( @@ -362,7 +372,7 @@ void main() { isA().having( (error) => error.message, 'message', - contains('xworkmate-bridge 未连接'), + contains('请先登录 svc.plus'), ), ), ); @@ -370,7 +380,7 @@ void main() { expect(fakeGoTaskService.executeCount, 0); expect( controller.chatMessages.last.text, - contains('xworkmate-bridge 未连接'), + contains('请先登录 svc.plus'), ); }, ); @@ -403,6 +413,16 @@ void main() { enableSecureStorage: false, ); await store.initialize(); + await store.saveAccountSessionToken('session-token'); + await store.saveAccountSessionSummary( + const AccountSessionSummary( + userId: 'user-1', + email: 'review@svc.plus', + name: 'Review User', + role: 'reviewer', + mfaEnabled: true, + ), + ); await store.saveAccountSyncState( AccountSyncState.defaults().copyWith( syncedDefaults: AccountRemoteProfile.defaults().copyWith( @@ -424,7 +444,9 @@ void main() { final controller = AppController( store: store, goTaskServiceClient: fakeGoTaskService, - environmentOverride: {}, + environmentOverride: { + 'BRIDGE_AUTH_TOKEN': 'bridge-token', + }, initialAvailableExecutionTargets: const [ AssistantExecutionTarget.agent, AssistantExecutionTarget.gateway, @@ -432,8 +454,30 @@ void main() { ); addTearDown(controller.dispose); + controller.settingsControllerInternal.accountSessionTokenInternal = + 'session-token'; + controller.settingsControllerInternal.accountSessionInternal = + const AccountSessionSummary( + userId: 'user-1', + email: 'review@svc.plus', + name: 'Review User', + role: 'reviewer', + mfaEnabled: true, + ); + controller.settingsControllerInternal.accountSyncStateInternal = + AccountSyncState.defaults().copyWith( + syncedDefaults: AccountRemoteProfile.defaults().copyWith( + bridgeServerUrl: capture.baseEndpoint.toString(), + ), + syncState: 'ready', + tokenConfigured: const AccountTokenConfigured( + bridge: true, + vault: false, + apisix: false, + ), + ); + await controller.sessionsController.switchSession('session-1'); - await _waitForRequest(capture, minimumCount: 1); await controller.setAssistantExecutionTarget( AssistantExecutionTarget.agent, ); @@ -445,14 +489,14 @@ void main() { isA().having( (error) => error.message, 'message', - contains('agent provider'), + contains('正在加载 Bridge 能力'), ), ), ); expect(fakeGoTaskService.executeCount, 0); - expect(capture.requestCount, greaterThanOrEqualTo(3)); - expect(controller.chatMessages.last.text, contains('agent provider')); + expect(capture.requestCount, lessThanOrEqualTo(2)); + expect(controller.chatMessages.last.text, contains('正在加载 Bridge 能力')); }, ); });