// Package model provides TUI data structures and state management package model import ( "time" "github.com/charmbracelet/bubbles/list" "github.com/charmbracelet/bubbles/spinner" "github.com/charmbracelet/bubbles/textinput" "github.com/charmbracelet/bubbles/viewport" "github.com/jfraeys/fetch_ml/internal/domain" ) // Re-export domain types for TUI use // Task represents a task in the TUI type Task = domain.Task // TrackingConfig specifies experiment tracking tools type TrackingConfig = domain.TrackingConfig // MLflowTrackingConfig controls MLflow integration type MLflowTrackingConfig = domain.MLflowTrackingConfig // TensorBoardTrackingConfig controls TensorBoard integration type TensorBoardTrackingConfig = domain.TensorBoardTrackingConfig // WandbTrackingConfig controls Weights & Biases integration type WandbTrackingConfig = domain.WandbTrackingConfig // ViewMode represents the current view mode in the TUI type ViewMode int // ViewMode constants represent different TUI views const ( ViewModeJobs ViewMode = iota // Jobs view mode ViewModeGPU // GPU status view mode ViewModeQueue // Queue status view mode ViewModeContainer // Container status view mode ViewModeSettings // Settings view mode ViewModeDatasets // Datasets view mode ViewModeExperiments // Experiments view mode ViewModeNarrative // Narrative/Outcome view mode ViewModeTeam // Team collaboration view mode ViewModeExperimentHistory // Experiment history view mode ViewModeConfig // Config view mode ViewModeLogs // Logs streaming view mode ) // DatasetInfo represents dataset information in the TUI type DatasetInfo struct { Name string `json:"name"` SizeBytes int64 `json:"size_bytes"` Location string `json:"location"` LastAccess time.Time `json:"last_access"` } // State holds the application state type State struct { Jobs []Job QueuedTasks []*Task Datasets []DatasetInfo JobList list.Model GpuView viewport.Model ContainerView viewport.Model QueueView viewport.Model SettingsView viewport.Model DatasetView viewport.Model ExperimentsView viewport.Model NarrativeView viewport.Model TeamView viewport.Model ExperimentHistoryView viewport.Model ConfigView viewport.Model LogsView viewport.Model SelectedJob Job Input textinput.Model APIKeyInput textinput.Model Status string ErrorMsg string InputMode bool Width int Height int ShowHelp bool Spinner spinner.Model ActiveView ViewMode LastRefresh time.Time LastFrameTime time.Time RefreshRate float64 // measured in ms FrameCount int LastGPUUpdate time.Time IsLoading bool JobStats map[JobStatus]int APIKey string SettingsIndex int Keys KeyMap } // InitialState creates the initial application state func InitialState(apiKey string) State { items := []list.Item{} delegate := NewJobListDelegate() jobList := list.New(items, delegate, 0, 0) jobList.Title = "ML Jobs & Queue" jobList.SetShowStatusBar(true) jobList.SetFilteringEnabled(true) jobList.SetShowHelp(false) jobList.Styles.Title = JobListTitleStyle() input := textinput.New() input.Placeholder = "Args: --epochs 100 --lr 0.001 --priority 5" input.Width = 60 input.CharLimit = 200 apiKeyInput := textinput.New() apiKeyInput.Placeholder = "Enter API key..." apiKeyInput.Width = 40 apiKeyInput.CharLimit = 200 s := spinner.New() s.Spinner = spinner.Dot s.Style = SpinnerStyle() return State{ JobList: jobList, GpuView: viewport.New(0, 0), ContainerView: viewport.New(0, 0), QueueView: viewport.New(0, 0), SettingsView: viewport.New(0, 0), DatasetView: viewport.New(0, 0), ExperimentsView: viewport.New(0, 0), NarrativeView: viewport.New(0, 0), TeamView: viewport.New(0, 0), ExperimentHistoryView: viewport.New(0, 0), ConfigView: viewport.New(0, 0), LogsView: viewport.New(0, 0), Input: input, APIKeyInput: apiKeyInput, Status: "Connected", InputMode: false, ShowHelp: false, Spinner: s, ActiveView: ViewModeJobs, LastRefresh: time.Now(), IsLoading: false, JobStats: make(map[JobStatus]int), APIKey: apiKey, SettingsIndex: 0, Keys: DefaultKeys(), } } // LogMsg represents a log line from a job type LogMsg struct { JobName string `json:"job_name"` Line string `json:"line"` Time string `json:"time"` } // JobUpdateMsg represents a real-time job status update via WebSocket type JobUpdateMsg struct { JobName string `json:"job_name"` Status string `json:"status"` TaskID string `json:"task_id"` Progress int `json:"progress"` } // GPUUpdateMsg represents a real-time GPU status update via WebSocket type GPUUpdateMsg struct { DeviceID int `json:"device_id"` Utilization int `json:"utilization"` MemoryUsed int64 `json:"memory_used"` MemoryTotal int64 `json:"memory_total"` Temperature int `json:"temperature"` }