SPB Git

spb/prisme Public MIT

Navigateur iOS intelligent — chaque page comprise localement avant d'être affichée. SwiftUI · WebKit · Foundation Models, 100% on-device.

Swift 96.7% JavaScript 3.3%
2.3 KB · 70 lines swift
Raw Blame History
1//2//  ModelRouter.swift3//  Prisme4//5//  Author: Simon-Pierre Boucher <contact@spboucher.ai>6//78import Foundation9import FoundationModels10import Observation1112/// Effort level a task declares. The router decides what actually runs —13/// no other code calls a model directly (CLAUDE.md §3).14enum Tier {15    /// Pure heuristics, zero AI. The first choice whenever it suffices.16    case none17    /// On-device Foundation Models: free, unlimited, offline.18    case local19    /// Private Cloud Compute: explicit user action only, never on20    /// sensitive-container content. Not wired yet (P2).21    case cloud22}2324/// Availability of the on-device model, with a user-presentable reason.25/// AI is an enhancement: Prisme must remain a great browser without it —26/// never an error screen, never a dead button (CLAUDE.md §2).27enum LocalModelAvailability: Equatable {28    case available29    case unavailable(reason: String)30}3132/// Single owner of model availability and session creation.33@MainActor34@Observable35final class ModelRouter {36    private(set) var local: LocalModelAvailability = .unavailable(reason: "")3738    /// Serializes on-device inference (Neural Engine runs requests in39    /// series; more than 2 in flight only builds a hidden queue).40    let queue = InferenceQueue(maxConcurrent: 2)4142    init() {43        refreshAvailability()44    }4546    var isLocalAvailable: Bool { local == .available }4748    func refreshAvailability() {49        switch SystemLanguageModel.default.availability {50        case .available:51            local = .available52        case .unavailable(let reason):53            local = .unavailable(reason: Self.describe(reason))54        }55    }5657    private static func describe(_ reason: SystemLanguageModel.Availability.UnavailableReason) -> String {58        switch reason {59        case .deviceNotEligible:60            "Cet appareil ne prend pas en charge l'intelligence locale. Prisme reste un navigateur complet."61        case .appleIntelligenceNotEnabled:62            "Apple Intelligence est désactivé. Activez-le dans Réglages pour les résumés locaux."63        case .modelNotReady:64            "Le modèle local se prépare (téléchargement en cours). Réessayez dans quelques minutes."65        @unknown default:66            "L'intelligence locale n'est pas disponible pour le moment."67        }68    }69}70