Closes the last two emission gaps from #77484: - tools/terminal_tool.py: both exception paths (generic except and TERMINAL_DEGRADED_MODE=fail) returned raw str(e) + traceback.format_exc() to the model — only the logger copy was redacted. Exception text can embed the failing command line and any secrets inline in it; both fields now pass through redact_sensitive_text. - acp_adapter/entry.py: _setup_logging cleared root handlers and installed a plain logging.Formatter, bypassing redaction entirely on ACP stderr. Now uses RedactingFormatter like every other logging surface. The other three gaps from #77484 (process(list), *_KEY regex variants, control-char splits) were fixed in #80964/#80965.
42 lines
1.3 KiB
Python
42 lines
1.3 KiB
Python
"""ACP adapter stderr logging must go through RedactingFormatter.
|
|
|
|
``_setup_logging`` clears root handlers and installs its own stderr handler;
|
|
before the fix it used a plain ``logging.Formatter`` — zero redaction on a
|
|
surface that logs request/response internals. See issue #77484.
|
|
"""
|
|
|
|
import logging
|
|
|
|
from acp_adapter.entry import _setup_logging
|
|
|
|
SECRET = "sk-proj-AbCdEf1234567890SecretValue999"
|
|
|
|
|
|
def test_acp_stderr_handler_redacts_secrets():
|
|
saved_handlers = logging.getLogger().handlers[:]
|
|
saved_level = logging.getLogger().level
|
|
try:
|
|
_setup_logging()
|
|
root = logging.getLogger()
|
|
assert root.handlers, "ACP logging setup installed no handler"
|
|
handler = root.handlers[0]
|
|
assert isinstance(handler, logging.StreamHandler)
|
|
record = logging.LogRecord(
|
|
name="acp.test",
|
|
level=logging.ERROR,
|
|
pathname=__file__,
|
|
lineno=1,
|
|
msg="request failed: OPENROUTER_API_KEY=%s",
|
|
args=(SECRET,),
|
|
exc_info=None,
|
|
)
|
|
out = handler.format(record)
|
|
assert SECRET not in out
|
|
assert "OPENROUTER_API_KEY=" in out
|
|
finally:
|
|
root = logging.getLogger()
|
|
root.handlers.clear()
|
|
for h in saved_handlers:
|
|
root.addHandler(h)
|
|
root.setLevel(saved_level)
|