Merge upstream/main into feat/canonical-pipeline

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
JerrettDavis 2026-04-22 12:57:19 -05:00
commit 87a13ef2cd
3 changed files with 46 additions and 4 deletions

View file

@ -1,5 +1,33 @@
"""Headroom CLI - Command-line interface for memory and proxy management."""
"""Headroom CLI - Command-line interface for memory and proxy management.
The subcommand submodules are imported eagerly below so they are bound as
attributes of `headroom.cli`. Click registration happens via side effects in
`main.py::_register_commands`, but that only binds them to the *main.py*
module. Tests that do `patch("headroom.cli.<sub>.<attr>")` resolve the target
by walking attributes on the package object, and that lookup fails when a
prior test has popped `headroom.cli` from `sys.modules` and re-imported it
through a path other than `main.py` (e.g. a test that replaces
`sys.modules["headroom.cli.main"]` with a fake to isolate one subcommand).
Doing `from . import ...` here means the submodule attribute binding
survives that kind of sys.modules mutation.
"""
from . import ( # noqa: F401
evals,
init,
install,
learn,
mcp,
perf,
proxy,
tools,
wrap,
)
from .main import main
try:
from . import memory # noqa: F401
except ImportError:
pass
__all__ = ["main"]

View file

@ -2,12 +2,26 @@
from __future__ import annotations
import sys
import types
from pathlib import Path
from unittest.mock import patch
import pytest
from click.testing import CliRunner
if "fastapi" not in sys.modules:
fastapi_mod = types.ModuleType("fastapi")
fastapi_mod.FastAPI = type("FastAPI", (), {})
fastapi_mod.Request = type("Request", (), {})
fastapi_mod.WebSocket = type("WebSocket", (), {})
sys.modules["fastapi"] = fastapi_mod
if "fastapi.responses" not in sys.modules:
responses_mod = types.ModuleType("fastapi.responses")
responses_mod.Response = type("Response", (), {})
sys.modules["fastapi.responses"] = responses_mod
from headroom.cli import wrap as wrap_cli
from headroom.cli.main import main

View file

@ -11,7 +11,7 @@ import pytest
ROOT = Path(__file__).resolve().parents[1]
def _load_handler_module(module_name: str, relative_path: str, monkeypatch: pytest.MonkeyPatch):
def _load_handler_module(monkeypatch: pytest.MonkeyPatch, module_name: str, relative_path: str):
proxy_pkg = types.ModuleType("headroom.proxy")
proxy_pkg.__path__ = [str(ROOT / "headroom" / "proxy")]
monkeypatch.setitem(sys.modules, "headroom.proxy", proxy_pkg)
@ -57,9 +57,9 @@ def _load_handler_module(module_name: str, relative_path: str, monkeypatch: pyte
@pytest.mark.asyncio
async def test_openai_passthrough_applies_copilot_auth(monkeypatch: pytest.MonkeyPatch) -> None:
openai_mod = _load_handler_module(
monkeypatch,
"tests.headroom_proxy_handlers_openai",
"headroom/proxy/handlers/openai.py",
monkeypatch,
)
seen: dict[str, object] = {}
@ -115,9 +115,9 @@ async def test_openai_passthrough_applies_copilot_auth(monkeypatch: pytest.Monke
@pytest.mark.asyncio
async def test_streaming_response_applies_copilot_auth(monkeypatch: pytest.MonkeyPatch) -> None:
streaming_mod = _load_handler_module(
monkeypatch,
"tests.headroom_proxy_handlers_streaming",
"headroom/proxy/handlers/streaming.py",
monkeypatch,
)
seen: dict[str, object] = {}