1pub mod sub;
2use crate::config::Config;
3use crate::config::Profile;
4use crate::models::Backend;
5use crate::models::{
6 BenchTuneConfig, DiscoveredModel, ModelSettings, ModelState, SearchResult, SearchSort,
7 ServerMetrics,
8};
9use ratatui::layout::Rect;
10use ratatui::text::Line;
11use std::collections::HashMap;
12use std::sync::atomic::AtomicBool;
13use std::sync::{Arc, Mutex};
14
15pub use sub::{
17 BenchTuneState, DownloadState, EditState, LoadingState, LogState, PendingOperations,
18 PickerState, SearchState, ServerState, SettingsState, UIState,
19};
20
21pub static API_PORT_CACHE: Mutex<(u16, String)> = Mutex::new((0, String::new()));
23
24pub struct ResizeState {
26 pub start_x: u16,
28 pub start_pct: u16,
30 pub container: Rect,
32}
33
34pub struct SettingsRenderCache {
36 pub hash: u64,
37 pub selected: usize,
38 pub lines: Vec<Line<'static>>,
39}
40
41#[derive(Debug, Clone, Copy, PartialEq, Eq)]
43pub enum ActivePanel {
44 Models,
45 Log,
46 ServerSettings,
47 LlmSettings,
48 Profiles,
49 SystemPromptPresets,
50 SearchReadme,
51 ActiveModel,
52 ModelInfo,
53 Downloads,
54}
55
56#[derive(Debug, Clone)]
58pub enum ModelsMode {
59 List,
61 Search {
63 query: String,
64 results: Vec<SearchResult>,
65 sort_by: SearchSort,
66 show_readme: bool,
67 page: usize,
68 loading: bool,
70 has_more: bool,
72 },
73 Files {
75 model_id: String,
76 files: Vec<(String, u64, String)>, selected_idx: Option<usize>,
78 previous_query: String,
79 previous_results: Vec<SearchResult>,
80 selected_result: Option<SearchResult>,
81 },
82 BenchTune,
84}
85
86#[derive(Debug, Clone, PartialEq)]
88pub enum GlobalMode {
89 Normal,
90 CmdLine {
91 cmd_line: String,
92 },
93 HostPicker {
94 entries: Vec<(String, String)>, selected: usize,
96 },
97 BackendPicker {
98 entries: Vec<(Backend, Option<String>)>,
99 selected: usize,
100 },
101 Confirmation {
102 selected: bool,
103 kind: ConfirmationKind,
104 },
105 RpcManager,
106 About,
107 MaxConcurrentPicker {
108 value: String,
109 },
110 SpecTypePicker {
111 entries: Vec<String>,
112 selected: usize,
113 },
114 YarnRoPESettings {
115 scale: String,
116 freq_base: String,
117 freq_scale: String,
118 selected_field: i32, editing: bool,
120 edit_buffer: String,
121 edit_cursor_pos: usize,
122 },
123 BenchTuneSetup {
124 config: BenchTuneConfig,
125 selected_idx: usize,
126 editing_param: bool,
127 editing_param_field: i32,
128 param_edit_buffer: String,
129 param_edit_cursor_pos: usize,
130 bench_mode_selection: usize,
131 editing_prompt: bool,
132 editing_kwargs: bool,
133 },
134 PromptPicker {
135 entries: Vec<(String, String)>, selected: usize,
137 editing: bool,
138 edit_buffer: String,
139 edit_cursor_pos: usize,
140 confirm_delete: bool,
141 },
142 ProfilePicker {
143 entries: Vec<(String, String)>, selected: usize,
145 profiles: Vec<Profile>,
146 },
147 DashboardPicker {
148 enabled: bool,
149 port: String,
150 auth_key: String,
151 tls_enabled: bool,
152 tls_cert: String,
153 tls_key: String,
154 selected_field: i32, editing: bool,
156 edit_buffer: String,
157 edit_cursor_pos: usize,
158 },
159 DashboardUrl {
160 host: String,
161 port: String,
162 auth_key: String,
163 ws_enabled: bool,
164 },
165 SearchInput {
166 buffer: String,
167 cursor_pos: usize,
168 },
169}
170
171#[derive(Debug, Clone, Copy, PartialEq, Eq)]
172pub enum ConfirmationKind {
173 Exit,
174 Reset,
175 Delete,
176 Unload,
177 DeleteBackend,
178}
179
180#[derive(Debug, Clone)]
182pub struct TextScrollState {
183 pub offset: usize,
184 pub last_tick: std::time::Instant,
185 pub direction: i8,
186 pub hold_count: u8,
187 pub max_offset: usize,
188 pub visible: bool,
189}
190
191#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
193pub enum LoadingPhase {
194 ServerStarting,
195 LoadingModel,
196 LoadingMeta,
197 LoadingTensors,
198 ServerListening,
199 Complete,
200}
201
202impl LoadingPhase {
203 pub fn label(&self) -> &'static str {
204 match self {
205 LoadingPhase::ServerStarting => "Server starting...",
206 LoadingPhase::LoadingModel => "Loading model weights...",
207 LoadingPhase::LoadingMeta => "Loading metadata...",
208 LoadingPhase::LoadingTensors => "Loading tensors...",
209 LoadingPhase::ServerListening => "Server listening...",
210 LoadingPhase::Complete => "Ready",
211 }
212 }
213}
214
215pub struct App {
217 pub running: bool,
219 pub config: Config,
220 pub models: Vec<DiscoveredModel>,
221 pub selected_model_idx: Option<usize>,
222 pub models_mode: ModelsMode,
223 pub settings: ModelSettings,
224 pub model_settings_cache: ModelSettings,
225 pub model_states: HashMap<String, ModelState>,
226 pub metrics: ServerMetrics,
227 pub max_threads: u32,
228 pub cancelled: Option<Arc<AtomicBool>>,
229 pub server_mode: crate::models::ServerMode,
230 pub router_max_models: u32,
231 pub ws_server_handle: Option<tokio::task::JoinHandle<()>>,
232 pub background_tasks: HashMap<String, tokio::task::JoinHandle<()>>,
233
234 pub settings_state: SettingsState,
236 pub picker: PickerState,
237 pub download: DownloadState,
238 pub server: ServerState,
239 pub bench_tune: BenchTuneState,
240 pub log: LogState,
241 pub loading: LoadingState,
242 pub pending: PendingOperations,
243 pub search: SearchState,
244 pub ui: UIState,
245 pub edit: EditState,
246}