Files
clawdbot/apps/shared/ClawdisKit/Sources/ClawdisChatUI/ChatModels.swift
2025-12-14 00:17:07 +00:00

148 lines
3.8 KiB
Swift

import ClawdisKit
import Foundation
#if canImport(AppKit)
import AppKit
public typealias ClawdisPlatformImage = NSImage
#elseif canImport(UIKit)
import UIKit
public typealias ClawdisPlatformImage = UIImage
#endif
public struct ClawdisChatMessageContent: Codable, Hashable, Sendable {
public let type: String?
public let text: String?
public let mimeType: String?
public let fileName: String?
public let content: String?
public init(
type: String?,
text: String?,
mimeType: String?,
fileName: String?,
content: String?)
{
self.type = type
self.text = text
self.mimeType = mimeType
self.fileName = fileName
self.content = content
}
}
public struct ClawdisChatMessage: Codable, Identifiable, Sendable {
public var id: UUID = .init()
public let role: String
public let content: [ClawdisChatMessageContent]
public let timestamp: Double?
enum CodingKeys: String, CodingKey {
case role, content, timestamp
}
public init(
id: UUID = .init(),
role: String,
content: [ClawdisChatMessageContent],
timestamp: Double?)
{
self.id = id
self.role = role
self.content = content
self.timestamp = timestamp
}
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.role = try container.decode(String.self, forKey: .role)
self.timestamp = try container.decodeIfPresent(Double.self, forKey: .timestamp)
if let decoded = try? container.decode([ClawdisChatMessageContent].self, forKey: .content) {
self.content = decoded
return
}
// Some session log formats store `content` as a plain string.
if let text = try? container.decode(String.self, forKey: .content) {
self.content = [
ClawdisChatMessageContent(
type: "text",
text: text,
mimeType: nil,
fileName: nil,
content: nil),
]
return
}
self.content = []
}
}
public struct ClawdisChatHistoryPayload: Codable, Sendable {
public let sessionKey: String
public let sessionId: String?
public let messages: [AnyCodable]?
public let thinkingLevel: String?
}
public struct ClawdisChatSendResponse: Codable, Sendable {
public let runId: String
public let status: String
}
public struct ClawdisChatEventPayload: Codable, Sendable {
public let runId: String?
public let sessionKey: String?
public let state: String?
public let message: AnyCodable?
public let errorMessage: String?
}
public struct ClawdisGatewayHealthOK: Codable, Sendable {
public let ok: Bool?
}
public struct ClawdisPendingAttachment: Identifiable {
public let id = UUID()
public let url: URL?
public let data: Data
public let fileName: String
public let mimeType: String
public let type: String
public let preview: ClawdisPlatformImage?
public init(
url: URL?,
data: Data,
fileName: String,
mimeType: String,
type: String = "file",
preview: ClawdisPlatformImage?)
{
self.url = url
self.data = data
self.fileName = fileName
self.mimeType = mimeType
self.type = type
self.preview = preview
}
}
public struct ClawdisChatAttachmentPayload: Codable, Sendable, Hashable {
public let type: String
public let mimeType: String
public let fileName: String
public let content: String
public init(type: String, mimeType: String, fileName: String, content: String) {
self.type = type
self.mimeType = mimeType
self.fileName = fileName
self.content = content
}
}