Closes MemTensor#2149
Adds enable_thinking configuration parameter for OpenAI-compatible
providers (qwen, deepseek, minimax) to control whether the model
produces <think> reasoning blocks before the actual response.
Changes:
- Added enable_thinking field (bool | None) to OpenAILLMConfig
- None (default): preserve provider's default behavior
- True: explicitly enable thinking mode
- False: explicitly disable thinking mode (prevents JSON breaking)
- OpenAILLM.generate / generate_stream now pass enable_thinking
to API calls when configured, via enable_thinking body param
- AzureLLM.generate / generate_stream also support the parameter
(gated by getattr for backward compatibility with older configs)
- Per-call override supported via kwargs (enable_thinking=True/False)
- Added tests covering default, config-level, and kwarg-level
enable_thinking behavior in test_enable_thinking.py
This is a non-breaking change: when enable_thinking is unset,
request bodies are identical to previous versions.
Test: python3 -m py_compile src/memos/configs/llm.py
Test: python3 -m py_compile src/memos/llms/openai.py
Test: python3 -m py_compile tests/llms/test_enable_thinking.py
Description
Fixes #2149
Adds
enable_thinkingconfiguration parameter for OpenAI-compatible providers (Qwen, DeepSeek, MiniMax, etc.) to control whether the model produces<think>reasoning blocks before the actual response.Models like Qwen3 and DeepSeek-R1 support an
enable_thinkingparameter in the chat completion body. When thinking is enabled, output contains<think>...</think>tags before the actual response, which can break JSON parsing in structured-output tasks (capture summarization, L3 abstraction, skill crystallization).Changes
enable_thinkingfield toOpenAILLMConfig—bool | Nonedefaulting toNone:None(default): provider's default behavior preserved (backward compatible)True: explicitly passenable_thinking=trueFalse: explicitly passenable_thinking=false(protects JSON output tasks)OpenAILLM.generate()— extracted_build_request_body()helper; passesenable_thinkingto request body when configuredOpenAILLM.generate_stream()— sameenable_thinkinginjectionAzureLLM.generate() / generate_stream()— addedgetattr-gated support forenable_thinking(future-proof)kwargs["enable_thinking"]takes precedence over config-level settingtests/llms/test_enable_thinking.py: default, config-level, kwarg-level, False-value, param-preservationBefore (provider default)
After (configurable)
Type of change
How Has This Been Tested?
python3 -m py_compile src/memos/configs/llm.pypython3 -m py_compile src/memos/llms/openai.pypython3 -m py_compile tests/llms/test_enable_thinking.pyenable_thinking=None→ param omitted;True/False→ param present; kwarg override winsenable_thinkingis not set (backward compatible)Checklist