import 'runtime_models_configs.dart'; import 'runtime_models_profiles.dart'; class AccountSessionSummary { const AccountSessionSummary({ required this.userId, required this.email, required this.name, required this.role, required this.mfaEnabled, this.totpEnabled = false, this.totpPending = false, }); final String userId; final String email; final String name; final String role; final bool mfaEnabled; final bool totpEnabled; final bool totpPending; AccountSessionSummary copyWith({ String? userId, String? email, String? name, String? role, bool? mfaEnabled, bool? totpEnabled, bool? totpPending, }) { return AccountSessionSummary( userId: userId ?? this.userId, email: email ?? this.email, name: name ?? this.name, role: role ?? this.role, mfaEnabled: mfaEnabled ?? this.mfaEnabled, totpEnabled: totpEnabled ?? this.totpEnabled, totpPending: totpPending ?? this.totpPending, ); } Map toJson() { return { 'userId': userId, 'email': email, 'name': name, 'role': role, 'mfaEnabled': mfaEnabled, 'totpEnabled': totpEnabled, 'totpPending': totpPending, }; } factory AccountSessionSummary.fromJson(Map json) { return AccountSessionSummary( userId: json['userId'] as String? ?? '', email: json['email'] as String? ?? '', name: json['name'] as String? ?? '', role: json['role'] as String? ?? '', mfaEnabled: json['mfaEnabled'] as bool? ?? false, totpEnabled: json['totpEnabled'] as bool? ?? false, totpPending: json['totpPending'] as bool? ?? false, ); } } class AccountTokenConfigured { const AccountTokenConfigured({ required this.bridge, required this.vault, required this.apisix, }); final bool bridge; final bool vault; final bool apisix; factory AccountTokenConfigured.defaults() { return const AccountTokenConfigured( bridge: false, vault: false, apisix: false, ); } AccountTokenConfigured copyWith({bool? bridge, bool? vault, bool? apisix}) { return AccountTokenConfigured( bridge: bridge ?? this.bridge, vault: vault ?? this.vault, apisix: apisix ?? this.apisix, ); } Map toJson() { return {'bridge': bridge, 'vault': vault, 'apisix': apisix}; } factory AccountTokenConfigured.fromJson(Map json) { return AccountTokenConfigured( bridge: json['bridge'] as bool? ?? false, vault: json['vault'] as bool? ?? false, apisix: json['apisix'] as bool? ?? false, ); } } class AccountSecretLocator { const AccountSecretLocator({ required this.id, required this.provider, required this.secretPath, required this.secretKey, required this.target, required this.required, }); final String id; final String provider; final String secretPath; final String secretKey; final String target; final bool required; AccountSecretLocator copyWith({ String? id, String? provider, String? secretPath, String? secretKey, String? target, bool? required, }) { return AccountSecretLocator( id: id ?? this.id, provider: provider ?? this.provider, secretPath: secretPath ?? this.secretPath, secretKey: secretKey ?? this.secretKey, target: target ?? this.target, required: required ?? this.required, ); } Map toJson() { return { 'id': id, 'provider': provider, 'secretPath': secretPath, 'secretKey': secretKey, 'target': target, 'required': required, }; } factory AccountSecretLocator.fromJson(Map json) { return AccountSecretLocator( id: json['id'] as String? ?? '', provider: json['provider'] as String? ?? 'vault', secretPath: json['secretPath'] as String? ?? '', secretKey: json['secretKey'] as String? ?? '', target: json['target'] as String? ?? '', required: json['required'] as bool? ?? false, ); } } class AccountRemoteProfile { const AccountRemoteProfile({ required this.bridgeServerUrl, required this.bridgeServerOrigin, required this.vaultUrl, required this.vaultNamespace, required this.apisixUrl, required this.secretLocators, }); final String bridgeServerUrl; final String bridgeServerOrigin; final String vaultUrl; final String vaultNamespace; final String apisixUrl; final List secretLocators; factory AccountRemoteProfile.defaults() { return const AccountRemoteProfile( bridgeServerUrl: '', bridgeServerOrigin: '', vaultUrl: '', vaultNamespace: '', apisixUrl: '', secretLocators: [], ); } AccountRemoteProfile copyWith({ String? bridgeServerUrl, String? bridgeServerOrigin, String? vaultUrl, String? vaultNamespace, String? apisixUrl, List? secretLocators, }) { return AccountRemoteProfile( bridgeServerUrl: bridgeServerUrl ?? this.bridgeServerUrl, bridgeServerOrigin: bridgeServerOrigin ?? this.bridgeServerOrigin, vaultUrl: vaultUrl ?? this.vaultUrl, vaultNamespace: vaultNamespace ?? this.vaultNamespace, apisixUrl: apisixUrl ?? this.apisixUrl, secretLocators: secretLocators ?? this.secretLocators, ); } Map toJson() { return { 'BRIDGE_SERVER_URL': bridgeServerUrl, 'bridgeServerOrigin': bridgeServerOrigin, 'vaultUrl': vaultUrl, 'vaultNamespace': vaultNamespace, 'apisixUrl': apisixUrl, 'secretLocators': secretLocators .map((item) => item.toJson()) .toList(growable: false), }; } factory AccountRemoteProfile.fromJson(Map json) { List decodeLocators(Object? value) { if (value is! List) { return const []; } return value .whereType() .map( (item) => AccountSecretLocator.fromJson(item.cast()), ) .toList(growable: false); } final defaults = AccountRemoteProfile.defaults(); return AccountRemoteProfile( bridgeServerUrl: json['BRIDGE_SERVER_URL'] as String? ?? defaults.bridgeServerUrl, bridgeServerOrigin: json['bridgeServerOrigin'] as String? ?? defaults.bridgeServerOrigin, vaultUrl: json['vaultUrl'] as String? ?? defaults.vaultUrl, vaultNamespace: json['vaultNamespace'] as String? ?? defaults.vaultNamespace, apisixUrl: json['apisixUrl'] as String? ?? defaults.apisixUrl, secretLocators: decodeLocators(json['secretLocators']), ); } AccountSecretLocator? locatorForTarget(String target) { final normalized = target.trim(); if (normalized.isEmpty) { return null; } for (final locator in secretLocators) { if (locator.target.trim() == normalized) { return locator; } } return null; } } enum AcpBridgeServerMode { cloudSynced } class AcpBridgeServerRemoteServerSummary { const AcpBridgeServerRemoteServerSummary({ required this.endpoint, required this.hasAdvancedOverrides, }); final String endpoint; final bool hasAdvancedOverrides; factory AcpBridgeServerRemoteServerSummary.defaults() { return const AcpBridgeServerRemoteServerSummary( endpoint: '', hasAdvancedOverrides: false, ); } AcpBridgeServerRemoteServerSummary copyWith({ String? endpoint, bool? hasAdvancedOverrides, }) { return AcpBridgeServerRemoteServerSummary( endpoint: endpoint ?? this.endpoint, hasAdvancedOverrides: hasAdvancedOverrides ?? this.hasAdvancedOverrides, ); } Map toJson() { return { 'endpoint': endpoint, 'hasAdvancedOverrides': hasAdvancedOverrides, }; } factory AcpBridgeServerRemoteServerSummary.fromJson( Map json, ) { return AcpBridgeServerRemoteServerSummary( endpoint: json['endpoint'] as String? ?? '', hasAdvancedOverrides: json['hasAdvancedOverrides'] as bool? ?? false, ); } } class AcpBridgeServerCloudSyncConfig { const AcpBridgeServerCloudSyncConfig({ required this.accountBaseUrl, required this.accountIdentifier, required this.lastSyncAt, required this.remoteServerSummary, }); final String accountBaseUrl; final String accountIdentifier; final int lastSyncAt; final AcpBridgeServerRemoteServerSummary remoteServerSummary; factory AcpBridgeServerCloudSyncConfig.defaults() { return AcpBridgeServerCloudSyncConfig( accountBaseUrl: '', accountIdentifier: '', lastSyncAt: 0, remoteServerSummary: AcpBridgeServerRemoteServerSummary.defaults(), ); } AcpBridgeServerCloudSyncConfig copyWith({ String? accountBaseUrl, String? accountIdentifier, int? lastSyncAt, AcpBridgeServerRemoteServerSummary? remoteServerSummary, }) { return AcpBridgeServerCloudSyncConfig( accountBaseUrl: accountBaseUrl ?? this.accountBaseUrl, accountIdentifier: accountIdentifier ?? this.accountIdentifier, lastSyncAt: lastSyncAt ?? this.lastSyncAt, remoteServerSummary: remoteServerSummary ?? this.remoteServerSummary, ); } Map toJson() { return { 'accountBaseUrl': accountBaseUrl, 'accountIdentifier': accountIdentifier, 'lastSyncAt': lastSyncAt, 'remoteServerSummary': remoteServerSummary.toJson(), }; } factory AcpBridgeServerCloudSyncConfig.fromJson(Map json) { return AcpBridgeServerCloudSyncConfig( accountBaseUrl: json['accountBaseUrl'] as String? ?? '', accountIdentifier: json['accountIdentifier'] as String? ?? '', lastSyncAt: (json['lastSyncAt'] as num?)?.toInt() ?? 0, remoteServerSummary: AcpBridgeServerRemoteServerSummary.fromJson( (json['remoteServerSummary'] as Map?)?.cast() ?? const {}, ), ); } } class AcpBridgeServerSelfHostedConfig { const AcpBridgeServerSelfHostedConfig({ required this.serverUrl, required this.username, required this.passwordRef, }); final String serverUrl; final String username; final String passwordRef; factory AcpBridgeServerSelfHostedConfig.defaults() { return const AcpBridgeServerSelfHostedConfig( serverUrl: '', username: '', passwordRef: 'acp_bridge_server_password', ); } AcpBridgeServerSelfHostedConfig copyWith({ String? serverUrl, String? username, String? passwordRef, }) { return AcpBridgeServerSelfHostedConfig( serverUrl: (serverUrl ?? this.serverUrl).trim(), username: (username ?? this.username).trim(), passwordRef: (passwordRef ?? this.passwordRef).trim(), ); } bool get isConfigured => serverUrl.trim().isNotEmpty && username.trim().isNotEmpty; Map toJson() { return { 'serverUrl': serverUrl, 'username': username, 'passwordRef': passwordRef, }; } factory AcpBridgeServerSelfHostedConfig.fromJson(Map json) { return AcpBridgeServerSelfHostedConfig( serverUrl: json['serverUrl'] as String? ?? '', username: json['username'] as String? ?? '', passwordRef: json['passwordRef'] as String? ?? AcpBridgeServerSelfHostedConfig.defaults().passwordRef, ); } } class AcpBridgeServerAdvancedOverrides { const AcpBridgeServerAdvancedOverrides({ required this.gatewayProfiles, required this.vault, required this.aiGateway, required this.authorizedSkillDirectories, }); final List gatewayProfiles; final VaultConfig vault; final AiGatewayProfile aiGateway; final List authorizedSkillDirectories; factory AcpBridgeServerAdvancedOverrides.defaults() { return AcpBridgeServerAdvancedOverrides( gatewayProfiles: normalizeGatewayProfiles(), vault: VaultConfig.defaults(), aiGateway: AiGatewayProfile.defaults(), authorizedSkillDirectories: normalizeAuthorizedSkillDirectories(), ); } AcpBridgeServerAdvancedOverrides copyWith({ List? gatewayProfiles, VaultConfig? vault, AiGatewayProfile? aiGateway, List? authorizedSkillDirectories, }) { return AcpBridgeServerAdvancedOverrides( gatewayProfiles: gatewayProfiles != null ? normalizeGatewayProfiles(profiles: gatewayProfiles) : this.gatewayProfiles, vault: vault ?? this.vault, aiGateway: aiGateway ?? this.aiGateway, authorizedSkillDirectories: authorizedSkillDirectories != null ? normalizeAuthorizedSkillDirectories( directories: authorizedSkillDirectories, ) : this.authorizedSkillDirectories, ); } Map toJson() { return { 'gatewayProfiles': gatewayProfiles .map((item) => item.toJson()) .toList(growable: false), 'vault': vault.toJson(), 'aiGateway': aiGateway.toJson(), 'authorizedSkillDirectories': authorizedSkillDirectories .map((item) => item.toJson()) .toList(growable: false), }; } factory AcpBridgeServerAdvancedOverrides.fromJson(Map json) { return AcpBridgeServerAdvancedOverrides( gatewayProfiles: normalizeGatewayProfiles( profiles: ((json['gatewayProfiles'] as List?) ?? const []) .whereType() .map( (item) => GatewayConnectionProfile.fromJson( item.cast(), ), ), ), vault: VaultConfig.fromJson( (json['vault'] as Map?)?.cast() ?? const {}, ), aiGateway: AiGatewayProfile.fromJson( (json['aiGateway'] as Map?)?.cast() ?? const {}, ), authorizedSkillDirectories: normalizeAuthorizedSkillDirectories( directories: ((json['authorizedSkillDirectories'] as List?) ?? const []) .whereType() .map( (item) => AuthorizedSkillDirectory.fromJson( item.cast(), ), ), ), ); } } class AcpBridgeServerModeConfig { const AcpBridgeServerModeConfig({ required this.mode, required this.cloudSynced, required this.selfHosted, required this.advancedOverrides, }); final AcpBridgeServerMode mode; final AcpBridgeServerCloudSyncConfig cloudSynced; final AcpBridgeServerSelfHostedConfig selfHosted; final AcpBridgeServerAdvancedOverrides advancedOverrides; factory AcpBridgeServerModeConfig.defaults() { return AcpBridgeServerModeConfig( mode: AcpBridgeServerMode.cloudSynced, cloudSynced: AcpBridgeServerCloudSyncConfig.defaults(), selfHosted: AcpBridgeServerSelfHostedConfig.defaults(), advancedOverrides: AcpBridgeServerAdvancedOverrides.defaults(), ); } AcpBridgeServerModeConfig copyWith({ AcpBridgeServerMode? mode, AcpBridgeServerCloudSyncConfig? cloudSynced, AcpBridgeServerSelfHostedConfig? selfHosted, AcpBridgeServerAdvancedOverrides? advancedOverrides, }) { return AcpBridgeServerModeConfig( mode: mode ?? this.mode, cloudSynced: cloudSynced ?? this.cloudSynced, selfHosted: selfHosted ?? this.selfHosted, advancedOverrides: advancedOverrides ?? this.advancedOverrides, ); } bool get usesSelfHostedBase => false; bool get usesCloudSyncBase => true; String get sourceTag => 'cloudSynced'; Map toJson() { return { 'mode': mode.name, 'cloudSynced': cloudSynced.toJson(), 'selfHosted': selfHosted.toJson(), 'advancedOverrides': advancedOverrides.toJson(), }; } factory AcpBridgeServerModeConfig.fromJson(Map json) { return AcpBridgeServerModeConfig( mode: AcpBridgeServerMode.cloudSynced, cloudSynced: AcpBridgeServerCloudSyncConfig.fromJson( (json['cloudSynced'] as Map?)?.cast() ?? const {}, ), selfHosted: AcpBridgeServerSelfHostedConfig.fromJson( (json['selfHosted'] as Map?)?.cast() ?? const {}, ), advancedOverrides: AcpBridgeServerAdvancedOverrides.fromJson( (json['advancedOverrides'] as Map?)?.cast() ?? const {}, ), ); } } class AccountSyncState { const AccountSyncState({ required this.syncedDefaults, required this.syncState, required this.syncMessage, required this.lastSyncAtMs, required this.lastSyncSource, required this.lastSyncError, required this.profileScope, required this.tokenConfigured, }); final AccountRemoteProfile syncedDefaults; final String syncState; final String syncMessage; final int lastSyncAtMs; final String lastSyncSource; final String lastSyncError; final String profileScope; final AccountTokenConfigured tokenConfigured; factory AccountSyncState.defaults() { return AccountSyncState( syncedDefaults: AccountRemoteProfile.defaults(), syncState: 'idle', syncMessage: 'Remote config not synced yet', lastSyncAtMs: 0, lastSyncSource: '', lastSyncError: '', profileScope: '', tokenConfigured: AccountTokenConfigured.defaults(), ); } AccountSyncState copyWith({ AccountRemoteProfile? syncedDefaults, String? syncState, String? syncMessage, int? lastSyncAtMs, String? lastSyncSource, String? lastSyncError, String? profileScope, AccountTokenConfigured? tokenConfigured, }) { return AccountSyncState( syncedDefaults: syncedDefaults ?? this.syncedDefaults, syncState: syncState ?? this.syncState, syncMessage: syncMessage ?? this.syncMessage, lastSyncAtMs: lastSyncAtMs ?? this.lastSyncAtMs, lastSyncSource: lastSyncSource ?? this.lastSyncSource, lastSyncError: lastSyncError ?? this.lastSyncError, profileScope: profileScope ?? this.profileScope, tokenConfigured: tokenConfigured ?? this.tokenConfigured, ); } Map toJson() { return { 'syncedDefaults': syncedDefaults.toJson(), 'syncState': syncState, 'syncMessage': syncMessage, 'lastSyncAtMs': lastSyncAtMs, 'lastSyncSource': lastSyncSource, 'lastSyncError': lastSyncError, 'profileScope': profileScope, 'tokenConfigured': tokenConfigured.toJson(), }; } factory AccountSyncState.fromJson(Map json) { return AccountSyncState( syncedDefaults: AccountRemoteProfile.fromJson( (json['syncedDefaults'] as Map?)?.cast() ?? const {}, ), syncState: json['syncState'] as String? ?? 'idle', syncMessage: json['syncMessage'] as String? ?? 'Remote config not synced yet', lastSyncAtMs: (json['lastSyncAtMs'] as num?)?.toInt() ?? 0, lastSyncSource: json['lastSyncSource'] as String? ?? '', lastSyncError: json['lastSyncError'] as String? ?? '', profileScope: json['profileScope'] as String? ?? '', tokenConfigured: AccountTokenConfigured.fromJson( (json['tokenConfigured'] as Map?)?.cast() ?? const {}, ), ); } } class AccountSyncResult { const AccountSyncResult({required this.state, required this.message}); final String state; final String message; } const String kAccountManagedSecretTargetBridgeAuthToken = 'bridge.auth_token'; const String kAccountManagedSecretTargetAIGatewayAccessToken = 'ai_gateway.access_token'; const String kAccountManagedSecretTargetOllamaCloudApiKey = 'ollama_cloud.api_key'; const List kAccountManagedSecretTargets = [ kAccountManagedSecretTargetBridgeAuthToken, kAccountManagedSecretTargetAIGatewayAccessToken, kAccountManagedSecretTargetOllamaCloudApiKey, ]; bool isSupportedAccountManagedSecretTarget(String target) { return kAccountManagedSecretTargets.contains(target.trim()); }