From a908b5118f2283c46a138ed2966c0911082dfd01 Mon Sep 17 00:00:00 2001 From: Cowork 3P Date: Thu, 4 Jun 2026 05:34:58 +0000 Subject: [PATCH] refactor: remove multi-agent orchestration subsystem (Path B) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove the entire multi-agent collaboration execution path, including: - MultiAgentOrchestrator and its 4-phase pipeline (Architect→Engineer→Tester→Iteration) - ARIS framework preset and mount infrastructure - Hardcoded model defaults (kimi-k2.5, minimax-m2.7, glm-5) - Deprecated runCliPromptInternal() and its fallback call chain - All related types: MultiAgentConfig, AgentWorkerConfig, MultiAgentRole, etc. This collapses the architecture to a single clean path: Flutter → GoTaskServiceClient → ACP Transport → Go Bridge → Remote Execution 2886 lines removed across 41 files. --- lib/app/app_controller_desktop_core.dart | 31 -- ...ntroller_desktop_external_acp_routing.dart | 1 - lib/app/app_controller_desktop_gateway.dart | 1 - .../app_controller_desktop_navigation.dart | 1 - ...ler_desktop_runtime_coordination_impl.dart | 61 --- ...pp_controller_desktop_runtime_helpers.dart | 13 - lib/app/app_controller_desktop_settings.dart | 8 +- ...p_controller_desktop_settings_runtime.dart | 17 +- ..._controller_desktop_skill_permissions.dart | 1 - ...app_controller_desktop_thread_actions.dart | 40 +- ...app_controller_desktop_thread_binding.dart | 1 - ...pp_controller_desktop_thread_sessions.dart | 17 - ...op_thread_sessions_collaboration_impl.dart | 236 -------- ...app_controller_desktop_thread_storage.dart | 49 -- ...ontroller_desktop_workspace_execution.dart | 1 - .../assistant/assistant_page_components.dart | 1 - .../assistant_page_components_core.dart | 1 - .../assistant_page_composer_bar.dart | 1 - .../assistant_page_composer_clipboard.dart | 1 - .../assistant_page_composer_skill_picker.dart | 1 - ...assistant_page_composer_state_helpers.dart | 1 - .../assistant_page_composer_support.dart | 1 - .../assistant/assistant_page_main.dart | 1 - .../assistant_page_message_widgets.dart | 1 - .../assistant_page_state_actions.dart | 10 - .../assistant_page_state_closure.dart | 1 - .../assistant/assistant_page_task_models.dart | 1 - .../assistant_page_tooltip_labels.dart | 1 - lib/runtime/aris_llm_chat_client.dart | 43 -- .../go_multi_agent_mount_desktop_client.dart | 77 --- lib/runtime/multi_agent_frameworks.dart | 74 --- lib/runtime/multi_agent_mount_resolver.dart | 49 -- lib/runtime/multi_agent_mounts.dart | 310 ----------- lib/runtime/multi_agent_orchestrator.dart | 4 - .../multi_agent_orchestrator_core.dart | 384 ------------- .../multi_agent_orchestrator_protocol.dart | 200 ------- .../multi_agent_orchestrator_support.dart | 269 --------- .../multi_agent_orchestrator_workflow.dart | 456 ---------------- lib/runtime/runtime_models.dart | 2 - lib/runtime/runtime_models_multi_agent.dart | 516 ------------------ .../runtime_models_settings_snapshot.dart | 10 - 41 files changed, 8 insertions(+), 2886 deletions(-) delete mode 100644 lib/runtime/aris_llm_chat_client.dart delete mode 100644 lib/runtime/go_multi_agent_mount_desktop_client.dart delete mode 100644 lib/runtime/multi_agent_frameworks.dart delete mode 100644 lib/runtime/multi_agent_mount_resolver.dart delete mode 100644 lib/runtime/multi_agent_mounts.dart delete mode 100644 lib/runtime/multi_agent_orchestrator.dart delete mode 100644 lib/runtime/multi_agent_orchestrator_core.dart delete mode 100644 lib/runtime/multi_agent_orchestrator_protocol.dart delete mode 100644 lib/runtime/multi_agent_orchestrator_support.dart delete mode 100644 lib/runtime/multi_agent_orchestrator_workflow.dart diff --git a/lib/app/app_controller_desktop_core.dart b/lib/app/app_controller_desktop_core.dart index 7a3c3319..fd5e6bcb 100644 --- a/lib/app/app_controller_desktop_core.dart +++ b/lib/app/app_controller_desktop_core.dart @@ -33,12 +33,9 @@ import '../runtime/desktop_thread_artifact_service.dart'; import '../runtime/external_code_agent_acp_desktop_transport.dart'; import '../runtime/go_task_service_client.dart'; import '../runtime/go_task_service_desktop_service.dart'; -import '../runtime/go_multi_agent_mount_desktop_client.dart'; import '../runtime/go_runtime_dispatch_desktop_client.dart'; import '../runtime/mode_switcher.dart'; import '../runtime/agent_registry.dart'; -import '../runtime/multi_agent_mounts.dart'; -import '../runtime/multi_agent_orchestrator.dart'; import '../runtime/platform_environment.dart'; import 'task_thread_repositories.dart'; import 'app_controller_openclaw_task_queue.dart'; @@ -71,7 +68,6 @@ class AppController extends ChangeNotifier { AccountRuntimeClient Function(String baseUrl)? accountClientFactory, Map? environmentOverride, GoTaskServiceClient? goTaskServiceClient, - MultiAgentMountManager? multiAgentMountManager, }) { environmentOverrideInternal = environmentOverride == null ? null @@ -165,19 +161,6 @@ class AppController extends ChangeNotifier { taskEndpointResolver: resolveExternalAcpEndpointForRequestInternal, ), ); - multiAgentOrchestratorInternal = MultiAgentOrchestrator( - config: resolveMultiAgentConfigInternal( - settingsControllerInternal.snapshot, - ), - ); - multiAgentMountManagerInternal = - multiAgentMountManager ?? - MultiAgentMountManager( - resolver: GoMultiAgentMountDesktopClient( - client: gatewayAcpClientInternal, - endpointResolver: resolveGatewayAcpEndpointInternal, - ), - ); bridgeAgentProviderCatalogInternal = normalizeSingleAgentProviderList( initialBridgeProviderCatalog ?? const [], ); @@ -223,7 +206,6 @@ class AppController extends ChangeNotifier { tasksControllerInternal.dispose(); storeInternal.dispose(); desktopPlatformServiceInternal.dispose(); - unawaited(multiAgentMountManagerInternal.dispose()); unawaited(goTaskServiceClientInternal.dispose()); unawaited(gatewayAcpClientInternal.dispose()); super.dispose(); @@ -249,9 +231,6 @@ class AppController extends ChangeNotifier { late final DesktopPlatformService desktopPlatformServiceInternal; late final GatewayAcpClient gatewayAcpClientInternal; late final GoTaskServiceClient goTaskServiceClientInternal; - late final MultiAgentOrchestrator multiAgentOrchestratorInternal; - late final MultiAgentMountManager multiAgentMountManagerInternal; - GoTaskServiceClient get goTaskServiceClientForTest => goTaskServiceClientInternal; @@ -291,7 +270,6 @@ class AppController extends ChangeNotifier { {}; int get openClawGatewayActiveTasksInternal => openClawGatewayActiveTurnsInternal.length; - bool multiAgentRunPendingInternal = false; int localMessageCounterInternal = 0; int assistantDraftSessionCounterInternal = 0; @@ -370,10 +348,6 @@ class AppController extends ChangeNotifier { GatewayAgentsController get agentsController => agentsControllerInternal; GatewaySessionsController get sessionsController => sessionsControllerInternal; - MultiAgentOrchestrator get multiAgentOrchestrator => - multiAgentOrchestratorInternal; - MultiAgentMountManager get multiAgentMountManager => - multiAgentMountManagerInternal; GatewayChatController get chatController => chatControllerInternal; SkillsController get skillsController => skillsControllerInternal; ModelsController get modelsController => modelsControllerInternal; @@ -618,11 +592,6 @@ class AppController extends ChangeNotifier { selectedSkillLabels: selectedSkillLabels, ); - Future refreshMultiAgentMounts({bool sync = false}) => - AppControllerDesktopThreadSessions( - this, - ).refreshMultiAgentMounts(sync: sync); - double get assistantSkillCount => skills.length.toDouble(); int get currentAssistantSkillCount => skills.length; } diff --git a/lib/app/app_controller_desktop_external_acp_routing.dart b/lib/app/app_controller_desktop_external_acp_routing.dart index 7a5fa516..afc06697 100644 --- a/lib/app/app_controller_desktop_external_acp_routing.dart +++ b/lib/app/app_controller_desktop_external_acp_routing.dart @@ -30,7 +30,6 @@ import '../runtime/desktop_thread_artifact_service.dart'; import '../runtime/go_task_service_client.dart'; import '../runtime/mode_switcher.dart'; import '../runtime/agent_registry.dart'; -import '../runtime/multi_agent_orchestrator.dart'; import '../runtime/platform_environment.dart'; import 'app_controller_desktop_core.dart'; import 'app_controller_desktop_thread_sessions.dart'; diff --git a/lib/app/app_controller_desktop_gateway.dart b/lib/app/app_controller_desktop_gateway.dart index d8da9614..33b16bf9 100644 --- a/lib/app/app_controller_desktop_gateway.dart +++ b/lib/app/app_controller_desktop_gateway.dart @@ -29,7 +29,6 @@ import '../runtime/assistant_artifacts.dart'; import '../runtime/desktop_thread_artifact_service.dart'; import '../runtime/mode_switcher.dart'; import '../runtime/agent_registry.dart'; -import '../runtime/multi_agent_orchestrator.dart'; import '../runtime/platform_environment.dart'; import '../runtime/account_runtime_client.dart'; import 'app_controller_desktop_core.dart'; diff --git a/lib/app/app_controller_desktop_navigation.dart b/lib/app/app_controller_desktop_navigation.dart index 20e5c25b..062e7f20 100644 --- a/lib/app/app_controller_desktop_navigation.dart +++ b/lib/app/app_controller_desktop_navigation.dart @@ -29,7 +29,6 @@ import '../runtime/assistant_artifacts.dart'; import '../runtime/desktop_thread_artifact_service.dart'; import '../runtime/mode_switcher.dart'; import '../runtime/agent_registry.dart'; -import '../runtime/multi_agent_orchestrator.dart'; import '../runtime/platform_environment.dart'; import 'app_controller_desktop_core.dart'; import 'app_controller_desktop_gateway.dart'; diff --git a/lib/app/app_controller_desktop_runtime_coordination_impl.dart b/lib/app/app_controller_desktop_runtime_coordination_impl.dart index 8b177b5d..491c1f42 100644 --- a/lib/app/app_controller_desktop_runtime_coordination_impl.dart +++ b/lib/app/app_controller_desktop_runtime_coordination_impl.dart @@ -29,7 +29,6 @@ import '../runtime/assistant_artifacts.dart'; import '../runtime/desktop_thread_artifact_service.dart'; import '../runtime/mode_switcher.dart'; import '../runtime/agent_registry.dart'; -import '../runtime/multi_agent_orchestrator.dart'; import '../runtime/platform_environment.dart'; import 'app_controller_desktop_core.dart'; import 'app_controller_desktop_navigation.dart'; @@ -73,26 +72,6 @@ Future refreshAcpCapabilitiesRuntimeInternal( .toString() .trim(); } - if (persistMountTargets && !controller.disposedInternal) { - try { - final currentConfig = controller.settings.multiAgent; - final nextConfig = await controller.multiAgentMountManagerInternal - .reconcile( - config: currentConfig, - aiGatewayUrl: controller.aiGatewayUrl, - ); - if (jsonEncode(nextConfig.toJson()) != - jsonEncode(currentConfig.toJson())) { - await controller.settingsControllerInternal.saveSnapshot( - controller.settings.copyWith(multiAgent: nextConfig), - ); - controller.multiAgentOrchestratorInternal.updateConfig(nextConfig); - } - } catch (_) { - // Mount reconciliation is an optional bridge capability. A missing or - // older remote method must not block assistant startup or task execution. - } - } if (!controller.disposedInternal) { controller.notifyListeners(); } @@ -122,46 +101,6 @@ Future refreshSingleAgentCapabilitiesRuntimeInternal( } } -List -mergeAcpCapabilitiesIntoMountTargetsRuntimeInternal( - AppController controller, - List current, - GatewayAcpCapabilities capabilities, -) { - final source = current.isEmpty ? ManagedMountTargetState.defaults() : current; - final agentProviders = capabilities.providerCatalog - .map((item) => item.providerId) - .toSet(); - final gatewayProviders = capabilities.gatewayProviderCatalog - .map((item) => item.providerId) - .toSet(); - return source - .map((item) { - final available = switch (item.targetId) { - 'codex' => agentProviders.contains('codex'), - 'opencode' => agentProviders.contains('opencode'), - 'gemini' => agentProviders.contains('gemini'), - 'openclaw' => gatewayProviders.contains('openclaw'), - _ => false, - }; - return item.copyWith( - available: available, - discoveryState: available ? 'ready' : 'unavailable', - syncState: available ? item.syncState : 'idle', - detail: available - ? appText( - '来源:Gateway ACP capabilities', - 'Source: Gateway ACP capabilities', - ) - : appText( - 'Gateway ACP 未报告该能力。', - 'Gateway ACP did not report this capability.', - ), - ); - }) - .toList(growable: false); -} - String? assistantWorkingDirectoryForSessionRuntimeInternal( AppController controller, String sessionKey, diff --git a/lib/app/app_controller_desktop_runtime_helpers.dart b/lib/app/app_controller_desktop_runtime_helpers.dart index 2fb1d551..6183c1f8 100644 --- a/lib/app/app_controller_desktop_runtime_helpers.dart +++ b/lib/app/app_controller_desktop_runtime_helpers.dart @@ -33,7 +33,6 @@ import '../runtime/desktop_thread_artifact_service.dart'; import '../runtime/go_task_service_client.dart'; import '../runtime/mode_switcher.dart'; import '../runtime/agent_registry.dart'; -import '../runtime/multi_agent_orchestrator.dart'; import '../runtime/platform_environment.dart'; import 'app_controller_desktop_core.dart'; import 'app_controller_desktop_navigation.dart'; @@ -602,15 +601,6 @@ extension AppControllerDesktopRuntimeHelpers on AppController { forceRefresh: forceRefresh, ); - List mergeAcpCapabilitiesIntoMountTargetsInternal( - List current, - GatewayAcpCapabilities capabilities, - ) => mergeAcpCapabilitiesIntoMountTargetsRuntimeInternal( - this, - current, - capabilities, - ); - String? assistantWorkingDirectoryForSessionInternal(String sessionKey) => assistantWorkingDirectoryForSessionRuntimeInternal(this, sessionKey); @@ -681,7 +671,6 @@ extension AppControllerDesktopRuntimeHelpers on AppController { cronJobsControllerInternal.addListener(relayChildChangeInternal); devicesControllerInternal.addListener(relayChildChangeInternal); tasksControllerInternal.addListener(relayChildChangeInternal); - multiAgentOrchestratorInternal.addListener(relayChildChangeInternal); } void detachChildListenersInternal() { @@ -696,7 +685,6 @@ extension AppControllerDesktopRuntimeHelpers on AppController { cronJobsControllerInternal.removeListener(relayChildChangeInternal); devicesControllerInternal.removeListener(relayChildChangeInternal); tasksControllerInternal.removeListener(relayChildChangeInternal); - multiAgentOrchestratorInternal.removeListener(relayChildChangeInternal); } void handleSettingsControllerChangeInternal() { @@ -737,7 +725,6 @@ extension AppControllerDesktopRuntimeHelpers on AppController { return; } setActiveAppLanguage(current.appLanguage); - multiAgentOrchestratorInternal.updateConfig(current.multiAgent); if (previous.codeAgentRuntimeMode != current.codeAgentRuntimeMode) { registerCodexExternalProviderInternal(); if (disposedInternal) { diff --git a/lib/app/app_controller_desktop_settings.dart b/lib/app/app_controller_desktop_settings.dart index 4432c535..ef8fd2fc 100644 --- a/lib/app/app_controller_desktop_settings.dart +++ b/lib/app/app_controller_desktop_settings.dart @@ -30,7 +30,6 @@ import '../runtime/assistant_artifacts.dart'; import '../runtime/desktop_thread_artifact_service.dart'; import '../runtime/mode_switcher.dart'; import '../runtime/agent_registry.dart'; -import '../runtime/multi_agent_orchestrator.dart'; import '../runtime/platform_environment.dart'; import 'app_controller_desktop_core.dart'; import 'app_controller_desktop_navigation.dart'; @@ -64,10 +63,8 @@ extension AppControllerDesktopSettings on AppController { return; } settingsDraftInternal = sanitizeFeatureFlagSettingsInternal( - sanitizeMultiAgentSettingsInternal( - sanitizeOllamaCloudSettingsInternal( - sanitizeCodeAgentSettingsInternal(snapshot), - ), + sanitizeOllamaCloudSettingsInternal( + sanitizeCodeAgentSettingsInternal(snapshot), ), ); settingsDraftInitializedInternal = true; @@ -304,7 +301,6 @@ extension AppControllerDesktopSettings on AppController { openClawGatewayQueuedTurnsInternal.clear(); openClawGatewayQueuedTurnsBySessionInternal.clear(); openClawGatewayActiveTurnsInternal.clear(); - multiAgentRunPendingInternal = false; final sessionKey = createAssistantDraftSessionKeyInternal(); initializeAssistantThreadContext( sessionKey, diff --git a/lib/app/app_controller_desktop_settings_runtime.dart b/lib/app/app_controller_desktop_settings_runtime.dart index 181995b8..cfa81005 100644 --- a/lib/app/app_controller_desktop_settings_runtime.dart +++ b/lib/app/app_controller_desktop_settings_runtime.dart @@ -31,7 +31,6 @@ import '../runtime/assistant_artifacts.dart'; import '../runtime/desktop_thread_artifact_service.dart'; import '../runtime/mode_switcher.dart'; import '../runtime/agent_registry.dart'; -import '../runtime/multi_agent_orchestrator.dart'; import '../runtime/platform_environment.dart'; import 'app_controller_desktop_core.dart'; import 'app_controller_desktop_navigation.dart'; @@ -434,11 +433,9 @@ extension AppControllerDesktopSettingsRuntime on AppController { } } final normalized = sanitizeFeatureFlagSettingsInternal( - sanitizeMultiAgentSettingsInternal( - sanitizeOllamaCloudSettingsInternal( - sanitizeCodeAgentSettingsInternal( - settingsControllerInternal.snapshot, - ), + sanitizeOllamaCloudSettingsInternal( + sanitizeCodeAgentSettingsInternal( + settingsControllerInternal.snapshot, ), ), ); @@ -460,7 +457,6 @@ extension AppControllerDesktopSettingsRuntime on AppController { } lastObservedSettingsSnapshotInternal = settings; modelsControllerInternal.restoreFromSettings(settings.aiGateway); - multiAgentOrchestratorInternal.updateConfig(settings.multiAgent); setActiveAppLanguage(settings.appLanguage); await desktopPlatformServiceInternal.initialize(settings.linuxDesktop); await desktopPlatformServiceInternal.setLaunchAtLogin( @@ -670,10 +666,8 @@ extension AppControllerDesktopSettingsRuntime on AppController { SettingsSnapshot snapshot, ) async { final sanitized = sanitizeFeatureFlagSettingsInternal( - sanitizeMultiAgentSettingsInternal( - sanitizeOllamaCloudSettingsInternal( - sanitizeCodeAgentSettingsInternal(snapshot), - ), + sanitizeOllamaCloudSettingsInternal( + sanitizeCodeAgentSettingsInternal(snapshot), ), ); lastObservedSettingsSnapshotInternal = sanitized; @@ -688,7 +682,6 @@ extension AppControllerDesktopSettingsRuntime on AppController { required bool refreshAfterSave, }) async { setActiveAppLanguage(current.appLanguage); - multiAgentOrchestratorInternal.updateConfig(current.multiAgent); agentsControllerInternal.restoreSelection( current .gatewayProfileForExecutionTarget( diff --git a/lib/app/app_controller_desktop_skill_permissions.dart b/lib/app/app_controller_desktop_skill_permissions.dart index fd5463ad..5ed7c8d3 100644 --- a/lib/app/app_controller_desktop_skill_permissions.dart +++ b/lib/app/app_controller_desktop_skill_permissions.dart @@ -29,7 +29,6 @@ import '../runtime/assistant_artifacts.dart'; import '../runtime/desktop_thread_artifact_service.dart'; import '../runtime/mode_switcher.dart'; import '../runtime/agent_registry.dart'; -import '../runtime/multi_agent_orchestrator.dart'; import '../runtime/platform_environment.dart'; import 'app_controller_desktop_core.dart'; import 'app_controller_desktop_navigation.dart'; diff --git a/lib/app/app_controller_desktop_thread_actions.dart b/lib/app/app_controller_desktop_thread_actions.dart index 1c13b671..e3a2d481 100644 --- a/lib/app/app_controller_desktop_thread_actions.dart +++ b/lib/app/app_controller_desktop_thread_actions.dart @@ -31,7 +31,6 @@ import '../runtime/desktop_thread_artifact_service.dart'; import '../runtime/go_task_service_client.dart'; import '../runtime/mode_switcher.dart'; import '../runtime/agent_registry.dart'; -import '../runtime/multi_agent_orchestrator.dart'; import '../runtime/platform_environment.dart'; import 'app_controller_openclaw_task_queue.dart'; import 'app_controller_desktop_core.dart'; @@ -74,11 +73,7 @@ extension AppControllerDesktopThreadActions on AppController { (turn) => !turn.cancelled, ) == true || - (multiAgentRunPendingInternal && - matchesSessionKey( - normalized, - sessionsControllerInternal.currentSessionKey, - )); + false; } Future connectSavedGateway() async { @@ -1505,39 +1500,6 @@ extension AppControllerDesktopThreadActions on AppController { } Future abortRun() async { - if (multiAgentRunPendingInternal) { - final sessionKey = normalizedAssistantSessionKeyInternal( - sessionsControllerInternal.currentSessionKey, - ); - try { - await goTaskServiceClientInternal.cancelTask( - route: GoTaskServiceRoute.externalAcpMulti, - target: assistantExecutionTargetForSession(sessionKey), - sessionId: sessionKey, - threadId: sessionKey, - association: taskThreadForSessionInternal( - sessionKey, - )?.openClawTaskAssociation, - ); - } catch (_) { - // Best effort cancellation only. - } - multiAgentRunPendingInternal = false; - upsertTaskThreadInternal( - sessionKey, - lifecycleStatus: 'ready', - lastRunAtMs: DateTime.now().millisecondsSinceEpoch.toDouble(), - lastResultCode: 'aborted', - lastRemoteWorkingDirectory: '', - lastArtifactSyncAtMs: DateTime.now().millisecondsSinceEpoch.toDouble(), - lastArtifactSyncStatus: 'failed', - lastTaskArtifactRelativePaths: const [], - updatedAtMs: DateTime.now().millisecondsSinceEpoch.toDouble(), - ); - recomputeTasksInternal(); - notifyIfActiveInternal(); - return; - } final sessionKey = normalizedAssistantSessionKeyInternal( sessionsControllerInternal.currentSessionKey, ); diff --git a/lib/app/app_controller_desktop_thread_binding.dart b/lib/app/app_controller_desktop_thread_binding.dart index 3898fff8..f8b1fe2f 100644 --- a/lib/app/app_controller_desktop_thread_binding.dart +++ b/lib/app/app_controller_desktop_thread_binding.dart @@ -29,7 +29,6 @@ import '../runtime/assistant_artifacts.dart'; import '../runtime/desktop_thread_artifact_service.dart'; import '../runtime/mode_switcher.dart'; import '../runtime/agent_registry.dart'; -import '../runtime/multi_agent_orchestrator.dart'; import '../runtime/platform_environment.dart'; import 'app_controller_desktop_core.dart'; import 'app_controller_desktop_navigation.dart'; diff --git a/lib/app/app_controller_desktop_thread_sessions.dart b/lib/app/app_controller_desktop_thread_sessions.dart index dd4c51b2..3b7a9119 100644 --- a/lib/app/app_controller_desktop_thread_sessions.dart +++ b/lib/app/app_controller_desktop_thread_sessions.dart @@ -29,7 +29,6 @@ import '../runtime/assistant_artifacts.dart'; import '../runtime/desktop_thread_artifact_service.dart'; import '../runtime/mode_switcher.dart'; import '../runtime/agent_registry.dart'; -import '../runtime/multi_agent_orchestrator.dart'; import '../runtime/platform_environment.dart'; import 'app_controller_desktop_core.dart'; import 'app_controller_desktop_navigation.dart'; @@ -481,22 +480,6 @@ extension AppControllerDesktopThreadSessions on AppController { Future loadAiGatewayApiKey() => loadAiGatewayApiKeyThreadSessionInternal(this); - Future saveMultiAgentConfig(MultiAgentConfig config) => - saveMultiAgentConfigThreadSessionInternal(this, config); - Future refreshMultiAgentMounts({bool sync = false}) => - refreshMultiAgentMountsThreadSessionInternal(this, sync: sync); - Future runMultiAgentCollaboration({ - required String rawPrompt, - required String composedPrompt, - required List attachments, - required List selectedSkillLabels, - }) => runMultiAgentCollaborationThreadSessionInternal( - this, - rawPrompt: rawPrompt, - composedPrompt: composedPrompt, - attachments: attachments, - selectedSkillLabels: selectedSkillLabels, - ); Future openOnlineWorkspace() => openOnlineWorkspaceThreadSessionInternal(this); List get aiGatewayModelChoices => diff --git a/lib/app/app_controller_desktop_thread_sessions_collaboration_impl.dart b/lib/app/app_controller_desktop_thread_sessions_collaboration_impl.dart index 0f90e2f5..c1554bab 100644 --- a/lib/app/app_controller_desktop_thread_sessions_collaboration_impl.dart +++ b/lib/app/app_controller_desktop_thread_sessions_collaboration_impl.dart @@ -30,7 +30,6 @@ import '../runtime/desktop_thread_artifact_service.dart'; import '../runtime/go_task_service_client.dart'; import '../runtime/mode_switcher.dart'; import '../runtime/agent_registry.dart'; -import '../runtime/multi_agent_orchestrator.dart'; import '../runtime/platform_environment.dart'; import 'app_controller_desktop_core.dart'; import 'app_controller_desktop_navigation.dart'; @@ -51,241 +50,6 @@ Future loadAiGatewayApiKeyThreadSessionInternal( return controller.settingsControllerInternal.loadEffectiveAiGatewayApiKey(); } -Future saveMultiAgentConfigThreadSessionInternal( - AppController controller, - MultiAgentConfig config, -) async { - final resolved = controller.resolveMultiAgentConfigInternal( - controller.settings.copyWith(multiAgent: config), - ); - await AppControllerDesktopSettings(controller).saveSettings( - controller.settings.copyWith(multiAgent: resolved), - refreshAfterSave: false, - ); - await refreshMultiAgentMountsThreadSessionInternal( - controller, - sync: resolved.autoSync, - ); -} - -Future refreshMultiAgentMountsThreadSessionInternal( - AppController controller, { - bool sync = false, -}) async { - final currentConfig = controller.settings.multiAgent; - final effectiveConfig = currentConfig.copyWith(autoSync: sync); - var nextConfig = await controller.multiAgentMountManagerInternal.reconcile( - config: effectiveConfig, - aiGatewayUrl: controller.aiGatewayUrl, - ); - if (nextConfig.autoSync != currentConfig.autoSync) { - nextConfig = nextConfig.copyWith(autoSync: currentConfig.autoSync); - } - if (jsonEncode(nextConfig.toJson()) != jsonEncode(currentConfig.toJson())) { - await controller.settingsControllerInternal.saveSnapshot( - controller.settings.copyWith(multiAgent: nextConfig), - ); - controller.multiAgentOrchestratorInternal.updateConfig(nextConfig); - } - await controller.refreshAcpCapabilitiesInternal(forceRefresh: true); - if (!controller.disposedInternal) { - controller.notifyListeners(); - } -} - -Future runMultiAgentCollaborationThreadSessionInternal( - AppController controller, { - required String rawPrompt, - required String composedPrompt, - required List attachments, - required List selectedSkillLabels, -}) async { - if (!controller.isAppOwnedAssistantSessionKeyInternal( - controller.currentSessionKey, - )) { - await controller.ensureActiveAssistantThreadInternal(); - } - final sessionKey = controller.currentSessionKey.trim(); - await controller.enqueueThreadTurnInternal(sessionKey, () async { - await controller.ensureDesktopTaskThreadBindingInternal( - sessionKey, - executionTarget: controller.assistantExecutionTargetForSession( - sessionKey, - ), - ); - final workingDirectory = controller - .assistantWorkingDirectoryForSessionInternal(sessionKey); - final remoteWorkingDirectoryHint = controller - .assistantRemoteWorkingDirectoryHintForSessionInternal(sessionKey); - if (workingDirectory == null || workingDirectory.trim().isEmpty) { - final error = StateError( - appText( - '当前线程缺少工作路径,无法启动 Gateway 协作。', - 'This thread has no workspace path, so gateway collaboration cannot start.', - ), - ); - controller.appendLocalSessionMessageInternal( - sessionKey, - GatewayChatMessage( - id: controller.nextLocalMessageIdInternal(), - role: 'assistant', - text: error.message.toString(), - timestampMs: DateTime.now().millisecondsSinceEpoch.toDouble(), - toolCallId: null, - toolName: 'Multi-Agent', - stopReason: null, - pending: false, - error: true, - ), - ); - controller.recomputeTasksInternal(); - controller.notifyIfActiveInternal(); - throw error; - } - controller.multiAgentRunPendingInternal = true; - controller.appendLocalSessionMessageInternal( - sessionKey, - GatewayChatMessage( - id: controller.nextLocalMessageIdInternal(), - role: 'user', - text: rawPrompt, - timestampMs: DateTime.now().millisecondsSinceEpoch.toDouble(), - toolCallId: null, - toolName: null, - stopReason: null, - pending: false, - error: false, - ), - ); - controller.recomputeTasksInternal(); - try { - final taskPrompt = controller.taskWorkspaceContextPromptInternal( - sessionKey: sessionKey, - userPrompt: composedPrompt, - workingDirectory: workingDirectory, - remoteWorkingDirectoryHint: remoteWorkingDirectoryHint?.trim() ?? '', - target: controller.assistantExecutionTargetForSession(sessionKey), - ); - final result = await controller.goTaskServiceClientInternal.executeTask( - GoTaskServiceRequest( - sessionId: sessionKey, - threadId: sessionKey, - target: controller.assistantExecutionTargetForSession(sessionKey), - prompt: taskPrompt, - workingDirectory: workingDirectory, - remoteWorkingDirectoryHint: remoteWorkingDirectoryHint?.trim() ?? '', - model: controller.assistantModelForSession(sessionKey), - thinking: 'medium', - selectedSkills: selectedSkillLabels, - inlineAttachments: const [], - localAttachments: attachments, - agentId: '', - metadata: const {}, - routingHint: 'gateway', - collaborationMode: GoTaskServiceCollaborationMode.standard, - resumeSession: true, - ), - onUpdate: (update) { - final text = update.text.trim().isNotEmpty - ? update.text.trim() - : update.message.trim(); - if (text.isEmpty) { - return; - } - controller.appendLocalSessionMessageInternal( - sessionKey, - GatewayChatMessage( - id: controller.nextLocalMessageIdInternal(), - role: 'assistant', - text: text, - timestampMs: DateTime.now().millisecondsSinceEpoch.toDouble(), - toolCallId: null, - toolName: 'Multi-Agent', - stopReason: null, - pending: update.pending, - error: update.error, - ), - ); - }, - ); - await controller.persistGoTaskArtifactsForSessionInternal( - sessionKey, - result, - ); - controller.upsertTaskThreadInternal( - sessionKey, - lastRemoteWorkingDirectory: - result.remoteWorkingDirectory.trim().isNotEmpty - ? result.remoteWorkingDirectory.trim() - : null, - lastRemoteWorkspaceRefKind: result.remoteWorkspaceRefKind, - updatedAtMs: DateTime.now().millisecondsSinceEpoch.toDouble(), - ); - controller.appendLocalSessionMessageInternal( - sessionKey, - GatewayChatMessage( - id: controller.nextLocalMessageIdInternal(), - role: 'assistant', - text: result.success - ? (result.message.trim().isNotEmpty - ? result.message.trim() - : appText( - '多 Agent 协作完成。', - 'Multi-agent collaboration completed.', - )) - : appText( - '多 Agent 协作失败:${result.errorMessage.trim().isEmpty ? result.message : result.errorMessage}', - 'Multi-agent collaboration failed: ${result.errorMessage.trim().isEmpty ? result.message : result.errorMessage}', - ), - timestampMs: DateTime.now().millisecondsSinceEpoch.toDouble(), - toolCallId: null, - toolName: 'Multi-Agent', - stopReason: null, - pending: false, - error: !result.success, - ), - ); - } on GatewayAcpException catch (error) { - controller.appendLocalSessionMessageInternal( - sessionKey, - GatewayChatMessage( - id: controller.nextLocalMessageIdInternal(), - role: 'assistant', - text: appText( - '多 Agent 协作不可用(ACP):${error.message}', - 'Multi-agent collaboration is unavailable (ACP): ${error.message}', - ), - timestampMs: DateTime.now().millisecondsSinceEpoch.toDouble(), - toolCallId: null, - toolName: 'Multi-Agent', - stopReason: null, - pending: false, - error: true, - ), - ); - } catch (error) { - controller.appendLocalSessionMessageInternal( - sessionKey, - GatewayChatMessage( - id: controller.nextLocalMessageIdInternal(), - role: 'assistant', - text: error.toString(), - timestampMs: DateTime.now().millisecondsSinceEpoch.toDouble(), - toolCallId: null, - toolName: 'Multi-Agent', - stopReason: null, - pending: false, - error: true, - ), - ); - } finally { - controller.multiAgentRunPendingInternal = false; - controller.recomputeTasksInternal(); - controller.notifyIfActiveInternal(); - } - }); -} - Future openOnlineWorkspaceThreadSessionInternal( AppController controller, ) async { diff --git a/lib/app/app_controller_desktop_thread_storage.dart b/lib/app/app_controller_desktop_thread_storage.dart index 5cd84db7..7dee75b6 100644 --- a/lib/app/app_controller_desktop_thread_storage.dart +++ b/lib/app/app_controller_desktop_thread_storage.dart @@ -29,7 +29,6 @@ import '../runtime/assistant_artifacts.dart'; import '../runtime/desktop_thread_artifact_service.dart'; import '../runtime/mode_switcher.dart'; import '../runtime/agent_registry.dart'; -import '../runtime/multi_agent_orchestrator.dart'; import '../runtime/platform_environment.dart'; import 'app_controller_desktop_core.dart'; import 'app_controller_desktop_navigation.dart'; @@ -166,17 +165,6 @@ extension AppControllerDesktopThreadStorage on AppController { } } - SettingsSnapshot sanitizeMultiAgentSettingsInternal( - SettingsSnapshot snapshot, - ) { - final resolved = resolveMultiAgentConfigInternal(snapshot); - if (jsonEncode(snapshot.multiAgent.toJson()) == - jsonEncode(resolved.toJson())) { - return snapshot; - } - return snapshot.copyWith(multiAgent: resolved); - } - SettingsSnapshot sanitizeFeatureFlagSettingsInternal( SettingsSnapshot snapshot, ) { @@ -184,9 +172,6 @@ extension AppControllerDesktopThreadStorage on AppController { final sanitizedExecutionTarget = sanitizeExecutionTargetInternal( features.sanitizeExecutionTarget(snapshot.assistantExecutionTarget), ); - final multiAgentConfig = features.supportsMultiAgent - ? snapshot.multiAgent - : snapshot.multiAgent.copyWith(enabled: false); final experimentalCanvas = features.allowsExperimentalSetting( UiFeatureKeys.settingsExperimentalCanvas, @@ -207,7 +192,6 @@ extension AppControllerDesktopThreadStorage on AppController { : false; return snapshot.copyWith( assistantExecutionTarget: sanitizedExecutionTarget, - multiAgent: multiAgentConfig, experimentalCanvas: experimentalCanvas, experimentalBridge: experimentalBridge, experimentalDebug: experimentalDebug, @@ -271,39 +255,6 @@ extension AppControllerDesktopThreadStorage on AppController { return sanitizeExecutionTargetInternal(target); } - MultiAgentConfig resolveMultiAgentConfigInternal(SettingsSnapshot snapshot) { - final defaults = MultiAgentConfig.defaults(); - final current = snapshot.multiAgent; - final ollamaEndpoint = snapshot.ollamaLocal.endpoint.trim().isEmpty - ? current.ollamaEndpoint - : snapshot.ollamaLocal.endpoint.trim(); - final engineerModel = current.engineer.model.trim().isNotEmpty - ? current.engineer.model.trim() - : snapshot.ollamaLocal.defaultModel.trim().isNotEmpty - ? snapshot.ollamaLocal.defaultModel.trim() - : defaults.engineer.model; - final architectModel = current.architect.model.trim().isNotEmpty - ? current.architect.model.trim() - : defaults.architect.model; - final testerModel = current.tester.model.trim().isNotEmpty - ? current.tester.model.trim() - : defaults.tester.model; - return current.copyWith( - framework: current.arisEnabled - ? MultiAgentFramework.aris - : current.framework, - arisEnabled: - current.framework == MultiAgentFramework.aris || current.arisEnabled, - ollamaEndpoint: ollamaEndpoint, - architect: current.architect.copyWith(model: architectModel), - engineer: current.engineer.copyWith(model: engineerModel), - tester: current.tester.copyWith(model: testerModel), - mountTargets: current.mountTargets.isEmpty - ? MultiAgentConfig.defaults().mountTargets - : current.mountTargets, - ); - } - void appendAssistantThreadMessageInternal( String sessionKey, GatewayChatMessage message, diff --git a/lib/app/app_controller_desktop_workspace_execution.dart b/lib/app/app_controller_desktop_workspace_execution.dart index b983ede0..ac92dac8 100644 --- a/lib/app/app_controller_desktop_workspace_execution.dart +++ b/lib/app/app_controller_desktop_workspace_execution.dart @@ -29,7 +29,6 @@ import '../runtime/assistant_artifacts.dart'; import '../runtime/desktop_thread_artifact_service.dart'; import '../runtime/mode_switcher.dart'; import '../runtime/agent_registry.dart'; -import '../runtime/multi_agent_orchestrator.dart'; import '../runtime/platform_environment.dart'; import 'app_controller_desktop_core.dart'; import 'app_controller_desktop_navigation.dart'; diff --git a/lib/features/assistant/assistant_page_components.dart b/lib/features/assistant/assistant_page_components.dart index fe9b5e12..58ac0ec5 100644 --- a/lib/features/assistant/assistant_page_components.dart +++ b/lib/features/assistant/assistant_page_components.dart @@ -16,7 +16,6 @@ import '../../app/app_metadata.dart'; import '../../app/ui_feature_manifest.dart'; import '../../i18n/app_language.dart'; import '../../models/app_models.dart'; -import '../../runtime/multi_agent_orchestrator.dart'; import '../../runtime/runtime_models.dart'; import '../../theme/app_palette.dart'; import '../../theme/app_theme.dart'; diff --git a/lib/features/assistant/assistant_page_components_core.dart b/lib/features/assistant/assistant_page_components_core.dart index ad698c6c..77a5f221 100644 --- a/lib/features/assistant/assistant_page_components_core.dart +++ b/lib/features/assistant/assistant_page_components_core.dart @@ -16,7 +16,6 @@ import '../../app/app_metadata.dart'; import '../../app/ui_feature_manifest.dart'; import '../../i18n/app_language.dart'; import '../../models/app_models.dart'; -import '../../runtime/multi_agent_orchestrator.dart'; import '../../runtime/runtime_models.dart'; import '../../theme/app_palette.dart'; import '../../theme/app_theme.dart'; diff --git a/lib/features/assistant/assistant_page_composer_bar.dart b/lib/features/assistant/assistant_page_composer_bar.dart index c95fdf93..da872222 100644 --- a/lib/features/assistant/assistant_page_composer_bar.dart +++ b/lib/features/assistant/assistant_page_composer_bar.dart @@ -15,7 +15,6 @@ import '../../app/app_metadata.dart'; import '../../app/ui_feature_manifest.dart'; import '../../i18n/app_language.dart'; import '../../models/app_models.dart'; -import '../../runtime/multi_agent_orchestrator.dart'; import '../../runtime/runtime_models.dart'; import '../../theme/app_palette.dart'; import '../../theme/app_theme.dart'; diff --git a/lib/features/assistant/assistant_page_composer_clipboard.dart b/lib/features/assistant/assistant_page_composer_clipboard.dart index 6a7d8090..c1ee2782 100644 --- a/lib/features/assistant/assistant_page_composer_clipboard.dart +++ b/lib/features/assistant/assistant_page_composer_clipboard.dart @@ -16,7 +16,6 @@ import '../../app/app_metadata.dart'; import '../../app/ui_feature_manifest.dart'; import '../../i18n/app_language.dart'; import '../../models/app_models.dart'; -import '../../runtime/multi_agent_orchestrator.dart'; import '../../runtime/runtime_models.dart'; import '../../theme/app_palette.dart'; import '../../theme/app_theme.dart'; diff --git a/lib/features/assistant/assistant_page_composer_skill_picker.dart b/lib/features/assistant/assistant_page_composer_skill_picker.dart index 6a170a60..765879ec 100644 --- a/lib/features/assistant/assistant_page_composer_skill_picker.dart +++ b/lib/features/assistant/assistant_page_composer_skill_picker.dart @@ -16,7 +16,6 @@ import '../../app/app_metadata.dart'; import '../../app/ui_feature_manifest.dart'; import '../../i18n/app_language.dart'; import '../../models/app_models.dart'; -import '../../runtime/multi_agent_orchestrator.dart'; import '../../runtime/runtime_models.dart'; import '../../theme/app_palette.dart'; import '../../theme/app_theme.dart'; diff --git a/lib/features/assistant/assistant_page_composer_state_helpers.dart b/lib/features/assistant/assistant_page_composer_state_helpers.dart index 95c2bc85..ca9f507a 100644 --- a/lib/features/assistant/assistant_page_composer_state_helpers.dart +++ b/lib/features/assistant/assistant_page_composer_state_helpers.dart @@ -16,7 +16,6 @@ import '../../app/app_metadata.dart'; import '../../app/ui_feature_manifest.dart'; import '../../i18n/app_language.dart'; import '../../models/app_models.dart'; -import '../../runtime/multi_agent_orchestrator.dart'; import '../../runtime/runtime_models.dart'; import '../../theme/app_palette.dart'; import '../../theme/app_theme.dart'; diff --git a/lib/features/assistant/assistant_page_composer_support.dart b/lib/features/assistant/assistant_page_composer_support.dart index b1fd2c98..c7049483 100644 --- a/lib/features/assistant/assistant_page_composer_support.dart +++ b/lib/features/assistant/assistant_page_composer_support.dart @@ -16,7 +16,6 @@ import '../../app/app_metadata.dart'; import '../../app/ui_feature_manifest.dart'; import '../../i18n/app_language.dart'; import '../../models/app_models.dart'; -import '../../runtime/multi_agent_orchestrator.dart'; import '../../runtime/runtime_models.dart'; import '../../theme/app_palette.dart'; import '../../theme/app_theme.dart'; diff --git a/lib/features/assistant/assistant_page_main.dart b/lib/features/assistant/assistant_page_main.dart index 251a5c55..3eda5f86 100644 --- a/lib/features/assistant/assistant_page_main.dart +++ b/lib/features/assistant/assistant_page_main.dart @@ -16,7 +16,6 @@ import '../../app/app_metadata.dart'; import '../../app/ui_feature_manifest.dart'; import '../../i18n/app_language.dart'; import '../../models/app_models.dart'; -import '../../runtime/multi_agent_orchestrator.dart'; import '../../runtime/runtime_models.dart'; import '../../theme/app_palette.dart'; import '../../theme/app_theme.dart'; diff --git a/lib/features/assistant/assistant_page_message_widgets.dart b/lib/features/assistant/assistant_page_message_widgets.dart index b2c108cf..9baede59 100644 --- a/lib/features/assistant/assistant_page_message_widgets.dart +++ b/lib/features/assistant/assistant_page_message_widgets.dart @@ -16,7 +16,6 @@ import '../../app/app_metadata.dart'; import '../../app/ui_feature_manifest.dart'; import '../../i18n/app_language.dart'; import '../../models/app_models.dart'; -import '../../runtime/multi_agent_orchestrator.dart'; import '../../runtime/runtime_models.dart'; import '../../theme/app_palette.dart'; import '../../theme/app_theme.dart'; diff --git a/lib/features/assistant/assistant_page_state_actions.dart b/lib/features/assistant/assistant_page_state_actions.dart index 7660b885..e995d4d1 100644 --- a/lib/features/assistant/assistant_page_state_actions.dart +++ b/lib/features/assistant/assistant_page_state_actions.dart @@ -15,7 +15,6 @@ import '../../app/app_metadata.dart'; import '../../app/ui_feature_manifest.dart'; import '../../i18n/app_language.dart'; import '../../models/app_models.dart'; -import '../../runtime/multi_agent_orchestrator.dart'; import '../../runtime/runtime_models.dart'; import '../../theme/app_palette.dart'; import '../../theme/app_theme.dart'; @@ -154,15 +153,6 @@ extension AssistantPageStateActionsInternal on AssistantPageStateInternal { sessionKey: submittedSessionKey, thinking: thinkingLabelInternal, attachments: attachmentPayloads, - localAttachments: submittedAttachments - .map( - (item) => CollaborationAttachment( - name: item.name, - description: item.mimeType, - path: item.path, - ), - ) - .toList(growable: false), selectedSkillLabels: selectedSkillLabels, ); clearComposerDraftForSessionInternal(submittedSessionKey); diff --git a/lib/features/assistant/assistant_page_state_closure.dart b/lib/features/assistant/assistant_page_state_closure.dart index ca287118..3eb38b45 100644 --- a/lib/features/assistant/assistant_page_state_closure.dart +++ b/lib/features/assistant/assistant_page_state_closure.dart @@ -16,7 +16,6 @@ import '../../app/app_metadata.dart'; import '../../app/ui_feature_manifest.dart'; import '../../i18n/app_language.dart'; import '../../models/app_models.dart'; -import '../../runtime/multi_agent_orchestrator.dart'; import '../../runtime/gateway_acp_client.dart'; import '../../runtime/runtime_models.dart'; import '../../theme/app_palette.dart'; diff --git a/lib/features/assistant/assistant_page_task_models.dart b/lib/features/assistant/assistant_page_task_models.dart index 1caf98c7..f3982dba 100644 --- a/lib/features/assistant/assistant_page_task_models.dart +++ b/lib/features/assistant/assistant_page_task_models.dart @@ -16,7 +16,6 @@ import '../../app/app_metadata.dart'; import '../../app/ui_feature_manifest.dart'; import '../../i18n/app_language.dart'; import '../../models/app_models.dart'; -import '../../runtime/multi_agent_orchestrator.dart'; import '../../runtime/runtime_models.dart'; import '../../theme/app_palette.dart'; import '../../theme/app_theme.dart'; diff --git a/lib/features/assistant/assistant_page_tooltip_labels.dart b/lib/features/assistant/assistant_page_tooltip_labels.dart index 3847fae1..c4332ec9 100644 --- a/lib/features/assistant/assistant_page_tooltip_labels.dart +++ b/lib/features/assistant/assistant_page_tooltip_labels.dart @@ -16,7 +16,6 @@ import '../../app/app_metadata.dart'; import '../../app/ui_feature_manifest.dart'; import '../../i18n/app_language.dart'; import '../../models/app_models.dart'; -import '../../runtime/multi_agent_orchestrator.dart'; import '../../runtime/runtime_models.dart'; import '../../theme/app_palette.dart'; import '../../theme/app_theme.dart'; diff --git a/lib/runtime/aris_llm_chat_client.dart b/lib/runtime/aris_llm_chat_client.dart deleted file mode 100644 index cc8c0bfe..00000000 --- a/lib/runtime/aris_llm_chat_client.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'dart:async'; - -class ArisLlmChatClient { - ArisLlmChatClient({Duration rpcTimeout = const Duration(minutes: 2)}); - - Future chat({ - required String endpoint, - required String apiKey, - required String model, - required String prompt, - String systemPrompt = '', - }) { - return _callTool( - toolName: 'chat', - environment: {}, - arguments: {}, - ); - } - - Future claudeReview({ - required String prompt, - String model = '', - String systemPrompt = '', - String tools = '', - }) { - return _callTool( - toolName: 'claude_review', - environment: {}, - arguments: {}, - ); - } - - Future _callTool({ - required String toolName, - required Map environment, - required Map arguments, - }) async { - // Local Go core execution is deprecated in favor of bridge-mediated execution. - throw UnsupportedError( - 'Local Go core execution is disabled. Use the managed bridge ACP runtime instead.', - ); - } -} diff --git a/lib/runtime/go_multi_agent_mount_desktop_client.dart b/lib/runtime/go_multi_agent_mount_desktop_client.dart deleted file mode 100644 index 1753a77e..00000000 --- a/lib/runtime/go_multi_agent_mount_desktop_client.dart +++ /dev/null @@ -1,77 +0,0 @@ -import 'gateway_acp_client.dart'; -import 'multi_agent_mount_resolver.dart'; -import 'runtime_models.dart'; - -class GoMultiAgentMountDesktopClient implements MultiAgentMountResolver { - GoMultiAgentMountDesktopClient({ - required GatewayAcpClient client, - required Uri? Function() endpointResolver, - }) : _client = client, - _endpointResolver = endpointResolver; - - final GatewayAcpClient _client; - final Uri? Function() _endpointResolver; - - @override - Future reconcile({ - required MultiAgentConfig config, - required String aiGatewayUrl, - required String codexHome, - required String opencodeHome, - required ArisMountProbe arisProbe, - }) async { - final response = await _client.request( - method: 'xworkmate.mounts.reconcile', - params: { - 'config': { - 'autoSync': config.autoSync, - 'usesAris': config.usesAris, - 'managedMcpServers': config.managedMcpServers - .map((item) => item.toJson()) - .toList(growable: false), - }, - 'aiGatewayUrl': aiGatewayUrl.trim(), - 'codexHome': codexHome.trim(), - 'opencodeHome': opencodeHome.trim(), - 'aris': arisProbe.toJson(), - }, - endpointOverride: _endpointResolver(), - ); - final result = _castMap(response['result']); - final rawTargets = result['mountTargets']; - final mountTargets = rawTargets is List - ? rawTargets - .whereType() - .map( - (item) => ManagedMountTargetState.fromJson( - item.cast(), - ), - ) - .toList(growable: false) - : config.mountTargets; - return config.copyWith( - mountTargets: mountTargets, - arisBundleVersion: - result['arisBundleVersion']?.toString().trim().isNotEmpty == true - ? result['arisBundleVersion'].toString().trim() - : config.arisBundleVersion, - arisCompatStatus: - result['arisCompatStatus']?.toString().trim().isNotEmpty == true - ? result['arisCompatStatus'].toString().trim() - : config.arisCompatStatus, - ); - } - - @override - Future dispose() => _client.dispose(); - - Map _castMap(Object? value) { - if (value is Map) { - return value; - } - if (value is Map) { - return value.cast(); - } - return const {}; - } -} diff --git a/lib/runtime/multi_agent_frameworks.dart b/lib/runtime/multi_agent_frameworks.dart deleted file mode 100644 index fce5fb64..00000000 --- a/lib/runtime/multi_agent_frameworks.dart +++ /dev/null @@ -1,74 +0,0 @@ -import 'runtime_models.dart'; - -abstract class FrameworkPreset { - const FrameworkPreset(); - - String get id; - String get label; - - Future roleInstructionBlock({ - required MultiAgentRole role, - required String tool, - required List selectedSkills, - }); -} - -class NativeFrameworkPreset extends FrameworkPreset { - const NativeFrameworkPreset(); - - @override - String get id => MultiAgentFramework.native.name; - - @override - String get label => MultiAgentFramework.native.label; - - @override - Future roleInstructionBlock({ - required MultiAgentRole role, - required String tool, - required List selectedSkills, - }) async { - final selected = selectedSkills.isEmpty - ? '- 无' - : selectedSkills.map((item) => '- $item').join('\n'); - return ''' -当前协作框架:$label -当前角色:${role.label} -当前工具:$tool - -用户当前选中的技能: -$selected -'''; - } -} - -class ArisFrameworkPreset extends FrameworkPreset { - const ArisFrameworkPreset(); - - @override - String get id => MultiAgentFramework.aris.name; - - @override - String get label => MultiAgentFramework.aris.label; - - @override - Future roleInstructionBlock({ - required MultiAgentRole role, - required String tool, - required List selectedSkills, - }) async { - // ARIS data has been removed from assets. - // Fallback to basic instruction. - final selected = selectedSkills.isEmpty - ? '- 无' - : selectedSkills.map((item) => '- $item').join('\n'); - return ''' -当前协作框架:$label -当前角色:${role.label} -当前工具:$tool - -用户当前选中的技能: -$selected -'''; - } -} diff --git a/lib/runtime/multi_agent_mount_resolver.dart b/lib/runtime/multi_agent_mount_resolver.dart deleted file mode 100644 index 9df71395..00000000 --- a/lib/runtime/multi_agent_mount_resolver.dart +++ /dev/null @@ -1,49 +0,0 @@ -import 'runtime_models.dart'; - -class ArisMountProbe { - const ArisMountProbe({ - required this.available, - required this.bundleVersion, - required this.llmChatServerPath, - required this.skillCount, - required this.bridgeAvailable, - this.error = '', - }); - - const ArisMountProbe.unavailable({this.error = ''}) - : available = false, - bundleVersion = '', - llmChatServerPath = '', - skillCount = 0, - bridgeAvailable = false; - - final bool available; - final String bundleVersion; - final String llmChatServerPath; - final int skillCount; - final bool bridgeAvailable; - final String error; - - Map toJson() { - return { - 'available': available, - 'bundleVersion': bundleVersion, - 'llmChatServerPath': llmChatServerPath, - 'skillCount': skillCount, - 'bridgeAvailable': bridgeAvailable, - 'error': error, - }; - } -} - -abstract class MultiAgentMountResolver { - Future reconcile({ - required MultiAgentConfig config, - required String aiGatewayUrl, - required String codexHome, - required String opencodeHome, - required ArisMountProbe arisProbe, - }); - - Future dispose(); -} diff --git a/lib/runtime/multi_agent_mounts.dart b/lib/runtime/multi_agent_mounts.dart deleted file mode 100644 index 7280894b..00000000 --- a/lib/runtime/multi_agent_mounts.dart +++ /dev/null @@ -1,310 +0,0 @@ -import 'codex_config_bridge.dart'; -import 'multi_agent_mount_resolver.dart'; -import 'opencode_config_bridge.dart'; -import 'runtime_models.dart'; - -/// 协作模式挂载管理器 -/// -/// 在云中性设计下,挂载目标的发现与状态调和应通过桥接同步到远程端点。 -class MultiAgentMountManager { - MultiAgentMountManager({ - CodexConfigBridge? codexConfigBridge, - OpencodeConfigBridge? opencodeConfigBridge, - MultiAgentMountResolver? resolver, - }) : this._( - codexConfigBridge: codexConfigBridge ?? CodexConfigBridge(), - opencodeConfigBridge: opencodeConfigBridge ?? OpencodeConfigBridge(), - resolver: resolver, - ); - - MultiAgentMountManager._({ - required CodexConfigBridge codexConfigBridge, - required OpencodeConfigBridge opencodeConfigBridge, - MultiAgentMountResolver? resolver, - }) : _codexConfigBridge = codexConfigBridge, - _opencodeConfigBridge = opencodeConfigBridge, - _resolver = resolver, - _adapters = [ - CodexMountAdapter(codexConfigBridge), - ClaudeMountAdapter(), - GeminiMountAdapter(), - OpencodeMountAdapter(opencodeConfigBridge), - OpenClawMountAdapter(), - ]; - - final CodexConfigBridge _codexConfigBridge; - final OpencodeConfigBridge _opencodeConfigBridge; - final MultiAgentMountResolver? _resolver; - final List _adapters; - - Future reconcile({ - required MultiAgentConfig config, - required String aiGatewayUrl, - }) async { - final resolved = await _resolver?.reconcile( - config: config, - aiGatewayUrl: aiGatewayUrl, - codexHome: _codexConfigBridge.codexHome, - opencodeHome: _opencodeConfigBridge.opencodeHome, - arisProbe: await _buildArisProbe(), - ); - if (resolved != null) { - return resolved; - } - return _reconcileLocally(config: config, aiGatewayUrl: aiGatewayUrl); - } - - Future dispose() async { - await _resolver?.dispose(); - } - - Future _buildArisProbe() async { - return const ArisMountProbe( - available: false, - bundleVersion: '', - llmChatServerPath: '', - skillCount: 0, - bridgeAvailable: false, - error: 'Legacy local agent execution is disabled.', - ); - } - - Future _reconcileLocally({ - required MultiAgentConfig config, - required String aiGatewayUrl, - }) async { - final states = []; - for (final adapter in _adapters) { - states.add( - await adapter.reconcile(config: config, aiGatewayUrl: aiGatewayUrl), - ); - } - return config.copyWith( - mountTargets: states, - arisBundleVersion: '', - arisCompatStatus: 'missing', - ); - } -} - -abstract class CliMountAdapter { - String get targetId; - String get label; - bool get supportsSkills; - bool get supportsMcp; - bool get supportsAiGatewayInjection; - - Future isInstalled(); - - Future reconcile({ - required MultiAgentConfig config, - required String aiGatewayUrl, - }); - - int countMcpTomlSections(String content) { - return RegExp( - r'^\[mcp_servers\.[^\]]+\]', - multiLine: true, - ).allMatches(content).length; - } -} - -class CodexMountAdapter extends CliMountAdapter { - CodexMountAdapter(CodexConfigBridge bridge); - - @override - String get targetId => 'codex'; - - @override - String get label => 'Codex'; - - @override - bool get supportsSkills => true; - - @override - bool get supportsMcp => true; - - @override - bool get supportsAiGatewayInjection => true; - - @override - Future isInstalled() async => false; - - @override - Future reconcile({ - required MultiAgentConfig config, - required String aiGatewayUrl, - }) async { - return ManagedMountTargetState.placeholder( - targetId: targetId, - label: label, - supportsSkills: supportsSkills, - supportsMcp: supportsMcp, - supportsAiGatewayInjection: supportsAiGatewayInjection, - ).copyWith( - available: false, - discoveryState: 'missing', - syncState: 'missing', - detail: - 'Local CLI interaction is disabled. Use bridge for orchestration.', - ); - } -} - -class ClaudeMountAdapter extends CliMountAdapter { - @override - String get targetId => 'claude'; - - @override - String get label => 'Claude'; - - @override - bool get supportsSkills => true; - - @override - bool get supportsMcp => true; - - @override - bool get supportsAiGatewayInjection => true; - - @override - Future isInstalled() async => false; - - @override - Future reconcile({ - required MultiAgentConfig config, - required String aiGatewayUrl, - }) async { - return ManagedMountTargetState.placeholder( - targetId: targetId, - label: label, - supportsSkills: supportsSkills, - supportsMcp: supportsMcp, - supportsAiGatewayInjection: supportsAiGatewayInjection, - ).copyWith( - available: false, - discoveryState: 'missing', - syncState: 'disabled', - detail: 'Local CLI interaction is disabled.', - ); - } -} - -class GeminiMountAdapter extends CliMountAdapter { - @override - String get targetId => 'gemini'; - - @override - String get label => 'Gemini'; - - @override - bool get supportsSkills => true; - - @override - bool get supportsMcp => true; - - @override - bool get supportsAiGatewayInjection => true; - - @override - Future isInstalled() async => false; - - @override - Future reconcile({ - required MultiAgentConfig config, - required String aiGatewayUrl, - }) async { - return ManagedMountTargetState.placeholder( - targetId: targetId, - label: label, - supportsSkills: supportsSkills, - supportsMcp: supportsMcp, - supportsAiGatewayInjection: supportsAiGatewayInjection, - ).copyWith( - available: false, - discoveryState: 'missing', - syncState: 'disabled', - detail: 'Local CLI interaction is disabled.', - ); - } -} - -class OpencodeMountAdapter extends CliMountAdapter { - OpencodeMountAdapter(OpencodeConfigBridge bridge); - - @override - String get targetId => 'opencode'; - - @override - String get label => 'OpenCode'; - - @override - bool get supportsSkills => true; - - @override - bool get supportsMcp => true; - - @override - bool get supportsAiGatewayInjection => true; - - @override - Future isInstalled() async => false; - - @override - Future reconcile({ - required MultiAgentConfig config, - required String aiGatewayUrl, - }) async { - return ManagedMountTargetState.placeholder( - targetId: targetId, - label: label, - supportsSkills: supportsSkills, - supportsMcp: supportsMcp, - supportsAiGatewayInjection: supportsAiGatewayInjection, - ).copyWith( - available: false, - discoveryState: 'missing', - syncState: 'missing', - detail: 'Local CLI interaction is disabled.', - ); - } -} - -class OpenClawMountAdapter extends CliMountAdapter { - @override - String get targetId => 'openclaw'; - - @override - String get label => 'OpenClaw'; - - @override - bool get supportsSkills => true; - - @override - bool get supportsMcp => false; - - @override - bool get supportsAiGatewayInjection => true; - - @override - Future isInstalled() async => false; - - @override - Future reconcile({ - required MultiAgentConfig config, - required String aiGatewayUrl, - }) async { - return ManagedMountTargetState.placeholder( - targetId: targetId, - label: label, - supportsSkills: supportsSkills, - supportsMcp: supportsMcp, - supportsAiGatewayInjection: supportsAiGatewayInjection, - ).copyWith( - available: false, - discoveryState: 'missing', - syncState: 'disabled', - detail: 'Local CLI interaction is disabled.', - ); - } -} diff --git a/lib/runtime/multi_agent_orchestrator.dart b/lib/runtime/multi_agent_orchestrator.dart deleted file mode 100644 index 445f8a82..00000000 --- a/lib/runtime/multi_agent_orchestrator.dart +++ /dev/null @@ -1,4 +0,0 @@ -export 'multi_agent_orchestrator_protocol.dart'; -export 'multi_agent_orchestrator_workflow.dart'; -export 'multi_agent_orchestrator_support.dart'; -export 'multi_agent_orchestrator_core.dart'; diff --git a/lib/runtime/multi_agent_orchestrator_core.dart b/lib/runtime/multi_agent_orchestrator_core.dart deleted file mode 100644 index 35f11eff..00000000 --- a/lib/runtime/multi_agent_orchestrator_core.dart +++ /dev/null @@ -1,384 +0,0 @@ -// ignore_for_file: unused_import, unnecessary_import - -import 'dart:async'; -import 'dart:convert'; -import 'dart:io'; -import 'package:flutter/foundation.dart'; -import 'embedded_agent_launch_policy.dart'; -import 'multi_agent_frameworks.dart'; -import 'runtime_models.dart'; -import 'multi_agent_orchestrator_protocol.dart'; -import 'multi_agent_orchestrator_workflow.dart'; -import 'multi_agent_orchestrator_support.dart'; - -/// 多 Agent 协作编排器 -/// -/// 管理 Architect(调度/文档)→ Lead Engineer(主程)→ Worker/Review(并行 worker + 复审) -/// 的工作流。 -/// -/// 在云中性设计下,编排逻辑应通过桥接转发到远程 ACP 端点执行。 -class MultiAgentOrchestrator extends ChangeNotifier { - MultiAgentOrchestrator({ - required MultiAgentConfig config, - HttpClient Function()? httpClientFactory, - }) : configInternal = config, - httpClientFactoryInternal = httpClientFactory ?? HttpClient.new; - - /// 当前配置 - MultiAgentConfig configInternal; - MultiAgentConfig get config => configInternal; - final HttpClient Function() httpClientFactoryInternal; - - HttpClient? activeHttpClientInternal; - bool abortRequestedInternal = false; - - /// 协作模式是否启用 - bool collaborationEnabledInternal = false; - bool get collaborationEnabled => collaborationEnabledInternal; - - /// 是否正在运行 - bool isRunningInternal = false; - bool get isRunning => isRunningInternal; - - /// 最后错误 - String? lastErrorInternal; - String? get lastError => lastErrorInternal; - - /// 当前迭代轮次 - int currentIterationInternal = 0; - int get currentIteration => currentIterationInternal; - - /// 状态日志 - final List logEntriesInternal = []; - List get logEntries => - List.unmodifiable(logEntriesInternal); - - /// 更新配置 - void updateConfig(MultiAgentConfig config) { - configInternal = config; - collaborationEnabledInternal = config.enabled; - notifyListeners(); - } - - Future abort() async { - abortRequestedInternal = true; - final client = activeHttpClientInternal; - activeHttpClientInternal = null; - if (client != null) { - try { - client.close(force: true); - } catch (_) { - // Best effort only. - } - } - } - - /// 启用协作模式 - void enable() { - configInternal = configInternal.copyWith(enabled: true); - collaborationEnabledInternal = true; - lastErrorInternal = null; - notifyListeners(); - } - - /// 禁用协作模式 - void disable() { - configInternal = configInternal.copyWith(enabled: false); - collaborationEnabledInternal = false; - notifyListeners(); - } - - /// 切换协作模式 - void toggle() { - if (collaborationEnabledInternal) { - disable(); - } else { - enable(); - } - } - - /// 执行完整的协作工作流 - Future runCollaboration({ - required String taskPrompt, - required String workingDirectory, - List attachments = const [], - List selectedSkills = const [], - void Function(MultiAgentRunEvent event)? onEvent, - }) async { - if (isRunningInternal) { - throw StateError('Collaboration is already running'); - } - - isRunningInternal = true; - currentIterationInternal = 0; - abortRequestedInternal = false; - logEntriesInternal.clear(); - lastErrorInternal = null; - notifyListeners(); - - final startTime = DateTime.now(); - final steps = []; - final preset = configInternal.usesAris - ? const ArisFrameworkPreset() - : const NativeFrameworkPreset(); - - try { - // === Phase 1: Architect 分析任务 === - throwIfAbortedInternal(); - logInternal( - CollaborationLogLevel.info, - '🎨', - '${roleLabelInternal(MultiAgentRole.architect)} 开始分析任务...', - ); - emitEventInternal( - onEvent, - MultiAgentRunEvent( - type: 'step', - title: roleLabelInternal(MultiAgentRole.architect), - message: '${roleLabelInternal(MultiAgentRole.architect)} 开始分析任务…', - pending: true, - error: false, - role: 'architect', - ), - ); - final architectResult = await runArchitectInternal( - taskPrompt, - preset: preset, - selectedSkills: selectedSkills, - ); - steps.add( - CollaborationStep( - role: 'architect', - status: StepStatus.completed, - output: architectResult.output, - duration: architectResult.duration, - ), - ); - emitEventInternal( - onEvent, - MultiAgentRunEvent( - type: 'step', - title: roleLabelInternal(MultiAgentRole.architect), - message: '完成任务分析并生成执行分解。', - pending: false, - error: false, - role: 'architect', - data: { - 'taskCount': architectResult.decomposedTasks.length, - }, - ), - ); - - // === Phase 2: Engineer 实现 === - throwIfAbortedInternal(); - logInternal( - CollaborationLogLevel.info, - '🔧', - '${roleLabelInternal(MultiAgentRole.engineer)} 开始实现...', - ); - emitEventInternal( - onEvent, - MultiAgentRunEvent( - type: 'step', - title: roleLabelInternal(MultiAgentRole.engineer), - message: '${roleLabelInternal(MultiAgentRole.engineer)} 开始实现任务…', - pending: true, - error: false, - role: 'engineer', - ), - ); - final engineerResult = await runEngineerInternal( - architectResult.decomposedTasks, - workingDirectory, - attachments, - preset: preset, - selectedSkills: selectedSkills, - ); - steps.add( - CollaborationStep( - role: 'engineer', - status: StepStatus.completed, - output: engineerResult.output, - duration: engineerResult.duration, - ), - ); - emitEventInternal( - onEvent, - MultiAgentRunEvent( - type: 'step', - title: roleLabelInternal(MultiAgentRole.engineer), - message: '完成首轮实现。', - pending: false, - error: false, - role: 'engineer', - ), - ); - - // === Phase 3: Tester 审阅 === - throwIfAbortedInternal(); - logInternal( - CollaborationLogLevel.info, - '🔍', - '${roleLabelInternal(MultiAgentRole.testerDoc)} 开始审阅...', - ); - emitEventInternal( - onEvent, - MultiAgentRunEvent( - type: 'step', - title: roleLabelInternal(MultiAgentRole.testerDoc), - message: '${roleLabelInternal(MultiAgentRole.testerDoc)} 开始审阅实现…', - pending: true, - error: false, - role: 'tester', - ), - ); - final testerResult = await runTesterInternal( - engineerResult.codeOutput, - preset: preset, - ); - steps.add( - CollaborationStep( - role: 'tester', - status: StepStatus.completed, - output: testerResult.output, - duration: testerResult.duration, - score: testerResult.score, - ), - ); - emitEventInternal( - onEvent, - MultiAgentRunEvent( - type: 'step', - title: roleLabelInternal(MultiAgentRole.testerDoc), - message: '完成代码审阅。', - pending: false, - error: false, - role: 'tester', - score: testerResult.score, - ), - ); - - // === Phase 4: 迭代审阅循环(如需要)=== - if (testerResult.score < configInternal.minAcceptableScore) { - logInternal( - CollaborationLogLevel.warning, - '⚠️', - '质量评分 ${testerResult.score}/10 未达标,开始迭代审阅...', - ); - - for (var i = 0; i < configInternal.maxIterations; i++) { - throwIfAbortedInternal(); - currentIterationInternal = i + 1; - logInternal( - CollaborationLogLevel.info, - '🔄', - '迭代 $currentIterationInternal/${configInternal.maxIterations}...', - ); - notifyListeners(); - - // Lead Engineer 接收反馈并修复 - final fixedResult = await runFixInternal( - engineerResult.codeOutput, - testerResult.feedback, - workingDirectory, - preset: preset, - ); - steps.add( - CollaborationStep( - role: 'engineer', - status: StepStatus.completed, - output: fixedResult.output, - duration: fixedResult.duration, - iteration: currentIterationInternal, - ), - ); - - // Tester 重新审阅 - final reReview = await runTesterInternal( - fixedResult.codeOutput, - preset: preset, - ); - steps.add( - CollaborationStep( - role: 'tester', - status: StepStatus.completed, - output: reReview.output, - duration: reReview.duration, - score: reReview.score, - iteration: currentIterationInternal, - ), - ); - - if (reReview.score >= configInternal.minAcceptableScore) { - logInternal( - CollaborationLogLevel.success, - '✅', - '质量达标 (${reReview.score}/10),迭代结束', - ); - engineerResult.codeOutput = fixedResult.codeOutput; - break; - } else if (currentIterationInternal >= configInternal.maxIterations) { - logInternal( - CollaborationLogLevel.error, - '❌', - '达到最大迭代次数 ${configInternal.maxIterations},质量仍未达标', - ); - } - } - } else { - logInternal( - CollaborationLogLevel.success, - '✅', - '质量达标 (${testerResult.score}/10),无需迭代', - ); - } - - final duration = DateTime.now().difference(startTime); - isRunningInternal = false; - notifyListeners(); - - return CollaborationResult( - success: true, - steps: steps, - finalCode: engineerResult.codeOutput, - finalScore: testerResult.score, - duration: duration, - iterations: currentIterationInternal, - ); - } catch (e) { - lastErrorInternal = e.toString(); - logInternal(CollaborationLogLevel.error, '❌', '协作失败: $lastErrorInternal'); - isRunningInternal = false; - notifyListeners(); - - return CollaborationResult( - success: false, - steps: steps, - finalCode: '', - finalScore: 0, - duration: DateTime.now().difference(startTime), - iterations: currentIterationInternal, - error: lastErrorInternal, - ); - } - } - - /// 记录日志 - void logInternal(CollaborationLogLevel level, String emoji, String message) { - logEntriesInternal.add( - CollaborationLogEntry( - timestamp: DateTime.now(), - level: level, - emoji: emoji, - message: message, - ), - ); - notifyListeners(); - } - - /// 清除日志 - void clearLogs() { - logEntriesInternal.clear(); - notifyListeners(); - } -} diff --git a/lib/runtime/multi_agent_orchestrator_protocol.dart b/lib/runtime/multi_agent_orchestrator_protocol.dart deleted file mode 100644 index 7909cd4c..00000000 --- a/lib/runtime/multi_agent_orchestrator_protocol.dart +++ /dev/null @@ -1,200 +0,0 @@ -// ignore_for_file: unused_import, unnecessary_import - -import 'dart:async'; -import 'dart:convert'; -import 'dart:io'; -import 'package:flutter/foundation.dart'; - -import 'embedded_agent_launch_policy.dart'; -import 'go_core.dart'; -import 'aris_llm_chat_client.dart'; -import 'multi_agent_frameworks.dart'; -import 'runtime_models.dart'; -import 'multi_agent_orchestrator_workflow.dart'; -import 'multi_agent_orchestrator_support.dart'; -import 'multi_agent_orchestrator_core.dart'; - -typedef CliProcessStarter = - Future Function( - String executable, - List arguments, { - Map? environment, - String? workingDirectory, - }); - -/// 协作日志条目 -class CollaborationLogEntry { - const CollaborationLogEntry({ - required this.timestamp, - required this.level, - required this.emoji, - required this.message, - }); - - final DateTime timestamp; - final CollaborationLogLevel level; - final String emoji; - final String message; - - String get formattedTime { - final h = timestamp.hour.toString().padLeft(2, '0'); - final m = timestamp.minute.toString().padLeft(2, '0'); - final s = timestamp.second.toString().padLeft(2, '0'); - return '$h:$m:$s'; - } -} - -enum CollaborationLogLevel { debug, info, warning, error, success } - -/// CLI 执行结果 -class CliResult { - const CliResult({ - required this.output, - required this.error, - required this.exitCode, - }); - - final String output; - final String error; - final int exitCode; - - bool get success => exitCode == 0 && error.isEmpty; -} - -/// Architect 执行结果 -class ArchitectResult { - ArchitectResult({ - required this.output, - required this.decomposedTasks, - required this.duration, - }); - - final String output; - final List decomposedTasks; - final Duration duration; -} - -/// Engineer 执行结果 -class EngineerResult { - EngineerResult({ - required this.output, - required this.codeOutput, - required this.completedTasks, - required this.duration, - }); - - final String output; - String codeOutput; - final List completedTasks; - final Duration duration; -} - -/// Tester 执行结果 -class TesterResult { - TesterResult({ - required this.output, - required this.score, - required this.feedback, - required this.duration, - }); - - final String output; - final int score; - final String feedback; - final Duration duration; -} - -/// 协作步骤 -class CollaborationStep { - const CollaborationStep({ - required this.role, - required this.status, - required this.output, - required this.duration, - this.iteration, - this.score, - }); - - final String role; - final StepStatus status; - final String output; - final Duration duration; - final int? iteration; - final int? score; - - Map toJson() { - return { - 'role': role, - 'status': status.name, - 'output': output, - 'durationMs': duration.inMilliseconds, - if (iteration != null) 'iteration': iteration, - if (score != null) 'score': score, - }; - } -} - -enum StepStatus { pending, running, completed, failed } - -/// 子任务 -class SubTask { - const SubTask({ - required this.id, - required this.description, - required this.order, - required this.type, - }); - - final String id; - final String description; - final int order; - final SubTaskType type; -} - -enum SubTaskType { design, implementation, testing, documentation, deployment } - -/// 附件 -class CollaborationAttachment { - const CollaborationAttachment({ - required this.name, - required this.description, - required this.path, - }); - - final String name; - final String description; - final String path; -} - -/// 协作最终结果 -class CollaborationResult { - const CollaborationResult({ - required this.success, - required this.steps, - required this.finalCode, - required this.finalScore, - required this.duration, - required this.iterations, - this.error, - }); - - final bool success; - final List steps; - final String finalCode; - final int finalScore; - final Duration duration; - final int iterations; - final String? error; - - Map toJson() { - return { - 'success': success, - 'steps': steps.map((item) => item.toJson()).toList(growable: false), - 'finalCode': finalCode, - 'finalScore': finalScore, - 'durationMs': duration.inMilliseconds, - 'iterations': iterations, - if (error != null) 'error': error, - }; - } -} diff --git a/lib/runtime/multi_agent_orchestrator_support.dart b/lib/runtime/multi_agent_orchestrator_support.dart deleted file mode 100644 index eee781bf..00000000 --- a/lib/runtime/multi_agent_orchestrator_support.dart +++ /dev/null @@ -1,269 +0,0 @@ -// ignore_for_file: unused_import, unnecessary_import - -import 'dart:async'; -import 'dart:convert'; -import 'dart:io'; -import 'package:flutter/foundation.dart'; - -import 'embedded_agent_launch_policy.dart'; -import 'go_core.dart'; -import 'aris_llm_chat_client.dart'; -import 'multi_agent_frameworks.dart'; -import 'runtime_models.dart'; -import 'multi_agent_orchestrator_protocol.dart'; -import 'multi_agent_orchestrator_workflow.dart'; -import 'multi_agent_orchestrator_core.dart'; - -extension MultiAgentOrchestratorSupportInternal on MultiAgentOrchestrator { - String openAiCompatibleBaseUrlInternal() { - final normalized = configInternal.ollamaEndpoint.trim(); - return normalized.endsWith('/v1') ? normalized : '$normalized/v1'; - } - - String openAiCompatibleApiKeyInternal() { - return 'ollama'; - } - - String systemPromptForRoleInternal(MultiAgentRole role) { - return switch (role) { - MultiAgentRole.architect => - 'You are the architecture and documentation lane in a multi-agent coding workflow. Focus on requirements, acceptance evidence, task slicing, and milestones.', - MultiAgentRole.engineer => - 'You are the lead engineer in a multi-agent coding workflow. Produce implementation-oriented output for the critical path.', - MultiAgentRole.testerDoc => - 'You are the worker-review lane in a multi-agent coding workflow. Review, score, and suggest follow-up fixes and worker follow-ups.', - }; - } - - String roleLabelInternal(MultiAgentRole role) { - return switch (role) { - MultiAgentRole.architect => 'Architect', - MultiAgentRole.engineer => 'Lead Engineer', - MultiAgentRole.testerDoc => 'Worker/Review', - }; - } - - String modelForRoleInternal(MultiAgentRole role) { - return switch (role) { - MultiAgentRole.architect => configInternal.architect.model, - MultiAgentRole.engineer => configInternal.engineer.model, - MultiAgentRole.testerDoc => configInternal.tester.model, - }; - } - - bool prefersOllamaLaunchInternal({ - required String tool, - required String model, - }) { - final normalizedTool = tool.trim().toLowerCase(); - final normalizedModel = model.trim(); - if (normalizedModel.isEmpty) { - return false; - } - if (normalizedTool != 'claude' && - normalizedTool != 'codex' && - normalizedTool != 'opencode') { - return false; - } - return true; - } - - List buildOllamaLaunchArgsInternal({ - required String tool, - required String model, - required String prompt, - required String cwd, - }) { - final args = ['launch', tool, '--model', model]; - if (tool == 'claude') { - args.add('--yes'); - args.addAll(['--', '-p', prompt]); - return args; - } - if (tool == 'codex') { - args.addAll([ - '--', - 'exec', - '--skip-git-repo-check', - '--color', - 'never', - if (cwd.isNotEmpty) ...['-C', cwd], - prompt, - ]); - return args; - } - if (tool == 'opencode') { - args.addAll([ - '--', - 'run', - '--format', - 'default', - if (cwd.isNotEmpty) ...['--dir', cwd], - prompt, - ]); - return args; - } - args.addAll(['--', '-p', prompt]); - return args; - } - - void throwIfAbortedInternal() { - if (abortRequestedInternal) { - throw StateError('Multi-agent collaboration aborted.'); - } - } - - /// 解析 Architect 分解的任务 - List parseDecomposedTasksInternal(String architectOutput) { - final tasks = []; - final lines = architectOutput.split('\n'); - - var order = 1; - for (final line in lines) { - final trimmed = line.trim(); - if (trimmed.isEmpty) continue; - - // 匹配 "- 描述" 或 "1. 描述" 格式 - final dashMatch = RegExp(r'^[-*]\s+(.+)').firstMatch(trimmed); - final numMatch = RegExp(r'^\d+[.、)]\s*(.+)').firstMatch(trimmed); - - String? description; - if (dashMatch != null) { - description = dashMatch.group(1); - } else if (numMatch != null) { - description = numMatch.group(1); - } - - if (description != null && description.isNotEmpty) { - // 去除复杂度等技术注释 - description = description.replaceAll(RegExp(r'\s*\|.*'), '').trim(); - - // 判断任务类型 - SubTaskType type = SubTaskType.implementation; - final lower = description.toLowerCase(); - if (lower.contains('测试') || lower.contains('test')) { - type = SubTaskType.testing; - } else if (lower.contains('文档') || lower.contains('doc')) { - type = SubTaskType.documentation; - } else if (lower.contains('设计') || lower.contains('design')) { - type = SubTaskType.design; - } else if (lower.contains('部署') || lower.contains('deploy')) { - type = SubTaskType.deployment; - } - - tasks.add( - SubTask( - id: order.toString(), - description: description, - order: order, - type: type, - ), - ); - order++; - } - } - - // 如果解析失败,至少返回一个包含完整需求的子任务 - if (tasks.isEmpty) { - tasks.add( - SubTask( - id: '1', - description: architectOutput.length > 200 - ? '${architectOutput.substring(0, 200)}...' - : architectOutput, - order: 1, - type: SubTaskType.implementation, - ), - ); - } - - return tasks; - } - - /// 解析审阅评分 - int parseReviewScoreInternal(String output) { - // 尝试匹配 "评分 (1-10)" 模式 - final patterns = [ - RegExp(r'评分\s*\(?[1100]\)?\s*[::]?\s*(\d+)'), - RegExp(r'score\s*[::]?\s*(\d+)', caseSensitive: false), - RegExp(r'评分[::\s]*(\d+)'), - RegExp(r'\*\*(\d+)\s*/\s*10\*\*'), - RegExp(r'(\d+)\s*/\s*10'), - ]; - - for (final pattern in patterns) { - final match = pattern.firstMatch(output); - if (match != null) { - final scoreStr = match.group(1)!; - final score = int.tryParse( - scoreStr.replaceAll('1', '1').replaceAll('0', '0'), - ); - if (score != null && score >= 1 && score <= 10) { - return score; - } - } - } - - // 默认中等评分 - return 5; - } - - /// 提取审阅反馈 - String extractFeedbackInternal(String output) { - final feedbackIndex = output.indexOf(RegExp(r'##?\s*问题|##?\s*改进|##?\s*建议')); - if (feedbackIndex >= 0) { - final endIndex = output.indexOf( - RegExp(r'##?\s*测试|##?\s*文档'), - feedbackIndex + 1, - ); - if (endIndex > feedbackIndex) { - return output.substring(feedbackIndex, endIndex).trim(); - } - return output.substring(feedbackIndex).trim(); - } - return output; - } - - /// 构建 Ollama 环境变量 - Map buildCliEnvVarsInternal({required String tool}) { - final baseEnv = {...Platform.environment}; - final ollamaEndpoint = configInternal.ollamaEndpoint.trim(); - if (ollamaEndpoint.isNotEmpty) { - baseEnv['OLLAMA_BASE_URL'] = ollamaEndpoint; - baseEnv['OLLAMA_HOST'] = ollamaEndpoint; - baseEnv['OPENAI_API_KEY'] = 'ollama'; - baseEnv['OPENAI_BASE_URL'] = ollamaEndpoint.endsWith('/v1') - ? ollamaEndpoint - : '$ollamaEndpoint/v1'; - } - if (tool == 'claude' || tool == 'codex') { - baseEnv['ANTHROPIC_AUTH_TOKEN'] = 'ollama'; - baseEnv['ANTHROPIC_API_KEY'] = ''; - baseEnv['ANTHROPIC_BASE_URL'] = ollamaEndpoint; - } - return baseEnv; - } - - /// 解析 CLI 工具路径 - String resolveCliPathInternal(String tool) { - switch (tool) { - case 'claude': - return 'claude'; - case 'codex': - return 'codex'; - case 'gemini': - return 'gemini'; - case 'opencode': - return 'opencode'; - default: - return tool; - } - } - - void emitEventInternal( - void Function(MultiAgentRunEvent event)? onEvent, - MultiAgentRunEvent event, - ) { - onEvent?.call(event); - } -} diff --git a/lib/runtime/multi_agent_orchestrator_workflow.dart b/lib/runtime/multi_agent_orchestrator_workflow.dart deleted file mode 100644 index 7657f518..00000000 --- a/lib/runtime/multi_agent_orchestrator_workflow.dart +++ /dev/null @@ -1,456 +0,0 @@ -// ignore_for_file: unused_import, unnecessary_import - -import 'dart:async'; -import 'dart:convert'; -import 'dart:io'; -import 'package:flutter/foundation.dart'; - -import 'embedded_agent_launch_policy.dart'; -import 'go_core.dart'; -import 'aris_llm_chat_client.dart'; -import 'multi_agent_frameworks.dart'; -import 'runtime_models.dart'; -import 'multi_agent_orchestrator_protocol.dart'; -import 'multi_agent_orchestrator_support.dart'; -import 'multi_agent_orchestrator_core.dart'; - -extension MultiAgentOrchestratorWorkflowInternal on MultiAgentOrchestrator { - /// 运行 Architect(调度/文档分析) - Future runArchitectInternal( - String task, { - required FrameworkPreset preset, - required List selectedSkills, - }) async { - final stopwatch = Stopwatch()..start(); - - try { - // 根据配置选择 Architect 工具 - if (configInternal.architectEnabled) { - final tool = await resolveToolForRoleInternal( - MultiAgentRole.architect, - configInternal.architectTool, - ); - final instructionBlock = await preset.roleInstructionBlock( - role: MultiAgentRole.architect, - tool: tool, - selectedSkills: selectedSkills, - ); - final result = await runCliPromptInternal( - role: MultiAgentRole.architect, - tool: tool, - model: resolvedModelForRoleInternal( - MultiAgentRole.architect, - configuredModel: configInternal.architectModel, - ), - prompt: buildArchitectPromptInternal( - task, - selectedSkills, - instructionBlock, - ), - cwd: '', - ); - stopwatch.stop(); - - // 解析分解后的任务 - final tasks = parseDecomposedTasksInternal(result.output); - return ArchitectResult( - output: result.output, - decomposedTasks: tasks, - duration: stopwatch.elapsed, - ); - } else { - // Architect 被禁用,直接返回原任务作为单一子任务 - stopwatch.stop(); - return ArchitectResult( - output: task, - decomposedTasks: [ - SubTask( - id: '1', - description: task, - order: 1, - type: SubTaskType.implementation, - ), - ], - duration: stopwatch.elapsed, - ); - } - } catch (e) { - stopwatch.stop(); - rethrow; - } - } - - /// 运行 Lead Engineer(主实现) - Future runEngineerInternal( - List tasks, - String workingDirectory, - List attachments, { - required FrameworkPreset preset, - required List selectedSkills, - }) async { - final stopwatch = Stopwatch()..start(); - final tool = await resolveToolForRoleInternal( - MultiAgentRole.engineer, - configInternal.engineerTool, - ); - final instructionBlock = await preset.roleInstructionBlock( - role: MultiAgentRole.engineer, - tool: tool, - selectedSkills: selectedSkills, - ); - - final taskList = tasks - .map((t) => '## ${t.order}. ${t.description}') - .join('\n\n'); - - final prompt = - ''' -$instructionBlock - -你是一个资深工程师,负责完成以下编码任务: - -### 任务列表 -$taskList - -### 工作目录 -$workingDirectory - -### 附件信息 -${attachments.map((a) => '- ${a.name}: ${a.description}').join('\n')} - -### 优先技能 -${selectedSkills.isEmpty ? '- 无' : selectedSkills.map((item) => '- $item').join('\n')} - -请完成这些任务,输出完整的代码实现。 -'''; - - final result = await runCliPromptInternal( - role: MultiAgentRole.engineer, - tool: tool, - model: resolvedModelForRoleInternal( - MultiAgentRole.engineer, - configuredModel: configInternal.engineerModel, - ), - prompt: prompt, - cwd: workingDirectory, - ); - stopwatch.stop(); - - return EngineerResult( - output: result.output, - codeOutput: result.output, - completedTasks: tasks, - duration: stopwatch.elapsed, - ); - } - - /// 运行 Worker/Review(代码审阅) - Future runTesterInternal( - String codeOutput, { - required FrameworkPreset preset, - }) async { - final stopwatch = Stopwatch()..start(); - final tool = await resolveToolForRoleInternal( - MultiAgentRole.testerDoc, - configInternal.testerTool, - ); - final instructionBlock = await preset.roleInstructionBlock( - role: MultiAgentRole.testerDoc, - tool: tool, - selectedSkills: const [], - ); - - final prompt = - ''' -$instructionBlock - -请审阅以下代码,并按以下格式输出: - -## 评分 (1-10) -[1-10 的分数,10 最高] - -## 问题列表 -[发现的问题,格式:- 问题描述 (严重程度: 高/中/低)] - -## 改进建议 -[具体的改进建议] - -## 测试用例 -```[语言] -[生成的测试用例代码] -``` - -## 文档建议 -[如有需要补充的文档说明] - -### 待审阅代码 -${codeOutput.length > 4000 ? '${codeOutput.substring(0, 4000)}\n...[代码已截断]' : codeOutput} -'''; - - final testerModel = resolvedModelForRoleInternal( - MultiAgentRole.testerDoc, - configuredModel: configInternal.testerModel, - ); - final result = configInternal.usesAris && tool == 'claude' - ? await runArisTesterViaClaudeReviewInternal( - model: testerModel, - prompt: prompt, - ) - : await runCliPromptInternal( - role: MultiAgentRole.testerDoc, - tool: tool, - model: testerModel, - prompt: prompt, - cwd: '', - ); - stopwatch.stop(); - - final score = parseReviewScoreInternal(result.output); - final feedback = extractFeedbackInternal(result.output); - - return TesterResult( - output: result.output, - score: score, - feedback: feedback, - duration: stopwatch.elapsed, - ); - } - - /// 运行修复(迭代循环中) - Future runFixInternal( - String originalCode, - String feedback, - String workingDirectory, { - required FrameworkPreset preset, - }) async { - final stopwatch = Stopwatch()..start(); - final tool = await resolveToolForRoleInternal( - MultiAgentRole.engineer, - configInternal.engineerTool, - ); - final instructionBlock = await preset.roleInstructionBlock( - role: MultiAgentRole.engineer, - tool: tool, - selectedSkills: const [], - ); - - final prompt = - ''' -$instructionBlock - -你是一个资深工程师。请根据审阅反馈修复代码。 - -## 审阅反馈 -$feedback - -## 原始代码 -$originalCode - -请完成修复,输出修复后的完整代码。 -'''; - - final result = await runCliPromptInternal( - role: MultiAgentRole.engineer, - tool: tool, - model: resolvedModelForRoleInternal( - MultiAgentRole.engineer, - configuredModel: configInternal.engineerModel, - ), - prompt: prompt, - cwd: workingDirectory, - ); - stopwatch.stop(); - - return EngineerResult( - output: result.output, - codeOutput: result.output, - completedTasks: [], - duration: stopwatch.elapsed, - ); - } - - /// 通用的 CLI 进程执行方法 (DEPRECATED: Use bridge instead) - Future runCliPromptInternal({ - required MultiAgentRole role, - required String tool, - required String model, - required String prompt, - required String cwd, - }) async { - // In cloud-neutral architecture, local CLI execution is disabled. - // We should fallback to OpenAI compatible API or bridge execution. - return runArisFallbackInternal(role: role, model: model, prompt: prompt); - } - - /// 构建 Architect 的 Prompt - String buildArchitectPromptInternal( - String task, - List selectedSkills, - String instructionBlock, - ) { - return ''' -$instructionBlock - -你是一个多 Agent 协作调度者。请先收敛 requirements -> acceptance evidence,再输出可执行的主程/worker分工。 - -## 用户需求 -$task - -## 优先技能 -${selectedSkills.isEmpty ? '- 无' : selectedSkills.map((item) => '- $item').join('\n')} - -请输出: -1. 任务概述(2-3 句话) -2. 子任务列表(3-5 个),每个子任务包含: - - 任务编号和描述 - - 负责角色(文档/主程/worker) - - 接受标准 - - 关键技术点 -3. 推荐的执行顺序与关键里程碑 - -请严格按以下格式输出: -## 概述 -[你的概述] - -## 子任务 -1. [任务描述] | 角色:[文档/主程/worker] | 接受标准:[可验证结果] | 关键技术:[技术点] -2. [任务描述] | 角色:[文档/主程/worker] | 接受标准:[可验证结果] | 关键技术:[技术点] -... -'''; - } - - Future resolveToolForRoleInternal( - MultiAgentRole role, - String configuredTool, - ) async { - return configuredTool; - } - - String resolvedModelForRoleInternal( - MultiAgentRole role, { - required String configuredModel, - }) { - final trimmed = configuredModel.trim(); - if (trimmed.isNotEmpty) { - return trimmed; - } - switch (role) { - case MultiAgentRole.architect: - return 'kimi-k2.5:cloud'; - case MultiAgentRole.engineer: - return 'minimax-m2.7:cloud'; - case MultiAgentRole.testerDoc: - return 'glm-5:cloud'; - } - } - - Future binaryExistsInternal(String command) async { - return false; - } - - Future runArisFallbackInternal({ - required MultiAgentRole role, - required String model, - required String prompt, - }) async { - if (role == MultiAgentRole.testerDoc) { - final viaLlmChat = await runArisTesterViaLlmChatInternal( - model: model, - prompt: prompt, - ); - if (viaLlmChat.success) { - return viaLlmChat; - } - } - return runOpenAiCompatiblePromptInternal( - role: role, - model: model, - prompt: prompt, - ); - } - - Future runArisTesterViaLlmChatInternal({ - required String model, - required String prompt, - }) async { - return runOpenAiCompatiblePromptInternal( - role: MultiAgentRole.testerDoc, - model: model, - prompt: prompt, - ); - } - - Future runArisTesterViaClaudeReviewInternal({ - required String model, - required String prompt, - }) async { - return runArisFallbackInternal( - role: MultiAgentRole.testerDoc, - model: model, - prompt: prompt, - ); - } - - Future runOpenAiCompatiblePromptInternal({ - required MultiAgentRole role, - required String model, - required String prompt, - }) async { - final client = httpClientFactoryInternal(); - activeHttpClientInternal = client; - try { - final request = await client.postUrl( - Uri.parse( - '${openAiCompatibleBaseUrlInternal().replaceAll(RegExp(r'/$'), '')}/chat/completions', - ), - ); - request.headers.set(HttpHeaders.contentTypeHeader, 'application/json'); - request.headers.set( - HttpHeaders.authorizationHeader, - 'Bearer ${openAiCompatibleApiKeyInternal()}', - ); - request.add( - utf8.encode( - jsonEncode({ - 'model': model, - 'stream': false, - 'messages': >[ - { - 'role': 'system', - 'content': systemPromptForRoleInternal(role), - }, - {'role': 'user', 'content': prompt}, - ], - }), - ), - ); - final response = await request.close().timeout( - Duration(seconds: configInternal.timeoutSeconds), - ); - final body = await utf8.decodeStream(response); - if (response.statusCode < 200 || response.statusCode >= 300) { - return CliResult( - output: '', - error: body, - exitCode: response.statusCode, - ); - } - final decoded = jsonDecode(body) as Map; - final choices = decoded['choices'] as List? ?? const []; - final firstChoice = choices.isNotEmpty ? choices.first : null; - final output = - ((firstChoice as Map?)?['message'] as Map?)?['content']?.toString() ?? - ''; - return CliResult(output: output, error: '', exitCode: 0); - } catch (error) { - return CliResult(output: '', error: error.toString(), exitCode: -1); - } finally { - activeHttpClientInternal = null; - try { - client.close(force: true); - } catch (_) { - // Best effort only. - } - } - } -} diff --git a/lib/runtime/runtime_models.dart b/lib/runtime/runtime_models.dart index 07863e86..a24fb24f 100644 --- a/lib/runtime/runtime_models.dart +++ b/lib/runtime/runtime_models.dart @@ -6,5 +6,3 @@ export 'runtime_models_settings_snapshot.dart'; export 'runtime_models_ui_state.dart'; export 'runtime_models_runtime_payloads.dart'; export 'runtime_models_gateway_entities.dart'; -export 'runtime_models_multi_agent.dart'; -export 'multi_agent_orchestrator_protocol.dart'; diff --git a/lib/runtime/runtime_models_multi_agent.dart b/lib/runtime/runtime_models_multi_agent.dart index 115e921f..98495ef3 100644 --- a/lib/runtime/runtime_models_multi_agent.dart +++ b/lib/runtime/runtime_models_multi_agent.dart @@ -1,107 +1,3 @@ -// ignore_for_file: unused_import, unnecessary_import - -import 'dart:convert'; -import '../i18n/app_language.dart'; -import '../models/app_models.dart'; -import 'runtime_models_connection.dart'; -import 'runtime_models_profiles.dart'; -import 'runtime_models_configs.dart'; -import 'runtime_models_settings_snapshot.dart'; -import 'runtime_models_runtime_payloads.dart'; -import 'runtime_models_gateway_entities.dart'; - -enum MultiAgentRole { - architect, // 调度/文档:需求收口、接受标准、工作流设计 - engineer, // 主程:关键实现、重构、集成 - testerDoc, // worker/review:并行切片、复审、回归建议 -} - -enum MultiAgentFramework { native, aris } - -extension MultiAgentFrameworkCopy on MultiAgentFramework { - String get label => switch (this) { - MultiAgentFramework.native => appText('原生多 Agent', 'Native Multi-Agent'), - MultiAgentFramework.aris => appText('ARIS 框架', 'ARIS Framework'), - }; - - static MultiAgentFramework fromJsonValue(String? value) { - return MultiAgentFramework.values.firstWhere( - (item) => item.name == value, - orElse: () => MultiAgentFramework.native, - ); - } -} - -extension MultiAgentRoleCopy on MultiAgentRole { - String get label => switch (this) { - MultiAgentRole.architect => 'Architect(调度/文档)', - MultiAgentRole.engineer => 'Lead Engineer(主程)', - MultiAgentRole.testerDoc => 'Worker/Review(Worker 池)', - }; - - String get description => switch (this) { - MultiAgentRole.architect => '负责需求收口、接受标准、文档与协作调度', - MultiAgentRole.engineer => '负责主实现、关键改动、集成收口', - MultiAgentRole.testerDoc => '负责并行 worker、复审、回归和补充说明', - }; -} - -enum AiGatewayInjectionPolicy { disabled, launchScoped, appManagedDefault } - -extension AiGatewayInjectionPolicyCopy on AiGatewayInjectionPolicy { - String get label => switch (this) { - AiGatewayInjectionPolicy.disabled => appText('禁用', 'Disabled'), - AiGatewayInjectionPolicy.launchScoped => appText( - '仅当前协作运行', - 'Launch scoped', - ), - AiGatewayInjectionPolicy.appManagedDefault => appText( - 'XWorkmate 默认', - 'XWorkmate default', - ), - }; - - static AiGatewayInjectionPolicy fromJsonValue(String? value) { - return AiGatewayInjectionPolicy.values.firstWhere( - (item) => item.name == value, - orElse: () => AiGatewayInjectionPolicy.appManagedDefault, - ); - } -} - -/// 单个 Agent Worker 配置 -class AgentWorkerConfig { - const AgentWorkerConfig({ - required this.role, - required this.cliTool, - required this.model, - required this.enabled, - this.maxRetries = 2, - }); - - final MultiAgentRole role; - final String cliTool; // e.g. 'claude' | 'codex' | 'opencode' | 'gemini' - final String model; - final bool enabled; - final int maxRetries; - - AgentWorkerConfig copyWith({ - MultiAgentRole? role, - String? cliTool, - String? model, - bool? enabled, - int? maxRetries, - }) { - return AgentWorkerConfig( - role: role ?? this.role, - cliTool: cliTool ?? this.cliTool, - model: model ?? this.model, - enabled: enabled ?? this.enabled, - maxRetries: maxRetries ?? this.maxRetries, - ); - } -} - class ManagedSkillEntry { const ManagedSkillEntry({ required this.key, @@ -426,415 +322,3 @@ class ManagedMountTargetState { ]; } } - -/// 多 Agent 协作配置 -class MultiAgentConfig { - const MultiAgentConfig({ - required this.enabled, - required this.autoSync, - required this.framework, - required this.arisEnabled, - required this.arisMode, - required this.arisBundleVersion, - required this.arisCompatStatus, - required this.architect, - required this.engineer, - required this.tester, - required this.ollamaEndpoint, - required this.maxIterations, - required this.minAcceptableScore, - required this.timeoutSeconds, - required this.aiGatewayInjectionPolicy, - required this.managedSkills, - required this.managedMcpServers, - required this.mountTargets, - }); - - final bool enabled; - final bool autoSync; - final MultiAgentFramework framework; - final bool arisEnabled; - final String arisMode; - final String arisBundleVersion; - final String arisCompatStatus; - final AgentWorkerConfig architect; - final AgentWorkerConfig engineer; - final AgentWorkerConfig tester; - final String ollamaEndpoint; - final int maxIterations; - final int minAcceptableScore; - final int timeoutSeconds; - final AiGatewayInjectionPolicy aiGatewayInjectionPolicy; - final List managedSkills; - final List managedMcpServers; - final List mountTargets; - - /// Architect 配置的便捷访问 - bool get architectEnabled => architect.enabled; - String get architectTool => architect.cliTool; - String get architectModel => architect.model; - - /// Engineer 配置的便捷访问 - String get engineerTool => engineer.cliTool; - String get engineerModel => engineer.model; - - /// Tester 配置的便捷访问 - String get testerTool => tester.cliTool; - String get testerModel => tester.model; - - bool get usesAris => arisEnabled || framework == MultiAgentFramework.aris; - - factory MultiAgentConfig.defaults() { - return MultiAgentConfig( - enabled: false, - autoSync: true, - framework: MultiAgentFramework.native, - arisEnabled: false, - arisMode: 'full', - arisBundleVersion: '', - arisCompatStatus: 'idle', - architect: const AgentWorkerConfig( - role: MultiAgentRole.architect, - cliTool: 'claude', - model: 'kimi-k2.5:cloud', - enabled: true, - ), - engineer: const AgentWorkerConfig( - role: MultiAgentRole.engineer, - cliTool: 'codex', - model: 'minimax-m2.7:cloud', - enabled: true, - ), - tester: const AgentWorkerConfig( - role: MultiAgentRole.testerDoc, - cliTool: 'opencode', - model: 'glm-5:cloud', - enabled: true, - ), - ollamaEndpoint: 'http://127.0.0.1:11434', - maxIterations: 3, - minAcceptableScore: 7, - timeoutSeconds: 120, - aiGatewayInjectionPolicy: AiGatewayInjectionPolicy.appManagedDefault, - managedSkills: const [], - managedMcpServers: const [], - mountTargets: const [ - ManagedMountTargetState( - targetId: 'aris', - label: 'ARIS', - available: false, - supportsSkills: true, - supportsMcp: true, - supportsAiGatewayInjection: false, - discoveryState: 'idle', - syncState: 'idle', - discoveredSkillCount: 0, - discoveredMcpCount: 0, - managedMcpCount: 0, - detail: '', - ), - ManagedMountTargetState( - targetId: 'codex', - label: 'Codex', - available: false, - supportsSkills: true, - supportsMcp: true, - supportsAiGatewayInjection: true, - discoveryState: 'idle', - syncState: 'idle', - discoveredSkillCount: 0, - discoveredMcpCount: 0, - managedMcpCount: 0, - detail: '', - ), - ManagedMountTargetState( - targetId: 'claude', - label: 'Claude', - available: false, - supportsSkills: true, - supportsMcp: true, - supportsAiGatewayInjection: true, - discoveryState: 'idle', - syncState: 'idle', - discoveredSkillCount: 0, - discoveredMcpCount: 0, - managedMcpCount: 0, - detail: '', - ), - ManagedMountTargetState( - targetId: 'gemini', - label: 'Gemini', - available: false, - supportsSkills: true, - supportsMcp: true, - supportsAiGatewayInjection: true, - discoveryState: 'idle', - syncState: 'idle', - discoveredSkillCount: 0, - discoveredMcpCount: 0, - managedMcpCount: 0, - detail: '', - ), - ManagedMountTargetState( - targetId: 'opencode', - label: 'OpenCode', - available: false, - supportsSkills: true, - supportsMcp: true, - supportsAiGatewayInjection: true, - discoveryState: 'idle', - syncState: 'idle', - discoveredSkillCount: 0, - discoveredMcpCount: 0, - managedMcpCount: 0, - detail: '', - ), - ManagedMountTargetState( - targetId: 'openclaw', - label: 'OpenClaw', - available: false, - supportsSkills: true, - supportsMcp: false, - supportsAiGatewayInjection: true, - discoveryState: 'idle', - syncState: 'idle', - discoveredSkillCount: 0, - discoveredMcpCount: 0, - managedMcpCount: 0, - detail: '', - ), - ], - ); - } - - MultiAgentConfig copyWith({ - bool? enabled, - bool? autoSync, - MultiAgentFramework? framework, - bool? arisEnabled, - String? arisMode, - String? arisBundleVersion, - String? arisCompatStatus, - AgentWorkerConfig? architect, - AgentWorkerConfig? engineer, - AgentWorkerConfig? tester, - String? ollamaEndpoint, - int? maxIterations, - int? minAcceptableScore, - int? timeoutSeconds, - AiGatewayInjectionPolicy? aiGatewayInjectionPolicy, - List? managedSkills, - List? managedMcpServers, - List? mountTargets, - }) { - return MultiAgentConfig( - enabled: enabled ?? this.enabled, - autoSync: autoSync ?? this.autoSync, - framework: framework ?? this.framework, - arisEnabled: arisEnabled ?? this.arisEnabled, - arisMode: arisMode ?? this.arisMode, - arisBundleVersion: arisBundleVersion ?? this.arisBundleVersion, - arisCompatStatus: arisCompatStatus ?? this.arisCompatStatus, - architect: architect ?? this.architect, - engineer: engineer ?? this.engineer, - tester: tester ?? this.tester, - ollamaEndpoint: ollamaEndpoint ?? this.ollamaEndpoint, - maxIterations: maxIterations ?? this.maxIterations, - minAcceptableScore: minAcceptableScore ?? this.minAcceptableScore, - timeoutSeconds: timeoutSeconds ?? this.timeoutSeconds, - aiGatewayInjectionPolicy: - aiGatewayInjectionPolicy ?? this.aiGatewayInjectionPolicy, - managedSkills: managedSkills ?? this.managedSkills, - managedMcpServers: managedMcpServers ?? this.managedMcpServers, - mountTargets: mountTargets ?? this.mountTargets, - ); - } - - Map toJson() { - return { - 'enabled': enabled, - 'autoSync': autoSync, - 'framework': framework.name, - 'arisEnabled': arisEnabled, - 'arisMode': arisMode, - 'arisBundleVersion': arisBundleVersion, - 'arisCompatStatus': arisCompatStatus, - 'architect': { - 'role': architect.role.name, - 'cliTool': architect.cliTool, - 'model': architect.model, - 'enabled': architect.enabled, - 'maxRetries': architect.maxRetries, - }, - 'engineer': { - 'role': engineer.role.name, - 'cliTool': engineer.cliTool, - 'model': engineer.model, - 'enabled': engineer.enabled, - 'maxRetries': engineer.maxRetries, - }, - 'tester': { - 'role': tester.role.name, - 'cliTool': tester.cliTool, - 'model': tester.model, - 'enabled': tester.enabled, - 'maxRetries': tester.maxRetries, - }, - 'ollamaEndpoint': ollamaEndpoint, - 'maxIterations': maxIterations, - 'minAcceptableScore': minAcceptableScore, - 'timeoutSeconds': timeoutSeconds, - 'aiGatewayInjectionPolicy': aiGatewayInjectionPolicy.name, - 'managedSkills': managedSkills.map((item) => item.toJson()).toList(), - 'managedMcpServers': managedMcpServers - .map((item) => item.toJson()) - .toList(), - 'mountTargets': mountTargets.map((item) => item.toJson()).toList(), - }; - } - - factory MultiAgentConfig.fromJson(Map json) { - final defaults = MultiAgentConfig.defaults(); - final architectJson = json['architect'] as Map? ?? {}; - final engineerJson = json['engineer'] as Map? ?? {}; - final testerJson = json['tester'] as Map? ?? {}; - final rawManagedSkills = json['managedSkills']; - final rawManagedMcpServers = json['managedMcpServers']; - final rawMountTargets = json['mountTargets']; - - AgentWorkerConfig parseWorker( - Map m, - MultiAgentRole role, - String defaultTool, - ) { - return AgentWorkerConfig( - role: role, - cliTool: m['cliTool'] as String? ?? defaultTool, - model: m['model'] as String? ?? '', - enabled: m['enabled'] as bool? ?? true, - maxRetries: m['maxRetries'] as int? ?? 2, - ); - } - - return MultiAgentConfig( - enabled: json['enabled'] as bool? ?? false, - autoSync: json['autoSync'] as bool? ?? defaults.autoSync, - framework: MultiAgentFrameworkCopy.fromJsonValue( - json['framework'] as String?, - ), - arisEnabled: json['arisEnabled'] as bool? ?? defaults.arisEnabled, - arisMode: json['arisMode'] as String? ?? defaults.arisMode, - arisBundleVersion: - json['arisBundleVersion'] as String? ?? defaults.arisBundleVersion, - arisCompatStatus: - json['arisCompatStatus'] as String? ?? defaults.arisCompatStatus, - architect: parseWorker( - architectJson, - MultiAgentRole.architect, - defaults.architect.cliTool, - ), - engineer: parseWorker( - engineerJson, - MultiAgentRole.engineer, - defaults.engineer.cliTool, - ), - tester: parseWorker( - testerJson, - MultiAgentRole.testerDoc, - defaults.tester.cliTool, - ), - ollamaEndpoint: - json['ollamaEndpoint'] as String? ?? defaults.ollamaEndpoint, - maxIterations: json['maxIterations'] as int? ?? defaults.maxIterations, - minAcceptableScore: - json['minAcceptableScore'] as int? ?? defaults.minAcceptableScore, - timeoutSeconds: json['timeoutSeconds'] as int? ?? defaults.timeoutSeconds, - aiGatewayInjectionPolicy: AiGatewayInjectionPolicyCopy.fromJsonValue( - json['aiGatewayInjectionPolicy'] as String?, - ), - managedSkills: rawManagedSkills is List - ? rawManagedSkills - .whereType() - .map( - (item) => - ManagedSkillEntry.fromJson(item.cast()), - ) - .toList(growable: false) - : defaults.managedSkills, - managedMcpServers: rawManagedMcpServers is List - ? rawManagedMcpServers - .whereType() - .map( - (item) => ManagedMcpServerEntry.fromJson( - item.cast(), - ), - ) - .toList(growable: false) - : defaults.managedMcpServers, - mountTargets: rawMountTargets is List - ? rawMountTargets - .whereType() - .map( - (item) => ManagedMountTargetState.fromJson( - item.cast(), - ), - ) - .toList(growable: false) - : defaults.mountTargets, - ); - } -} - -class MultiAgentRunEvent { - const MultiAgentRunEvent({ - required this.type, - required this.title, - required this.message, - required this.pending, - required this.error, - this.role, - this.iteration, - this.score, - this.data = const {}, - }); - - final String type; - final String title; - final String message; - final bool pending; - final bool error; - final String? role; - final int? iteration; - final int? score; - final Map data; - - Map toJson() { - return { - 'type': type, - 'title': title, - 'message': message, - 'pending': pending, - 'error': error, - if (role != null) 'role': role, - if (iteration != null) 'iteration': iteration, - if (score != null) 'score': score, - 'data': data, - }; - } - - factory MultiAgentRunEvent.fromJson(Map json) { - return MultiAgentRunEvent( - type: json['type'] as String? ?? 'status', - title: json['title'] as String? ?? '', - message: json['message'] as String? ?? '', - pending: json['pending'] as bool? ?? false, - error: json['error'] as bool? ?? false, - role: json['role'] as String?, - iteration: (json['iteration'] as num?)?.toInt(), - score: (json['score'] as num?)?.toInt(), - data: - (json['data'] as Map?)?.cast() ?? - const {}, - ); - } -} diff --git a/lib/runtime/runtime_models_settings_snapshot.dart b/lib/runtime/runtime_models_settings_snapshot.dart index 1134de6b..076757d2 100644 --- a/lib/runtime/runtime_models_settings_snapshot.dart +++ b/lib/runtime/runtime_models_settings_snapshot.dart @@ -10,7 +10,6 @@ import 'runtime_models_profiles.dart'; import 'runtime_models_configs.dart'; import 'runtime_models_runtime_payloads.dart'; import 'runtime_models_gateway_entities.dart'; -import 'runtime_models_multi_agent.dart'; const int settingsSnapshotSchemaVersion = 2; @@ -34,7 +33,6 @@ class SettingsSnapshot { required this.vault, required this.aiGateway, required this.webSessionPersistence, - required this.multiAgent, required this.themeMode, required this.experimentalCanvas, required this.experimentalBridge, @@ -67,7 +65,6 @@ class SettingsSnapshot { final VaultConfig vault; final AiGatewayProfile aiGateway; final WebSessionPersistenceConfig webSessionPersistence; - final MultiAgentConfig multiAgent; final ThemeMode themeMode; final bool experimentalCanvas; final bool experimentalBridge; @@ -101,7 +98,6 @@ class SettingsSnapshot { vault: VaultConfig.defaults(), aiGateway: AiGatewayProfile.defaults(), webSessionPersistence: WebSessionPersistenceConfig.defaults(), - multiAgent: MultiAgentConfig.defaults(), themeMode: ThemeMode.system, experimentalCanvas: false, experimentalBridge: false, @@ -136,7 +132,6 @@ class SettingsSnapshot { VaultConfig? vault, AiGatewayProfile? aiGateway, WebSessionPersistenceConfig? webSessionPersistence, - MultiAgentConfig? multiAgent, ThemeMode? themeMode, bool? experimentalCanvas, bool? experimentalBridge, @@ -179,7 +174,6 @@ class SettingsSnapshot { aiGateway: aiGateway ?? this.aiGateway, webSessionPersistence: webSessionPersistence ?? this.webSessionPersistence, - multiAgent: multiAgent ?? this.multiAgent, themeMode: themeMode ?? this.themeMode, experimentalCanvas: experimentalCanvas ?? this.experimentalCanvas, experimentalBridge: experimentalBridge ?? this.experimentalBridge, @@ -223,7 +217,6 @@ class SettingsSnapshot { 'vault': vault.toJson(), 'aiGateway': aiGateway.toJson(), 'webSessionPersistence': webSessionPersistence.toJson(), - 'multiAgent': multiAgent.toJson(), 'themeMode': themeMode.name, 'experimentalCanvas': experimentalCanvas, 'experimentalBridge': experimentalBridge, @@ -307,9 +300,6 @@ class SettingsSnapshot { (json['webSessionPersistence'] as Map?)?.cast() ?? const {}, ), - multiAgent: MultiAgentConfig.fromJson( - (json['multiAgent'] as Map?)?.cast() ?? const {}, - ), themeMode: ThemeMode.values.firstWhere( (m) => m.name == json['themeMode'], orElse: () => ThemeMode.system,