include argus workflow

This commit is contained in:
joyzhuo
2026-03-29 06:29:18 -04:00
parent 275a53ab40
commit 56673078f5
23 changed files with 3098 additions and 307 deletions

View File

@@ -109,6 +109,32 @@ struct Step: Identifiable, Codable, Hashable {
// MARK: - Focus Session
/// Subset of the JSONB checkpoint dict stored on the backend session record.
/// Populated by argus when it POSTs to /distractions/analyze-result.
struct SessionCheckpoint: Codable {
/// Written by POST /distractions/analyze-result (argus live mode).
let lastVlmSummary: String?
/// Written by POST /distractions/analyze-screenshot (Swift fallback).
let lastScreenshotAnalysis: String?
/// Concise summary of the last completed action.
let lastActionSummary: String?
/// Frontmost application name at last checkpoint.
let activeApp: String?
/// Running count of distractions logged during this session.
let distractionCount: Int?
/// Returns whichever VLM summary field is populated, preferring the most recent.
var vlmSummary: String? { lastVlmSummary ?? lastScreenshotAnalysis }
enum CodingKeys: String, CodingKey {
case lastVlmSummary = "last_vlm_summary"
case lastScreenshotAnalysis = "last_screenshot_analysis"
case lastActionSummary = "last_action_summary"
case activeApp = "active_app"
case distractionCount = "distraction_count"
}
}
struct FocusSession: Identifiable, Codable {
let id: String
let userId: String
@@ -117,9 +143,11 @@ struct FocusSession: Identifiable, Codable {
let startedAt: String
var endedAt: String?
var status: String
/// Live checkpoint data written by argus (nil when no checkpoint exists yet).
var checkpoint: SessionCheckpoint?
enum CodingKeys: String, CodingKey {
case id, platform, status
case id, platform, status, checkpoint
case userId = "user_id"
case taskId = "task_id"
case startedAt = "started_at"
@@ -144,8 +172,10 @@ struct BrainDumpResponse: Codable {
struct ParsedTask: Codable, Identifiable {
// local UUID for list identity before saving
var localId: String = UUID().uuidString
var id: String { localId }
var id: String { taskId ?? localId }
/// Set by backend when the brain-dump endpoint creates the task automatically.
let taskId: String?
let title: String
let description: String?
let priority: Int
@@ -154,6 +184,7 @@ struct ParsedTask: Codable, Identifiable {
let tags: [String]
enum CodingKeys: String, CodingKey {
case taskId = "task_id"
case title, description, priority, deadline, tags
case estimatedMinutes = "estimated_minutes"
}
@@ -208,14 +239,29 @@ struct FrictionInfo: Codable {
var isResumption: Bool { type == "task_resumption" }
}
/// Session lifecycle action suggested by the VLM (new argus feature).
struct SessionAction: Codable {
/// resume | switch | complete | start_new | none
let type: String
let sessionId: String?
let reason: String?
enum CodingKeys: String, CodingKey {
case type, reason
case sessionId = "session_id"
}
}
struct DistractionAnalysisResponse: Codable {
let onTask: Bool
let currentStepId: String?
let inferredTask: String?
let checkpointNoteUpdate: String?
let stepsCompleted: [String]
// Upgraded Argus prompt fields (nil when backend uses legacy prompt)
let friction: FrictionInfo?
let intent: String? // skimming | engaged | unclear | null
let sessionAction: SessionAction? // new argus: session lifecycle suggestions
let intent: String? // skimming | engaged | unclear | null
let distractionType: String?
let appName: String?
let confidence: Double
@@ -225,9 +271,11 @@ struct DistractionAnalysisResponse: Codable {
enum CodingKeys: String, CodingKey {
case onTask = "on_task"
case currentStepId = "current_step_id"
case inferredTask = "inferred_task"
case checkpointNoteUpdate = "checkpoint_note_update"
case stepsCompleted = "steps_completed"
case friction, intent
case sessionAction = "session_action"
case distractionType = "distraction_type"
case appName = "app_name"
case confidence
@@ -298,6 +346,8 @@ struct ProactiveCard: Identifiable {
case vlmFriction(frictionType: String, description: String?, actions: [ProposedAction])
/// Heuristic app-switch loop detected by NSWorkspace observer (fallback when VLM hasn't returned friction yet).
case appSwitchLoop(apps: [String], switchCount: Int)
/// VLM suggests a session lifecycle action (new argus: resume, switch, complete, start_new).
case sessionAction(type: String, taskTitle: String, checkpoint: String, reason: String, sessionId: String?)
}
let id = UUID()
@@ -316,6 +366,14 @@ struct ProactiveCard: Identifiable {
}
case .appSwitchLoop:
return "Repetitive Pattern Detected"
case .sessionAction(let type, let taskTitle, _, _, _):
switch type {
case "resume": return "Resume: \(taskTitle)"
case "switch": return "Switch to: \(taskTitle)"
case "complete": return "Done with \(taskTitle)?"
case "start_new": return "Start a Focus Session?"
default: return "Session Suggestion"
}
}
}
@@ -332,6 +390,14 @@ struct ProactiveCard: Identifiable {
}
case .appSwitchLoop:
return "arrow.triangle.2.circlepath"
case .sessionAction(let type, _, _, _, _):
switch type {
case "resume": return "arrow.counterclockwise.circle"
case "switch": return "arrow.left.arrow.right"
case "complete": return "checkmark.circle"
case "start_new": return "plus.circle"
default: return "circle"
}
}
}
}