Merge branch 'codex/dynamic-provider-source'

# Conflicts:
#	lib/app/app_controller_desktop_core.dart
#	test/runtime/acp_bridge_provider_hub_suite.dart
This commit is contained in:
Haitao Pan 2026-04-10 15:03:26 +08:00
commit 1399187e6b
3 changed files with 63 additions and 2 deletions

View File

@ -100,7 +100,14 @@ Future<void> refreshSingleAgentCapabilitiesRuntimeInternal(
),
);
final next = <SingleAgentProvider, SingleAgentCapabilities>{};
for (final provider in controller.configuredSingleAgentProviders) {
final candidateProviders =
normalizeSingleAgentProviderList(<SingleAgentProvider>[
...controller.configuredSingleAgentProviders,
...capabilities.providers.map(
controller.settings.resolveSingleAgentProvider,
),
]);
for (final provider in candidateProviders) {
if (!capabilities.providers.contains(provider)) {
next[provider] = const SingleAgentCapabilities.unavailable(endpoint: '');
continue;

View File

@ -319,7 +319,9 @@ extension AppControllerDesktopThreadSessions on AppController {
singleAgentShouldShowModelControlForSession(currentSessionKey);
List<SingleAgentProvider> get singleAgentProviderOptions =>
configuredSingleAgentProviders;
availableSingleAgentProviders.isNotEmpty
? availableSingleAgentProviders
: configuredSingleAgentProviders;
String singleAgentProviderLabelForSession(String sessionKey) {
return singleAgentProviderForSession(sessionKey).label;

View File

@ -119,6 +119,58 @@ void main() {
);
});
test(
'self-hosted bridge capabilities add dynamic builtin providers to the single-agent picker',
() async {
SharedPreferences.setMockInitialValues(<String, Object>{});
final store = createIsolatedTestStore(enableSecureStorage: false);
final controller = AppController(
store: store,
goTaskServiceClient: FakeGoTaskServiceClientInternal(
capabilities: ExternalCodeAgentAcpCapabilities(
singleAgent: true,
multiAgent: false,
providers: <SingleAgentProvider>{
SingleAgentProvider.codex,
SingleAgentProvider.opencode,
},
raw: <String, dynamic>{},
),
),
);
addTearDown(controller.dispose);
await _waitFor(() => !controller.initializing);
await controller.saveSettings(
controller.settings.copyWith(
acpBridgeServerModeConfig: controller
.settings
.acpBridgeServerModeConfig
.copyWith(
mode: AcpBridgeServerMode.selfHosted,
selfHosted: controller
.settings
.acpBridgeServerModeConfig
.selfHosted
.copyWith(serverUrl: 'https://xworkmate-bridge.svc.plus'),
),
),
refreshAfterSave: false,
);
await controller.refreshSingleAgentCapabilitiesInternal(
forceRefresh: true,
);
expect(
controller.singleAgentProviderOptions
.map((item) => item.providerId)
.toList(growable: false),
const <String>['codex', 'opencode'],
);
},
);
test(
'local sync-only custom provider does not appear unless bridge advertises it',
() async {