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 tls_enabled: bool,
165 },
166 SearchInput {
167 buffer: String,
168 cursor_pos: usize,
169 },
170}
171
172#[derive(Debug, Clone, Copy, PartialEq, Eq)]
173pub enum ConfirmationKind {
174 Exit,
175 Reset,
176 Delete,
177 Unload,
178 DeleteBackend,
179}
180
181#[derive(Debug, Clone)]
183pub struct TextScrollState {
184 pub offset: usize,
185 pub last_tick: std::time::Instant,
186 pub direction: i8,
187 pub hold_count: u8,
188 pub max_offset: usize,
189 pub visible: bool,
190}
191
192#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
194pub enum LoadingPhase {
195 ServerStarting,
196 LoadingModel,
197 LoadingMeta,
198 LoadingTensors,
199 ServerListening,
200 Complete,
201}
202
203impl LoadingPhase {
204 pub fn label(&self) -> &'static str {
205 match self {
206 LoadingPhase::ServerStarting => "Server starting...",
207 LoadingPhase::LoadingModel => "Loading model weights...",
208 LoadingPhase::LoadingMeta => "Loading metadata...",
209 LoadingPhase::LoadingTensors => "Loading tensors...",
210 LoadingPhase::ServerListening => "Server listening...",
211 LoadingPhase::Complete => "Ready",
212 }
213 }
214}
215
216pub struct App {
218 pub running: bool,
220 pub config: Config,
221 pub models: Vec<DiscoveredModel>,
222 pub selected_model_idx: Option<usize>,
223 pub models_mode: ModelsMode,
224 pub settings: ModelSettings,
225 pub model_settings_cache: ModelSettings,
226 pub model_states: HashMap<String, ModelState>,
227 pub metrics: ServerMetrics,
228 pub max_threads: u32,
229 pub cancelled: Option<Arc<AtomicBool>>,
230 pub server_mode: crate::models::ServerMode,
231 pub router_max_models: u32,
232 pub ws_server_handle: Option<tokio::task::JoinHandle<()>>,
233 pub background_tasks: HashMap<String, tokio::task::JoinHandle<()>>,
234
235 pub settings_state: SettingsState,
237 pub picker: PickerState,
238 pub download: DownloadState,
239 pub server: ServerState,
240 pub bench_tune: BenchTuneState,
241 pub log: LogState,
242 pub loading: LoadingState,
243 pub pending: PendingOperations,
244 pub search: SearchState,
245 pub ui: UIState,
246 pub edit: EditState,
247}