nexus_core/app/
settings.rs1#![allow(
5 clippy::cast_possible_truncation,
6 clippy::cast_possible_wrap,
7 clippy::cast_precision_loss,
8 clippy::cast_sign_loss
9)]
10use anyhow::{Result, bail};
11
12use super::{App, OCR_ENGINES, SEARCH_PROVIDERS, VERBOSITY_LEVELS};
13
14impl App {
15 pub fn cycle_ocr_engine(&mut self) -> Result<()> {
22 let i = super::OCR_ENGINES
23 .iter()
24 .position(|&e| e == self.ocr_engine)
25 .unwrap_or(0);
26 let next = super::OCR_ENGINES[(i + 1) % super::OCR_ENGINES.len()];
27 if next == "local" {
28 self.ocr_local_install("");
29 return Ok(());
30 }
31 self.ocr_engine = next.to_string();
32 self.db.set_setting("ocr_engine", &self.ocr_engine)?;
33 Ok(())
34 }
35
36 pub fn set_setting(&mut self, key: &str, value: &str) -> Result<()> {
42 if !SETTING_KEYS.contains(&key) {
43 bail!("unknown setting: {key}");
44 }
45 if !valid_setting_value(key, value) {
46 bail!("invalid value for {key}: {value:?}");
47 }
48 self.apply_setting(key, value);
49 if key == "blocked_domains" {
50 std::fs::write(
53 self.space.blocked_domains_path(&self.active_space.name),
54 value,
55 )?;
56 } else {
57 self.db.set_setting(key, value)?;
58 }
59 self.refresh_toolbox();
60 self.push_status(format!("{key} set"));
61 Ok(())
62 }
63}
64
65const SETTING_KEYS: [&str; 21] = [
68 "show_stats",
69 "show_reasoning",
70 "hide_hints",
71 "usage_range",
72 "temperature",
73 "top_p",
74 "max_tokens",
75 "memory_model",
76 "transcriber_model",
77 "ocr_model",
78 "ocr_engine",
79 "local_ocr_model",
80 "embedding_model",
81 "image_gen_model",
82 "video_gen_model",
83 "compact_threshold",
84 "searxng_url",
85 "verbosity",
86 "langsearch_key",
87 "search_provider",
88 "blocked_domains",
89];
90
91fn valid_setting_value(key: &str, value: &str) -> bool {
95 match key {
96 "show_stats" | "show_reasoning" | "hide_hints" => matches!(value, "0" | "1"),
97 "temperature" | "top_p" => value.parse::<f32>().is_ok(),
98 "max_tokens" => value.parse::<u32>().is_ok(),
99 "compact_threshold" => value.parse::<u8>().is_ok(),
100 "usage_range" => crate::db::UsageRange::CYCLE
101 .iter()
102 .any(|r| r.key() == value),
103 "ocr_engine" => OCR_ENGINES.contains(&value),
104 "verbosity" => VERBOSITY_LEVELS.contains(&value),
105 "search_provider" => SEARCH_PROVIDERS.contains(&value),
106 _ => true, }
108}