mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-03 02:11:48 +00:00
fix: wire PII redaction + token empty warnings for plugin platforms
PII redaction: build_session_context_prompt() now checks the plugin registry's pii_safe flag in addition to the hardcoded _PII_SAFE_PLATFORMS frozenset. Plugin platforms that set pii_safe=True (e.g. phone-based messaging bridges) get their user IDs redacted before LLM context. Token empty warnings: the empty-token diagnostic at config load now checks the plugin registry's required_env when a platform isn't in the hardcoded _token_env_names dict. Catches 'enabled but empty' for plugin platforms too.
This commit is contained in:
parent
2e20f6ae2d
commit
457128d4e8
2 changed files with 32 additions and 13 deletions
|
|
@ -891,6 +891,15 @@ def _validate_gateway_config(config: "GatewayConfig") -> None:
|
||||||
if not pconfig.enabled:
|
if not pconfig.enabled:
|
||||||
continue
|
continue
|
||||||
env_name = _token_env_names.get(platform)
|
env_name = _token_env_names.get(platform)
|
||||||
|
if not env_name:
|
||||||
|
# Check plugin registry for required_env
|
||||||
|
try:
|
||||||
|
from gateway.platform_registry import platform_registry
|
||||||
|
entry = platform_registry.get(platform.value)
|
||||||
|
if entry and entry.required_env:
|
||||||
|
env_name = entry.required_env[0] # primary env var
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
if env_name and pconfig.token is not None and not pconfig.token.strip():
|
if env_name and pconfig.token is not None and not pconfig.token.strip():
|
||||||
logger.warning(
|
logger.warning(
|
||||||
"%s is enabled but %s is empty. "
|
"%s is enabled but %s is empty. "
|
||||||
|
|
|
||||||
|
|
@ -234,7 +234,7 @@ def build_session_context_prompt(
|
||||||
) -> str:
|
) -> str:
|
||||||
"""
|
"""
|
||||||
Build the dynamic system prompt section that tells the agent about its context.
|
Build the dynamic system prompt section that tells the agent about its context.
|
||||||
|
|
||||||
This is injected into the system prompt so the agent knows:
|
This is injected into the system prompt so the agent knows:
|
||||||
- Where messages are coming from
|
- Where messages are coming from
|
||||||
- What platforms are connected
|
- What platforms are connected
|
||||||
|
|
@ -246,13 +246,23 @@ def build_session_context_prompt(
|
||||||
Platforms like Discord are excluded because mentions need real IDs.
|
Platforms like Discord are excluded because mentions need real IDs.
|
||||||
Routing still uses the original values (they stay in SessionSource).
|
Routing still uses the original values (they stay in SessionSource).
|
||||||
"""
|
"""
|
||||||
# Only apply redaction on platforms where IDs aren't needed for mentions
|
# Only apply redaction on platforms where IDs aren't needed for mentions.
|
||||||
redact_pii = redact_pii and context.source.platform in _PII_SAFE_PLATFORMS
|
# Check both the hardcoded set (builtins) and the plugin registry.
|
||||||
|
_is_pii_safe = context.source.platform in _PII_SAFE_PLATFORMS
|
||||||
|
if not _is_pii_safe:
|
||||||
|
try:
|
||||||
|
from gateway.platform_registry import platform_registry
|
||||||
|
entry = platform_registry.get(context.source.platform.value)
|
||||||
|
if entry and entry.pii_safe:
|
||||||
|
_is_pii_safe = True
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
redact_pii = redact_pii and _is_pii_safe
|
||||||
lines = [
|
lines = [
|
||||||
"## Current Session Context",
|
"## Current Session Context",
|
||||||
"",
|
"",
|
||||||
]
|
]
|
||||||
|
|
||||||
# Source info
|
# Source info
|
||||||
platform_name = context.source.platform.value.title()
|
platform_name = context.source.platform.value.title()
|
||||||
if context.source.platform == Platform.LOCAL:
|
if context.source.platform == Platform.LOCAL:
|
||||||
|
|
@ -277,7 +287,7 @@ def build_session_context_prompt(
|
||||||
else:
|
else:
|
||||||
desc = src.description
|
desc = src.description
|
||||||
lines.append(f"**Source:** {platform_name} ({desc})")
|
lines.append(f"**Source:** {platform_name} ({desc})")
|
||||||
|
|
||||||
# Channel topic (if available - provides context about the channel's purpose)
|
# Channel topic (if available - provides context about the channel's purpose)
|
||||||
if context.source.chat_topic:
|
if context.source.chat_topic:
|
||||||
lines.append(f"**Channel Topic:** {context.source.chat_topic}")
|
lines.append(f"**Channel Topic:** {context.source.chat_topic}")
|
||||||
|
|
@ -302,7 +312,7 @@ def build_session_context_prompt(
|
||||||
if redact_pii:
|
if redact_pii:
|
||||||
uid = _hash_sender_id(uid)
|
uid = _hash_sender_id(uid)
|
||||||
lines.append(f"**User ID:** {uid}")
|
lines.append(f"**User ID:** {uid}")
|
||||||
|
|
||||||
# Platform-specific behavioral notes
|
# Platform-specific behavioral notes
|
||||||
if context.source.platform == Platform.SLACK:
|
if context.source.platform == Platform.SLACK:
|
||||||
lines.append("")
|
lines.append("")
|
||||||
|
|
@ -368,9 +378,9 @@ def build_session_context_prompt(
|
||||||
for p in context.connected_platforms:
|
for p in context.connected_platforms:
|
||||||
if p != Platform.LOCAL:
|
if p != Platform.LOCAL:
|
||||||
platforms_list.append(f"{p.value}: Connected ✓")
|
platforms_list.append(f"{p.value}: Connected ✓")
|
||||||
|
|
||||||
lines.append(f"**Connected Platforms:** {', '.join(platforms_list)}")
|
lines.append(f"**Connected Platforms:** {', '.join(platforms_list)}")
|
||||||
|
|
||||||
# Home channels
|
# Home channels
|
||||||
if context.home_channels:
|
if context.home_channels:
|
||||||
lines.append("")
|
lines.append("")
|
||||||
|
|
@ -378,11 +388,11 @@ def build_session_context_prompt(
|
||||||
for platform, home in context.home_channels.items():
|
for platform, home in context.home_channels.items():
|
||||||
hc_id = _hash_chat_id(home.chat_id) if redact_pii else home.chat_id
|
hc_id = _hash_chat_id(home.chat_id) if redact_pii else home.chat_id
|
||||||
lines.append(f" - {platform.value}: {home.name} (ID: {hc_id})")
|
lines.append(f" - {platform.value}: {home.name} (ID: {hc_id})")
|
||||||
|
|
||||||
# Delivery options for scheduled tasks
|
# Delivery options for scheduled tasks
|
||||||
lines.append("")
|
lines.append("")
|
||||||
lines.append("**Delivery options for scheduled tasks:**")
|
lines.append("**Delivery options for scheduled tasks:**")
|
||||||
|
|
||||||
from hermes_constants import display_hermes_home
|
from hermes_constants import display_hermes_home
|
||||||
|
|
||||||
# Origin delivery
|
# Origin delivery
|
||||||
|
|
@ -398,15 +408,15 @@ def build_session_context_prompt(
|
||||||
lines.append(
|
lines.append(
|
||||||
f"- `\"local\"` → Save to local files only ({display_hermes_home()}/cron/output/)"
|
f"- `\"local\"` → Save to local files only ({display_hermes_home()}/cron/output/)"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Platform home channels
|
# Platform home channels
|
||||||
for platform, home in context.home_channels.items():
|
for platform, home in context.home_channels.items():
|
||||||
lines.append(f"- `\"{platform.value}\"` → Home channel ({home.name})")
|
lines.append(f"- `\"{platform.value}\"` → Home channel ({home.name})")
|
||||||
|
|
||||||
# Note about explicit targeting
|
# Note about explicit targeting
|
||||||
lines.append("")
|
lines.append("")
|
||||||
lines.append("*For explicit targeting, use `\"platform:chat_id\"` format if the user provides a specific chat ID.*")
|
lines.append("*For explicit targeting, use `\"platform:chat_id\"` format if the user provides a specific chat ID.*")
|
||||||
|
|
||||||
return "\n".join(lines)
|
return "\n".join(lines)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue