1 //! Tauri command: `chat_list_models`
2 //!
3 //! Returns the on-device models the user can switch between, sourced from the
4 //! onde SDK's `SUPPORTED_MODEL_INFO` catalogue (filtered to the subset the
5 //! engine can actually load), with the currently selected model flagged.
6
7 use super::ModelInfo;
8
9 /// Normalise a model description for Apple builds.
10 ///
11 /// The shared onde model catalogue is cross-platform and also names sibling
12 /// products, so its descriptions mention Android/Windows/Linux and "siGit Code".
13 /// Apple's App Store Review Guideline 2.3.10 (Accurate Metadata) forbids
14 /// referencing other platforms in an iOS/macOS app's UI or metadata, so on
15 /// Apple builds we drop those mentions before the text reaches Settings. We
16 /// also neutralise the cross-product reference, which would only confuse a Siti
17 /// user. Apple's own platforms (iOS, macOS, tvOS) are kept.
18 #[cfg(any(target_os = "macos", target_os = "ios"))]
19 fn sanitize_description(desc: &str) -> String {
20 desc.replace("iOS & Android", "iOS")
21 .replace("macOS & Android", "macOS")
22 .replace("macOS, Linux, and Windows", "macOS")
23 .replace(", Linux, and Windows", "")
24 .replace(", Linux and Windows", "")
25 .replace(" & Android", "")
26 .replace(" and Android", "")
27 .replace("siGit Code", "coding tasks")
28 }
29
30 /// On Android the catalogue text is already accurate, so pass it through.
31 #[cfg(target_os = "android")]
32 fn sanitize_description(desc: &str) -> String {
33 desc.to_string()
34 }
35
36 /// List the supported on-device models, smallest first, with the currently
37 /// selected model marked. Used to populate the Settings model dropdown.
38 #[cfg(any(target_os = "macos", target_os = "ios", target_os = "android"))]
39 #[tauri::command]
40 pub async fn chat_list_models() -> Vec<ModelInfo> {
41 use super::{config_for_model_id, SELECTED_MODEL};
42
43 let selected = SELECTED_MODEL.lock().map(|g| g.clone()).unwrap_or_default();
44
45 let mut models: Vec<ModelInfo> = crate::inference::models::SUPPORTED_MODEL_INFO
46 .iter()
47 // Only include models the engine can build a loadable config for.
48 .filter_map(|info| {
49 config_for_model_id(info.id).map(|cfg| ModelInfo {
50 id: info.id.to_string(),
51 name: info.name.to_string(),
52 org: info.org.to_string(),
53 description: sanitize_description(info.description),
54 approx_memory: cfg.approx_memory,
55 size_bytes: Some(info.expected_size_bytes),
56 is_selected: info.id == selected,
57 })
58 })
59 .collect();
60
61 // Smallest (most device-friendly) first.
62 models.sort_by_key(|m| m.size_bytes.unwrap_or(u64::MAX));
63 models
64 }
65
66 #[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "android")))]
67 #[tauri::command]
68 pub async fn chat_list_models() -> Vec<ModelInfo> {
69 log::debug!("On-device models are only supported on macOS, iOS, and Android.");
70 Vec::new()
71 }