Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions clients/shared/Network/AppsClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ 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?
Expand Down Expand Up @@ -35,6 +36,7 @@ public struct AppOpenResult: Sendable {
}

/// Gateway-backed implementation of ``AppsClientProtocol``.
@MainActor
public struct AppsClient: AppsClientProtocol {
nonisolated public init() {}

Expand Down
4 changes: 3 additions & 1 deletion clients/shared/Network/BtwClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,21 @@ 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<String, Error>
}

/// Gateway-backed implementation of ``BtwClientProtocol``.
@MainActor
public struct BtwClient: BtwClientProtocol {
nonisolated public init() {}

/// Send a BTW side-chain question and stream the response text.
/// Returns an `AsyncThrowingStream` that yields text deltas from SSE `btw_text_delta` events.
public func sendMessage(content: String, conversationKey: String) -> AsyncThrowingStream<String, Error> {
return AsyncThrowingStream { continuation in
let task = Task {
let task = Task { @MainActor in
do {
try await Self.streamBtw(content: content, conversationKey: conversationKey, continuation: continuation)
} catch {
Expand Down
2 changes: 2 additions & 0 deletions clients/shared/Network/ChannelClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ 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]
}
Expand Down Expand Up @@ -44,6 +45,7 @@ public struct ReadinessCheck: Sendable {
}

/// Gateway-backed implementation of ``ChannelClientProtocol``.
@MainActor
public struct ChannelClient: ChannelClientProtocol {
nonisolated public init() {}

Expand Down
2 changes: 2 additions & 0 deletions clients/shared/Network/ComputerUseClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ 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() {}

Expand Down
2 changes: 2 additions & 0 deletions clients/shared/Network/ContactClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ 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,
Expand Down Expand Up @@ -50,6 +51,7 @@ public struct NewContactChannel: Codable {
}

/// Gateway-backed implementation of ``ContactClientProtocol``.
@MainActor
public struct ContactClient: ContactClientProtocol {
nonisolated public init() {}

Expand Down
2 changes: 2 additions & 0 deletions clients/shared/Network/ConversationClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ 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() {}

Expand Down
2 changes: 2 additions & 0 deletions clients/shared/Network/ConversationDetailClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ 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() {}

Expand Down
2 changes: 2 additions & 0 deletions clients/shared/Network/ConversationForkClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ 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() {}

Expand Down
2 changes: 2 additions & 0 deletions clients/shared/Network/ConversationHistoryClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ 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() {}

Expand Down
2 changes: 2 additions & 0 deletions clients/shared/Network/ConversationListClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ 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) async -> ConversationListResponse?
func switchConversation(conversationId: String) async -> Bool
Expand All @@ -17,6 +18,7 @@ public protocol ConversationListClientProtocol {
}

/// Gateway-backed implementation of ``ConversationListClientProtocol``.
@MainActor
public struct ConversationListClient: ConversationListClientProtocol {
nonisolated public init() {}

Expand Down
2 changes: 2 additions & 0 deletions clients/shared/Network/ConversationQueueClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ 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() {}

Expand Down
2 changes: 2 additions & 0 deletions clients/shared/Network/ConversationUnreadClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@ 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() {}

Expand Down
2 changes: 2 additions & 0 deletions clients/shared/Network/DiagnosticsClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ 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() {}

Expand Down
2 changes: 2 additions & 0 deletions clients/shared/Network/DictationClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ 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() {}

Expand Down
2 changes: 2 additions & 0 deletions clients/shared/Network/DocumentClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ 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?
func saveDocument(surfaceId: String, conversationId: String, title: String, content: String, wordCount: Int) async -> DocumentSaveResponse?
}

/// Gateway-backed implementation of ``DocumentClientProtocol``.
@MainActor
public struct DocumentClient: DocumentClientProtocol {
nonisolated public init() {}

Expand Down
2 changes: 2 additions & 0 deletions clients/shared/Network/FeatureFlagClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ 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
Expand Down Expand Up @@ -63,6 +64,7 @@ public enum FeatureFlagError: Error, LocalizedError {
// MARK: - Gateway-Backed Implementation

/// Gateway-backed implementation of ``FeatureFlagClientProtocol``.
@MainActor
public struct FeatureFlagClient: FeatureFlagClientProtocol {
nonisolated public init() {}

Expand Down
10 changes: 5 additions & 5 deletions clients/shared/Network/GatewayConnectionManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ public final class GatewayConnectionManager: ObservableObject {

private func performHealthCheck() async throws {
do {
let isManaged = (try? await GatewayHTTPClient.isConnectionManaged()) ?? false
let isManaged = (try? GatewayHTTPClient.isConnectionManaged()) ?? false
let healthPath = isManaged ? "assistants/{assistantId}/health" : "health"
let response = try await GatewayHTTPClient.get(
path: healthPath,
Expand All @@ -280,8 +280,8 @@ public final class GatewayConnectionManager: ObservableObject {

guard response.isSuccess else {
if response.statusCode == 401 {
await handleAuthenticationFailure()
let isManaged = (try? await GatewayHTTPClient.isConnectionManaged()) ?? false
handleAuthenticationFailure()
let isManaged = (try? GatewayHTTPClient.isConnectionManaged()) ?? false
if isManaged {
shouldReconnect = false
}
Expand Down Expand Up @@ -481,8 +481,8 @@ public final class GatewayConnectionManager: ObservableObject {

// MARK: - 401 Recovery

private func handleAuthenticationFailure() async {
let isManaged = (try? await GatewayHTTPClient.isConnectionManaged()) ?? false
private func handleAuthenticationFailure() {
let isManaged = (try? GatewayHTTPClient.isConnectionManaged()) ?? false
if isManaged {
log.warning("401 in managed mode — session token may be expired")
eventStreamClient.broadcastMessage(.conversationError(ConversationErrorMessage(
Expand Down
Loading