- Add MemoryToolAdapter for unified memory across providers
- Anthropic: Uses native memory tool (memory_20250818) for subscription safety
- OpenAI/Gemini/Others: Uses function calling format
- All providers share the same semantic vector store backend
- Simplify CLI to single --memory flag with auto-detection
- Add proper resource cleanup (close methods) to fix test isolation
- Update README with memory documentation
Root Cause:
The `find_tool_units()` function in `parser.py` only detected OpenAI
format tool calls (assistant.tool_calls + role="tool" messages), not
Anthropic format (assistant.content[type=tool_use] + user.content[type=tool_result]).
This caused RollingWindow and IntelligentContext transforms to treat
Anthropic tool_use and tool_result as separate, independently droppable
messages. When context needed to be trimmed, the assistant message with
tool_use could be dropped while keeping the user message with tool_result,
creating orphaned tool_result blocks.
When sent to the Anthropic API, this produces the error:
"unexpected tool_use_id found in tool_result blocks"
Changes:
1. parser.py: Extended `find_tool_units()` to detect Anthropic format:
- Scan user messages for content blocks with type="tool_result"
- Scan assistant messages for content blocks with type="tool_use"
- Map tool_use_id to corresponding response message indices
2. rolling_window.py: Extended `_get_protected_indices()` to protect
Anthropic format tool pairs:
- Detect tool_use blocks in assistant.content
- Find and protect matching user messages with tool_result blocks
3. tests/test_parser.py: Added 4 new tests for Anthropic format:
- test_anthropic_format_tool_use_and_result
- test_anthropic_format_multiple_tool_uses
- test_anthropic_format_orphaned_tool_result
- test_mixed_openai_and_anthropic_formats
Test Results: 82 passed (including 4 new Anthropic format tests)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>