diff --git a/config.example.toml b/config.example.toml index b5343535..eb16c23f 100644 --- a/config.example.toml +++ b/config.example.toml @@ -144,6 +144,7 @@ memory_path = "~/.codewhale/memory.md" allow_shell = true approval_policy = "on-request" # on-request | untrusted | never sandbox_mode = "workspace-write" # read-only | workspace-write | danger-full-access | external-sandbox +# prompt_suggestion = true # opt-in: show ghost-text follow-up question in composer after each turn # Typed permission rules live in a sibling `permissions.toml` file, not in # config.toml. This schema slice is ask-only and is parsed for follow-up diff --git a/crates/tui/src/config.rs b/crates/tui/src/config.rs index f71400b7..f9c0c0bd 100644 --- a/crates/tui/src/config.rs +++ b/crates/tui/src/config.rs @@ -1550,6 +1550,9 @@ pub struct Config { /// missing optional file doesn't fail the launch. pub instructions: Option>, pub allow_shell: Option, + /// Opt-in ghost-text follow-up prompt suggestion after each completed turn. + /// Default: false — the user must explicitly set this to true to enable. + pub prompt_suggestion: Option, pub approval_policy: Option, pub sandbox_mode: Option, pub yolo: Option, @@ -2707,6 +2710,11 @@ impl Config { self.allow_shell.unwrap_or(false) } + /// Whether ghost-text prompt suggestion is enabled (opt-in, default off). + pub fn prompt_suggestion_enabled(&self) -> bool { + self.prompt_suggestion.unwrap_or(false) + } + /// Return the maximum number of concurrent sub-agents. /// Checks `[subagents] max_concurrent` first, then top-level `max_subagents`, /// then falls back to `DEFAULT_MAX_SUBAGENTS`. @@ -4253,6 +4261,7 @@ fn merge_config(base: Config, override_cfg: Config) -> Config { // both — they list `~/global.md` inside the project array. instructions: override_cfg.instructions.or(base.instructions), allow_shell: override_cfg.allow_shell.or(base.allow_shell), + prompt_suggestion: override_cfg.prompt_suggestion.or(base.prompt_suggestion), yolo: override_cfg.yolo.or(base.yolo), approval_policy: override_cfg.approval_policy.or(base.approval_policy), sandbox_mode: override_cfg.sandbox_mode.or(base.sandbox_mode), diff --git a/crates/tui/src/tui/ui.rs b/crates/tui/src/tui/ui.rs index 24bdd9ad..7b70d702 100644 --- a/crates/tui/src/tui/ui.rs +++ b/crates/tui/src/tui/ui.rs @@ -1843,11 +1843,13 @@ async fn run_event_loop( // Generate ghost-text follow-up suggestion asynchronously. if status == crate::core::events::TurnOutcomeStatus::Completed + && config.prompt_suggestion_enabled() && app.api_messages.len() >= 2 { let suggestion_cell = app.prompt_suggestion_cell.clone(); let api_key = config.deepseek_api_key().unwrap_or_default(); let base_url = config.deepseek_base_url(); + let model = config.default_model(); let messages: Vec = app.api_messages.clone(); let gen_token = app .prompt_suggestion_gen @@ -1860,10 +1862,7 @@ async fn run_event_loop( ); if let Some(suggestion) = crate::tui::prompt_suggestion::generate_suggestion( - &api_key, - &base_url, - "deepseek-v4-flash", - &summary, + &api_key, &base_url, &model, &summary, ) .await && let Ok(mut guard) = suggestion_cell.lock()