Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions agents/hermes/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,27 @@ RUN (apt-get remove --purge -y gcc gcc-12 g++ g++-12 cpp cpp-12 make \

# Hermes v2026.4.13+ auto-detects HTTPS_PROXY and skips fallback-IP
# transport when a proxy is present. The sandbox proxy chain
# (decode-proxy → OpenShell L7 proxy) handles credential placeholder
# rewriting and hostname-based policy enforcement. No monkey patch needed.
# (decode-proxy -> OpenShell L7 proxy) handles REST credential placeholder
# rewriting and hostname-based policy enforcement. A Hermes-only local Discord
# facade handles discord.py's Gateway session inside the sandbox and forwards
# REST through the same placeholder-substitution path.
ENV HERMES_TELEGRAM_DISABLE_FALLBACK_IPS=1

# Copy NemoClaw plugin for Hermes (Python-based)
COPY agents/hermes/plugin/ /opt/nemoclaw-hermes-plugin/
RUN chmod -R a+rX /opt/nemoclaw-hermes-plugin/

# Copy config generator and URL-decode proxy
# Copy config generator, Discord facade, and URL-decode proxy
COPY agents/hermes/generate-config.ts /opt/nemoclaw-hermes-config/generate-config.ts
COPY agents/hermes/config/ /opt/nemoclaw-hermes-config/config/
RUN find /opt/nemoclaw-hermes-config -type d -exec chmod 755 {} + \
&& find /opt/nemoclaw-hermes-config -type f -exec chmod 444 {} +
COPY agents/hermes/decode-proxy.py /usr/local/bin/nemoclaw-decode-proxy
RUN chmod 755 /usr/local/bin/nemoclaw-decode-proxy
COPY agents/hermes/discord-facade.py /usr/local/bin/nemoclaw-discord-facade
COPY agents/hermes/discord-preload/ /opt/nemoclaw-hermes-discord-preload/
RUN chmod 755 /usr/local/bin/nemoclaw-decode-proxy /usr/local/bin/nemoclaw-discord-facade \
&& find /opt/nemoclaw-hermes-discord-preload -type d -exec chmod 755 {} + \
&& find /opt/nemoclaw-hermes-discord-preload -type f -exec chmod 444 {} +

# Copy blueprint (shared infrastructure)
COPY nemoclaw-blueprint/ /opt/nemoclaw-blueprint/
Expand Down
11 changes: 11 additions & 0 deletions agents/hermes/config/messaging-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ const CHANNEL_TOKEN_ENVS: Record<string, string[]> = {
slack: ["SLACK_BOT_TOKEN", "SLACK_APP_TOKEN"],
};

const HERMES_DISCORD_PROXY = "http://127.0.0.1:3129";
const HERMES_DISCORD_FACADE = "http://127.0.0.1:3130";

export function buildMessagingEnvLines(
enabledChannels: Set<string>,
allowedIds: MessagingAllowedIds,
Expand All @@ -21,6 +24,14 @@ export function buildMessagingEnvLines(
for (const envKey of envKeys) {
envLines.push(`${envKey}=openshell:resolve:env:${envKey}`);
}
if (channel === "discord") {
envLines.push(`DISCORD_PROXY=${HERMES_DISCORD_PROXY}`);
envLines.push(`NEMOCLAW_DISCORD_FACADE_URL=${HERMES_DISCORD_FACADE}`);
const guildIds = Object.keys(discordGuilds).filter(Boolean);
if (guildIds.length > 0) {
envLines.push(`NEMOCLAW_DISCORD_GUILD_IDS=${guildIds.join(",")}`);
}
}
}

const discordAllowedUsers = collectDiscordAllowedUsers(allowedIds, discordGuilds);
Expand Down
4 changes: 4 additions & 0 deletions agents/hermes/decode-proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
URL-decodes the CONNECT target and request paths so the placeholders
are restored before reaching the L7 proxy.

This is intentionally not a WebSocket frame rewriter. After the initial
HTTP proxy request is forwarded, bytes are relayed unchanged; Discord
gateway IDENTIFY payloads are not inspected or modified here.

Usage: Launched by start.sh, listens on 127.0.0.1:3129.
HTTPS_PROXY=http://127.0.0.1:3129 hermes gateway run
"""
Expand Down
Loading
Loading