Avoid false OpenAI stream failures on completed responses - #272
Merged
Conversation
The Responses streaming path treated any stream that ended without response.completed as a hard runtime error, including cancel/incomplete cases that already carried usable partial state. Accept response.incomplete, synthesize partial terminal responses when needed, and cover the behavior with focused regressions. Constraint: keep provider-specific handling inside spoon-core and preserve existing streaming callbacks and metadata. Rejected: surfacing the failure to spoon-bot as a generic runtime error; clearing partial output on incomplete streams. Confidence: high Scope-risk: medium Reversibility: high Directive: incomplete OpenAI Responses streams should degrade gracefully instead of poisoning agent control flow. Tested: python -m pytest tests/test_tool_streaming_output.py::test_openai_chat_with_tools_accepts_response_incomplete_terminal_event tests/test_tool_streaming_output.py::test_openai_chat_with_tools_falls_back_to_streamed_tool_call_when_terminal_event_is_missing tests/test_tool_streaming_output.py::test_openai_chat_stream_uses_responses_reasoning_summary_when_effort_requested -q Not-tested: full spoon-core suite Related: OpenAI Responses stream cancel and incomplete handling
Context: OpenAI Responses can report a completed native terminal state while the canonical finish reason is stop, and text attached to tool-call turns should not be surfaced as final user-facing content. Constraint: Keep provider-specific behavior inside core and avoid prompt-routing or bot-side hardcoding. Rejected: Treating pre-tool text as normal content, because it can leak stale commentary into final responses when tools are still pending. Confidence: Medium-high; covered by focused agent integration tests. Scope-risk: Limited to ToolCallAgent streaming classification, SpoonReactAI custom prompt preservation, and related tests. Reversibility: Revert this commit to restore prior terminal-state and streaming behavior. Directive: Do not commit local config, build artifacts, or secrets. Tested: python -m py_compile spoon_ai\\agents\\toolcall.py spoon_ai\\agents\\spoon_react.py; python -m pytest tests/test_agent_llm_integration.py -q Not-tested: Full suite and live spoon-bot websocket replay. Related: spoon-bot interrupt/session testing surfaced empty or polluted response risk.
…mplete-stream # Conflicts: # spoon_ai/agents/toolcall.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
completedas a successful terminal state when it maps to canonicalstopthinking/pre_toolinstead of final contentSpoonReactAIprompts across initialization and keep integration tests isolated from local.envTests
python -m py_compile spoon_ai\agents\toolcall.py spoon_ai\agents\spoon_react.pypython -m pytest tests/test_agent_llm_integration.py -qNot included
dist-local/pr-body-core.md