diff --git a/clients/shared/App/Auth/AuthService.swift b/clients/shared/App/Auth/AuthService.swift index 0e738ff0508..bc5ce5d4898 100644 --- a/clients/shared/App/Auth/AuthService.swift +++ b/clients/shared/App/Auth/AuthService.swift @@ -3,6 +3,13 @@ import os private let log = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.vellum.vellum-assistant", category: "AuthService") +// MARK: - Thread-safe configuredBaseURL storage (module-private) +// These live outside the @MainActor class so they are nonisolated by default. +// GatewayHTTPClient (nonisolated) reads via AuthService.currentConfiguredBaseURL; +// SettingsStore (@MainActor) writes via AuthService.shared.configuredBaseURL. +private let _configuredBaseURLLock = NSLock() +private var _configuredBaseURLValue: String = "" + @MainActor public final class AuthService { public static let shared = AuthService() @@ -20,7 +27,29 @@ public final class AuthService { /// Platform base URL from daemon config. Set by SettingsStore when the /// `platform_config_response` arrives. When non-empty, takes precedence /// over persisted defaults, but an explicit per-launch env override still wins. - public var configuredBaseURL: String = "" + /// + /// Backed by a lock-protected static so that `GatewayHTTPClient` (nonisolated) + /// can read the value without crossing into `@MainActor` isolation. + public var configuredBaseURL: String { + get { + _configuredBaseURLLock.lock() + defer { _configuredBaseURLLock.unlock() } + return _configuredBaseURLValue + } + set { + _configuredBaseURLLock.lock() + defer { _configuredBaseURLLock.unlock() } + _configuredBaseURLValue = newValue + } + } + + /// Read the current configured base URL from any isolation context. + /// Uses lock-based synchronization — safe to call from nonisolated code. + nonisolated static var currentConfiguredBaseURL: String { + _configuredBaseURLLock.lock() + defer { _configuredBaseURLLock.unlock() } + return _configuredBaseURLValue + } public var baseURL: String { Self.resolveBaseURL( @@ -32,7 +61,9 @@ public final class AuthService { private init() {} - static func resolveBaseURL( + /// Pure URL resolution logic — safe to call from any isolation context. + /// All inputs are value types; no mutable shared state is accessed. + nonisolated static func resolveBaseURL( configuredBaseURL: String, environment: [String: String], userDefaults: UserDefaults @@ -52,7 +83,7 @@ public final class AuthService { return defaultBaseURL } - private static func normalizedBaseURL(_ raw: String?) -> String? { + nonisolated private static func normalizedBaseURL(_ raw: String?) -> String? { let trimmed = raw?.trimmingCharacters(in: .whitespacesAndNewlines) ?? "" let normalized = trimmed.replacingOccurrences(of: "/+$", with: "", options: .regularExpression) return normalized.isEmpty ? nil : normalized diff --git a/clients/shared/Network/AppsClient.swift b/clients/shared/Network/AppsClient.swift index e3f4b277b5c..0553487fd94 100644 --- a/clients/shared/Network/AppsClient.swift +++ b/clients/shared/Network/AppsClient.swift @@ -7,7 +7,6 @@ private let log = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.vellum. /// /// Covers listing, opening, deleting, previewing, bundling, sharing, and /// version history for both local and shared apps. -@MainActor public protocol AppsClientProtocol { func fetchAppsList() async -> AppsListResponse? func openApp(id: String) async -> AppOpenResult? @@ -36,7 +35,6 @@ public struct AppOpenResult: Sendable { } /// Gateway-backed implementation of ``AppsClientProtocol``. -@MainActor public struct AppsClient: AppsClientProtocol { nonisolated public init() {} diff --git a/clients/shared/Network/BtwClient.swift b/clients/shared/Network/BtwClient.swift index a0e1c809856..027616e3078 100644 --- a/clients/shared/Network/BtwClient.swift +++ b/clients/shared/Network/BtwClient.swift @@ -4,13 +4,11 @@ import os private let log = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.vellum.vellum-assistant", category: "BtwClient") /// Focused client for BTW side-chain messages routed through the gateway. -@MainActor public protocol BtwClientProtocol { func sendMessage(content: String, conversationKey: String) -> AsyncThrowingStream } /// Gateway-backed implementation of ``BtwClientProtocol``. -@MainActor public struct BtwClient: BtwClientProtocol { nonisolated public init() {} diff --git a/clients/shared/Network/ChannelClient.swift b/clients/shared/Network/ChannelClient.swift index f48cb389bdc..b2d2b06debf 100644 --- a/clients/shared/Network/ChannelClient.swift +++ b/clients/shared/Network/ChannelClient.swift @@ -4,7 +4,6 @@ import os private let log = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.vellum.vellum-assistant", category: "ChannelClient") /// Focused client for channel readiness operations routed through the gateway. -@MainActor public protocol ChannelClientProtocol { func fetchChannelReadiness() async -> [String: ChannelReadinessInfo] } @@ -45,7 +44,6 @@ public struct ReadinessCheck: Sendable { } /// Gateway-backed implementation of ``ChannelClientProtocol``. -@MainActor public struct ChannelClient: ChannelClientProtocol { nonisolated public init() {} diff --git a/clients/shared/Network/ComputerUseClient.swift b/clients/shared/Network/ComputerUseClient.swift index 16b8972de89..9f9bc97c7ad 100644 --- a/clients/shared/Network/ComputerUseClient.swift +++ b/clients/shared/Network/ComputerUseClient.swift @@ -4,14 +4,12 @@ import os private let log = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.vellum.vellum-assistant", category: "ComputerUseClient") /// Focused client for watch observation and recording lifecycle operations via the gateway. -@MainActor public protocol ComputerUseClientProtocol { func sendWatchObservation(_ msg: WatchObservationMessage) async -> Bool func sendRecordingStatus(_ msg: RecordingStatus) async -> Bool } /// Gateway-backed implementation of ``ComputerUseClientProtocol``. -@MainActor public struct ComputerUseClient: ComputerUseClientProtocol { nonisolated public init() {} diff --git a/clients/shared/Network/ContactClient.swift b/clients/shared/Network/ContactClient.swift index 6a520e29bc7..dbcbf7a2980 100644 --- a/clients/shared/Network/ContactClient.swift +++ b/clients/shared/Network/ContactClient.swift @@ -4,7 +4,6 @@ import os private let log = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.vellum.vellum-assistant", category: "ContactClient") /// Focused client for contact management operations routed through the gateway. -@MainActor public protocol ContactClientProtocol { func updateContact( contactId: String, @@ -51,7 +50,6 @@ public struct NewContactChannel: Codable { } /// Gateway-backed implementation of ``ContactClientProtocol``. -@MainActor public struct ContactClient: ContactClientProtocol { nonisolated public init() {} diff --git a/clients/shared/Network/ConversationClient.swift b/clients/shared/Network/ConversationClient.swift index a3629dcb425..e65ae5575bf 100644 --- a/clients/shared/Network/ConversationClient.swift +++ b/clients/shared/Network/ConversationClient.swift @@ -4,13 +4,11 @@ import os private let log = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.vellum.vellum-assistant", category: "ConversationClient") /// Focused client for conversation-related operations routed through the gateway. -@MainActor public protocol ConversationClientProtocol { func fetchMessageContent(conversationId: String, messageId: String) async -> MessageContentResponse? } /// Gateway-backed implementation of ``ConversationClientProtocol``. -@MainActor public struct ConversationClient: ConversationClientProtocol { nonisolated public init() {} diff --git a/clients/shared/Network/ConversationDetailClient.swift b/clients/shared/Network/ConversationDetailClient.swift index 14759ded83c..ed5d6731caf 100644 --- a/clients/shared/Network/ConversationDetailClient.swift +++ b/clients/shared/Network/ConversationDetailClient.swift @@ -4,13 +4,11 @@ import os private let log = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.vellum.vellum-assistant", category: "ConversationDetailClient") /// Focused client for fetching a single conversation summary through the gateway. -@MainActor public protocol ConversationDetailClientProtocol { func fetchConversation(conversationId: String) async -> ConversationListResponseItem? } /// Gateway-backed implementation of ``ConversationDetailClientProtocol``. -@MainActor public struct ConversationDetailClient: ConversationDetailClientProtocol { nonisolated public init() {} diff --git a/clients/shared/Network/ConversationForkClient.swift b/clients/shared/Network/ConversationForkClient.swift index 96197c51633..e1dc202ad93 100644 --- a/clients/shared/Network/ConversationForkClient.swift +++ b/clients/shared/Network/ConversationForkClient.swift @@ -4,13 +4,11 @@ import os private let log = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.vellum.vellum-assistant", category: "ConversationForkClient") /// Focused client for creating conversation forks through the gateway. -@MainActor public protocol ConversationForkClientProtocol { func forkConversation(conversationId: String, throughMessageId: String?) async -> ConversationListResponseItem? } /// Gateway-backed implementation of ``ConversationForkClientProtocol``. -@MainActor public struct ConversationForkClient: ConversationForkClientProtocol { nonisolated public init() {} diff --git a/clients/shared/Network/ConversationHistoryClient.swift b/clients/shared/Network/ConversationHistoryClient.swift index 149d7ffb490..a16223cb784 100644 --- a/clients/shared/Network/ConversationHistoryClient.swift +++ b/clients/shared/Network/ConversationHistoryClient.swift @@ -5,13 +5,11 @@ private let log = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.vellum. private let perfLog = OSLog(subsystem: Bundle.main.bundleIdentifier ?? "com.vellum.vellum-assistant", category: .pointsOfInterest) /// Focused client for conversation history operations routed through the gateway. -@MainActor public protocol ConversationHistoryClientProtocol { func fetchHistory(conversationId: String, limit: Int?, beforeTimestamp: Double?, mode: String?, maxTextChars: Int?, maxToolResultChars: Int?) async -> HistoryResponse? } /// Gateway-backed implementation of ``ConversationHistoryClientProtocol``. -@MainActor public struct ConversationHistoryClient: ConversationHistoryClientProtocol { nonisolated public init() {} diff --git a/clients/shared/Network/ConversationListClient.swift b/clients/shared/Network/ConversationListClient.swift index e0ab91bd366..80cbb94b5b3 100644 --- a/clients/shared/Network/ConversationListClient.swift +++ b/clients/shared/Network/ConversationListClient.swift @@ -4,7 +4,6 @@ import os private let log = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.vellum.vellum-assistant", category: "ConversationListClient") /// Focused client for conversation list and management operations via the gateway. -@MainActor public protocol ConversationListClientProtocol { func fetchConversationList(offset: Int, limit: Int, conversationType: String?) async -> ConversationListResponse? func switchConversation(conversationId: String) async -> Bool @@ -18,7 +17,6 @@ public protocol ConversationListClientProtocol { } /// Gateway-backed implementation of ``ConversationListClientProtocol``. -@MainActor public struct ConversationListClient: ConversationListClientProtocol { nonisolated public init() {} diff --git a/clients/shared/Network/ConversationQueueClient.swift b/clients/shared/Network/ConversationQueueClient.swift index 94c231b7955..258ac075178 100644 --- a/clients/shared/Network/ConversationQueueClient.swift +++ b/clients/shared/Network/ConversationQueueClient.swift @@ -4,13 +4,11 @@ import os private let log = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.vellum.vellum-assistant", category: "ConversationQueueClient") /// Focused client for message queue operations routed through the gateway. -@MainActor public protocol ConversationQueueClientProtocol { func deleteQueuedMessage(conversationId: String, requestId: String) async -> Bool } /// Gateway-backed implementation of ``ConversationQueueClientProtocol``. -@MainActor public struct ConversationQueueClient: ConversationQueueClientProtocol { nonisolated public init() {} diff --git a/clients/shared/Network/ConversationUnreadClient.swift b/clients/shared/Network/ConversationUnreadClient.swift index 75edfaefcf5..dcf3b55315d 100644 --- a/clients/shared/Network/ConversationUnreadClient.swift +++ b/clients/shared/Network/ConversationUnreadClient.swift @@ -16,13 +16,11 @@ public enum ConversationUnreadError: LocalizedError { } /// Focused client for marking conversations as unread through the gateway. -@MainActor public protocol ConversationUnreadClientProtocol { func sendConversationUnread(_ signal: ConversationUnreadSignal) async throws } /// Gateway-backed implementation of ``ConversationUnreadClientProtocol``. -@MainActor public struct ConversationUnreadClient: ConversationUnreadClientProtocol { nonisolated public init() {} diff --git a/clients/shared/Network/DiagnosticsClient.swift b/clients/shared/Network/DiagnosticsClient.swift index 3c077ce55da..fc765616e82 100644 --- a/clients/shared/Network/DiagnosticsClient.swift +++ b/clients/shared/Network/DiagnosticsClient.swift @@ -4,13 +4,11 @@ import os private let log = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.vellum.vellum-assistant", category: "DiagnosticsClient") /// Focused client for diagnostics operations routed through the gateway. -@MainActor public protocol DiagnosticsClientProtocol { func fetchEnvVars() async -> EnvVarsResponseMessage? } /// Gateway-backed implementation of ``DiagnosticsClientProtocol``. -@MainActor public struct DiagnosticsClient: DiagnosticsClientProtocol { nonisolated public init() {} diff --git a/clients/shared/Network/DictationClient.swift b/clients/shared/Network/DictationClient.swift index 600328780fa..e55523ffb9b 100644 --- a/clients/shared/Network/DictationClient.swift +++ b/clients/shared/Network/DictationClient.swift @@ -4,13 +4,11 @@ import os private let log = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.vellum.vellum-assistant", category: "DictationClient") /// Focused client for dictation requests routed through the gateway. -@MainActor public protocol DictationClientProtocol { func process(_ request: DictationRequest) async -> DictationResponseMessage } /// Gateway-backed implementation of ``DictationClientProtocol``. -@MainActor public struct DictationClient: DictationClientProtocol { nonisolated public init() {} diff --git a/clients/shared/Network/DocumentClient.swift b/clients/shared/Network/DocumentClient.swift index 0dc6e4ec133..8e4147172aa 100644 --- a/clients/shared/Network/DocumentClient.swift +++ b/clients/shared/Network/DocumentClient.swift @@ -4,7 +4,6 @@ import os private let log = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.vellum.vellum-assistant", category: "DocumentClient") /// Focused client for document persistence operations routed through the gateway. -@MainActor public protocol DocumentClientProtocol { func fetchList(conversationId: String?) async -> DocumentListResponse? func fetchDocument(surfaceId: String) async -> DocumentLoadResponse? @@ -12,7 +11,6 @@ public protocol DocumentClientProtocol { } /// Gateway-backed implementation of ``DocumentClientProtocol``. -@MainActor public struct DocumentClient: DocumentClientProtocol { nonisolated public init() {} diff --git a/clients/shared/Network/FeatureFlagClient.swift b/clients/shared/Network/FeatureFlagClient.swift index 7173f8bf37a..de8dac7910a 100644 --- a/clients/shared/Network/FeatureFlagClient.swift +++ b/clients/shared/Network/FeatureFlagClient.swift @@ -4,7 +4,6 @@ import os private let log = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.vellum.vellum-assistant", category: "FeatureFlagClient") /// Focused client for feature-flag and privacy-config operations routed through the gateway. -@MainActor public protocol FeatureFlagClientProtocol { func getFeatureFlags() async throws -> [AssistantFeatureFlag] func setFeatureFlag(key: String, enabled: Bool) async throws @@ -69,7 +68,6 @@ public enum FeatureFlagError: Error, LocalizedError { // MARK: - Gateway-Backed Implementation /// Gateway-backed implementation of ``FeatureFlagClientProtocol``. -@MainActor public struct FeatureFlagClient: FeatureFlagClientProtocol { nonisolated public init() {} diff --git a/clients/shared/Network/GatewayHTTPClient.swift b/clients/shared/Network/GatewayHTTPClient.swift index 2b7566e3d01..f305f6e6a89 100644 --- a/clients/shared/Network/GatewayHTTPClient.swift +++ b/clients/shared/Network/GatewayHTTPClient.swift @@ -10,7 +10,6 @@ private let log = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.vellum. /// /// let response = try await GatewayHTTPClient.get(path: "health") /// let response = try await GatewayHTTPClient.post(path: "assistants/upgrade") -@MainActor public enum GatewayHTTPClient { /// Response from a gateway HTTP request. @@ -383,7 +382,20 @@ public enum GatewayHTTPClient { guard let token = SessionTokenManager.getToken(), !token.isEmpty else { throw ClientError.notAuthenticated } - let baseURL = assistant.runtimeUrl ?? AuthService.shared.baseURL + let baseURL: String + if let runtimeUrl = assistant.runtimeUrl { + baseURL = runtimeUrl + } else { + // Call the nonisolated pure function directly to avoid + // crossing into @MainActor isolation. The instance property + // `AuthService.shared.baseURL` is @MainActor-isolated and + // cannot be read from a nonisolated synchronous context. + baseURL = AuthService.resolveBaseURL( + configuredBaseURL: AuthService.currentConfiguredBaseURL, + environment: ProcessInfo.processInfo.environment, + userDefaults: .standard + ) + } return ConnectionInfo(baseURL: baseURL, authHeader: ("X-Session-Token", token), assistantId: assistant.assistantId, isManaged: true) } else { let token = ActorTokenManager.getToken() diff --git a/clients/shared/Network/GuardianClient.swift b/clients/shared/Network/GuardianClient.swift index 75a920d5e61..ea896649180 100644 --- a/clients/shared/Network/GuardianClient.swift +++ b/clients/shared/Network/GuardianClient.swift @@ -4,7 +4,6 @@ import os private let log = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.vellum.vellum-assistant", category: "GuardianClient") /// Focused client for guardian operations routed through the gateway. -@MainActor public protocol GuardianClientProtocol { func fetchPendingActions(conversationId: String) async -> GuardianActionsPendingResponseMessage? func submitDecision(requestId: String, action: String, conversationId: String?) async -> GuardianActionDecisionResponseMessage? @@ -12,7 +11,6 @@ public protocol GuardianClientProtocol { } /// Gateway-backed implementation of ``GuardianClientProtocol``. -@MainActor public struct GuardianClient: GuardianClientProtocol { nonisolated public init() {} diff --git a/clients/shared/Network/HealthCheckClient.swift b/clients/shared/Network/HealthCheckClient.swift index 8d0d818f00b..e2d29245841 100644 --- a/clients/shared/Network/HealthCheckClient.swift +++ b/clients/shared/Network/HealthCheckClient.swift @@ -8,7 +8,6 @@ private let log = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.vellum. /// Local assistants are checked by hitting their own gateway's `/readyz` endpoint /// directly (unauthenticated). Remote/managed assistants route through /// `GatewayHTTPClient` which handles URL resolution, authentication, and 401 retry. -@MainActor public enum HealthCheckClient { /// Check whether the currently connected assistant is reachable. diff --git a/clients/shared/Network/HeartbeatClient.swift b/clients/shared/Network/HeartbeatClient.swift index 221e8b94783..2285f44e876 100644 --- a/clients/shared/Network/HeartbeatClient.swift +++ b/clients/shared/Network/HeartbeatClient.swift @@ -7,7 +7,6 @@ private let log = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.vellum. /// /// Covers heartbeat configuration, run history, on-demand runs, and checklist /// management. -@MainActor public protocol HeartbeatClientProtocol { func fetchConfig() async -> HeartbeatConfigResponse? func updateConfig(enabled: Bool?, intervalMs: Double?, activeHoursStart: Double?, activeHoursEnd: Double?) async -> HeartbeatConfigResponse? @@ -18,7 +17,6 @@ public protocol HeartbeatClientProtocol { } /// Gateway-backed implementation of ``HeartbeatClientProtocol``. -@MainActor public struct HeartbeatClient: HeartbeatClientProtocol { nonisolated public init() {} diff --git a/clients/shared/Network/HostProxyClient.swift b/clients/shared/Network/HostProxyClient.swift index d2bbbb85aee..3168c871d97 100644 --- a/clients/shared/Network/HostProxyClient.swift +++ b/clients/shared/Network/HostProxyClient.swift @@ -4,7 +4,6 @@ import os private let log = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.vellum.vellum-assistant", category: "HostProxyClient") /// Focused client for posting host proxy execution results back to the gateway. -@MainActor public protocol HostProxyClientProtocol { func postBashResult(_ result: HostBashResultPayload) async -> Bool func postFileResult(_ result: HostFileResultPayload) async -> Bool @@ -12,7 +11,6 @@ public protocol HostProxyClientProtocol { } /// Gateway-backed implementation of ``HostProxyClientProtocol``. -@MainActor public struct HostProxyClient: HostProxyClientProtocol { nonisolated public init() {} diff --git a/clients/shared/Network/IdentityClient.swift b/clients/shared/Network/IdentityClient.swift index 5983b82b1b4..8ddb65372f5 100644 --- a/clients/shared/Network/IdentityClient.swift +++ b/clients/shared/Network/IdentityClient.swift @@ -29,7 +29,6 @@ public struct RemoteIdentityInfo: Decodable { } /// Focused client for fetching remote assistant identity via the gateway. -@MainActor public protocol IdentityClientProtocol { func fetchRemoteIdentity() async -> RemoteIdentityInfo? func fetchIdentity() async -> IdentityGetResponse? @@ -37,7 +36,6 @@ public protocol IdentityClientProtocol { } /// Gateway-backed implementation of ``IdentityClientProtocol``. -@MainActor public struct IdentityClient: IdentityClientProtocol { nonisolated public init() {} diff --git a/clients/shared/Network/IntegrationClient.swift b/clients/shared/Network/IntegrationClient.swift index 8e5467cc095..8fef2091b37 100644 --- a/clients/shared/Network/IntegrationClient.swift +++ b/clients/shared/Network/IntegrationClient.swift @@ -4,7 +4,6 @@ import os private let log = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.vellum.vellum-assistant", category: "IntegrationClient") /// Focused client for integration status operations routed through the gateway. -@MainActor public protocol IntegrationClientProtocol { func fetchIntegrationsStatus() async -> IntegrationsStatusResponse? } @@ -18,7 +17,6 @@ public struct IntegrationsStatusResponse: Decodable, Sendable { } /// Gateway-backed implementation of ``IntegrationClientProtocol``. -@MainActor public struct IntegrationClient: IntegrationClientProtocol { nonisolated public init() {} diff --git a/clients/shared/Network/InteractionClient.swift b/clients/shared/Network/InteractionClient.swift index 06ba8f4414a..898fc004bc4 100644 --- a/clients/shared/Network/InteractionClient.swift +++ b/clients/shared/Network/InteractionClient.swift @@ -5,14 +5,12 @@ private let log = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.vellum. /// Focused client for user interaction responses (confirmations, secrets) /// routed through the gateway. -@MainActor public protocol InteractionClientProtocol { func sendConfirmationResponse(requestId: String, decision: String, selectedPattern: String?, selectedScope: String?) async -> Bool func sendSecretResponse(requestId: String, value: String?, delivery: String?) async -> Bool } /// Gateway-backed implementation of ``InteractionClientProtocol``. -@MainActor public struct InteractionClient: InteractionClientProtocol { nonisolated public init() {} diff --git a/clients/shared/Network/LLMContextClient.swift b/clients/shared/Network/LLMContextClient.swift index 46326cb16b8..e1511258f31 100644 --- a/clients/shared/Network/LLMContextClient.swift +++ b/clients/shared/Network/LLMContextClient.swift @@ -525,14 +525,12 @@ public enum LLMContextFetchResult: Sendable { /// Focused client for fetching LLM request/response context for a given message, /// routed through the gateway. -@MainActor public protocol LLMContextClientProtocol { func fetchContext(messageId: String) async -> LLMContextResponse? func fetchContextResult(messageId: String) async throws -> LLMContextFetchResult } /// Gateway-backed implementation of ``LLMContextClientProtocol``. -@MainActor public struct LLMContextClient: LLMContextClientProtocol { nonisolated public init() {} diff --git a/clients/shared/Network/MemoryItemClient.swift b/clients/shared/Network/MemoryItemClient.swift index 567f18e3f74..a58aeb5ed7d 100644 --- a/clients/shared/Network/MemoryItemClient.swift +++ b/clients/shared/Network/MemoryItemClient.swift @@ -4,7 +4,6 @@ import os private let log = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.vellum.vellum-assistant", category: "MemoryItemClient") /// Focused client for memory item operations routed through the gateway. -@MainActor public protocol MemoryItemClientProtocol { func fetchMemoryItems( kind: String?, @@ -39,7 +38,6 @@ public protocol MemoryItemClientProtocol { } /// Gateway-backed implementation of ``MemoryItemClientProtocol``. -@MainActor public struct MemoryItemClient: MemoryItemClientProtocol { nonisolated public init() {} diff --git a/clients/shared/Network/MessageClient.swift b/clients/shared/Network/MessageClient.swift index 009c899c649..49461994480 100644 --- a/clients/shared/Network/MessageClient.swift +++ b/clients/shared/Network/MessageClient.swift @@ -25,14 +25,12 @@ public enum MessageSendResult: Sendable { } /// Focused client for uploading attachments and sending user messages. -@MainActor public protocol MessageClientProtocol { func uploadAttachment(filename: String, mimeType: String, data: String, filePath: String?) async -> AttachmentUploadResult func sendMessage(content: String?, conversationKey: String, attachmentIds: [String], conversationType: String?, automated: Bool?, bypassSecretCheck: Bool?) async -> MessageSendResult } /// Gateway-backed implementation of ``MessageClientProtocol``. -@MainActor public struct MessageClient: MessageClientProtocol { nonisolated public init() {} diff --git a/clients/shared/Network/NotificationClient.swift b/clients/shared/Network/NotificationClient.swift index fd663173c78..11744e2299d 100644 --- a/clients/shared/Network/NotificationClient.swift +++ b/clients/shared/Network/NotificationClient.swift @@ -4,13 +4,11 @@ import os private let log = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.vellum.vellum-assistant", category: "NotificationClient") /// Focused client for notification delivery acknowledgments. -@MainActor public protocol NotificationClientProtocol { func sendIntentResult(deliveryId: String, success: Bool, errorMessage: String?, errorCode: String?) async } /// Gateway-backed implementation of ``NotificationClientProtocol``. -@MainActor public struct NotificationClient: NotificationClientProtocol { nonisolated public init() {} diff --git a/clients/shared/Network/PairingClient.swift b/clients/shared/Network/PairingClient.swift index ae4cf995331..490f6b4549e 100644 --- a/clients/shared/Network/PairingClient.swift +++ b/clients/shared/Network/PairingClient.swift @@ -4,7 +4,6 @@ import os private let log = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.vellum.vellum-assistant", category: "PairingClient") /// Focused client for pairing approval and device management operations routed through the gateway. -@MainActor public protocol PairingClientProtocol { func sendPairingApprovalResponse(pairingRequestId: String, decision: String) async throws -> Bool func fetchApprovedDevices() async throws -> [ApprovedDevicesListResponseMessage.Device] @@ -13,7 +12,6 @@ public protocol PairingClientProtocol { } /// Gateway-backed implementation of ``PairingClientProtocol``. -@MainActor public struct PairingClient: PairingClientProtocol { nonisolated public init() {} diff --git a/clients/shared/Network/PublishClient.swift b/clients/shared/Network/PublishClient.swift index 39cb657888e..e58525353ef 100644 --- a/clients/shared/Network/PublishClient.swift +++ b/clients/shared/Network/PublishClient.swift @@ -4,7 +4,6 @@ import os private let log = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.vellum.vellum-assistant", category: "PublishClient") /// Focused client for page publishing and link-open operations routed through the gateway. -@MainActor public protocol PublishClientProtocol { func publishPage(html: String, title: String?, appId: String?) async throws -> PublishPageResponseMessage? func unpublishPage(deploymentId: String) async -> Bool @@ -12,7 +11,6 @@ public protocol PublishClientProtocol { } /// Gateway-backed implementation of ``PublishClientProtocol``. -@MainActor public struct PublishClient: PublishClientProtocol { nonisolated public init() {} diff --git a/clients/shared/Network/RegenerateClient.swift b/clients/shared/Network/RegenerateClient.swift index 6f30c3ad9b0..f522ebadcb9 100644 --- a/clients/shared/Network/RegenerateClient.swift +++ b/clients/shared/Network/RegenerateClient.swift @@ -4,13 +4,11 @@ import os private let log = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.vellum.vellum-assistant", category: "RegenerateClient") /// Focused client for regenerating the last assistant response through the gateway. -@MainActor public protocol RegenerateClientProtocol { func regenerate(conversationId: String) async -> Bool } /// Gateway-backed implementation of ``RegenerateClientProtocol``. -@MainActor public struct RegenerateClient: RegenerateClientProtocol { nonisolated public init() {} diff --git a/clients/shared/Network/ScheduleClient.swift b/clients/shared/Network/ScheduleClient.swift index 61ee7beb56f..aac5a568c62 100644 --- a/clients/shared/Network/ScheduleClient.swift +++ b/clients/shared/Network/ScheduleClient.swift @@ -4,7 +4,6 @@ import os private let log = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.vellum.vellum-assistant", category: "ScheduleClient") /// Focused client for schedule management operations routed through the gateway. -@MainActor public protocol ScheduleClientProtocol { func fetchSchedulesList() async throws -> [ScheduleItem] func toggleSchedule(id: String, enabled: Bool) async throws -> [ScheduleItem] @@ -15,7 +14,6 @@ public protocol ScheduleClientProtocol { } /// Gateway-backed implementation of ``ScheduleClientProtocol``. -@MainActor public struct ScheduleClient: ScheduleClientProtocol { nonisolated public init() {} diff --git a/clients/shared/Network/SettingsClient.swift b/clients/shared/Network/SettingsClient.swift index 48eaf6f9b8a..6444a44f3a4 100644 --- a/clients/shared/Network/SettingsClient.swift +++ b/clients/shared/Network/SettingsClient.swift @@ -7,7 +7,6 @@ private let log = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.vellum. /// /// Covers Vercel API config, model info, Telegram config, and channel /// verification status — the endpoints invoked during `SettingsStore.init()`. -@MainActor public protocol SettingsClientProtocol { func fetchVercelConfig() async -> VercelApiConfigResponseMessage? func saveVercelConfig(apiToken: String) async -> VercelApiConfigResponseMessage? @@ -48,7 +47,6 @@ public protocol SettingsClientProtocol { } /// Gateway-backed implementation of ``SettingsClientProtocol``. -@MainActor public struct SettingsClient: SettingsClientProtocol { nonisolated public init() {} diff --git a/clients/shared/Network/SkillsClient.swift b/clients/shared/Network/SkillsClient.swift index 255fb0183b7..51c4e08e3b4 100644 --- a/clients/shared/Network/SkillsClient.swift +++ b/clients/shared/Network/SkillsClient.swift @@ -7,7 +7,6 @@ private let log = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.vellum. /// /// Covers listing, enabling, disabling, configuring, installing, uninstalling, /// updating, searching, inspecting, drafting, and creating skills. -@MainActor public protocol SkillsClientProtocol { func fetchSkillsList(includeCatalog: Bool) async -> SkillsListResponseMessage? func enableSkill(name: String) async -> SkillsOperationResponseMessage? @@ -26,7 +25,6 @@ public protocol SkillsClientProtocol { } /// Gateway-backed implementation of ``SkillsClientProtocol``. -@MainActor public struct SkillsClient: SkillsClientProtocol { nonisolated public init() {} diff --git a/clients/shared/Network/SubagentClient.swift b/clients/shared/Network/SubagentClient.swift index 3066952d6dd..39d8144af47 100644 --- a/clients/shared/Network/SubagentClient.swift +++ b/clients/shared/Network/SubagentClient.swift @@ -4,7 +4,6 @@ import os private let log = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.vellum.vellum-assistant", category: "SubagentClient") /// Focused client for subagent operations routed through the gateway. -@MainActor public protocol SubagentClientProtocol { func abort(subagentId: String, conversationId: String?) async -> Bool func fetchDetail(subagentId: String, conversationId: String) async -> SubagentDetailResponse? @@ -12,7 +11,6 @@ public protocol SubagentClientProtocol { } /// Gateway-backed implementation of ``SubagentClientProtocol``. -@MainActor public struct SubagentClient: SubagentClientProtocol { nonisolated public init() {} diff --git a/clients/shared/Network/SurfaceActionClient.swift b/clients/shared/Network/SurfaceActionClient.swift index 9b2caaafa55..9d6ab1b4220 100644 --- a/clients/shared/Network/SurfaceActionClient.swift +++ b/clients/shared/Network/SurfaceActionClient.swift @@ -4,14 +4,12 @@ import os private let log = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.vellum.vellum-assistant", category: "SurfaceActionClient") /// Focused client for surface action and undo operations routed through the gateway. -@MainActor public protocol SurfaceActionClientProtocol { func sendSurfaceAction(conversationId: String?, surfaceId: String, actionId: String, data: [String: AnyCodable]?) async func sendSurfaceUndo(conversationId: String, surfaceId: String) async } /// Gateway-backed implementation of ``SurfaceActionClientProtocol``. -@MainActor public struct SurfaceActionClient: SurfaceActionClientProtocol { nonisolated public init() {} diff --git a/clients/shared/Network/TTSClient.swift b/clients/shared/Network/TTSClient.swift index a0b4a23d3c5..e9cc2d588b6 100644 --- a/clients/shared/Network/TTSClient.swift +++ b/clients/shared/Network/TTSClient.swift @@ -18,13 +18,11 @@ public enum TTSResult: Sendable { } /// Focused client for message text-to-speech synthesis routed through the gateway. -@MainActor public protocol TTSClientProtocol { func synthesize(messageId: String, conversationId: String?) async -> TTSResult } /// Gateway-backed implementation of ``TTSClientProtocol``. -@MainActor public struct TTSClient: TTSClientProtocol { nonisolated public init() {} diff --git a/clients/shared/Network/TelemetryClient.swift b/clients/shared/Network/TelemetryClient.swift index d5b67c89a9c..fae64bd1ea5 100644 --- a/clients/shared/Network/TelemetryClient.swift +++ b/clients/shared/Network/TelemetryClient.swift @@ -4,13 +4,11 @@ import os private let log = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.vellum.vellum-assistant", category: "TelemetryClient") /// Focused client for telemetry operations routed through the gateway. -@MainActor public protocol TelemetryClientProtocol { func recordLifecycleEvent(_ eventName: String) async } /// Gateway-backed implementation of ``TelemetryClientProtocol``. -@MainActor public struct TelemetryClient: TelemetryClientProtocol { nonisolated public init() {} diff --git a/clients/shared/Network/ToolClient.swift b/clients/shared/Network/ToolClient.swift index 95e072a44dc..1acdc86ef63 100644 --- a/clients/shared/Network/ToolClient.swift +++ b/clients/shared/Network/ToolClient.swift @@ -4,7 +4,6 @@ import os private let log = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.vellum.vellum-assistant", category: "ToolClient") /// Focused client for tool-related operations routed through the gateway. -@MainActor public protocol ToolClientProtocol { func fetchToolNamesList() async throws -> ToolNamesListResponseMessage func simulateToolPermission( @@ -17,7 +16,6 @@ public protocol ToolClientProtocol { } /// Gateway-backed implementation of ``ToolClientProtocol``. -@MainActor public struct ToolClient: ToolClientProtocol { nonisolated public init() {} diff --git a/clients/shared/Network/TraceEventClient.swift b/clients/shared/Network/TraceEventClient.swift index 8cd6c84c1a1..3d39688b0e2 100644 --- a/clients/shared/Network/TraceEventClient.swift +++ b/clients/shared/Network/TraceEventClient.swift @@ -4,13 +4,11 @@ import os private let log = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.vellum.vellum-assistant", category: "TraceEventClient") /// Focused client for trace event history operations routed through the gateway. -@MainActor public protocol TraceEventClientProtocol { func fetchHistory(conversationId: String) async throws -> [TraceEventMessage] } /// Gateway-backed implementation of ``TraceEventClientProtocol``. -@MainActor public struct TraceEventClient: TraceEventClientProtocol { nonisolated public init() {} diff --git a/clients/shared/Network/TrustRuleClient.swift b/clients/shared/Network/TrustRuleClient.swift index 70d66a42f9f..2e2a1bc52fe 100644 --- a/clients/shared/Network/TrustRuleClient.swift +++ b/clients/shared/Network/TrustRuleClient.swift @@ -4,7 +4,6 @@ import os private let log = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.vellum.vellum-assistant", category: "TrustRuleClient") /// Focused client for trust rule management operations routed through the gateway. -@MainActor public protocol TrustRuleClientProtocol { func fetchTrustRules() async throws -> [TrustRuleItem] func addTrustRule( @@ -27,7 +26,6 @@ public protocol TrustRuleClientProtocol { } /// Gateway-backed implementation of ``TrustRuleClientProtocol``. -@MainActor public struct TrustRuleClient: TrustRuleClientProtocol { nonisolated public init() {} diff --git a/clients/shared/Network/WorkItemClient.swift b/clients/shared/Network/WorkItemClient.swift index 0f804fa51d7..9abf86872a2 100644 --- a/clients/shared/Network/WorkItemClient.swift +++ b/clients/shared/Network/WorkItemClient.swift @@ -7,7 +7,6 @@ private let log = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.vellum. /// /// Covers listing, completing, deleting, running, fetching output, and updating /// work items. -@MainActor public protocol WorkItemClientProtocol { func fetchList(status: String?) async -> WorkItemsListResponse? func complete(id: String) async -> Bool @@ -21,7 +20,6 @@ public protocol WorkItemClientProtocol { } /// Gateway-backed implementation of ``WorkItemClientProtocol``. -@MainActor public struct WorkItemClient: WorkItemClientProtocol { nonisolated public init() {} diff --git a/clients/shared/Network/WorkspaceClient.swift b/clients/shared/Network/WorkspaceClient.swift index 88e262b8fe2..6c79fdceafe 100644 --- a/clients/shared/Network/WorkspaceClient.swift +++ b/clients/shared/Network/WorkspaceClient.swift @@ -4,7 +4,6 @@ import os private let log = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.vellum.vellum-assistant", category: "WorkspaceClient") /// Focused client for workspace file-system operations routed through the gateway. -@MainActor public protocol WorkspaceClientProtocol { func fetchWorkspaceTree(path: String, showHidden: Bool) async -> WorkspaceTreeResponse? func fetchWorkspaceFile(path: String, showHidden: Bool) async -> WorkspaceFileResponse? @@ -17,7 +16,6 @@ public protocol WorkspaceClientProtocol { } /// Gateway-backed implementation of ``WorkspaceClientProtocol``. -@MainActor public struct WorkspaceClient: WorkspaceClientProtocol { nonisolated public init() {}