Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 29 additions & 3 deletions rust/crates/rusty-claude-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8767,6 +8767,8 @@ impl AnthropicRuntimeClient {
let mut markdown_stream = MarkdownStreamState::default();
let mut events = Vec::new();
let mut pending_tool: Option<(String, String, String)> = None;
// 累积 reasoning_content 到 Thinking 块(修复 DeepSeek V4 reasoning_content 协议 bug)
let mut pending_thinking: Option<(String, Option<String>)> = None;
let mut block_has_thinking_summary = false;
let mut saw_stop = false;
let mut received_any_event = false;
Expand Down Expand Up @@ -8808,6 +8810,10 @@ impl AnthropicRuntimeClient {
}
}
ApiStreamEvent::ContentBlockStart(start) => {
// 特判 Thinking 块:初始化 pending_thinking(用于累积后续 ThinkingDelta)
if let OutputContentBlock::Thinking { thinking, signature } = &start.content_block {
pending_thinking = Some((thinking.clone(), signature.clone()));
}
push_output_block(
start.content_block,
out,
Expand Down Expand Up @@ -8836,13 +8842,22 @@ impl AnthropicRuntimeClient {
input.push_str(&partial_json);
}
}
ContentBlockDelta::ThinkingDelta { .. } => {
ContentBlockDelta::ThinkingDelta { thinking } => {
if !block_has_thinking_summary {
render_thinking_block_summary(out, None, false)?;
block_has_thinking_summary = true;
}
// 累积 thinking 文本到 pending_thinking(让 session 持久化能拿到)
if let Some((t, _)) = &mut pending_thinking {
t.push_str(&thinking);
}
}
ContentBlockDelta::SignatureDelta { signature } => {
// 累积 signature 到 pending_thinking
if let Some((_, sig)) = &mut pending_thinking {
sig.get_or_insert_with(String::new).push_str(&signature);
}
}
ContentBlockDelta::SignatureDelta { .. } => {}
},
ApiStreamEvent::ContentBlockStop(_) => {
block_has_thinking_summary = false;
Expand All @@ -8851,6 +8866,10 @@ impl AnthropicRuntimeClient {
.and_then(|()| out.flush())
.map_err(|error| RuntimeError::new(error.to_string()))?;
}
// 把累积的 thinking 转成 AssistantEvent::Thinking(让 build_assistant_message 写入 session)
if let Some((thinking, signature)) = pending_thinking.take() {
events.push(AssistantEvent::Thinking { thinking, signature });
}
if let Some((id, name, input)) = pending_tool.take() {
if let Some(progress_reporter) = &self.progress_reporter {
progress_reporter.mark_tool_phase(&name, &input);
Expand Down Expand Up @@ -9987,7 +10006,14 @@ fn convert_messages(messages: &[ConversationMessage]) -> Vec<InputMessage> {
ContentBlock::Text { text } => {
Some(InputContentBlock::Text { text: text.clone() })
}
ContentBlock::Thinking { .. } => None,
ContentBlock::Thinking { thinking, signature } => {
// 保留 Thinking 块:OpenAI 兼容协议会把它转成 reasoning_content 字段
// 回传给 DeepSeek V4(避免 400 "reasoning_content must be passed back" 错误)
Some(InputContentBlock::Thinking {
thinking: thinking.clone(),
signature: signature.clone(),
})
}
ContentBlock::ToolUse { id, name, input } => Some(InputContentBlock::ToolUse {
id: id.clone(),
name: name.clone(),
Expand Down