Skip to content

Commit 41ce14b

Browse files
Extract wire debug format policy (#1978)
## Description Extracts opt-in Codex wire-debug formatting from `helpers.py` into `headroom.proxy.wire_debug_format_policy`. The existing helper functions now delegate to the pure policy so filename-safe event names and proxy-log previews are directly testable. Closes # ## 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 `wire_debug_format_policy.py` for safe wire-debug name fragments and compact log previews. - Kept `_safe_event_name` and `_wire_debug_preview` in `helpers.py` as compatibility delegates. - Added direct tests for unsafe-name replacement, length capping, JSON preview compaction, byte decoding/truncation, and `None` handling. - Carried forward the LiteLLM callback compatibility shim needed for current mypy on `main`. ## Testing - [x] Unit tests pass (`pytest`) - [x] Linting passes (`ruff check .`) - [x] Type checking passes (`mypy headroom`) - [x] New tests added for new functionality - [ ] Manual testing performed ### Test Output ```text python -m pytest tests\test_wire_debug_format_policy.py 5 passed in 0.19s python -m ruff check . All checks passed! python -m ruff format --check . 1095 files already formatted python -m mypy headroom --ignore-missing-imports Success: no issues found in 409 source files gitleaks protect --staged --no-banner --redact no leaks found ``` ## Real Behavior Proof - Environment: Windows, Python 3.13.13, branch `jd/architecture-slice-28`. - Exact command / steps: ran focused wire-debug format policy tests, ruff, ruff format check, mypy, and staged gitleaks scan. - Observed result: formatting policy behavior is directly covered and local lint/type/security checks pass. - Not tested: live wire-debug capture writing; this slice preserves the existing helper entry points. ## 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 N/A for this internal architecture-only refactor. The push reported existing default-branch Dependabot alerts; no staged secret leaks were found for this PR. --------- Co-authored-by: Tejas Chopra <chopratejas@gmail.com>
1 parent ec3c3cd commit 41ce14b

3 files changed

Lines changed: 72 additions & 18 deletions

File tree

headroom/proxy/helpers.py

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,12 @@
2424

2525
from headroom import paths as _paths
2626
from headroom._subprocess import run
27-
from headroom.proxy import request_limit_policy, sse_byte_buffer_policy, wire_debug_redaction_policy
27+
from headroom.proxy import (
28+
request_limit_policy,
29+
sse_byte_buffer_policy,
30+
wire_debug_format_policy,
31+
wire_debug_redaction_policy,
32+
)
2833
from headroom.proxy.body_forwarding import (
2934
BodyMutationTracker as BodyMutationTracker, # noqa: F401 - compatibility export
3035
)
@@ -119,7 +124,7 @@ def redact_for_wire_debug(value: Any) -> Any:
119124

120125

121126
def _safe_event_name(event: str) -> str:
122-
return "".join(ch if ch.isalnum() or ch in ("-", "_") else "_" for ch in event)[:80]
127+
return wire_debug_format_policy.safe_wire_debug_name(event)
123128

124129

125130
def _wire_debug_preview(value: Any, *, max_chars: int | None = None) -> str:
@@ -130,22 +135,7 @@ def _wire_debug_preview(value: Any, *, max_chars: int | None = None) -> str:
130135
deliberate trim boundary belongs.
131136
"""
132137

133-
try:
134-
if isinstance(value, bytes):
135-
text = value.decode("utf-8", errors="replace")
136-
elif isinstance(value, str):
137-
text = value
138-
elif value is None:
139-
return ""
140-
else:
141-
text = json.dumps(value, ensure_ascii=False, default=str, separators=(",", ":"))
142-
except Exception:
143-
text = repr(value)
144-
145-
text = " ".join(text.split())
146-
if max_chars is not None and len(text) > max_chars:
147-
return text[: max_chars - 1] + "…"
148-
return text
138+
return wire_debug_format_policy.wire_debug_preview(value, max_chars=max_chars)
149139

150140

151141
def capture_codex_wire_debug(
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
"""Formatting policy for opt-in proxy wire debug artifacts."""
2+
3+
from __future__ import annotations
4+
5+
import json
6+
from typing import Any
7+
8+
WIRE_DEBUG_NAME_MAX_CHARS = 80
9+
10+
11+
def safe_wire_debug_name(value: str) -> str:
12+
"""Return a filename-safe wire-debug name fragment."""
13+
return "".join(ch if ch.isalnum() or ch in ("-", "_") else "_" for ch in value)[
14+
:WIRE_DEBUG_NAME_MAX_CHARS
15+
]
16+
17+
18+
def wire_debug_preview(value: Any, *, max_chars: int | None = None) -> str:
19+
"""Return the compact wire payload preview used in proxy logs."""
20+
try:
21+
if isinstance(value, bytes):
22+
text = value.decode("utf-8", errors="replace")
23+
elif isinstance(value, str):
24+
text = value
25+
elif value is None:
26+
return ""
27+
else:
28+
text = json.dumps(value, ensure_ascii=False, default=str, separators=(",", ":"))
29+
except Exception:
30+
text = repr(value)
31+
32+
text = " ".join(text.split())
33+
if max_chars is not None and len(text) > max_chars:
34+
return text[: max_chars - 1] + "…"
35+
return text
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
from __future__ import annotations
2+
3+
from headroom.proxy.wire_debug_format_policy import (
4+
WIRE_DEBUG_NAME_MAX_CHARS,
5+
safe_wire_debug_name,
6+
wire_debug_preview,
7+
)
8+
9+
10+
def test_safe_wire_debug_name_replaces_path_unsafe_characters() -> None:
11+
assert safe_wire_debug_name("req/id:with spaces") == "req_id_with_spaces"
12+
13+
14+
def test_safe_wire_debug_name_caps_length() -> None:
15+
assert safe_wire_debug_name("a" * 200) == "a" * WIRE_DEBUG_NAME_MAX_CHARS
16+
17+
18+
def test_wire_debug_preview_compacts_json_like_values() -> None:
19+
preview = wire_debug_preview({"message": "hello\nworld", "count": 2})
20+
21+
assert preview == '{"message":"hello\\nworld","count":2}'
22+
23+
24+
def test_wire_debug_preview_decodes_bytes_and_truncates() -> None:
25+
assert wire_debug_preview(b"hello world", max_chars=8) == "hello w…"
26+
27+
28+
def test_wire_debug_preview_returns_empty_string_for_none() -> None:
29+
assert wire_debug_preview(None) == ""

0 commit comments

Comments
 (0)