fix for stats and model selection
Some checks failed
Weekly OSV dependency audit / dependency-audit (push) Failing after 5s
Some checks failed
Weekly OSV dependency audit / dependency-audit (push) Failing after 5s
This commit is contained in:
13
migrations/20260905090000_allow_qwen_session_model/down.sql
Normal file
13
migrations/20260905090000_allow_qwen_session_model/down.sql
Normal file
@@ -0,0 +1,13 @@
|
||||
ALTER TABLE sessions ADD COLUMN model_without_qwen TEXT
|
||||
CHECK (model_without_qwen IS NULL OR model_without_qwen IN (
|
||||
'deepseek-v4-flash-0731',
|
||||
'deepseek-v4-pro',
|
||||
'glm-5.2',
|
||||
'glm-5.3-flash'
|
||||
));
|
||||
UPDATE sessions SET model_without_qwen = CASE
|
||||
WHEN model = 'qwen3.8-flash-next' THEN NULL
|
||||
ELSE model
|
||||
END;
|
||||
ALTER TABLE sessions DROP COLUMN model;
|
||||
ALTER TABLE sessions RENAME COLUMN model_without_qwen TO model;
|
||||
11
migrations/20260905090000_allow_qwen_session_model/up.sql
Normal file
11
migrations/20260905090000_allow_qwen_session_model/up.sql
Normal file
@@ -0,0 +1,11 @@
|
||||
ALTER TABLE sessions ADD COLUMN model_with_qwen TEXT
|
||||
CHECK (model_with_qwen IS NULL OR model_with_qwen IN (
|
||||
'deepseek-v4-flash-0731',
|
||||
'deepseek-v4-pro',
|
||||
'glm-5.2',
|
||||
'glm-5.3-flash',
|
||||
'qwen3.8-flash-next'
|
||||
));
|
||||
UPDATE sessions SET model_with_qwen = model;
|
||||
ALTER TABLE sessions DROP COLUMN model;
|
||||
ALTER TABLE sessions RENAME COLUMN model_with_qwen TO model;
|
||||
46
src/app.rs
46
src/app.rs
@@ -148,8 +148,9 @@ pub(crate) struct App {
|
||||
pub(super) kv_cache_report: KvCacheReport,
|
||||
last_cache_scan: Instant,
|
||||
last_http_requests: u64,
|
||||
last_ssd_selected_requests: u64,
|
||||
last_ssd_requested_bytes: u64,
|
||||
last_ssd_cache_misses: u64,
|
||||
last_ssd_cache_evictions: u64,
|
||||
last_ssd_pread_bytes: u64,
|
||||
last_ssd_wait_ms: u64,
|
||||
#[cfg(target_os = "macos")]
|
||||
generation_service: Option<GenerationService>,
|
||||
@@ -344,8 +345,9 @@ pub(super) struct MetricsPoint {
|
||||
pub(super) http_requests_per_second: f32,
|
||||
pub(super) kv_read_bytes_per_second: f32,
|
||||
pub(super) kv_write_bytes_per_second: f32,
|
||||
pub(super) ssd_requests_per_second: f32,
|
||||
pub(super) ssd_bytes_per_second: f32,
|
||||
pub(super) ssd_misses_per_second: f32,
|
||||
pub(super) ssd_evictions_per_second: f32,
|
||||
pub(super) ssd_pread_bytes_per_second: f32,
|
||||
pub(super) ssd_wait_ms_per_second: f32,
|
||||
}
|
||||
|
||||
@@ -685,8 +687,9 @@ impl App {
|
||||
kv_cache_report: KvCacheReport::default(),
|
||||
last_cache_scan: Instant::now() - CACHE_SCAN_INTERVAL,
|
||||
last_http_requests: 0,
|
||||
last_ssd_selected_requests: 0,
|
||||
last_ssd_requested_bytes: 0,
|
||||
last_ssd_cache_misses: 0,
|
||||
last_ssd_cache_evictions: 0,
|
||||
last_ssd_pread_bytes: 0,
|
||||
last_ssd_wait_ms: 0,
|
||||
#[cfg(target_os = "macos")]
|
||||
generation_service,
|
||||
@@ -848,8 +851,9 @@ impl App {
|
||||
kv_cache_report: KvCacheReport::default(),
|
||||
last_cache_scan: Instant::now() - CACHE_SCAN_INTERVAL,
|
||||
last_http_requests: 0,
|
||||
last_ssd_selected_requests: 0,
|
||||
last_ssd_requested_bytes: 0,
|
||||
last_ssd_cache_misses: 0,
|
||||
last_ssd_cache_evictions: 0,
|
||||
last_ssd_pread_bytes: 0,
|
||||
last_ssd_wait_ms: 0,
|
||||
#[cfg(target_os = "macos")]
|
||||
generation_service,
|
||||
@@ -2280,21 +2284,26 @@ impl App {
|
||||
let kv_write_bytes_per_second =
|
||||
kv_write_bytes as f32 / METRICS_SAMPLE_INTERVAL.as_secs_f32();
|
||||
let sample_seconds = METRICS_SAMPLE_INTERVAL.as_secs_f32();
|
||||
let ssd_requests_per_second = snapshot
|
||||
.ssd_selected_requests
|
||||
.saturating_sub(self.last_ssd_selected_requests)
|
||||
let ssd_misses_per_second = snapshot
|
||||
.ssd_cache_misses
|
||||
.saturating_sub(self.last_ssd_cache_misses) as f32
|
||||
/ sample_seconds;
|
||||
let ssd_evictions_per_second = snapshot
|
||||
.ssd_cache_evictions
|
||||
.saturating_sub(self.last_ssd_cache_evictions)
|
||||
as f32
|
||||
/ sample_seconds;
|
||||
let ssd_bytes_per_second = snapshot
|
||||
.ssd_requested_bytes
|
||||
.saturating_sub(self.last_ssd_requested_bytes)
|
||||
let ssd_pread_bytes_per_second = snapshot
|
||||
.ssd_pread_bytes
|
||||
.saturating_sub(self.last_ssd_pread_bytes)
|
||||
as f32
|
||||
/ sample_seconds;
|
||||
let ssd_wait_ms_per_second =
|
||||
snapshot.ssd_wait_ms.saturating_sub(self.last_ssd_wait_ms) as f32 / sample_seconds;
|
||||
self.last_http_requests = snapshot.http_requests;
|
||||
self.last_ssd_selected_requests = snapshot.ssd_selected_requests;
|
||||
self.last_ssd_requested_bytes = snapshot.ssd_requested_bytes;
|
||||
self.last_ssd_cache_misses = snapshot.ssd_cache_misses;
|
||||
self.last_ssd_cache_evictions = snapshot.ssd_cache_evictions;
|
||||
self.last_ssd_pread_bytes = snapshot.ssd_pread_bytes;
|
||||
self.last_ssd_wait_ms = snapshot.ssd_wait_ms;
|
||||
self.metrics_history.push_back(MetricsPoint {
|
||||
decode_tokens_per_second: if snapshot.phase == crate::metrics::RuntimePhase::Generating
|
||||
@@ -2307,8 +2316,9 @@ impl App {
|
||||
http_requests_per_second,
|
||||
kv_read_bytes_per_second,
|
||||
kv_write_bytes_per_second,
|
||||
ssd_requests_per_second,
|
||||
ssd_bytes_per_second,
|
||||
ssd_misses_per_second,
|
||||
ssd_evictions_per_second,
|
||||
ssd_pread_bytes_per_second,
|
||||
ssd_wait_ms_per_second,
|
||||
});
|
||||
if self.metrics_history.len() > 120 {
|
||||
|
||||
@@ -250,29 +250,43 @@ impl App {
|
||||
column![
|
||||
mini_chart(
|
||||
&self.metrics_history,
|
||||
|point| point.ssd_requests_per_second,
|
||||
|point| point.ssd_misses_per_second,
|
||||
Color::from_rgb8(240, 180, 70),
|
||||
),
|
||||
row![
|
||||
text("Selected loads")
|
||||
text("Cache misses")
|
||||
.size(12)
|
||||
.color(Color::from_rgb8(240, 180, 70)),
|
||||
Space::new().width(Length::Fill),
|
||||
text(format!("{:.1}/s", latest.ssd_requests_per_second))
|
||||
text(format!("{:.1}/s", latest.ssd_misses_per_second))
|
||||
.size(12)
|
||||
.color(muted_text()),
|
||||
],
|
||||
mini_chart(
|
||||
&self.metrics_history,
|
||||
|point| point.ssd_bytes_per_second,
|
||||
|point| point.ssd_pread_bytes_per_second,
|
||||
Color::from_rgb8(67, 194, 203),
|
||||
),
|
||||
row![
|
||||
text("Requested expert data")
|
||||
text("Direct SSD reads")
|
||||
.size(12)
|
||||
.color(Color::from_rgb8(67, 194, 203)),
|
||||
Space::new().width(Length::Fill),
|
||||
text(format_rate(latest.ssd_bytes_per_second))
|
||||
text(format_rate(latest.ssd_pread_bytes_per_second))
|
||||
.size(12)
|
||||
.color(muted_text()),
|
||||
],
|
||||
mini_chart(
|
||||
&self.metrics_history,
|
||||
|point| point.ssd_evictions_per_second,
|
||||
Color::from_rgb8(157, 119, 255),
|
||||
),
|
||||
row![
|
||||
text("Cache evictions")
|
||||
.size(12)
|
||||
.color(Color::from_rgb8(157, 119, 255)),
|
||||
Space::new().width(Length::Fill),
|
||||
text(format!("{:.1}/s", latest.ssd_evictions_per_second))
|
||||
.size(12)
|
||||
.color(muted_text()),
|
||||
],
|
||||
|
||||
@@ -945,6 +945,50 @@ mod tests {
|
||||
fs::remove_file(path).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn session_model_migration_preserves_data_and_accepts_catalog() {
|
||||
let id = SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_nanos();
|
||||
let path = std::env::temp_dir().join(format!("ds4-session-models-{id}.sqlite3"));
|
||||
let mut database = Database::open(&path).unwrap();
|
||||
let project = database
|
||||
.create_project("DS4", "/tmp/ds4-session-models")
|
||||
.unwrap();
|
||||
let existing = database
|
||||
.create_session(
|
||||
project.id,
|
||||
"Existing",
|
||||
PermissionMode::Ai,
|
||||
crate::model::ModelChoice::DeepSeekV4Flash0731,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
database
|
||||
.connection
|
||||
.revert_last_migration(MIGRATIONS)
|
||||
.unwrap();
|
||||
database
|
||||
.connection
|
||||
.run_pending_migrations(MIGRATIONS)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
database.load_projects().unwrap()[0].sessions[0].model(),
|
||||
existing.model()
|
||||
);
|
||||
|
||||
for model in crate::model::MODEL_CHOICES {
|
||||
let session = database
|
||||
.create_session(project.id, model.id(), PermissionMode::Ai, model)
|
||||
.unwrap();
|
||||
assert_eq!(session.model(), Some(model));
|
||||
}
|
||||
|
||||
drop(database);
|
||||
fs::remove_file(path).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sessions_are_ordered_by_recent_use_within_sidebar_groups() {
|
||||
let id = SystemTime::now()
|
||||
|
||||
Reference in New Issue
Block a user