ios: initial commit
This commit is contained in:
314
ios/Packages/Sybil/Sources/Sybil/SybilModels.swift
Normal file
314
ios/Packages/Sybil/Sources/Sybil/SybilModels.swift
Normal file
@@ -0,0 +1,314 @@
|
||||
import Foundation
|
||||
|
||||
public enum Provider: String, Codable, CaseIterable, Hashable, Sendable {
|
||||
case openai
|
||||
case anthropic
|
||||
case xai
|
||||
|
||||
public var displayName: String {
|
||||
switch self {
|
||||
case .openai: return "OpenAI"
|
||||
case .anthropic: return "Anthropic"
|
||||
case .xai: return "xAI"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum MessageRole: String, Codable, Hashable, Sendable {
|
||||
case system
|
||||
case user
|
||||
case assistant
|
||||
case tool
|
||||
}
|
||||
|
||||
public struct ChatSummary: Codable, Identifiable, Hashable, Sendable {
|
||||
public var id: String
|
||||
public var title: String?
|
||||
public var createdAt: Date
|
||||
public var updatedAt: Date
|
||||
public var initiatedProvider: Provider?
|
||||
public var initiatedModel: String?
|
||||
public var lastUsedProvider: Provider?
|
||||
public var lastUsedModel: String?
|
||||
}
|
||||
|
||||
public struct SearchSummary: Codable, Identifiable, Hashable, Sendable {
|
||||
public var id: String
|
||||
public var title: String?
|
||||
public var query: String?
|
||||
public var createdAt: Date
|
||||
public var updatedAt: Date
|
||||
}
|
||||
|
||||
public struct Message: Codable, Identifiable, Hashable, Sendable {
|
||||
public var id: String
|
||||
public var createdAt: Date
|
||||
public var role: MessageRole
|
||||
public var content: String
|
||||
public var name: String?
|
||||
}
|
||||
|
||||
public struct ChatDetail: Codable, Identifiable, Hashable, Sendable {
|
||||
public var id: String
|
||||
public var title: String?
|
||||
public var createdAt: Date
|
||||
public var updatedAt: Date
|
||||
public var initiatedProvider: Provider?
|
||||
public var initiatedModel: String?
|
||||
public var lastUsedProvider: Provider?
|
||||
public var lastUsedModel: String?
|
||||
public var messages: [Message]
|
||||
}
|
||||
|
||||
public struct SearchResultItem: Codable, Identifiable, Hashable, Sendable {
|
||||
public var id: String
|
||||
public var createdAt: Date
|
||||
public var rank: Int
|
||||
public var title: String?
|
||||
public var url: String
|
||||
public var publishedDate: String?
|
||||
public var author: String?
|
||||
public var text: String?
|
||||
public var highlights: [String]?
|
||||
public var highlightScores: [Double]?
|
||||
public var score: Double?
|
||||
public var favicon: String?
|
||||
public var image: String?
|
||||
}
|
||||
|
||||
public struct SearchCitation: Codable, Hashable, Sendable {
|
||||
public var id: String?
|
||||
public var url: String?
|
||||
public var title: String?
|
||||
public var publishedDate: String?
|
||||
public var author: String?
|
||||
public var text: String?
|
||||
}
|
||||
|
||||
public struct SearchDetail: Codable, Identifiable, Hashable, Sendable {
|
||||
public var id: String
|
||||
public var title: String?
|
||||
public var query: String?
|
||||
public var createdAt: Date
|
||||
public var updatedAt: Date
|
||||
public var requestId: String?
|
||||
public var latencyMs: Int?
|
||||
public var error: String?
|
||||
public var answerText: String?
|
||||
public var answerRequestId: String?
|
||||
public var answerCitations: [SearchCitation]?
|
||||
public var answerError: String?
|
||||
public var results: [SearchResultItem]
|
||||
}
|
||||
|
||||
public struct SearchRunRequest: Codable, Sendable {
|
||||
public var query: String?
|
||||
public var title: String?
|
||||
public var type: String?
|
||||
public var numResults: Int?
|
||||
public var includeDomains: [String]?
|
||||
public var excludeDomains: [String]?
|
||||
|
||||
public init(
|
||||
query: String? = nil,
|
||||
title: String? = nil,
|
||||
type: String? = nil,
|
||||
numResults: Int? = nil,
|
||||
includeDomains: [String]? = nil,
|
||||
excludeDomains: [String]? = nil
|
||||
) {
|
||||
self.query = query
|
||||
self.title = title
|
||||
self.type = type
|
||||
self.numResults = numResults
|
||||
self.includeDomains = includeDomains
|
||||
self.excludeDomains = excludeDomains
|
||||
}
|
||||
}
|
||||
|
||||
public struct CompletionRequestMessage: Codable, Sendable {
|
||||
public var role: MessageRole
|
||||
public var content: String
|
||||
public var name: String?
|
||||
|
||||
public init(role: MessageRole, content: String, name: String? = nil) {
|
||||
self.role = role
|
||||
self.content = content
|
||||
self.name = name
|
||||
}
|
||||
}
|
||||
|
||||
public struct CompletionStreamMeta: Codable, Sendable {
|
||||
public var chatId: String
|
||||
public var callId: String
|
||||
public var provider: Provider
|
||||
public var model: String
|
||||
}
|
||||
|
||||
public struct CompletionStreamDelta: Codable, Sendable {
|
||||
public var text: String
|
||||
}
|
||||
|
||||
public struct CompletionStreamDone: Codable, Sendable {
|
||||
public var text: String
|
||||
}
|
||||
|
||||
public struct StreamErrorPayload: Codable, Sendable {
|
||||
public var message: String
|
||||
}
|
||||
|
||||
public enum CompletionStreamEvent: Sendable {
|
||||
case meta(CompletionStreamMeta)
|
||||
case delta(CompletionStreamDelta)
|
||||
case done(CompletionStreamDone)
|
||||
case error(StreamErrorPayload)
|
||||
case ignored
|
||||
}
|
||||
|
||||
public struct SearchResultsPayload: Codable, Sendable {
|
||||
public var requestId: String?
|
||||
public var results: [SearchResultItem]
|
||||
}
|
||||
|
||||
public struct SearchErrorPayload: Codable, Sendable {
|
||||
public var error: String
|
||||
}
|
||||
|
||||
public struct SearchAnswerPayload: Codable, Sendable {
|
||||
public var answerText: String?
|
||||
public var answerRequestId: String?
|
||||
public var answerCitations: [SearchCitation]?
|
||||
}
|
||||
|
||||
public struct SearchDonePayload: Codable, Sendable {
|
||||
public var search: SearchDetail
|
||||
}
|
||||
|
||||
public enum SearchStreamEvent: Sendable {
|
||||
case searchResults(SearchResultsPayload)
|
||||
case searchError(SearchErrorPayload)
|
||||
case answer(SearchAnswerPayload)
|
||||
case answerError(SearchErrorPayload)
|
||||
case done(SearchDonePayload)
|
||||
case error(StreamErrorPayload)
|
||||
case ignored
|
||||
}
|
||||
|
||||
public struct ProviderModelInfo: Codable, Hashable, Sendable {
|
||||
public var models: [String]
|
||||
public var loadedAt: Date?
|
||||
public var error: String?
|
||||
}
|
||||
|
||||
public struct ModelCatalogResponse: Codable, Hashable, Sendable {
|
||||
public var providers: [Provider: ProviderModelInfo]
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case providers
|
||||
}
|
||||
|
||||
public init(providers: [Provider: ProviderModelInfo]) {
|
||||
self.providers = providers
|
||||
}
|
||||
|
||||
public init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||
let rawProviders = try container.decode([String: ProviderModelInfo].self, forKey: .providers)
|
||||
var mapped: [Provider: ProviderModelInfo] = [:]
|
||||
for (key, value) in rawProviders {
|
||||
if let provider = Provider(rawValue: key) {
|
||||
mapped[provider] = value
|
||||
}
|
||||
}
|
||||
self.providers = mapped
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
let raw = Dictionary(uniqueKeysWithValues: providers.map { ($0.key.rawValue, $0.value) })
|
||||
try container.encode(raw, forKey: .providers)
|
||||
}
|
||||
}
|
||||
|
||||
struct AuthSession: Codable {
|
||||
var authenticated: Bool
|
||||
var mode: String
|
||||
}
|
||||
|
||||
struct ChatListResponse: Codable {
|
||||
var chats: [ChatSummary]
|
||||
}
|
||||
|
||||
struct SearchListResponse: Codable {
|
||||
var searches: [SearchSummary]
|
||||
}
|
||||
|
||||
struct ChatDetailResponse: Codable {
|
||||
var chat: ChatDetail
|
||||
}
|
||||
|
||||
struct SearchDetailResponse: Codable {
|
||||
var search: SearchDetail
|
||||
}
|
||||
|
||||
struct ChatCreateResponse: Codable {
|
||||
var chat: ChatSummary
|
||||
}
|
||||
|
||||
struct SearchCreateResponse: Codable {
|
||||
var search: SearchSummary
|
||||
}
|
||||
|
||||
struct DeleteResponse: Codable {
|
||||
var deleted: Bool
|
||||
}
|
||||
|
||||
struct SuggestTitleBody: Codable {
|
||||
var chatId: String
|
||||
var content: String
|
||||
}
|
||||
|
||||
enum APIError: LocalizedError {
|
||||
case invalidBaseURL
|
||||
case httpError(statusCode: Int, message: String)
|
||||
case networkError(message: String)
|
||||
case decodingError(message: String)
|
||||
case invalidResponse
|
||||
case noResponseStream
|
||||
|
||||
var errorDescription: String? {
|
||||
switch self {
|
||||
case .invalidBaseURL:
|
||||
return "Invalid API URL"
|
||||
case let .httpError(_, message):
|
||||
return message
|
||||
case let .networkError(message):
|
||||
return message
|
||||
case let .decodingError(message):
|
||||
return message
|
||||
case .invalidResponse:
|
||||
return "Unexpected server response"
|
||||
case .noResponseStream:
|
||||
return "No response stream"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension DateFormatter {
|
||||
static let sybilDisplayDate: DateFormatter = {
|
||||
let formatter = DateFormatter()
|
||||
formatter.locale = .autoupdatingCurrent
|
||||
formatter.dateStyle = .medium
|
||||
formatter.timeStyle = .short
|
||||
return formatter
|
||||
}()
|
||||
}
|
||||
|
||||
extension Date {
|
||||
var sybilRelativeLabel: String {
|
||||
let formatter = RelativeDateTimeFormatter()
|
||||
formatter.locale = .autoupdatingCurrent
|
||||
formatter.unitsStyle = .abbreviated
|
||||
return formatter.localizedString(for: self, relativeTo: Date())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user