import 'gateway_acp_client.dart'; import 'runtime_dispatch_resolver.dart'; import 'runtime_external_code_agents.dart'; class GoRuntimeDispatchDesktopClient implements RuntimeDispatchResolver { GoRuntimeDispatchDesktopClient({ required GatewayAcpClient client, required Uri? Function() endpointResolver, }) : _client = client, _endpointResolver = endpointResolver; final GatewayAcpClient _client; final Uri? Function() _endpointResolver; @override Future selectProviderId({ required List providers, String preferredProviderId = '', Iterable requiredCapabilities = const [], }) async { final response = await _client.request( method: 'xworkmate.routing.resolve', params: { 'routing': { 'routingMode': 'auto', if (preferredProviderId.trim().isNotEmpty) 'preferredGatewayProviderId': preferredProviderId.trim(), 'explicitExecutionTarget': '', 'explicitProviderId': preferredProviderId.trim(), 'explicitModel': '', 'explicitSkills': const [], 'allowSkillInstall': false, 'availableSkills': const [], }, 'preferredProviderId': preferredProviderId.trim(), 'requiredCapabilities': requiredCapabilities .map((item) => item.trim()) .where((item) => item.isNotEmpty) .toList(growable: false), 'providers': providers.map(_providerToJson).toList(growable: false), }, endpointOverride: _endpointResolver(), ); final result = _castMap(response['result']); return result['providerId']?.toString().trim().isNotEmpty == true ? result['providerId'].toString().trim() : null; } @override Future resolveGatewayDispatch({ required List providers, required String preferredProviderId, required Iterable requiredCapabilities, required Map nodeState, required Map nodeInfo, }) async { final response = await _client.request( method: 'xworkmate.routing.resolve', params: { 'routing': { 'routingMode': 'auto', if (preferredProviderId.trim().isNotEmpty) 'preferredGatewayProviderId': preferredProviderId.trim(), 'explicitExecutionTarget': '', 'explicitProviderId': preferredProviderId.trim(), 'explicitModel': '', 'explicitSkills': const [], 'allowSkillInstall': false, 'availableSkills': const [], }, 'preferredProviderId': preferredProviderId.trim(), 'requiredCapabilities': requiredCapabilities .map((item) => item.trim()) .where((item) => item.isNotEmpty) .toList(growable: false), 'providers': providers.map(_providerToJson).toList(growable: false), 'nodeState': nodeState, 'nodeInfo': nodeInfo, }, endpointOverride: _endpointResolver(), ); final result = _castMap(response['result']); return RuntimeDispatchResolution( agentId: result['agentId']?.toString().trim().isNotEmpty == true ? result['agentId'].toString().trim() : null, providerId: result['providerId']?.toString().trim().isNotEmpty == true ? result['providerId'].toString().trim() : null, metadata: _castMap(result['metadata']), raw: result, ); } @override Future dispose() => _client.dispose(); Map _providerToJson(ExternalCodeAgentProvider provider) { return { 'id': provider.id, 'name': provider.name, 'defaultArgs': provider.defaultArgs, 'capabilities': provider.capabilities, }; } Map _castMap(Object? value) { if (value is Map) { return value; } if (value is Map) { return value.cast(); } return const {}; } }