diff --git a/agent/agent_runtime_helpers.py b/agent/agent_runtime_helpers.py index cae1a685a53..b0ea2f62112 100644 --- a/agent/agent_runtime_helpers.py +++ b/agent/agent_runtime_helpers.py @@ -1217,12 +1217,24 @@ def dump_api_request_debug( timestamp = datetime.now().strftime("%Y%m%d_%H%M%S_%f") dump_file = agent.logs_dir / f"request_dump_{agent.session_id}_{timestamp}.json" - atomic_json_write(dump_file, dump_payload, default=str) + + # Redact secrets before persisting/printing. This dump captures the + # full request body (system prompt, tool defs, context-embedded + # values), and this path fires unconditionally on API errors — so it + # otherwise lands any context-embedded secret in cleartext on disk. + # Run the serialized dump through the same scrubber used for logs/tool + # output. Atomicity preserved via temp-file + Path.replace. + from agent.redact import redact_sensitive_text + _serialized = json.dumps(dump_payload, ensure_ascii=False, indent=2, default=str) + _redacted = redact_sensitive_text(_serialized, force=True) + _tmp = dump_file.with_name(dump_file.name + ".tmp") + _tmp.write_text(_redacted, encoding="utf-8") + _tmp.replace(dump_file) agent._vprint(f"{agent.log_prefix}🧾 Request debug dump written to: {dump_file}") if env_var_enabled("HERMES_DUMP_REQUEST_STDOUT"): - print(json.dumps(dump_payload, ensure_ascii=False, indent=2, default=str)) + print(_redacted) return dump_file except Exception as dump_error: diff --git a/agent/redact.py b/agent/redact.py index 6c713cb4e41..de247ec0ad2 100644 --- a/agent/redact.py +++ b/agent/redact.py @@ -104,6 +104,7 @@ _PREFIX_PATTERNS = [ r"mem0_[A-Za-z0-9]{10,}", # Mem0 Platform API key r"brv_[A-Za-z0-9]{10,}", # ByteRover API key r"xai-[A-Za-z0-9]{30,}", # xAI (Grok) API key + r"ntn_[A-Za-z0-9]{10,}", # Notion internal integration token ] # ENV assignment patterns: KEY=value where KEY contains a secret-like name