fix: emit final response after stream parse fallback#8367
Conversation
There was a problem hiding this comment.
Code Review
This pull request updates the OpenAI stream query logic to accumulate streamed text, reasoning parts, and usage. If an exception occurs during stream processing, the method now yields a final fallback LLMResponse containing the accumulated content instead of silently returning. A unit test has been added to verify this behavior. The reviewer suggests initializing result_chain with a MessageChain in the fallback LLMResponse to avoid potential inconsistencies or errors in downstream handlers that expect a valid MessageChain object.
| yield LLMResponse( | ||
| "assistant", | ||
| completion_text="".join(streamed_text_parts), | ||
| reasoning_content="".join(streamed_reasoning_parts) or None, | ||
| usage=latest_usage, | ||
| ) |
There was a problem hiding this comment.
In AstrBot, LLMResponse objects typically expect result_chain to be populated with a MessageChain when text content is present (as seen in _parse_openai_completion and the chunk-yielding logic). Yielding an LLMResponse with result_chain=None and only completion_text set can cause inconsistency or potential AttributeErrors in downstream handlers that expect a valid MessageChain object.
It is highly recommended to initialize result_chain using MessageChain().message(...) when yielding the fallback response.
| yield LLMResponse( | |
| "assistant", | |
| completion_text="".join(streamed_text_parts), | |
| reasoning_content="".join(streamed_reasoning_parts) or None, | |
| usage=latest_usage, | |
| ) | |
| yield LLMResponse( | |
| "assistant", | |
| result_chain=MessageChain().message("".join(streamed_text_parts)) if streamed_text_parts else None, | |
| reasoning_content="".join(streamed_reasoning_parts) or None, | |
| usage=latest_usage, | |
| ) |
There was a problem hiding this comment.
Hey - I've left some high level feedback:
- In the
get_final_completionerror handler, consider usinglogger.exceptioninstead oflogger.errorso the traceback is preserved when re-raising the parsing error and debugging downstream failures is easier.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In the `get_final_completion` error handler, consider using `logger.exception` instead of `logger.error` so the traceback is preserved when re-raising the parsing error and debugging downstream failures is easier.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
|
Closing this PR because the root cause was misattributed. The observed failure is in the Multica runtime completion/comment-delivery contract, not in AstrBot's OpenAI provider. |
Summary
Fixes #8366
Tests
uv run pytest tests/test_openai_source.pyuv run ruff check astrbot/core/provider/sources/openai_source.py tests/test_openai_source.pySummary by Sourcery
Ensure OpenAI-compatible streaming queries emit a usable final assistant response when final completion parsing fails while preserving streamed output.
Bug Fixes:
Enhancements:
Tests: