fix: sanitize compacted tool history before Anthropic dispatch#64
Open
saxyguy81 wants to merge 1 commit into
Open
fix: sanitize compacted tool history before Anthropic dispatch#64saxyguy81 wants to merge 1 commit into
saxyguy81 wants to merge 1 commit into
Conversation
This was referenced May 9, 2026
Author
|
Coordination note for reviewers: This PR is intentionally parallel to #65 and #66.
There is no intended dependency between these PRs. They can be reviewed and merged independently; if one lands first, I will rebase the others only if GitHub reports a conflict. |
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
tool_resultblocks when their matchingtool_useis no longer in the immediately preceding assistant messagetool_useblocks when the next user message no longer contains the correspondingtool_resultWhy
The earlier v0.2 sanitizer handles orphaned
tool_resultblocks, but currentmaincan still send invalid compacted histories to Anthropic:tool_useleft without a followingtool_resulttool_resultplus another orphanedtool_resultI reproduced this against current
mainwith local services:/claude/v1/messagesrequest returns 200 on bothmainand this branchtool_use:mainreturns 400 (tool_use ids were found without tool_result blocks immediately after); this branch returns 200tool_result:mainreturns 400 (unexpected tool_use_id found in tool_result blocks); this branch returns 200Notes
This supersedes #33 for the current
mainbranch. I rebased the change onto currentmainand removed the noisy/manual SDK investigation test from the older PR so this PR only contains deterministic unit/regression coverage.Validation
uv run ruff check ccproxy/llms/formatters/openai_to_anthropic/requests.py ccproxy/llms/utils/__init__.py ccproxy/llms/utils/context_truncation.py ccproxy/llms/utils/token_estimation.py ccproxy/plugins/claude_api/adapter.py ccproxy/plugins/claude_sdk/adapter.py ccproxy/streaming/deferred.py tests/test_tool_result_sanitization.py tests/plugins/claude_api/unit/test_native_anthropic_sanitization.py tests/unit/llms/test_context_window_management.py tests/unit/llms/test_truncation_creates_orphans.py tests/unit/streaming/test_deferred_stream_errors.pyuv run ruff format --check ccproxy/llms/formatters/openai_to_anthropic/requests.py ccproxy/llms/utils/__init__.py ccproxy/llms/utils/context_truncation.py ccproxy/llms/utils/token_estimation.py ccproxy/plugins/claude_api/adapter.py ccproxy/plugins/claude_sdk/adapter.py ccproxy/streaming/deferred.py tests/test_tool_result_sanitization.py tests/plugins/claude_api/unit/test_native_anthropic_sanitization.py tests/unit/llms/test_context_window_management.py tests/unit/llms/test_truncation_creates_orphans.py tests/unit/streaming/test_deferred_stream_errors.pyuv run mypy ccproxy/llms/formatters/openai_to_anthropic/requests.py ccproxy/llms/utils/__init__.py ccproxy/llms/utils/context_truncation.py ccproxy/llms/utils/token_estimation.py ccproxy/plugins/claude_api/adapter.py ccproxy/plugins/claude_sdk/adapter.py ccproxy/streaming/deferred.pyuv run python scripts/check_import_boundaries.pyuv run pytest tests/test_tool_result_sanitization.py tests/plugins/claude_api/unit/test_native_anthropic_sanitization.py tests/unit/llms/test_context_window_management.py tests/unit/llms/test_truncation_creates_orphans.py tests/unit/streaming/test_deferred_stream_errors.py(69 passed)uv run pytest --ignore=tests/plugins/copilot/integration -k 'not test_openai_chat_stream_to_anthropic_sample'(1249 passed, 6 skipped, 60 deselected, 1 warning)