// // AppEnvironment.swift // Zyquo Atlas // // Author: Simon-Pierre Boucher // Mail: contact@spboucher.ai // // App-wide shared services injected into the view tree: the model catalog // (all Zyquo Cloud models) and the encrypted key vault. Held once at the app // root so every window/tab shares one catalog and one vault. // import Foundation import SwiftUI @MainActor final class AppEnvironment: ObservableObject { let catalog = ModelCatalog() let vault = KeyVaultStore() let bookmarks = BookmarksService() let history = HistoryService() /// The user's default browsing model (recommended-first from the catalog). var defaultModel: AIModel? { catalog.defaultModel } /// Resolves the model for an action class, honoring per-action overrides. func model(for action: AIActionClass) -> AIModel? { if let id = actionModelIDs[action], let m = catalog.all.first(where: { $0.id == id }) { return m } switch action { case .fast: return catalog.builtIn.first { !$0.isLegacy && !$0.capabilities.reasoning } ?? defaultModel case .standard, .deep: return defaultModel } } /// Per-action-class default model overrides (fast hovers vs deep chat). @Published var actionModelIDs: [AIActionClass: String] = [:] } /// Model tiers for per-action default selection (docs/AI-BROWSER-RESEARCH.md §3). enum AIActionClass: String, Codable, CaseIterable { case fast // hover/auto summaries — cheap & quick case standard // summarize, translate, selection actions case deep // chat-with-page, multi-tab reasoning }