refactor(proxy): extract tool definition serialization (#1998)

## Description

Extracts canonical memory-tool definition byte serialization from
`headroom.proxy.helpers` into a focused pure module. The existing helper
function remains as a compatibility wrapper for sticky memory tool and
CCR replay code.

## Type of Change

- [ ] Bug fix (non-breaking change that fixes an issue)
- [ ] New feature (non-breaking change that adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to change)
- [ ] Documentation update
- [ ] Performance improvement
- [x] Code refactoring (no functional changes)

## Changes Made

- Added `headroom.proxy.tool_definition_serialization` for deterministic
compact UTF-8 tool definition serialization.
- Kept `helpers.serialize_tool_definition_canonical()` as a
compatibility wrapper.
- Added direct unit tests for compact separators, Unicode preservation,
insertion-order byte stability, and parity with the existing body
canonicalizer.

## Testing

- [x] Unit tests pass (`pytest`)
- [x] Linting passes (`ruff check`)
- [x] Formatting passes (`ruff format --check`)
- [x] New tests added for new functionality
- [ ] Manual testing performed

### Test Output

```text
uv run pytest tests/test_tool_definition_serialization.py tests/test_ccr_tool_always_on.py tests/test_memory_tool_session_sticky.py tests/test_proxy_byte_faithful_forwarding.py -q
85 passed, 1 warning in 2.47s

uvx --from ruff==0.15.17 ruff check headroom/proxy/helpers.py headroom/proxy/tool_definition_serialization.py tests/test_tool_definition_serialization.py --output-format concise
All checks passed!

uvx --from ruff==0.15.17 ruff format --check headroom/proxy/helpers.py headroom/proxy/tool_definition_serialization.py tests/test_tool_definition_serialization.py
3 files already formatted
```

## Real Behavior Proof

- Environment: Windows, Python 3.13.x
- Exact command / steps: Ran direct serializer tests plus CCR always-on,
sticky memory tool, and proxy byte-faithful forwarding regression
coverage; then checked the touched files with the CI-pinned Ruff
version.
- Observed result: Serializer byte contract remains directly covered
while existing sticky replay and byte-faithful proxy behavior stay
green.
- Not tested: Full repository pytest suite locally; GitHub CI is green
for the current head.

## Review Readiness

- [x] I have performed a self-review
- [x] This PR is ready for human review

## Checklist

- [x] My code follows the project's style guidelines
- [x] I have performed a self-review of my code
- [x] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
- [ ] I have updated the CHANGELOG.md if applicable

## Screenshots (if applicable)

N/A

## Additional Notes

Documentation and changelog updates are not applicable for this internal
refactor. The current head is mergeable and GitHub checks are green.

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This commit is contained in:
JD Davis 2026-07-15 18:36:52 +00:00 committed by GitHub
parent 96bc4cd128
commit ad6ab48cbb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 55 additions and 2 deletions

View file

@ -64,7 +64,9 @@ from headroom.proxy.body_forwarding import (
from headroom.proxy.body_forwarding import (
prepare_outbound_body_bytes as prepare_outbound_body_bytes, # noqa: F401 - compatibility export
)
from headroom.proxy.body_forwarding import serialize_body_canonical
from headroom.proxy.body_forwarding import (
serialize_body_canonical as serialize_body_canonical, # noqa: F401 - compatibility export
)
from headroom.proxy.ccr_golden_policy import (
create_fresh_ccr_tool_definition,
replay_golden_ccr_tool_definition,
@ -88,6 +90,9 @@ from headroom.proxy.memory_golden_policy import (
replay_golden_memory_tool_definition,
serialize_memory_tool_definition_canonical,
)
from headroom.proxy.tool_definition_serialization import (
serialize_tool_definition_canonical as _serialize_tool_definition_canonical,
)
from headroom.proxy.tool_injection_config import (
ToolInjectionStickyMode,
)
@ -1856,7 +1861,7 @@ def serialize_tool_definition_canonical(tool_definition: dict[str, Any]) -> byte
follow-up turn must inject byte-equal output to keep the prefix
cache hot.
"""
return serialize_body_canonical(tool_definition)
return _serialize_tool_definition_canonical(tool_definition)
class SessionToolTracker(_SessionToolTracker):

View file

@ -0,0 +1,16 @@
"""Canonical byte serialization for sticky memory tool definitions."""
from __future__ import annotations
import json
from typing import Any
def serialize_tool_definition_canonical(tool_definition: dict[str, Any]) -> bytes:
"""Serialize a tool definition to deterministic compact UTF-8 JSON bytes."""
return json.dumps(
tool_definition,
ensure_ascii=False,
separators=(",", ":"),
).encode("utf-8")

View file

@ -0,0 +1,32 @@
from __future__ import annotations
from headroom.proxy.body_forwarding import serialize_body_canonical
from headroom.proxy.tool_definition_serialization import serialize_tool_definition_canonical
def test_serialize_tool_definition_canonical_uses_compact_separators() -> None:
tool = {"name": "memory_save", "input_schema": {"type": "object"}}
assert serialize_tool_definition_canonical(tool) == (
b'{"name":"memory_save","input_schema":{"type":"object"}}'
)
def test_serialize_tool_definition_canonical_preserves_unicode() -> None:
tool = {"name": "memory_save", "description": "remember cafe notes"}
tool["description"] = "remember caf\u00e9 notes"
assert b"caf\xc3\xa9" in serialize_tool_definition_canonical(tool)
def test_serialize_tool_definition_canonical_preserves_insertion_order() -> None:
first = {"name": "memory_save", "description": "desc"}
second = {"description": "desc", "name": "memory_save"}
assert serialize_tool_definition_canonical(first) != serialize_tool_definition_canonical(second)
def test_serialize_tool_definition_canonical_matches_body_canonicalizer() -> None:
tool = {"name": "memory_save", "input_schema": {"type": "object"}}
assert serialize_tool_definition_canonical(tool) == serialize_body_canonical(tool)