mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-13 03:52:00 +00:00
redact secrets from serialized content before going into summarizer LLM
This commit is contained in:
parent
b909a9efef
commit
1f804d171a
2 changed files with 24 additions and 6 deletions
|
|
@ -28,6 +28,7 @@ from agent.model_metadata import (
|
||||||
get_model_context_length,
|
get_model_context_length,
|
||||||
estimate_messages_tokens_rough,
|
estimate_messages_tokens_rough,
|
||||||
)
|
)
|
||||||
|
from agent.redact import redact_sensitive_text
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
@ -270,11 +271,15 @@ class ContextCompressor(ContextEngine):
|
||||||
Includes tool call arguments and result content (up to
|
Includes tool call arguments and result content (up to
|
||||||
``_CONTENT_MAX`` chars per message) so the summarizer can preserve
|
``_CONTENT_MAX`` chars per message) so the summarizer can preserve
|
||||||
specific details like file paths, commands, and outputs.
|
specific details like file paths, commands, and outputs.
|
||||||
|
|
||||||
|
All content is redacted before serialization to prevent secrets
|
||||||
|
(API keys, tokens, passwords) from leaking into the summary that
|
||||||
|
gets sent to the auxiliary model and persisted across compactions.
|
||||||
"""
|
"""
|
||||||
parts = []
|
parts = []
|
||||||
for msg in turns:
|
for msg in turns:
|
||||||
role = msg.get("role", "unknown")
|
role = msg.get("role", "unknown")
|
||||||
content = msg.get("content") or ""
|
content = redact_sensitive_text(msg.get("content") or "")
|
||||||
|
|
||||||
# Tool results: keep enough content for the summarizer
|
# Tool results: keep enough content for the summarizer
|
||||||
if role == "tool":
|
if role == "tool":
|
||||||
|
|
@ -295,7 +300,7 @@ class ContextCompressor(ContextEngine):
|
||||||
if isinstance(tc, dict):
|
if isinstance(tc, dict):
|
||||||
fn = tc.get("function", {})
|
fn = tc.get("function", {})
|
||||||
name = fn.get("name", "?")
|
name = fn.get("name", "?")
|
||||||
args = fn.get("arguments", "")
|
args = redact_sensitive_text(fn.get("arguments", ""))
|
||||||
# Truncate long arguments but keep enough for context
|
# Truncate long arguments but keep enough for context
|
||||||
if len(args) > self._TOOL_ARGS_MAX:
|
if len(args) > self._TOOL_ARGS_MAX:
|
||||||
args = args[:self._TOOL_ARGS_HEAD] + "..."
|
args = args[:self._TOOL_ARGS_HEAD] + "..."
|
||||||
|
|
@ -353,7 +358,11 @@ class ContextCompressor(ContextEngine):
|
||||||
"assistant that continues the conversation. "
|
"assistant that continues the conversation. "
|
||||||
"Do NOT respond to any questions or requests in the conversation — "
|
"Do NOT respond to any questions or requests in the conversation — "
|
||||||
"only output the structured summary. "
|
"only output the structured summary. "
|
||||||
"Do NOT include any preamble, greeting, or prefix."
|
"Do NOT include any preamble, greeting, or prefix. "
|
||||||
|
"NEVER include API keys, tokens, passwords, secrets, credentials, "
|
||||||
|
"or connection strings in the summary — replace any that appear "
|
||||||
|
"with [REDACTED]. Note that the user had credentials present, but "
|
||||||
|
"do not preserve their values."
|
||||||
)
|
)
|
||||||
|
|
||||||
# Shared structured template (used by both paths).
|
# Shared structured template (used by both paths).
|
||||||
|
|
@ -394,7 +403,7 @@ class ContextCompressor(ContextEngine):
|
||||||
[What remains to be done — framed as context, not instructions]
|
[What remains to be done — framed as context, not instructions]
|
||||||
|
|
||||||
## Critical Context
|
## Critical Context
|
||||||
[Any specific values, error messages, configuration details, or data that would be lost without explicit preservation]
|
[Any specific values, error messages, configuration details, or data that would be lost without explicit preservation. NEVER include API keys, tokens, passwords, or credentials — write [REDACTED] instead.]
|
||||||
|
|
||||||
## Tools & Patterns
|
## Tools & Patterns
|
||||||
[Which tools were used, how they were used effectively, and any tool-specific discoveries]
|
[Which tools were used, how they were used effectively, and any tool-specific discoveries]
|
||||||
|
|
@ -437,7 +446,7 @@ Use this exact structure:
|
||||||
prompt += f"""
|
prompt += f"""
|
||||||
|
|
||||||
FOCUS TOPIC: "{focus_topic}"
|
FOCUS TOPIC: "{focus_topic}"
|
||||||
The user has requested that this compaction PRIORITISE preserving all information related to the focus topic above. For content related to "{focus_topic}", include full detail — exact values, file paths, command outputs, error messages, and decisions. For content NOT related to the focus topic, summarise more aggressively (brief one-liners or omit if truly irrelevant). The focus topic sections should receive roughly 60-70% of the summary token budget."""
|
The user has requested that this compaction PRIORITISE preserving all information related to the focus topic above. For content related to "{focus_topic}", include full detail — exact values, file paths, command outputs, error messages, and decisions. For content NOT related to the focus topic, summarise more aggressively (brief one-liners or omit if truly irrelevant). The focus topic sections should receive roughly 60-70% of the summary token budget. Even for the focus topic, NEVER preserve API keys, tokens, passwords, or credentials — use [REDACTED]."""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
call_kwargs = {
|
call_kwargs = {
|
||||||
|
|
|
||||||
11
uv.lock
generated
11
uv.lock
generated
|
|
@ -1737,6 +1737,7 @@ all = [
|
||||||
{ name = "dingtalk-stream" },
|
{ name = "dingtalk-stream" },
|
||||||
{ name = "discord-py", extra = ["voice"] },
|
{ name = "discord-py", extra = ["voice"] },
|
||||||
{ name = "elevenlabs" },
|
{ name = "elevenlabs" },
|
||||||
|
{ name = "fastapi" },
|
||||||
{ name = "faster-whisper" },
|
{ name = "faster-whisper" },
|
||||||
{ name = "honcho-ai" },
|
{ name = "honcho-ai" },
|
||||||
{ name = "lark-oapi" },
|
{ name = "lark-oapi" },
|
||||||
|
|
@ -1756,6 +1757,7 @@ all = [
|
||||||
{ name = "slack-bolt" },
|
{ name = "slack-bolt" },
|
||||||
{ name = "slack-sdk" },
|
{ name = "slack-sdk" },
|
||||||
{ name = "sounddevice" },
|
{ name = "sounddevice" },
|
||||||
|
{ name = "uvicorn", extra = ["standard"] },
|
||||||
]
|
]
|
||||||
cli = [
|
cli = [
|
||||||
{ name = "simple-term-menu" },
|
{ name = "simple-term-menu" },
|
||||||
|
|
@ -1842,6 +1844,10 @@ voice = [
|
||||||
{ name = "numpy" },
|
{ name = "numpy" },
|
||||||
{ name = "sounddevice" },
|
{ name = "sounddevice" },
|
||||||
]
|
]
|
||||||
|
web = [
|
||||||
|
{ name = "fastapi" },
|
||||||
|
{ name = "uvicorn", extra = ["standard"] },
|
||||||
|
]
|
||||||
yc-bench = [
|
yc-bench = [
|
||||||
{ name = "yc-bench", marker = "python_full_version >= '3.12'" },
|
{ name = "yc-bench", marker = "python_full_version >= '3.12'" },
|
||||||
]
|
]
|
||||||
|
|
@ -1866,6 +1872,7 @@ requires-dist = [
|
||||||
{ name = "exa-py", specifier = ">=2.9.0,<3" },
|
{ name = "exa-py", specifier = ">=2.9.0,<3" },
|
||||||
{ name = "fal-client", specifier = ">=0.13.1,<1" },
|
{ name = "fal-client", specifier = ">=0.13.1,<1" },
|
||||||
{ name = "fastapi", marker = "extra == 'rl'", specifier = ">=0.104.0,<1" },
|
{ name = "fastapi", marker = "extra == 'rl'", specifier = ">=0.104.0,<1" },
|
||||||
|
{ name = "fastapi", marker = "extra == 'web'", specifier = ">=0.104.0,<1" },
|
||||||
{ name = "faster-whisper", marker = "extra == 'voice'", specifier = ">=1.0.0,<2" },
|
{ name = "faster-whisper", marker = "extra == 'voice'", specifier = ">=1.0.0,<2" },
|
||||||
{ name = "fire", specifier = ">=0.7.1,<1" },
|
{ name = "fire", specifier = ">=0.7.1,<1" },
|
||||||
{ name = "firecrawl-py", specifier = ">=4.16.0,<5" },
|
{ name = "firecrawl-py", specifier = ">=4.16.0,<5" },
|
||||||
|
|
@ -1894,6 +1901,7 @@ requires-dist = [
|
||||||
{ name = "hermes-agent", extras = ["sms"], marker = "extra == 'all'" },
|
{ name = "hermes-agent", extras = ["sms"], marker = "extra == 'all'" },
|
||||||
{ name = "hermes-agent", extras = ["tts-premium"], marker = "extra == 'all'" },
|
{ name = "hermes-agent", extras = ["tts-premium"], marker = "extra == 'all'" },
|
||||||
{ name = "hermes-agent", extras = ["voice"], marker = "extra == 'all'" },
|
{ name = "hermes-agent", extras = ["voice"], marker = "extra == 'all'" },
|
||||||
|
{ name = "hermes-agent", extras = ["web"], marker = "extra == 'all'" },
|
||||||
{ name = "honcho-ai", marker = "extra == 'honcho'", specifier = ">=2.0.1,<3" },
|
{ name = "honcho-ai", marker = "extra == 'honcho'", specifier = ">=2.0.1,<3" },
|
||||||
{ name = "httpx", extras = ["socks"], specifier = ">=0.28.1,<1" },
|
{ name = "httpx", extras = ["socks"], specifier = ">=0.28.1,<1" },
|
||||||
{ name = "jinja2", specifier = ">=3.1.5,<4" },
|
{ name = "jinja2", specifier = ">=3.1.5,<4" },
|
||||||
|
|
@ -1929,10 +1937,11 @@ requires-dist = [
|
||||||
{ name = "tenacity", specifier = ">=9.1.4,<10" },
|
{ name = "tenacity", specifier = ">=9.1.4,<10" },
|
||||||
{ name = "tinker", marker = "extra == 'rl'", git = "https://github.com/thinking-machines-lab/tinker.git" },
|
{ name = "tinker", marker = "extra == 'rl'", git = "https://github.com/thinking-machines-lab/tinker.git" },
|
||||||
{ name = "uvicorn", extras = ["standard"], marker = "extra == 'rl'", specifier = ">=0.24.0,<1" },
|
{ name = "uvicorn", extras = ["standard"], marker = "extra == 'rl'", specifier = ">=0.24.0,<1" },
|
||||||
|
{ name = "uvicorn", extras = ["standard"], marker = "extra == 'web'", specifier = ">=0.24.0,<1" },
|
||||||
{ name = "wandb", marker = "extra == 'rl'", specifier = ">=0.15.0,<1" },
|
{ name = "wandb", marker = "extra == 'rl'", specifier = ">=0.15.0,<1" },
|
||||||
{ name = "yc-bench", marker = "python_full_version >= '3.12' and extra == 'yc-bench'", git = "https://github.com/collinear-ai/yc-bench.git" },
|
{ name = "yc-bench", marker = "python_full_version >= '3.12' and extra == 'yc-bench'", git = "https://github.com/collinear-ai/yc-bench.git" },
|
||||||
]
|
]
|
||||||
provides-extras = ["modal", "daytona", "dev", "messaging", "cron", "slack", "matrix", "cli", "tts-premium", "voice", "pty", "honcho", "mcp", "homeassistant", "sms", "acp", "mistral", "termux", "dingtalk", "feishu", "rl", "yc-bench", "all"]
|
provides-extras = ["modal", "daytona", "dev", "messaging", "cron", "slack", "matrix", "cli", "tts-premium", "voice", "pty", "honcho", "mcp", "homeassistant", "sms", "acp", "mistral", "termux", "dingtalk", "feishu", "web", "rl", "yc-bench", "all"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hf-transfer"
|
name = "hf-transfer"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue