mirror of
https://github.com/headroomlabs-ai/headroom.git
synced 2026-08-27 14:17:10 -04:00
Merge 8a7e96ef6c into d30e3e052d
This commit is contained in:
commit
e7a1a528b4
2 changed files with 100 additions and 0 deletions
|
|
@ -418,6 +418,18 @@ def dashboard(port: int, no_open: bool) -> None:
|
|||
"Env: HEADROOM_NO_CCR_PROACTIVE_EXPANSION."
|
||||
),
|
||||
)
|
||||
@click.option(
|
||||
"--no-ccr-response-handling",
|
||||
is_flag=True,
|
||||
envvar="HEADROOM_NO_CCR_RESPONSE_HANDLING",
|
||||
help=(
|
||||
"Disable server-side buffering of streaming responses for CCR response "
|
||||
"handling, independent of --no-ccr. A client that offers the "
|
||||
"headroom_retrieve tool itself (e.g. the bundled OpenCode plugin) "
|
||||
"otherwise always takes the buffered-stream path with no opt-out "
|
||||
"(issue #3082). Env: HEADROOM_NO_CCR_RESPONSE_HANDLING."
|
||||
),
|
||||
)
|
||||
@click.option(
|
||||
"--proxy-extension",
|
||||
"proxy_extension",
|
||||
|
|
@ -1033,6 +1045,7 @@ def proxy(
|
|||
lossless: bool,
|
||||
ccr_inline_resolve: bool,
|
||||
no_ccr_proactive_expansion: bool,
|
||||
no_ccr_response_handling: bool,
|
||||
proxy_extension: tuple[str, ...],
|
||||
compressor: tuple[str, ...],
|
||||
no_subscription_tracking: bool,
|
||||
|
|
@ -1349,6 +1362,10 @@ def proxy(
|
|||
ccr_resolve_markers_inline=ccr_inline_resolve,
|
||||
lossless=lossless,
|
||||
ccr_proactive_expansion=not no_ccr_proactive_expansion,
|
||||
# Independent of --no-ccr: a client can offer headroom_retrieve itself
|
||||
# (see the --no-ccr-response-handling help text), which unconditionally
|
||||
# takes the buffered-stream path with no other opt-out (issue #3082).
|
||||
ccr_handle_responses=not no_ccr_response_handling,
|
||||
# Flatten repeat-flag tuple AND any comma-separated values inside it.
|
||||
# `--proxy-extension a,b --proxy-extension c` and `HEADROOM_PROXY_EXTENSIONS=a,b,c`
|
||||
# both yield ["a", "b", "c"]. None when nothing was supplied.
|
||||
|
|
|
|||
|
|
@ -960,6 +960,89 @@ class TestCLICompressionOnlyFlags:
|
|||
assert cfg.ccr_inject_tool is False
|
||||
|
||||
|
||||
class TestCLINoCcrResponseHandlingFlag:
|
||||
"""--no-ccr-response-handling / HEADROOM_NO_CCR_RESPONSE_HANDLING must flip
|
||||
ccr_handle_responses, independent of --no-ccr (issue #3082).
|
||||
|
||||
Before this flag existed, ccr_handle_responses had no CLI/env wiring at
|
||||
all — a client that offers the headroom_retrieve tool itself (e.g. the
|
||||
bundled OpenCode plugin) always took the buffered-stream path with no
|
||||
supported opt-out, even with --no-ccr set.
|
||||
"""
|
||||
|
||||
def test_ccr_handle_responses_defaults_on(self, runner):
|
||||
"""Without the flag, ccr_handle_responses stays enabled (no behavior change)."""
|
||||
captured_config = {}
|
||||
|
||||
def mock_run_server(config, **kwargs):
|
||||
captured_config["config"] = config
|
||||
|
||||
with patch("headroom.proxy.server.run_server", mock_run_server):
|
||||
result = runner.invoke(main, ["proxy"], catch_exceptions=False)
|
||||
|
||||
assert result.exit_code == 0, result.output
|
||||
assert captured_config["config"].ccr_handle_responses is True
|
||||
|
||||
def test_no_ccr_response_handling_flag(self, runner):
|
||||
"""--no-ccr-response-handling disables ccr_handle_responses only."""
|
||||
captured_config = {}
|
||||
|
||||
def mock_run_server(config, **kwargs):
|
||||
captured_config["config"] = config
|
||||
|
||||
with patch("headroom.proxy.server.run_server", mock_run_server):
|
||||
result = runner.invoke(
|
||||
main, ["proxy", "--no-ccr-response-handling"], catch_exceptions=False
|
||||
)
|
||||
|
||||
assert result.exit_code == 0, result.output
|
||||
cfg = captured_config["config"]
|
||||
assert cfg.ccr_handle_responses is False
|
||||
# Unrelated CCR knobs stay on: this flag is independent of --no-ccr.
|
||||
assert cfg.ccr_inject_tool is True
|
||||
assert cfg.ccr_inject_marker is True
|
||||
|
||||
def test_no_ccr_response_handling_from_env(self, runner):
|
||||
"""HEADROOM_NO_CCR_RESPONSE_HANDLING env var disables ccr_handle_responses."""
|
||||
captured_config = {}
|
||||
|
||||
def mock_run_server(config, **kwargs):
|
||||
captured_config["config"] = config
|
||||
|
||||
with patch("headroom.proxy.server.run_server", mock_run_server):
|
||||
result = runner.invoke(
|
||||
main,
|
||||
["proxy"],
|
||||
env={"HEADROOM_NO_CCR_RESPONSE_HANDLING": "1"},
|
||||
catch_exceptions=False,
|
||||
)
|
||||
|
||||
assert result.exit_code == 0, result.output
|
||||
assert captured_config["config"].ccr_handle_responses is False
|
||||
|
||||
def test_no_ccr_response_handling_combines_with_no_ccr(self, runner):
|
||||
"""--no-ccr-response-handling composes with --no-ccr instead of being
|
||||
implied by it: both can be set together for a fully unbuffered,
|
||||
no-retrieval-path configuration."""
|
||||
captured_config = {}
|
||||
|
||||
def mock_run_server(config, **kwargs):
|
||||
captured_config["config"] = config
|
||||
|
||||
with patch("headroom.proxy.server.run_server", mock_run_server):
|
||||
result = runner.invoke(
|
||||
main,
|
||||
["proxy", "--no-ccr", "--no-ccr-response-handling"],
|
||||
catch_exceptions=False,
|
||||
)
|
||||
|
||||
assert result.exit_code == 0, result.output
|
||||
cfg = captured_config["config"]
|
||||
assert cfg.ccr_inject_tool is False
|
||||
assert cfg.ccr_inject_marker is False
|
||||
assert cfg.ccr_handle_responses is False
|
||||
|
||||
|
||||
class TestNoCcrMarkerCompressors:
|
||||
"""Verify --no-ccr actually suppresses <<ccr:...>> markers
|
||||
from every compressor, not just SmartCrusher (#1022)."""
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue