- _add_reaction now returns reaction_id on success
- Add _remove_reaction_sync and _remove_reaction methods
- Remove reaction when stream ends to clear processing indicator
- Store reaction_id in metadata for later removal
Fixes#2591
The "nanobot is thinking..." spinner was printing ANSI escape codes
literally in some terminals, causing garbled output like:
?[2K?[32m⠧?[0m ?[2mnanobot is thinking...?[0m
Root causes:
1. Console created without force_terminal=True, so Rich couldn't
reliably detect terminal capabilities
2. Spinner continued running during user input prompt, conflicting
with prompt_toolkit
Changes:
- Set force_terminal=True in _make_console() for proper ANSI handling
- Add stop_for_input() method to StreamRenderer
- Call stop_for_input() before reading user input in interactive mode
- Add tests for the new functionality
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>
The test test_openai_compat_strips_message_level_reasoning_fields was
added in fbedf7a and incorrectly asserted that reasoning_content and
extra_content should be stripped from messages. This contradicts the
intent of b5302b6 which explicitly added these fields to _ALLOWED_MSG_KEYS
to preserve them through sanitization.
Rename the test and fix assertions to match the original design intent:
reasoning_content and extra_content at message level should be preserved,
and extra_content inside tool_calls should also be preserved.
Signed-off-by: Lingao Meng <menglingao@xiaomi.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>
Use dream_log and dream_restore in Telegram's bot command menu so command registration succeeds, while still accepting the original dream-log and dream-restore forms in chat. Keep the internal command routing unchanged and add coverage for the alias normalization path.
- Added Jinja2 template support for various agent responses, including identity, skills, and memory consolidation.
- Introduced new templates for evaluating notifications, handling subagent announcements, and managing platform policies.
- Updated the agent context and memory modules to utilize the new templating system for improved readability and maintainability.
- Added a new dependency on Jinja2 in pyproject.toml.
Add regression tests for the non-streaming (_parse dict branch) and
streaming (_parse_chunks dict and SDK-object branches) paths that extract
reasoning_content, ensuring the field is populated when present and None
when absent.
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>