Skip to content
Closed
Show file tree
Hide file tree
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
28 changes: 21 additions & 7 deletions lib/llm/src/preprocessor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1260,13 +1260,15 @@ impl OpenAIPreprocessor {
}
Some("deepseek_r1") | Some("deepseek_v4") | Some("deepseek-v4")
| Some("deepseekv4") => {
if let Some(args) = chat_template_args {
if let Some(thinking) = args.get("thinking") {
return thinking == &serde_json::Value::Bool(false);
}
if let Some(mode) = args.get("thinking_mode").and_then(|v| v.as_str()) {
return mode == "chat";
}
if let Some(enabled) =
crate::preprocessor::prompt::thinking_bool_from_args(chat_template_args)
{
return !enabled;
}
if let Some(args) = chat_template_args
&& let Some(mode) = args.get("thinking_mode").and_then(|v| v.as_str())
{
return mode == "chat";
}
false
}
Expand Down Expand Up @@ -1875,6 +1877,18 @@ mod tests {
true,
"deepseekv4 (joined alias) + thinking_mode=chat → disabled",
),
(
Some("deepseek_v4"),
Some(&enable_thinking_false),
true,
"deepseek_v4 + enable_thinking=false → disabled (vLLM alias)",
),
(
Some("deepseek_v4"),
Some(&enable_thinking_true),
false,
"deepseek_v4 + enable_thinking=true → enabled (vLLM alias)",
),
];

for (parser, args, expected, desc) in cases {
Expand Down
20 changes: 20 additions & 0 deletions lib/llm/src/preprocessor/prompt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,26 @@ mod template;

pub use template::{ChatTemplate, ContextMixins};

/// Shared helper: extract a boolean thinking toggle from `chat_template_args`.
///
/// Reads the two equivalent keys (`thinking`, `enable_thinking` — vLLM's
/// canonical kwarg) in order and returns the first bool value found, or `None`
/// if neither key is present (or neither carries a bool). Used by the V4
/// formatter's `resolve_thinking_mode` and by the reasoning-parser gate in
/// `OpenAIPreprocessor::is_reasoning_disabled_by_request` so both paths agree
/// on the signal interpretation.
pub(crate) fn thinking_bool_from_args(
args: Option<&HashMap<String, serde_json::Value>>,
) -> Option<bool> {
let args = args?;
for key in ["thinking", "enable_thinking"] {
if let Some(v) = args.get(key).and_then(|x| x.as_bool()) {
return Some(v);
}
}
None
}

#[derive(Debug)]
pub enum TokenInput {
Single(Vec<u32>),
Expand Down
Loading
Loading