// 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, required this.label, required this.source, required this.selected, }); final String key; final String label; final String source; final bool selected; ManagedSkillEntry copyWith({ String? key, String? label, String? source, bool? selected, }) { return ManagedSkillEntry( key: key ?? this.key, label: label ?? this.label, source: source ?? this.source, selected: selected ?? this.selected, ); } Map toJson() { return {'key': key, 'label': label, 'source': source, 'selected': selected}; } factory ManagedSkillEntry.fromJson(Map json) { return ManagedSkillEntry( key: json['key'] as String? ?? '', label: json['label'] as String? ?? '', source: json['source'] as String? ?? '', selected: json['selected'] as bool? ?? false, ); } } class ManagedMcpServerEntry { const ManagedMcpServerEntry({ required this.id, required this.name, required this.transport, required this.command, required this.url, required this.args, required this.envKeys, required this.enabled, }); final String id; final String name; final String transport; final String command; final String url; final List args; final List envKeys; final bool enabled; ManagedMcpServerEntry copyWith({ String? id, String? name, String? transport, String? command, String? url, List? args, List? envKeys, bool? enabled, }) { return ManagedMcpServerEntry( id: id ?? this.id, name: name ?? this.name, transport: transport ?? this.transport, command: command ?? this.command, url: url ?? this.url, args: args ?? this.args, envKeys: envKeys ?? this.envKeys, enabled: enabled ?? this.enabled, ); } Map toJson() { return { 'id': id, 'name': name, 'transport': transport, 'command': command, 'url': url, 'args': args, 'envKeys': envKeys, 'enabled': enabled, }; } factory ManagedMcpServerEntry.fromJson(Map json) { final rawArgs = json['args']; final rawEnvKeys = json['envKeys']; return ManagedMcpServerEntry( id: json['id'] as String? ?? '', name: json['name'] as String? ?? '', transport: json['transport'] as String? ?? 'stdio', command: json['command'] as String? ?? '', url: json['url'] as String? ?? '', args: rawArgs is List ? rawArgs.map((item) => item.toString()).toList(growable: false) : const [], envKeys: rawEnvKeys is List ? rawEnvKeys.map((item) => item.toString()).toList(growable: false) : const [], enabled: json['enabled'] as bool? ?? true, ); } } class ManagedMountTargetState { const ManagedMountTargetState({ required this.targetId, required this.label, required this.available, required this.supportsSkills, required this.supportsMcp, required this.supportsAiGatewayInjection, required this.discoveryState, required this.syncState, required this.discoveredSkillCount, required this.discoveredMcpCount, required this.managedMcpCount, required this.detail, }); final String targetId; final String label; final bool available; final bool supportsSkills; final bool supportsMcp; final bool supportsAiGatewayInjection; final String discoveryState; final String syncState; final int discoveredSkillCount; final int discoveredMcpCount; final int managedMcpCount; final String detail; ManagedMountTargetState copyWith({ String? targetId, String? label, bool? available, bool? supportsSkills, bool? supportsMcp, bool? supportsAiGatewayInjection, String? discoveryState, String? syncState, int? discoveredSkillCount, int? discoveredMcpCount, int? managedMcpCount, String? detail, }) { return ManagedMountTargetState( targetId: targetId ?? this.targetId, label: label ?? this.label, available: available ?? this.available, supportsSkills: supportsSkills ?? this.supportsSkills, supportsMcp: supportsMcp ?? this.supportsMcp, supportsAiGatewayInjection: supportsAiGatewayInjection ?? this.supportsAiGatewayInjection, discoveryState: discoveryState ?? this.discoveryState, syncState: syncState ?? this.syncState, discoveredSkillCount: discoveredSkillCount ?? this.discoveredSkillCount, discoveredMcpCount: discoveredMcpCount ?? this.discoveredMcpCount, managedMcpCount: managedMcpCount ?? this.managedMcpCount, detail: detail ?? this.detail, ); } Map toJson() { return { 'targetId': targetId, 'label': label, 'available': available, 'supportsSkills': supportsSkills, 'supportsMcp': supportsMcp, 'supportsAiGatewayInjection': supportsAiGatewayInjection, 'discoveryState': discoveryState, 'syncState': syncState, 'discoveredSkillCount': discoveredSkillCount, 'discoveredMcpCount': discoveredMcpCount, 'managedMcpCount': managedMcpCount, 'detail': detail, }; } factory ManagedMountTargetState.fromJson(Map json) { return ManagedMountTargetState( targetId: json['targetId'] as String? ?? '', label: json['label'] as String? ?? '', available: json['available'] as bool? ?? false, supportsSkills: json['supportsSkills'] as bool? ?? false, supportsMcp: json['supportsMcp'] as bool? ?? false, supportsAiGatewayInjection: json['supportsAiGatewayInjection'] as bool? ?? false, discoveryState: json['discoveryState'] as String? ?? 'idle', syncState: json['syncState'] as String? ?? 'idle', discoveredSkillCount: json['discoveredSkillCount'] as int? ?? 0, discoveredMcpCount: json['discoveredMcpCount'] as int? ?? 0, managedMcpCount: json['managedMcpCount'] as int? ?? 0, detail: json['detail'] as String? ?? '', ); } factory ManagedMountTargetState.placeholder({ required String targetId, required String label, required bool supportsSkills, required bool supportsMcp, required bool supportsAiGatewayInjection, }) { return ManagedMountTargetState( targetId: targetId, label: label, available: false, supportsSkills: supportsSkills, supportsMcp: supportsMcp, supportsAiGatewayInjection: supportsAiGatewayInjection, discoveryState: 'idle', syncState: 'idle', discoveredSkillCount: 0, discoveredMcpCount: 0, managedMcpCount: 0, detail: '', ); } static List defaults() { return 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: '', ), ]; } } /// 多 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 {}, ); } }