diff --git a/Cargo.lock b/Cargo.lock index ae44fa05..3f292122 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1080,7 +1080,7 @@ dependencies = [ [[package]] name = "deepseek-agent" -version = "0.8.13" +version = "0.8.14" dependencies = [ "deepseek-config", "serde", @@ -1088,7 +1088,7 @@ dependencies = [ [[package]] name = "deepseek-app-server" -version = "0.8.13" +version = "0.8.14" dependencies = [ "anyhow", "axum", @@ -1110,7 +1110,7 @@ dependencies = [ [[package]] name = "deepseek-config" -version = "0.8.13" +version = "0.8.14" dependencies = [ "anyhow", "deepseek-secrets", @@ -1122,7 +1122,7 @@ dependencies = [ [[package]] name = "deepseek-core" -version = "0.8.13" +version = "0.8.14" dependencies = [ "anyhow", "chrono", @@ -1140,7 +1140,7 @@ dependencies = [ [[package]] name = "deepseek-execpolicy" -version = "0.8.13" +version = "0.8.14" dependencies = [ "anyhow", "deepseek-protocol", @@ -1149,7 +1149,7 @@ dependencies = [ [[package]] name = "deepseek-hooks" -version = "0.8.13" +version = "0.8.14" dependencies = [ "anyhow", "async-trait", @@ -1163,7 +1163,7 @@ dependencies = [ [[package]] name = "deepseek-mcp" -version = "0.8.13" +version = "0.8.14" dependencies = [ "anyhow", "serde", @@ -1172,7 +1172,7 @@ dependencies = [ [[package]] name = "deepseek-protocol" -version = "0.8.13" +version = "0.8.14" dependencies = [ "serde", "serde_json", @@ -1180,7 +1180,7 @@ dependencies = [ [[package]] name = "deepseek-secrets" -version = "0.8.13" +version = "0.8.14" dependencies = [ "dirs", "keyring", @@ -1193,7 +1193,7 @@ dependencies = [ [[package]] name = "deepseek-state" -version = "0.8.13" +version = "0.8.14" dependencies = [ "anyhow", "chrono", @@ -1205,7 +1205,7 @@ dependencies = [ [[package]] name = "deepseek-tools" -version = "0.8.13" +version = "0.8.14" dependencies = [ "anyhow", "async-trait", @@ -1218,7 +1218,7 @@ dependencies = [ [[package]] name = "deepseek-tui" -version = "0.8.13" +version = "0.8.14" dependencies = [ "anyhow", "arboard", @@ -1277,7 +1277,7 @@ dependencies = [ [[package]] name = "deepseek-tui-cli" -version = "0.8.13" +version = "0.8.14" dependencies = [ "anyhow", "chrono", @@ -1301,7 +1301,7 @@ dependencies = [ [[package]] name = "deepseek-tui-core" -version = "0.8.13" +version = "0.8.14" [[package]] name = "deranged" diff --git a/Cargo.toml b/Cargo.toml index e62bba41..5ce0111d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ default-members = ["crates/cli", "crates/app-server", "crates/tui"] resolver = "2" [workspace.package] -version = "0.8.13" +version = "0.8.14" edition = "2024" # Rust 1.88 stabilized `let_chains` in `if`/`while` conditions, which the # codebase relies on extensively. Cargo enforces this so users on older diff --git a/crates/agent/Cargo.toml b/crates/agent/Cargo.toml index f206a820..7a16bd30 100644 --- a/crates/agent/Cargo.toml +++ b/crates/agent/Cargo.toml @@ -7,5 +7,5 @@ repository.workspace = true description = "Model/provider registry and fallback strategy for DeepSeek workspace architecture" [dependencies] -deepseek-config = { path = "../config", version = "0.8.13" } +deepseek-config = { path = "../config", version = "0.8.14" } serde.workspace = true diff --git a/crates/app-server/Cargo.toml b/crates/app-server/Cargo.toml index 9c547e6a..498ca9a0 100644 --- a/crates/app-server/Cargo.toml +++ b/crates/app-server/Cargo.toml @@ -10,15 +10,15 @@ description = "Codex-style app-server transport for DeepSeek workspace architect anyhow.workspace = true axum.workspace = true clap.workspace = true -deepseek-agent = { path = "../agent", version = "0.8.13" } -deepseek-config = { path = "../config", version = "0.8.13" } -deepseek-core = { path = "../core", version = "0.8.13" } -deepseek-execpolicy = { path = "../execpolicy", version = "0.8.13" } -deepseek-hooks = { path = "../hooks", version = "0.8.13" } -deepseek-mcp = { path = "../mcp", version = "0.8.13" } -deepseek-protocol = { path = "../protocol", version = "0.8.13" } -deepseek-state = { path = "../state", version = "0.8.13" } -deepseek-tools = { path = "../tools", version = "0.8.13" } +deepseek-agent = { path = "../agent", version = "0.8.14" } +deepseek-config = { path = "../config", version = "0.8.14" } +deepseek-core = { path = "../core", version = "0.8.14" } +deepseek-execpolicy = { path = "../execpolicy", version = "0.8.14" } +deepseek-hooks = { path = "../hooks", version = "0.8.14" } +deepseek-mcp = { path = "../mcp", version = "0.8.14" } +deepseek-protocol = { path = "../protocol", version = "0.8.14" } +deepseek-state = { path = "../state", version = "0.8.14" } +deepseek-tools = { path = "../tools", version = "0.8.14" } serde.workspace = true serde_json.workspace = true tokio.workspace = true diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index 38a82952..a2030fb3 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -14,13 +14,13 @@ path = "src/main.rs" anyhow.workspace = true clap.workspace = true clap_complete.workspace = true -deepseek-agent = { path = "../agent", version = "0.8.13" } -deepseek-app-server = { path = "../app-server", version = "0.8.13" } -deepseek-config = { path = "../config", version = "0.8.13" } -deepseek-execpolicy = { path = "../execpolicy", version = "0.8.13" } -deepseek-mcp = { path = "../mcp", version = "0.8.13" } -deepseek-secrets = { path = "../secrets", version = "0.8.13" } -deepseek-state = { path = "../state", version = "0.8.13" } +deepseek-agent = { path = "../agent", version = "0.8.14" } +deepseek-app-server = { path = "../app-server", version = "0.8.14" } +deepseek-config = { path = "../config", version = "0.8.14" } +deepseek-execpolicy = { path = "../execpolicy", version = "0.8.14" } +deepseek-mcp = { path = "../mcp", version = "0.8.14" } +deepseek-secrets = { path = "../secrets", version = "0.8.14" } +deepseek-state = { path = "../state", version = "0.8.14" } chrono.workspace = true dirs.workspace = true serde.workspace = true diff --git a/crates/config/Cargo.toml b/crates/config/Cargo.toml index bea370cd..b8481a7f 100644 --- a/crates/config/Cargo.toml +++ b/crates/config/Cargo.toml @@ -8,7 +8,7 @@ description = "Config schema and precedence model for DeepSeek workspace archite [dependencies] anyhow.workspace = true -deepseek-secrets = { path = "../secrets", version = "0.8.13" } +deepseek-secrets = { path = "../secrets", version = "0.8.14" } dirs.workspace = true serde.workspace = true toml.workspace = true diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index efc84690..4bfc7221 100644 --- a/crates/core/Cargo.toml +++ b/crates/core/Cargo.toml @@ -9,13 +9,13 @@ description = "Core runtime boundaries for DeepSeek workspace architecture" [dependencies] anyhow.workspace = true chrono.workspace = true -deepseek-agent = { path = "../agent", version = "0.8.13" } -deepseek-config = { path = "../config", version = "0.8.13" } -deepseek-execpolicy = { path = "../execpolicy", version = "0.8.13" } -deepseek-hooks = { path = "../hooks", version = "0.8.13" } -deepseek-mcp = { path = "../mcp", version = "0.8.13" } -deepseek-protocol = { path = "../protocol", version = "0.8.13" } -deepseek-state = { path = "../state", version = "0.8.13" } -deepseek-tools = { path = "../tools", version = "0.8.13" } +deepseek-agent = { path = "../agent", version = "0.8.14" } +deepseek-config = { path = "../config", version = "0.8.14" } +deepseek-execpolicy = { path = "../execpolicy", version = "0.8.14" } +deepseek-hooks = { path = "../hooks", version = "0.8.14" } +deepseek-mcp = { path = "../mcp", version = "0.8.14" } +deepseek-protocol = { path = "../protocol", version = "0.8.14" } +deepseek-state = { path = "../state", version = "0.8.14" } +deepseek-tools = { path = "../tools", version = "0.8.14" } serde_json.workspace = true uuid.workspace = true diff --git a/crates/execpolicy/Cargo.toml b/crates/execpolicy/Cargo.toml index 13922780..c0d9f3e5 100644 --- a/crates/execpolicy/Cargo.toml +++ b/crates/execpolicy/Cargo.toml @@ -8,5 +8,5 @@ description = "Execution policy and approval model parity for DeepSeek workspace [dependencies] anyhow.workspace = true -deepseek-protocol = { path = "../protocol", version = "0.8.13" } +deepseek-protocol = { path = "../protocol", version = "0.8.14" } serde.workspace = true diff --git a/crates/hooks/Cargo.toml b/crates/hooks/Cargo.toml index a62dc254..82151a5b 100644 --- a/crates/hooks/Cargo.toml +++ b/crates/hooks/Cargo.toml @@ -10,7 +10,7 @@ description = "Hook dispatch and notifications parity for DeepSeek workspace arc anyhow.workspace = true async-trait.workspace = true chrono.workspace = true -deepseek-protocol = { path = "../protocol", version = "0.8.13" } +deepseek-protocol = { path = "../protocol", version = "0.8.14" } reqwest.workspace = true serde.workspace = true serde_json.workspace = true diff --git a/crates/tools/Cargo.toml b/crates/tools/Cargo.toml index 1d131812..6318c5b6 100644 --- a/crates/tools/Cargo.toml +++ b/crates/tools/Cargo.toml @@ -9,7 +9,7 @@ description = "Tool invocation lifecycle, schema validation, and scheduler paral [dependencies] anyhow.workspace = true async-trait.workspace = true -deepseek-protocol = { path = "../protocol", version = "0.8.13" } +deepseek-protocol = { path = "../protocol", version = "0.8.14" } serde.workspace = true serde_json.workspace = true tokio.workspace = true diff --git a/crates/tui/Cargo.toml b/crates/tui/Cargo.toml index 3b544911..804832cb 100644 --- a/crates/tui/Cargo.toml +++ b/crates/tui/Cargo.toml @@ -21,8 +21,8 @@ path = "src/main.rs" [dependencies] anyhow = "1.0.100" arboard = "3.4" -deepseek-secrets = { path = "../secrets", version = "0.8.13" } -deepseek-tools = { path = "../tools", version = "0.8.13" } +deepseek-secrets = { path = "../secrets", version = "0.8.14" } +deepseek-tools = { path = "../tools", version = "0.8.14" } schemaui = { version = "0.12.0", default-features = false, optional = true } async-stream = "0.3.6" async-trait = "0.1" diff --git a/crates/tui/src/client.rs b/crates/tui/src/client.rs index b57b9c24..e0421063 100644 --- a/crates/tui/src/client.rs +++ b/crates/tui/src/client.rs @@ -806,13 +806,22 @@ pub(super) fn parse_usage(usage: Option<&Value>) -> Usage { .and_then(|u| u.get("input_tokens").or_else(|| u.get("prompt_tokens"))) .and_then(Value::as_u64) .unwrap_or(0); - let output_tokens = usage + let mut output_tokens = usage .and_then(|u| { u.get("output_tokens") .or_else(|| u.get("completion_tokens")) }) .and_then(Value::as_u64) .unwrap_or(0); + let reasoning_tokens_raw = usage + .and_then(|u| u.get("completion_tokens_details")) + .and_then(|details| details.get("reasoning_tokens")) + .and_then(Value::as_u64); + if output_tokens == 0 + && let Some(reasoning_tokens) = reasoning_tokens_raw + { + output_tokens = reasoning_tokens; + } let cached_tokens = usage .and_then(|u| u.get("prompt_tokens_details")) .and_then(|details| details.get("cached_tokens")) @@ -827,11 +836,7 @@ pub(super) fn parse_usage(usage: Option<&Value>) -> Usage { .and_then(Value::as_u64) .or_else(|| cached_tokens.map(|cached| input_tokens.saturating_sub(cached))) .map(|v| v as u32); - let reasoning_tokens = usage - .and_then(|u| u.get("completion_tokens_details")) - .and_then(|details| details.get("reasoning_tokens")) - .and_then(Value::as_u64) - .map(|v| v as u32); + let reasoning_tokens = reasoning_tokens_raw.map(|v| v as u32); let server_tool_use = usage.and_then(|u| u.get("server_tool_use")).map(|server| { let code_execution_requests = server @@ -1694,6 +1699,26 @@ mod tests { assert_eq!(usage.reasoning_tokens, Some(12)); } + #[test] + fn parse_usage_counts_reasoning_tokens_when_completion_tokens_are_zero() { + let usage = parse_usage(Some(&json!({ + "prompt_tokens": 100, + "completion_tokens": 0, + "completion_tokens_details": { + "reasoning_tokens": 12 + } + }))); + + assert_eq!(usage.input_tokens, 100); + assert_eq!(usage.output_tokens, 12); + assert_eq!(usage.reasoning_tokens, Some(12)); + assert!( + crate::pricing::calculate_turn_cost_from_usage("deepseek-v4-pro", &usage) + .expect("DeepSeek V4 Pro pricing should apply") + > 0.0 + ); + } + #[test] fn parse_usage_reads_v4_prompt_tokens_details_cached_tokens() { let usage = parse_usage(Some(&json!({ diff --git a/npm/deepseek-tui/package.json b/npm/deepseek-tui/package.json index 1a1f0d88..0b4c2ebd 100644 --- a/npm/deepseek-tui/package.json +++ b/npm/deepseek-tui/package.json @@ -1,7 +1,7 @@ { "name": "deepseek-tui", - "version": "0.8.13", - "deepseekBinaryVersion": "0.8.13", + "version": "0.8.14", + "deepseekBinaryVersion": "0.8.14", "description": "Install and run deepseek and deepseek-tui binaries from GitHub release artifacts.", "author": "Hmbown", "license": "MIT",