Disable auto RLM and bump version to 0.0.2

This commit is contained in:
Hunter Bown
2026-01-20 09:32:48 -06:00
parent 93e62b64c2
commit b8d477f751
10 changed files with 192 additions and 4 deletions
+7 -1
View File
@@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
## [0.0.2] - 2026-01-20
### Fixed
- Disabled automatic RLM mode switching; use /rlm or /aleph to enter RLM mode.
## [0.0.1] - 2026-01-19
### Added
@@ -84,7 +89,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Hooks system and config profiles
- Example skills and launch assets
[Unreleased]: https://github.com/Hmbown/DeepSeek-CLI/compare/v0.0.1...HEAD
[Unreleased]: https://github.com/Hmbown/DeepSeek-CLI/compare/v0.0.2...HEAD
[0.0.2]: https://github.com/Hmbown/DeepSeek-CLI/releases/tag/v0.0.2
[0.0.1]: https://github.com/Hmbown/DeepSeek-CLI/releases/tag/v0.0.1
[0.1.9]: https://github.com/Hmbown/DeepSeek-CLI/compare/v0.1.8...v0.1.9
[0.1.8]: https://github.com/Hmbown/DeepSeek-CLI/compare/v0.1.7...v0.1.8
Generated
+1 -1
View File
@@ -611,7 +611,7 @@ dependencies = [
[[package]]
name = "deepseek-tui"
version = "0.1.0"
version = "0.0.2"
dependencies = [
"anyhow",
"arboard",
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "deepseek-tui"
version = "0.1.0"
version = "0.0.2"
edition = "2024"
description = "Unofficial DeepSeek CLI - Just run 'deepseek' to start chatting"
license = "MIT"
+3
View File
@@ -125,6 +125,9 @@ pub fn set_config(app: &mut App, args: Option<&str>) -> CommandResult {
compaction.model = app.model.clone();
action = Some(AppAction::UpdateCompaction(compaction));
}
"auto_rlm" => {
app.auto_rlm = settings.auto_rlm;
}
"show_thinking" | "thinking" => {
app.show_thinking = settings.show_thinking;
app.mark_history_updated();
+78 -1
View File
@@ -3,7 +3,7 @@
use std::fmt::Write;
use crate::tools::plan::PlanState;
use crate::tui::app::{App, AppAction};
use crate::tui::app::{App, AppAction, AppMode};
use crate::tui::views::{HelpView, ModalKind, SubAgentsView};
use super::CommandResult;
@@ -96,3 +96,80 @@ Docs: https://platform.deepseek.com/docs\n\n\
Tip: API keys are available in the dashboard console.",
)
}
/// Show home dashboard with stats and quick actions
pub fn home_dashboard(app: &mut App) -> CommandResult {
let mut stats = String::new();
// Basic info
let _ = writeln!(stats, "DeepSeek CLI Home Dashboard");
let _ = writeln!(stats, "============================================");
// Model & mode
let _ = writeln!(stats, "Model: {}", app.model);
let _ = writeln!(stats, "Mode: {}", app.mode.label());
let _ = writeln!(stats, "Workspace: {}", app.workspace.display());
// Session stats
let history_count = app.history.len();
let total_tokens = app.total_conversation_tokens;
let queued_messages = app.queued_messages.len();
let _ = writeln!(stats, "History: {} messages", history_count);
let _ = writeln!(stats, "Tokens: {} (session)", total_tokens);
if queued_messages > 0 {
let _ = writeln!(stats, "Queued: {} messages", queued_messages);
}
// Sub-agents
let subagent_count = app.subagent_cache.len();
if subagent_count > 0 {
let _ = writeln!(stats, "Sub-agents: {} active", subagent_count);
}
// Active skill
if let Some(skill) = &app.active_skill {
let _ = writeln!(stats, "Skill: {} (active)", skill);
}
// Quick actions section
let _ = writeln!(stats, "\nQuick Actions");
let _ = writeln!(stats, "--------------------------------------------");
let _ = writeln!(stats, "/deepseek - Dashboard & API links");
let _ = writeln!(stats, "/skills - List available skills");
let _ = writeln!(stats, "/config - Show current configuration");
let _ = writeln!(stats, "/settings - Show persistent settings");
let _ = writeln!(stats, "/model - Switch or view model");
let _ = writeln!(stats, "/subagents - List sub-agent status");
let _ = writeln!(stats, "/help - Show help");
// Mode-specific tips
let _ = writeln!(stats, "\nMode Tips");
let _ = writeln!(stats, "--------------------------------------------");
match app.mode {
AppMode::Normal => {
let _ = writeln!(stats, "Normal mode - Chat with the assistant");
}
AppMode::Agent => {
let _ = writeln!(stats, "Agent mode - Use tools for autonomous tasks");
let _ = writeln!(stats, " Type /yolo to enable full tool access");
}
AppMode::Yolo => {
let _ = writeln!(stats, "YOLO mode - Full tool access, no approvals");
let _ = writeln!(stats, " Be careful with destructive operations!");
}
AppMode::Plan => {
let _ = writeln!(stats, "Plan mode - Design before implementing");
let _ = writeln!(stats, " Use /plan to create structured checklists");
}
AppMode::Rlm => {
let _ = writeln!(stats, "RLM mode - Recursive language model sandbox");
let _ = writeln!(stats, " Use /repl to toggle REPL input");
}
AppMode::Duo => {
let _ = writeln!(stats, "Duo mode - Dialectical autocoding");
let _ = writeln!(stats, " Player-coach loop for complex tasks");
}
}
CommandResult::message(stats)
}
+15
View File
@@ -7,6 +7,7 @@ mod config;
mod core;
mod debug;
mod init;
mod note;
mod queue;
pub mod rlm;
mod session;
@@ -120,6 +121,18 @@ pub const COMMANDS: &[CommandInfo] = &[
description: "Show DeepSeek dashboard and docs links",
usage: "/deepseek",
},
CommandInfo {
name: "home",
aliases: &["stats", "overview"],
description: "Show home dashboard with stats and quick actions",
usage: "/home",
},
CommandInfo {
name: "note",
aliases: &[],
description: "Append note to persistent notes file (.deepseek/notes.md)",
usage: "/note <text>",
},
// Session commands
CommandInfo {
name: "save",
@@ -288,6 +301,8 @@ pub fn execute(cmd: &str, app: &mut App) -> CommandResult {
"queue" | "queued" => queue::queue(app, arg),
"subagents" | "agents" => core::subagents(app),
"deepseek" | "dashboard" | "api" => core::deepseek_links(),
"home" | "stats" | "overview" => core::home_dashboard(app),
"note" => note::note(app, arg),
// Session commands
"save" => session::save(app, arg),
+59
View File
@@ -0,0 +1,59 @@
//! Note command: append to persistent notes file
use std::fs;
use std::io::Write;
use crate::tui::app::App;
use super::CommandResult;
/// Append a note to the persistent notes file
pub fn note(app: &mut App, content: Option<&str>) -> CommandResult {
let note_content = match content {
Some(c) => c.trim(),
None => {
return CommandResult::error("Usage: /note <text>");
}
};
if note_content.is_empty() {
return CommandResult::error("Note content cannot be empty");
}
// Determine notes path: workspace/.deepseek/notes.md
let notes_path = app.workspace.join(".deepseek").join("notes.md");
// Ensure parent directory exists
if let Some(parent) = notes_path.parent() {
if let Err(e) = fs::create_dir_all(parent) {
return CommandResult::error(format!(
"Failed to create notes directory: {e}"
));
}
}
// Append to notes file
let mut file = match fs::OpenOptions::new()
.create(true)
.append(true)
.open(&notes_path)
{
Ok(f) => f,
Err(e) => {
return CommandResult::error(format!(
"Failed to open notes file: {e}"
));
}
};
// Write separator and note content
if let Err(e) = writeln!(file, "\n---\n{}", note_content) {
return CommandResult::error(format!(
"Failed to write note: {e}"
));
}
CommandResult::message(format!(
"Note appended to {}",
notes_path.display()
))
}
+8
View File
@@ -15,6 +15,8 @@ pub struct Settings {
pub theme: String,
/// Auto-compact conversations when they get long
pub auto_compact: bool,
/// Auto-switch to RLM mode when large inputs are detected
pub auto_rlm: bool,
/// Show thinking blocks from the model
pub show_thinking: bool,
/// Show detailed tool output
@@ -34,6 +36,7 @@ impl Default for Settings {
Self {
theme: "default".to_string(),
auto_compact: true,
auto_rlm: false,
show_thinking: true,
show_tool_details: true,
default_mode: "agent".to_string(),
@@ -99,6 +102,9 @@ impl Settings {
"auto_compact" | "compact" => {
self.auto_compact = parse_bool(value)?;
}
"auto_rlm" => {
self.auto_rlm = parse_bool(value)?;
}
"show_thinking" | "thinking" => {
self.show_thinking = parse_bool(value)?;
}
@@ -154,6 +160,7 @@ impl Settings {
lines.push("─────────────────────────────".to_string());
lines.push(format!(" theme: {}", self.theme));
lines.push(format!(" auto_compact: {}", self.auto_compact));
lines.push(format!(" auto_rlm: {}", self.auto_rlm));
lines.push(format!(" show_thinking: {}", self.show_thinking));
lines.push(format!(" show_tool_details: {}", self.show_tool_details));
lines.push(format!(" default_mode: {}", self.default_mode));
@@ -179,6 +186,7 @@ impl Settings {
vec![
("theme", "Color theme: default, dark, light"),
("auto_compact", "Auto-compact conversations: on/off"),
("auto_rlm", "Auto-switch to RLM mode for large inputs: on/off"),
("show_thinking", "Show model thinking: on/off"),
("show_tool_details", "Show detailed tool output: on/off"),
("default_mode", "Default mode: agent, plan, yolo, rlm, duo"),
+3
View File
@@ -176,6 +176,7 @@ pub struct App {
pub input_history: Vec<String>,
pub history_index: Option<usize>,
pub auto_compact: bool,
pub auto_rlm: bool,
pub show_thinking: bool,
pub show_tool_details: bool,
#[allow(dead_code)]
@@ -335,6 +336,7 @@ impl App {
let needs_onboarding = !has_api_key(config);
let settings = Settings::load().unwrap_or_else(|_| Settings::default());
let auto_compact = settings.auto_compact;
let auto_rlm = settings.auto_rlm;
let show_thinking = settings.show_thinking;
let show_tool_details = settings.show_tool_details;
let max_input_history = settings.max_input_history;
@@ -421,6 +423,7 @@ impl App {
input_history: Vec::new(),
history_index: None,
auto_compact,
auto_rlm,
show_thinking,
show_tool_details,
compact_threshold: 50000,
+17
View File
@@ -1234,6 +1234,9 @@ struct AutoRlmLoaded {
}
fn maybe_auto_switch_to_rlm(app: &mut App, input: &str) -> Option<String> {
if !app.auto_rlm {
return None;
}
let already_rlm = app.mode == AppMode::Rlm;
let decision = auto_rlm_decision(app, input, already_rlm)?;
@@ -3301,6 +3304,20 @@ mod tests {
}
}
#[test]
fn auto_rlm_is_disabled_when_setting_off() {
let tmp = tempdir().expect("tempdir");
let mut app = make_test_app_with_workspace(tmp.path().to_path_buf());
app.auto_rlm = false;
let content = "a".repeat(AUTO_RLM_PASTE_MIN_CHARS + 5);
let input = format!("Summarize this\n\n{content}");
let override_query = maybe_auto_switch_to_rlm(&mut app, &input);
assert!(override_query.is_none());
assert_ne!(app.mode, AppMode::Rlm);
}
#[test]
fn parse_plan_choice_accepts_numbers() {
assert_eq!(parse_plan_choice("1"), Some(PlanChoice::ImplementAgent));