From bbbddaceaa493e5c6a36722c7362d77ef4968717 Mon Sep 17 00:00:00 2001 From: Hikari Date: Wed, 6 May 2026 13:18:46 -0700 Subject: [PATCH 1/7] feat: add claude-opus-4-7 model and update all model costs Adds Claude Opus 4.7 to the model picker as the new most capable model. Reorganises model list to reflect current vs previous generation, and marks Sonnet 4 and Opus 4 as deprecated (retiring June 15, 2026). Also corrects claude-opus-4-6 context window from 200K to 1M tokens, and updates pricing comments to reflect May 2026 source date. Closes #268 --- src-tauri/src/stats.rs | 37 ++++++++++++++++++++----- src/lib/components/ConfigSidebar.svelte | 13 +++++---- src/lib/stores/stats.ts | 8 ++++-- 3 files changed, 43 insertions(+), 15 deletions(-) diff --git a/src-tauri/src/stats.rs b/src-tauri/src/stats.rs index 16dd45e..ff7efdd 100644 --- a/src-tauri/src/stats.rs +++ b/src-tauri/src/stats.rs @@ -86,9 +86,10 @@ impl ContextWarning { /// Get the context window limit (in tokens) for a given model fn get_context_window_limit(model: &str) -> u64 { match model { - // Claude 4.6 family - "claude-opus-4-6" => 200_000, - "claude-sonnet-4-6" => 1_000_000, // 1M token context window + // Claude 4.7 - 1M token context window + "claude-opus-4-7" => 1_000_000, + // Claude 4.6 family - 1M token context window + "claude-opus-4-6" | "claude-sonnet-4-6" => 1_000_000, // Claude 4.5 family - 200K standard context "claude-opus-4-5-20251101" | "claude-sonnet-4-5-20250929" @@ -490,7 +491,7 @@ fn is_consecutive_day(prev_date: &str, current_date: &str) -> bool { } } -// Pricing as of February 2026 +// Pricing as of May 2026 // https://platform.claude.com/docs/en/about-claude/models/overview // Cache pricing: https://platform.claude.com/docs/en/build-with-claude/prompt-caching pub fn calculate_cost( @@ -501,14 +502,17 @@ pub fn calculate_cost( cache_read_tokens: Option, ) -> f64 { let (input_price_per_million, output_price_per_million) = match model { - // Current generation (Claude 4.6) - "claude-opus-4-6" => (5.0, 25.0), + // Current generation (Claude 4.7/4.6/4.5) + "claude-opus-4-7" => (5.0, 25.0), "claude-sonnet-4-6" => (3.0, 15.0), + "claude-haiku-4-5-20251001" => (1.0, 5.0), + + // Previous generation (Claude 4.6) + "claude-opus-4-6" => (5.0, 25.0), // Previous generation (Claude 4.5) "claude-opus-4-5-20251101" => (5.0, 25.0), "claude-sonnet-4-5-20250929" => (3.0, 15.0), - "claude-haiku-4-5-20251001" => (1.0, 5.0), // Previous generation (Claude 4.x) "claude-opus-4-1-20250805" => (15.0, 75.0), @@ -681,6 +685,15 @@ mod tests { assert!((cost - 0.165).abs() < 0.0001); } + #[test] + fn test_cost_calculation_opus_47() { + let cost = calculate_cost(1000, 2000, "claude-opus-4-7", None, None); + // Opus 4.7 pricing: $5/MTok input, $25/MTok output + // 1000 input tokens = $0.005, 2000 output tokens = $0.05 + // Total = $0.055 + assert!((cost - 0.055).abs() < 0.0001); + } + #[test] fn test_cost_calculation_opus_45() { let cost = calculate_cost(1000, 2000, "claude-opus-4-5-20251101", None, None); @@ -1019,6 +1032,16 @@ mod tests { // Context Window Tracking tests // ===================== + #[test] + fn test_context_window_limit_opus_47() { + assert_eq!(get_context_window_limit("claude-opus-4-7"), 1_000_000); + } + + #[test] + fn test_context_window_limit_opus_46() { + assert_eq!(get_context_window_limit("claude-opus-4-6"), 1_000_000); + } + #[test] fn test_context_window_limit_claude_4() { assert_eq!(get_context_window_limit("claude-opus-4-5-20251101"), 200_000); diff --git a/src/lib/components/ConfigSidebar.svelte b/src/lib/components/ConfigSidebar.svelte index 9b2877e..d057762 100644 --- a/src/lib/components/ConfigSidebar.svelte +++ b/src/lib/components/ConfigSidebar.svelte @@ -144,17 +144,20 @@ const availableModels = [ { value: "", label: "Default (from ~/.claude)" }, - // Current generation (Claude 4.6) - { value: "claude-opus-4-6", label: "Claude Opus 4.6 (Most Capable)" }, + // Current generation (Claude 4.7/4.6/4.5) + { value: "claude-opus-4-7", label: "Claude Opus 4.7 (Most Capable)" }, { value: "claude-sonnet-4-6", label: "Claude Sonnet 4.6 (Recommended)" }, + { value: "claude-haiku-4-5-20251001", label: "Claude Haiku 4.5 (Fast & Cheap)" }, + // Previous generation (Claude 4.6) + { value: "claude-opus-4-6", label: "Claude Opus 4.6" }, // Previous generation (Claude 4.5) { value: "claude-sonnet-4-5-20250929", label: "Claude Sonnet 4.5" }, - { value: "claude-haiku-4-5-20251001", label: "Claude Haiku 4.5 (Fast & Cheap)" }, { value: "claude-opus-4-5-20251101", label: "Claude Opus 4.5" }, // Previous generation (Claude 4.x) { value: "claude-opus-4-1-20250805", label: "Claude Opus 4.1" }, - { value: "claude-sonnet-4-20250514", label: "Claude Sonnet 4" }, - { value: "claude-opus-4-20250514", label: "Claude Opus 4" }, + // Deprecated — retire June 15, 2026 + { value: "claude-sonnet-4-20250514", label: "Claude Sonnet 4 (Deprecated)" }, + { value: "claude-opus-4-20250514", label: "Claude Opus 4 (Deprecated)" }, ]; const commonTools = [ diff --git a/src/lib/stores/stats.ts b/src/lib/stores/stats.ts index 46d18cc..0eed746 100644 --- a/src/lib/stores/stats.ts +++ b/src/lib/stores/stats.ts @@ -10,13 +10,15 @@ export type BudgetType = "token" | "cost"; // Model pricing (per million tokens) - keep in sync with stats.rs // Source: https://platform.claude.com/docs/en/about-claude/models/overview export const MODEL_PRICING: Record = { - // Current generation (Claude 4.6) - "claude-opus-4-6": { input: 5.0, output: 25.0 }, + // Current generation (Claude 4.7/4.6/4.5) + "claude-opus-4-7": { input: 5.0, output: 25.0 }, "claude-sonnet-4-6": { input: 3.0, output: 15.0 }, + "claude-haiku-4-5-20251001": { input: 1.0, output: 5.0 }, + // Previous generation (Claude 4.6) + "claude-opus-4-6": { input: 5.0, output: 25.0 }, // Previous generation (Claude 4.5) "claude-opus-4-5-20251101": { input: 5.0, output: 25.0 }, "claude-sonnet-4-5-20250929": { input: 3.0, output: 15.0 }, - "claude-haiku-4-5-20251001": { input: 1.0, output: 5.0 }, // Previous generation (Claude 4.x) "claude-opus-4-1-20250805": { input: 15.0, output: 75.0 }, "claude-opus-4-20250514": { input: 15.0, output: 75.0 }, -- 2.52.0 From 3f57937d54d08c8d17886c6ea1f24646d2a58204 Mon Sep 17 00:00:00 2001 From: Hikari Date: Wed, 6 May 2026 13:37:13 -0700 Subject: [PATCH 2/7] feat: expose effort level setting in UI (#269) Adds `--effort ` CLI flag support with a dropdown selector in the config sidebar. Valid options are low, medium, high, xhigh (Opus 4.7 only), and max. --- src-tauri/src/config.rs | 12 +++++++++++ src-tauri/src/wsl_bridge.rs | 15 +++++++++++++ src/lib/commands/slashCommands.ts | 2 ++ src/lib/components/ConfigSidebar.svelte | 24 +++++++++++++++++++++ src/lib/components/ElicitationModal.svelte | 1 + src/lib/components/InputBar.svelte | 1 + src/lib/components/PermissionModal.svelte | 1 + src/lib/components/StatusBar.svelte | 3 +++ src/lib/components/TaskLoopPanel.svelte | 1 + src/lib/components/UserQuestionModal.svelte | 1 + src/lib/stores/config.test.ts | 3 +++ src/lib/stores/config.ts | 3 +++ 12 files changed, 67 insertions(+) diff --git a/src-tauri/src/config.rs b/src-tauri/src/config.rs index 9ca2af7..157aec3 100644 --- a/src-tauri/src/config.rs +++ b/src-tauri/src/config.rs @@ -70,6 +70,11 @@ pub struct ClaudeStartOptions { /// Sets `ANTHROPIC_CUSTOM_MODEL_OPTION` env var for custom model providers (v2.1.81+). #[serde(default)] pub custom_model_option: Option, + + /// Passes `--effort ` to set the effort level (v2.1.111+). + /// Valid values: "low", "medium", "high", "xhigh" (Opus 4.7 only), "max". None uses CLI default. + #[serde(default)] + pub effort_level: Option, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -236,6 +241,11 @@ pub struct HikariConfig { /// Sets `ANTHROPIC_CUSTOM_MODEL_OPTION` env var for custom model providers (v2.1.81+). #[serde(default)] pub custom_model_option: Option, + + /// Passes `--effort ` to set the effort level (v2.1.111+). + /// Valid values: "low", "medium", "high", "xhigh" (Opus 4.7 only), "max". None uses CLI default. + #[serde(default)] + pub effort_level: Option, } impl Default for HikariConfig { @@ -291,6 +301,7 @@ impl Default for HikariConfig { bare_mode: false, show_clear_context_on_plan_accept: true, custom_model_option: None, + effort_level: None, } } } @@ -508,6 +519,7 @@ mod tests { bare_mode: false, show_clear_context_on_plan_accept: true, custom_model_option: None, + effort_level: None, }; let json = serde_json::to_string(&config).unwrap(); diff --git a/src-tauri/src/wsl_bridge.rs b/src-tauri/src/wsl_bridge.rs index 4197fdf..2267af2 100644 --- a/src-tauri/src/wsl_bridge.rs +++ b/src-tauri/src/wsl_bridge.rs @@ -308,6 +308,14 @@ impl WslBridge { cmd.arg("--bare"); } + // Add effort level if specified (v2.1.111+) + if let Some(ref level) = options.effort_level { + if !level.is_empty() { + cmd.arg("--effort"); + cmd.arg(level); + } + } + // Pass combined settings via --settings flag if any settings are specified { let has_memory_dir = options @@ -532,6 +540,13 @@ impl WslBridge { claude_cmd.push_str(" --bare"); } + // Add effort level if specified (v2.1.111+) + if let Some(ref level) = options.effort_level { + if !level.is_empty() { + claude_cmd.push_str(&format!(" --effort {}", level)); + } + } + // Pass combined settings via --settings flag if any settings are specified { let has_memory_dir = options diff --git a/src/lib/commands/slashCommands.ts b/src/lib/commands/slashCommands.ts index 4bef72e..a41d921 100644 --- a/src/lib/commands/slashCommands.ts +++ b/src/lib/commands/slashCommands.ts @@ -77,6 +77,7 @@ async function changeDirectory(path: string): Promise { bare_mode: config.bare_mode ?? false, show_clear_context_on_plan_accept: config.show_clear_context_on_plan_accept ?? true, custom_model_option: config.custom_model_option || null, + effort_level: config.effort_level || null, }, }); @@ -164,6 +165,7 @@ async function startNewConversation(): Promise { bare_mode: config.bare_mode ?? false, show_clear_context_on_plan_accept: config.show_clear_context_on_plan_accept ?? true, custom_model_option: config.custom_model_option || null, + effort_level: config.effort_level || null, }, }); diff --git a/src/lib/components/ConfigSidebar.svelte b/src/lib/components/ConfigSidebar.svelte index d057762..eb34cf5 100644 --- a/src/lib/components/ConfigSidebar.svelte +++ b/src/lib/components/ConfigSidebar.svelte @@ -78,6 +78,7 @@ task_loop_auto_commit: false, task_loop_commit_prefix: "feat", task_loop_include_summary: false, + effort_level: null, }); let showCustomThemeEditor = $state(false); @@ -716,6 +717,29 @@

+ +
+ + +

+ Passes --effort to tune speed vs. intelligence. Requires Claude + Code v2.1.111+. +

+
+
+ +
+ + +

+ Sets ENABLE_PROMPT_CACHING_1H or + FORCE_PROMPT_CACHING_5M. Requires Claude Code v2.1.108+. +

+
+