summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorVika <vika@fireburn.ru>2025-02-19 23:35:53 +0300
committerVika <vika@fireburn.ru>2025-02-24 04:38:26 +0300
commitb46585e0cfcbd665f730a4d0a20eb67e6fea5f70 (patch)
tree079c69855c80128d0875f1a0e5697b30249b5c73 /src
parent657a2672fead185eb37ea4a61f587a7a796b6a0d (diff)
downloadbowl-b46585e0cfcbd665f730a4d0a20eb67e6fea5f70.tar.zst
Show a warning on usage of Smart Summary
This was a planned feature since the introduction of LLM
enhancements. Some users need a sobering reminder that LLMs are not
intelligent, because it is really easy to believe otherwise.
Diffstat (limited to 'src')
-rw-r--r--src/components/preferences.rs21
-rw-r--r--src/components/smart_summary.rs45
2 files changed, 57 insertions, 9 deletions
diff --git a/src/components/preferences.rs b/src/components/preferences.rs
index 09fbdf7..f1f37f9 100644
--- a/src/components/preferences.rs
+++ b/src/components/preferences.rs
@@ -13,7 +13,8 @@ struct LanguageModelPreferencesWidgets {
 
     general_group: adw::PreferencesGroup,
     llm_endpoint: adw::EntryRow,
-
+    smart_summary_show_warning: adw::SwitchRow,
+    
     smart_summary_group: adw::PreferencesGroup,
     smart_summary_model: adw::EntryRow,
     smart_summary_system_prompt: adw::EntryRow,
@@ -36,7 +37,9 @@ impl LanguageModelPreferencesWidgets {
             .title(gettext("General"))
             .build();
         let llm_endpoint = adw::EntryRow::new();
+        let smart_summary_show_warning = adw::SwitchRow::new();
         general_group.add(&llm_endpoint);
+        general_group.add(&smart_summary_show_warning);
         page.add(&general_group);
 
         let smart_summary_group = adw::PreferencesGroup::builder()
@@ -57,6 +60,7 @@ impl LanguageModelPreferencesWidgets {
 
             general_group,
             llm_endpoint,
+            smart_summary_show_warning,
 
             smart_summary_group,
             smart_summary_model,
@@ -67,14 +71,15 @@ impl LanguageModelPreferencesWidgets {
 
         let schema = settings.settings_schema().unwrap();
 
-        for (row, key) in [
-            (&widgets.llm_endpoint, "llm-endpoint"),
-            (&widgets.smart_summary_model, "smart-summary-model"),
-            (&widgets.smart_summary_system_prompt, "smart-summary-system-prompt"),
-            (&widgets.smart_summary_prompt_prefix, "smart-summary-prompt-prefix"),
-            (&widgets.smart_summary_prompt_suffix, "smart-summary-prompt-suffix"),
+        for (row, key, property) in [
+            (widgets.llm_endpoint.upcast_ref::<adw::PreferencesRow>(), "llm-endpoint", "text"),
+            (widgets.smart_summary_show_warning.upcast_ref::<_>(), "smart-summary-show-warning", "active"),
+            (widgets.smart_summary_model.upcast_ref::<_>(), "smart-summary-model", "text"),
+            (widgets.smart_summary_system_prompt.upcast_ref::<_>(), "smart-summary-system-prompt", "text"),
+            (widgets.smart_summary_prompt_prefix.upcast_ref::<_>(), "smart-summary-prompt-prefix", "text"),
+            (widgets.smart_summary_prompt_suffix.upcast_ref::<_>(), "smart-summary-prompt-suffix", "text"),
         ] {
-            settings.bind(key, row, "text")
+            settings.bind(key, row, property)
                 .get()
                 .set()
                 .build();
diff --git a/src/components/smart_summary.rs b/src/components/smart_summary.rs
index 67419cb..5b98186 100644
--- a/src/components/smart_summary.rs
+++ b/src/components/smart_summary.rs
@@ -152,6 +152,7 @@ pub(crate) enum Error {
 #[derive(Debug)]
 pub(crate) enum Input {
     #[doc(hidden)] ButtonPressed,
+    #[doc(hidden)] WarningAccepted,
     Text(String),
     Cancel,
 }
@@ -224,7 +225,49 @@ impl Component for SmartSummaryButton {
                     log::warn!("Parent component asked us to cancel, but we're not running a task.");
                 }
             },
-            Input::ButtonPressed => if let Ok(()) = sender.output(Output::Start) {
+            Input::ButtonPressed => {
+                let settings = gio::Settings::new(crate::APPLICATION_ID);
+                if !settings.get::<bool>("smart-summary-show-warning") {
+                    return self.update(Input::WarningAccepted, sender, _root);
+                } else {
+                    // TODO: show warning dialog
+                    let skip_warning_checkbox = gtk::CheckButton::with_label(
+                        &gettext("Show this warning next time")
+                    );
+
+                    settings.bind(
+                        "smart-summary-show-warning",
+                        &skip_warning_checkbox, "active"
+                    ).get().set().build();
+
+                    let dialog = adw::AlertDialog::builder()
+                        .heading(gettext("LLMs can be deceiving"))
+                        .body(gettext("Language models inherently lack any sort of intelligence, understanding of the text they take or produce, or conscience to feel guilty for lying or deceiving their user.
+
+<b>Smart Summary</b> is only designed to generate draft-quality output that must be proof-read by a human before being posted."))
+                        .body_use_markup(true)
+                        .default_response("continue")
+                        .extra_child(&skip_warning_checkbox)
+                        .build();
+                    dialog.add_responses(&[
+                        ("close", &gettext("Cancel")),
+                        ("continue", &gettext("Proceed"))
+                    ]);
+                    dialog.choose(
+                        &_root.root().unwrap(),
+                        None::<&gio::Cancellable>,
+                        glib::clone!(
+                            #[strong] sender,
+                            move |res| match res.as_str() {
+                                "continue" => {
+                                    sender.input(Input::WarningAccepted);
+                                },
+                                _ => {},
+                            }
+                        ))
+                }
+            },
+            Input::WarningAccepted => if let Ok(()) = sender.output(Output::Start) {
                 self.waiting = true;
                 log::debug!("Requesting text to summarize from parent component...");
                 // TODO: set timeout in case parent component never replies