✦
┌──────────────────┐
│ struct Models │
├──────────────────┤
│ ArchonProject │
│ ArchonTask │
│ ChatMessage │
│ TaskEvent │
│ ProviderMetadata │
│ APIError │
└──────────────────┘
Models Reference
Complete Codable model reference for all data types.
: Codable
: Identifiable
: Hashable
─────────────
snake_case ↔
camelCase
Models Reference
Complete Codable model reference for all data types.
Overview
All models in Archon conform to Codable and use a shared JSONDecoder configured with snake_case key decoding strategy. Models are defined in the Models/ directory.
// Shared decoder configuration
extension JSONDecoder {
static let archonDecoder: JSONDecoder = {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
decoder.dateDecodingStrategy = .iso8601
return decoder
}()
}
ArchonProject
struct ArchonProject: Codable, Identifiable, Hashable {
let id: UUID
var name: String
var description: String?
var createdAt: Date
var updatedAt: Date
var taskCount: Int?
var lastTaskAt: Date?
}
// Database columns (snake_case):
// id, name, description, created_at, updated_at, task_count, last_task_at
ArchonTask
struct ArchonTask: Codable, Identifiable, Hashable {
let id: UUID
let projectId: UUID
var title: String
var status: TaskStatus
var errorMessage: String?
var creditsUsed: Int?
var modelUsed: String?
var createdAt: Date
var updatedAt: Date
var completedAt: Date?
var events: [TaskEvent]
}
enum TaskStatus: String, Codable, CaseIterable {
case created
case running
case completed
case failed
case cancelled
}
ChatMessage
struct ChatMessage: Codable, Identifiable, Hashable {
let id: UUID
let projectId: UUID
var role: MessageRole
var content: String
var createdAt: Date
var creditsUsed: Int?
}
enum MessageRole: String, Codable {
case user
case assistant
case system
}
TaskEvent
struct TaskEvent: Codable, Identifiable, Hashable {
let id: UUID
let taskId: UUID
let type: EventType
let message: String
let stepIndex: Int?
let metadata: [String: String]?
let createdAt: Date
}
enum EventType: String, Codable, CaseIterable {
case stepStarted
case stepCompleted
case fileCreated
case fileModified
case fileDeleted
case error
case info
case progress
}
ProviderMetadata
struct ProviderMetadata: Codable, Hashable {
var provider: String // "anthropic", "openai", "google"
var model: String // "claude-sonnet-4-20250514"
var tokensInput: Int?
var tokensOutput: Int?
var latencyMs: Int?
var fallbackUsed: Bool?
}
APIError
enum APIError: Error, LocalizedError {
case notAuthenticated
case notFound
case conflict
case validationError(String)
case serverError(Int)
case networkError(Error)
case decodingError(Error)
case rateLimited(retryAfter: TimeInterval)
case quotaExceeded
var errorDescription: String? {
switch self {
case .notAuthenticated: return "Session expired. Please sign in."
case .notFound: return "Resource not found."
case .conflict: return "Resource already exists."
case .validationError(let msg): return msg
case .serverError(let code): return "Server error (\(code))"
case .networkError: return "Network connection lost."
case .decodingError: return "Unexpected response format."
case .rateLimited: return "Too many requests. Please wait."
case .quotaExceeded: return "Credit limit reached."
}
}
}
UserProfile
struct UserProfile: Codable, Identifiable {
let id: UUID
var email: String
var displayName: String?
var avatarUrl: String?
var creditsRemaining: Int
var creditsTotal: Int
var createdAt: Date
var subscriptionTier: SubscriptionTier
}
enum SubscriptionTier: String, Codable {
case free
case pro
case team
}
FileNode
struct FileNode: Codable, Identifiable, Hashable {
let id: UUID
let projectId: UUID
var path: String // "src/components/Button.tsx"
var fileName: String // "Button.tsx"
var content: String?
var language: String? // "typescript", "swift", "html"
var sizeBytes: Int
var isDirectory: Bool
var children: [FileNode]?
var createdAt: Date
var updatedAt: Date
}
ChatRequest / ChatResponse
struct ChatRequest: Encodable {
let projectId: UUID
let message: String
let conversationId: UUID?
}
struct ChatResponse: Decodable {
let jobId: UUID
let status: String
let creditsUsed: Int?
}
// SSE event payloads (during streaming):
struct SSETextEvent: Decodable {
let type: String // "text"
let content: String
}
struct SSETaskEvent: Decodable {
let type: String // "task_start", "task_progress", "task_complete"
let taskId: UUID
let step: String?
}
struct SSEDoneEvent: Decodable {
let type: String // "done"
let creditsUsed: Int
}