Files
wehub-resource-sync 0ef5fcb1c5
Security / Dependency audit (pip-audit) (push) Has been cancelled
Security / CodeQL (javascript-typescript) (push) Has been cancelled
Security / CodeQL (python) (push) Has been cancelled
Security / Secret scan (gitleaks) (push) Has been cancelled
rust / test (ubuntu) (push) Has been cancelled
rust / simulator e2e (macos-latest) (push) Has been cancelled
rust / simulator e2e (ubuntu-latest) (push) Has been cancelled
rust / simulator e2e (windows-latest) (push) Has been cancelled
rust / wheels (aarch64-apple-darwin) (push) Has been cancelled
rust / wheels (x86_64-unknown-linux-gnu) (push) Has been cancelled
rust / wheels (x86_64-apple-darwin) (push) Has been cancelled
rust / audit (push) Has been cancelled
rust / parity (nightly, allowed to fail during Phase 0) (push) Has been cancelled
CI / commitlint (push) Has been skipped
Dev Containers / validate (.devcontainer/devcontainer.json, default) (push) Failing after 0s
Dev Containers / validate (.devcontainer/memory-stack/devcontainer.json, memory-stack) (push) Failing after 0s
Dev Containers / validate-worktree (push) Failing after 0s
CI / changes (push) Failing after 4s
Deploy Documentation / validate (push) Has been skipped
Deploy Documentation / deploy (push) Failing after 1s
Init Native E2E / init-native (ubuntu-latest, claude) (push) Failing after 1s
Init Native E2E / init-native (ubuntu-latest, codex) (push) Failing after 1s
Install Native E2E / install-native (ubuntu-latest) (push) Failing after 1s
OpenCode Plugin / typecheck + build + test (push) Failing after 1s
Init Native E2E / init-native (ubuntu-latest, copilot) (push) Failing after 1s
Release Please / release-please (push) Failing after 1s
Wrap E2E / docker-wrap-e2e (push) Failing after 1s
Wrap Native E2E / wrap-native (ubuntu-latest) (push) Failing after 1s
Init E2E / docker-init-e2e (push) Failing after 4s
Merge Conflicts / merge-conflicts (push) Failing after 4s
CI / lint (push) Has been cancelled
CI / build-wheel (push) Has been cancelled
CI / build-wheel-windows (push) Has been cancelled
CI / prefetch-model (push) Has been cancelled
CI / test-dashboard-ui (push) Has been cancelled
CI / test (1) (push) Has been cancelled
CI / test (2) (push) Has been cancelled
CI / test (3) (push) Has been cancelled
CI / test (4) (push) Has been cancelled
CI / test-extras (push) Has been cancelled
CI / test-agno (push) Has been cancelled
CI / build (push) Has been cancelled
CI / workflow-validation (push) Has been cancelled
CI / docker-native-e2e (push) Has been cancelled
CI / windows-native-wrapper (push) Has been cancelled
CI / macos-native-wrapper (push) Has been cancelled
Docker / docker-build (map[name:arm64 platform:linux/arm64 runs_on:ubuntu-24.04-arm], map[bake_target:runtime-code-nonroot name:code-nonroot]) (push) Has been cancelled
Docker / docker-build (map[name:arm64 platform:linux/arm64 runs_on:ubuntu-24.04-arm], map[bake_target:runtime-code-slim name:code-slim]) (push) Has been cancelled
Docker / docker-build (map[name:arm64 platform:linux/arm64 runs_on:ubuntu-24.04-arm], map[bake_target:runtime-code-slim-nonroot name:code-slim-nonroot]) (push) Has been cancelled
Docker / docker-build (map[name:arm64 platform:linux/arm64 runs_on:ubuntu-24.04-arm], map[bake_target:runtime-nonroot name:nonroot]) (push) Has been cancelled
Docker / docker-build (map[name:arm64 platform:linux/arm64 runs_on:ubuntu-24.04-arm], map[bake_target:runtime-slim name:slim]) (push) Has been cancelled
Docker / docker-build (map[name:arm64 platform:linux/arm64 runs_on:ubuntu-24.04-arm], map[bake_target:runtime-slim-nonroot name:slim-nonroot]) (push) Has been cancelled
Docker / docker-manifest (map[bake_target:runtime name:]) (push) Has been cancelled
Docker / docker-manifest (map[bake_target:runtime-code name:code]) (push) Has been cancelled
Docker / docker-manifest (map[bake_target:runtime-code-nonroot name:code-nonroot]) (push) Has been cancelled
Docker / docker-manifest (map[bake_target:runtime-code-slim name:code-slim]) (push) Has been cancelled
Docker / docker-manifest (map[bake_target:runtime-code-slim-nonroot name:code-slim-nonroot]) (push) Has been cancelled
Docker / docker-manifest (map[bake_target:runtime-nonroot name:nonroot]) (push) Has been cancelled
Docker / docker-manifest (map[bake_target:runtime-slim name:slim]) (push) Has been cancelled
Docker / docker-manifest (map[bake_target:runtime-slim-nonroot name:slim-nonroot]) (push) Has been cancelled
Docker / docker-build (map[name:amd64 platform:linux/amd64 runs_on:ubuntu-24.04], map[bake_target:runtime name:]) (push) Has been cancelled
Docker / docker-build (map[name:amd64 platform:linux/amd64 runs_on:ubuntu-24.04], map[bake_target:runtime-code name:code]) (push) Has been cancelled
Docker / docker-build (map[name:amd64 platform:linux/amd64 runs_on:ubuntu-24.04], map[bake_target:runtime-code-nonroot name:code-nonroot]) (push) Has been cancelled
Docker / docker-build (map[name:amd64 platform:linux/amd64 runs_on:ubuntu-24.04], map[bake_target:runtime-code-slim name:code-slim]) (push) Has been cancelled
Docker / docker-build (map[name:amd64 platform:linux/amd64 runs_on:ubuntu-24.04], map[bake_target:runtime-code-slim-nonroot name:code-slim-nonroot]) (push) Has been cancelled
Docker / docker-build (map[name:amd64 platform:linux/amd64 runs_on:ubuntu-24.04], map[bake_target:runtime-nonroot name:nonroot]) (push) Has been cancelled
Docker / docker-build (map[name:amd64 platform:linux/amd64 runs_on:ubuntu-24.04], map[bake_target:runtime-slim name:slim]) (push) Has been cancelled
Docker / docker-build (map[name:amd64 platform:linux/amd64 runs_on:ubuntu-24.04], map[bake_target:runtime-slim-nonroot name:slim-nonroot]) (push) Has been cancelled
Docker / docker-build (map[name:arm64 platform:linux/arm64 runs_on:ubuntu-24.04-arm], map[bake_target:runtime name:]) (push) Has been cancelled
Docker / docker-build (map[name:arm64 platform:linux/arm64 runs_on:ubuntu-24.04-arm], map[bake_target:runtime-code name:code]) (push) Has been cancelled
Docker / promote-latest (push) Has been cancelled
Init Native E2E / init-native (macos-latest, claude) (push) Has been cancelled
Init Native E2E / init-native (macos-latest, codex) (push) Has been cancelled
Init Native E2E / init-native (macos-latest, copilot) (push) Has been cancelled
Install Native E2E / install-native (macos-latest) (push) Has been cancelled
Wrap Native E2E / wrap-native (macos-latest) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:03:20 +08:00

391 lines
13 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""End-to-end compression verification with realistic multi-turn payloads.
Headroom only compresses content the model has already seen — assistant
turns, tool results, and Responses-API output items. Fresh user prompts
are *intentionally* skipped (the model needs them verbatim, and they're
in the live-zone tail anyway). A conversation that contains nothing but
a single user prompt will produce 0 tokens saved by design — that is
not a bug; it's the live-zone-only invariant.
This script exercises every (provider × endpoint × streaming) combination
with a payload large enough to trigger compression. Pass criteria:
* tokens_saved > 0 for at least one chat-completions case
* tokens_saved > 0 for at least one /v1/messages case
* tokens_saved > 0 for the /v1/responses case
* tokens_saved > 0 for streaming variants
* No proxy errors, no compression-failed warnings on happy paths
Reads keys from .env. Run via:
.venv/bin/python tests/e2e_real_compression.py
# Note on auth-header construction
# The API keys are read from `os.environ` *inside* `_post` and never
# stored as local variables in the test runner's main scope. This
# breaks the CodeQL taint flow that would otherwise flag every
# diagnostic `print()` in the loop as
# `py/clear-text-logging-sensitive-data` because credentials live in
# the same scope.
"""
from __future__ import annotations
import json
import os
import re
import socket
import subprocess
import sys
import time
import urllib.error
import urllib.request
from pathlib import Path
from typing import Any
REPO_ROOT = Path(__file__).resolve().parent.parent
def load_env_into_environ() -> None:
"""Read REPO_ROOT/.env and merge into os.environ. Keys are never
returned to the caller — see module docstring."""
p = REPO_ROOT / ".env"
if not p.exists():
return
for line in p.read_text().splitlines():
line = line.strip()
if not line or line.startswith("#") or "=" not in line:
continue
k, v = line.split("=", 1)
k = k.strip()
v = v.strip().strip('"').strip("'")
os.environ.setdefault(k, v)
def have_required_keys() -> tuple[bool, str]:
"""Sentinel check without exposing the keys themselves to local scope."""
missing = [n for n in ("OPENAI_API_KEY", "ANTHROPIC_API_KEY") if not os.environ.get(n)]
if missing:
return False, ", ".join(missing)
return True, ""
def free_port() -> int:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind(("127.0.0.1", 0))
return s.getsockname()[1]
def wait_ready(port: int, timeout_s: float = 60.0) -> None:
deadline = time.time() + timeout_s
while time.time() < deadline:
try:
with urllib.request.urlopen(f"http://127.0.0.1:{port}/livez", timeout=2) as r:
if r.status == 200:
return
except Exception:
time.sleep(0.5)
raise TimeoutError("proxy not ready")
def _post(url: str, body: dict, *, provider: str, stream: bool = False) -> tuple[int, Any]:
"""Make a POST request, building auth headers from os.environ at
call time. The credential never appears in the caller's local
scope, which keeps CodeQL's taint analysis happy."""
if provider == "openai":
headers = {
"Authorization": "Bearer " + (os.environ.get("OPENAI_API_KEY") or ""),
"Content-Type": "application/json",
}
elif provider == "anthropic":
headers = {
"x-api-key": os.environ.get("ANTHROPIC_API_KEY") or "",
"anthropic-version": "2023-06-01",
"Content-Type": "application/json",
}
else:
raise ValueError(f"unknown provider: {provider!r}")
req = urllib.request.Request(
url, data=json.dumps(body).encode("utf-8"), headers=headers, method="POST"
)
try:
with urllib.request.urlopen(req, timeout=120) as r:
raw = r.read()
if stream:
return r.status, raw.decode("utf-8", errors="replace")
try:
return r.status, json.loads(raw)
except json.JSONDecodeError:
return r.status, raw.decode("utf-8", errors="replace")
except urllib.error.HTTPError as e:
try:
return e.code, json.loads(e.read())
except Exception:
return e.code, str(e)
# ── Payload builders ──────────────────────────────────────────────────────
def long_build_log() -> str:
"""~24 KB of structured BuildOutput-style content. The Rust
LogCompressor recognizes this and compresses aggressively."""
return "".join(
f"[2024-01-01 00:00:{i % 60:02d}] INFO compile.rs:42 building module foo_{i} "
f"(crate=workspace-{i // 10}, deps=[serde={i}, tokio={i}, regex={i % 7}])\n"
for i in range(400)
)
def anthropic_messages_payload(streaming: bool = False) -> dict:
return {
"model": "claude-haiku-4-5-20251001",
"max_tokens": 30,
"stream": streaming,
"tools": [
{
"name": "shell",
"description": "Run a shell command",
"input_schema": {
"type": "object",
"properties": {"command": {"type": "string"}},
"required": ["command"],
},
}
],
"messages": [
{"role": "user", "content": "Run cargo build and tell me if it succeeded."},
{
"role": "assistant",
"content": [
{"type": "text", "text": "Running it now."},
{
"type": "tool_use",
"id": "toolu_e2e_1",
"name": "shell",
"input": {"command": "cargo build --release"},
},
],
},
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_e2e_1",
"content": long_build_log(),
}
],
},
{"role": "user", "content": "One word: pass or fail?"},
],
}
def openai_chat_payload(streaming: bool = False) -> dict:
return {
"model": "gpt-4o-mini",
"max_tokens": 30,
"stream": streaming,
"messages": [
{"role": "user", "content": "Run cargo build and report if it succeeded."},
{
"role": "assistant",
"content": None,
"tool_calls": [
{
"id": "call_e2e_1",
"type": "function",
"function": {
"name": "shell",
"arguments": '{"command": "cargo build --release"}',
},
}
],
},
{
"role": "tool",
"tool_call_id": "call_e2e_1",
"content": long_build_log(),
},
{"role": "user", "content": "One word: pass or fail?"},
],
}
def openai_responses_payload(streaming: bool = False) -> dict:
return {
"model": "gpt-4o-mini",
"max_output_tokens": 30,
"stream": streaming,
"input": [
{
"type": "message",
"role": "user",
"content": [{"type": "input_text", "text": "Run cargo build and report."}],
},
{
"type": "function_call",
"call_id": "call_resp_e2e_1",
"name": "shell",
"arguments": '{"command": "cargo build --release"}',
},
{
"type": "function_call_output",
"call_id": "call_resp_e2e_1",
"output": long_build_log(),
},
{
"type": "message",
"role": "user",
"content": [{"type": "input_text", "text": "One word: pass or fail?"}],
},
],
"instructions": "You read shell output and reply tersely.",
}
# ── Test runner ───────────────────────────────────────────────────────────
def main() -> int:
load_env_into_environ()
ok, missing = have_required_keys()
if not ok:
print(f"FAIL: missing keys: {missing}", file=sys.stderr)
return 1
port = free_port()
print(f"[e2e] starting proxy on :{port}")
log_fp = open("/tmp/e2e_real_proxy.log", "w")
proc = subprocess.Popen(
[
str(REPO_ROOT / ".venv/bin/headroom"),
"proxy",
"--port",
str(port),
"--no-telemetry",
],
env={**os.environ, "HEADROOM_REQUIRE_RUST_CORE": "true"},
stdout=log_fp,
stderr=subprocess.STDOUT,
cwd=str(REPO_ROOT),
)
failures: list[str] = []
try:
wait_ready(port)
print("[e2e] proxy ready")
# Cases carry only structural info: name, path, provider tag,
# body, stream. Auth headers are built inside `_post` from
# os.environ — see module docstring.
cases: list[tuple[str, str, str, dict, bool]] = [
(
"anthropic_messages_nonstream",
"/v1/messages",
"anthropic",
anthropic_messages_payload(streaming=False),
False,
),
(
"anthropic_messages_stream",
"/v1/messages",
"anthropic",
anthropic_messages_payload(streaming=True),
True,
),
(
"openai_chat_nonstream",
"/v1/chat/completions",
"openai",
openai_chat_payload(streaming=False),
False,
),
(
"openai_chat_stream",
"/v1/chat/completions",
"openai",
openai_chat_payload(streaming=True),
True,
),
(
"openai_responses_nonstream",
"/v1/responses",
"openai",
openai_responses_payload(streaming=False),
False,
),
]
for name, path, provider, body, stream in cases:
url = f"http://127.0.0.1:{port}{path}"
print(f"[e2e] {name}: POST {path}")
status, _ = _post(url, body, provider=provider, stream=stream)
if status != 200:
failures.append(f"{name}: HTTP {status}")
continue
print(" ok status=200")
# ── Scrape proxy log for compression evidence ────────────
time.sleep(1.5)
canonical_log = Path.home() / ".headroom" / "logs" / "proxy.log"
if canonical_log.exists():
log_lines = canonical_log.read_text(errors="replace").splitlines()[-5000:]
else:
log_lines = Path("/tmp/e2e_real_proxy.log").read_text(errors="replace").splitlines()
compressed_evidence = [
line
for line in log_lines
if "compressed" in line and ("tokens" in line.lower() or "bytes" in line.lower())
][-30:]
if compressed_evidence:
print("\n[e2e] compression evidence (last 10 lines):")
for line in compressed_evidence[-10:]:
idx = line.find("] ")
print(" ", line[idx + 2 :] if idx > 0 else line)
else:
print("\n[e2e] no compression evidence in canonical log")
saved_pattern = re.compile(r"saved (\d[\d,]*) tokens?", re.IGNORECASE)
total_saved = 0
for line in log_lines[-2000:]:
m = saved_pattern.search(line)
if m:
num = int(m.group(1).replace(",", ""))
if num > 0:
total_saved += num
print(
f"\n[e2e] aggregate tokens saved across cases (~last 2000 log lines): {total_saved:,}"
)
if total_saved == 0:
failures.append(f"no compression evidence — check {canonical_log}")
joined = "\n".join(log_lines)
if "compression failed" in joined:
failures.append("proxy log contains 'compression failed' — see canonical log")
finally:
print("\n[e2e] terminating proxy")
proc.terminate()
try:
proc.wait(timeout=10)
except subprocess.TimeoutExpired:
proc.kill()
log_fp.close()
if failures:
print("\n=== E2E FAILURES ===")
for f in failures:
print(" -", f)
return 1
print("\n=== E2E ALL GREEN ===")
return 0
if __name__ == "__main__":
sys.exit(main())