- Inject `thinking={"type": "enabled|disabled"}` via extra_body for
Kimi thinking-capable models (kimi-k2.5, k2.6-code-preview).
- Add _is_kimi_thinking_model helper to handle both bare slugs and
OpenRouter-style prefixed names (e.g. moonshotai/kimi-k2.5).
- reasoning_effort="minimal" maps to disabled; any other value enables it.
- Add tests for enabled/disabled states and OpenRouter prefix handling.
Ensure assistant tool-call function.arguments is always emitted as valid JSON text so strict OpenAI-compatible backends (including Alibaba code models) do not reject requests. Add regressions for dict and malformed-string argument payloads in message sanitization.
Made-with: Cursor
When a subagent result is injected with current_role="assistant",
_enforce_role_alternation drops the trailing assistant message, leaving
only the system prompt. Providers like Zhipu/GLM reject such requests
with error 1214 ("messages parameter invalid"). Now the last popped
assistant message is recovered as a user message when no user/tool
messages remain.
When a non-transient LLM error occurs with image content, the retry
mechanism strips images from a copy but never updates the original
conversation history. Subsequent iterations rebuild context from the
unmodified history, causing the same error-retry cycle to repeat
every iteration until max_iterations is reached.
Add _strip_image_content_inplace() that mutates the original message
content lists in-place after a successful no-image retry, so callers
sharing those references (e.g. the runner's conversation history)
also see the stripped version.
Keep tool-call assistant messages valid across provider sanitization and avoid trailing user-only history after model errors. This prevents follow-up requests from sending broken tool chains back to the gateway.
Resolved conflict in azure_openai_provider.py by keeping main's
Responses API implementation (role alternation not needed for the
Responses API input format).
Made-with: Cursor
- Add reasoning_content fallback from reasoning in _parse dict branch
- Add content fallback from msg.reasoning in _parse SDK object branch
- Add reasoning_content fallback in _parse SDK object branch
- Add reasoning fallback in _parse_chunks dict branch
- Add reasoning fallback in _parse_chunks SDK object branch
This ensures StepFun Plan API works correctly in both streaming and
non-streaming modes, for both dict and SDK object response formats.
StepFun Plan API returns response content in the 'reasoning' field when
the model is in thinking mode and 'content' is empty. OpenAICompatProvider
previously only checked 'content' and 'reasoning_content', missing this field.
This patch adds a fallback: if content is empty and 'reasoning' is present,
extract text from reasoning to populate content, ensuring StepFun models
(step-3.5-flash, step-3.5-flash-2603) work correctly with tool calls.
Co-authored-by: moranfong <moranfong@gmail.com>
Extends reasoning_effort to accept 'adaptive' in addition to
low/medium/high. When set, uses Anthropic's type: 'adaptive'
thinking API instead of a fixed budget, letting the model decide
when and how much to think per turn.
Also auto-enables interleaved thinking between tool calls on
claude-sonnet-4-6 and claude-opus-4-6.
Usage:
"reasoning_effort": "adaptive" in agents.defaults config
Merge the three retry-after header parsers (base, OpenAI, Anthropic)
into a single _extract_retry_after_from_headers on LLMProvider that
handles retry-after-ms, case-insensitive lookup, and HTTP date.
Remove the per-provider _parse_retry_after_headers duplicates and
their now-unused email.utils / time imports. Add test for retry-after-ms.
Made-with: Cursor
- Add byteplus and byteplus_coding_plan to thinking param providers
- Only send extra_body when reasoning_effort is explicitly set
- Use setdefault().update() to avoid clobbering existing extra_body
- Add 7 regression tests for thinking params
Made-with: Cursor
- Use import importlib.util (not bare importlib) for find_spec
- Warn and fall back to standard openai instead of crashing with
ImportError when LANGFUSE_SECRET_KEY is set but langfuse is missing
Made-with: Cursor
The streaming path in OpenAICompatProvider.chat_stream() was passing
reasoning_content deltas through on_content_delta(), causing model
internal reasoning to be displayed to the user alongside the actual
response content.
reasoning_content is already collected separately in _parse_chunks()
and stored in LLMResponse.reasoning_content for session history.
It should never be forwarded to the user-facing stream.
Enable GPT-5 models (gpt-5, gpt-5.4, gpt-5.4-mini, etc.) to work
correctly with the OpenAI-compatible provider by:
- Setting `supports_max_completion_tokens=True` on the OpenAI provider
spec so `max_completion_tokens` is sent instead of the deprecated
`max_tokens` parameter that GPT-5 rejects.
- Adding `_supports_temperature()` to conditionally omit the
`temperature` parameter for reasoning models (o1/o3/o4) and when
`reasoning_effort` is active, matching the existing Azure provider
behaviour.
Both changes are backward-compatible: older GPT-4 models continue to
work as before since `max_completion_tokens` is accepted by all recent
OpenAI models and temperature is only omitted when reasoning is active.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
reasoning_content and extra_content were accidentally dropped from
_ALLOWED_MSG_KEYS.
Also fix session/manager.py to include reasoning_content when building
LLM messages from session history, so the field is not lost across
turns.
Without this fix, providers such as Kimi, emit reasoning_content in
assistant messages will have it stripped on the next request, breaking
multi-turn thinking mode.
Fixes: https://github.com/HKUDS/nanobot/issues/2777
Signed-off-by: Lingao Meng <menglingao@xiaomi.com>
Extract reasoning_content from both non-streaming and streaming responses
in OpenAICompatProvider. Accumulate chunks during streaming and merge into
LLMResponse, enabling reasoning chain display for models like MiMo and DeepSeek-R1.
Signed-off-by: Lingao Meng <menglingao@xiaomi.com>
Register xiaomi_mimo as an OpenAI-compatible provider with its API base URL,
add xiaomi_mimo to the provider config schema, and document it in README.
Signed-off-by: Lingao Meng <menglingao@xiaomi.com>