fix(sse): do not ZWJ-obfuscate the substring hermes in user text (#10488)

Keep the #8350 Hermes system-prompt drops, but remove hermes from the
factory obfuscate_words list so hostnames and CLI mentions stay intact.

Co-authored-by: Ravi Tharuma <RaviTharuma@users.noreply.github.com>
This commit is contained in:
Ravi Tharuma
2026-08-17 12:04:48 +02:00
committed by GitHub
parent 8bd0b840f6
commit 48e5cf7fe4
5 changed files with 36 additions and 7 deletions

View File

@@ -0,0 +1 @@
- fix(sse): stop ZWJ-obfuscating the substring "hermes" in user messages and hostnames (#10484)

View File

@@ -96,9 +96,10 @@ export const DEFAULT_OBFUSCATE_WORDS = [
// Open WebUI additions
"openwebui",
"open-webui",
// Hermes additions (#8350)
"hermes-agent",
"hermes",
// Do not add "hermes" / "hermes-agent" here. #8350 is handled by
// HERMES_PARAGRAPH_ANCHORS + HERMES_IDENTITY_PREFIXES (system-prompt
// drops only). ZWJ on the short substring "hermes" rewrites user
// messages and hostnames (#10484).
];
/**

View File

@@ -81,8 +81,6 @@ const DEFAULT_OBFUSCATE_WORDS = [
"codecompanion",
"openwebui",
"open-webui",
"hermes-agent",
"hermes",
];
// Mirror of DEFAULT_SYSTEM_TRANSFORMS_CONFIG from open-sse/services/systemTransforms.ts.

View File

@@ -68,3 +68,34 @@ test("non-Hermes system prompt passes through byte-identical through the claude
"a normal operator system prompt with no third-party-agent anchors must pass through untouched"
);
});
// #10484 — #8358 added "hermes" to DEFAULT_OBFUSCATE_WORDS. The ZWJ op
// targets user messages with a case-insensitive, no-word-boundary regex, so
// hostnames and ordinary mentions of the OmniRoute hermes CLI tool were
// rewritten. System-prompt identity drops (#8350) must stay; user text must not
// be mutated.
test("user message containing hermes hostname stays byte-identical (#10484)", () => {
const body = {
system: [
{
type: "text",
text: "You are a helpful operator-configured assistant. Follow company policy X and always answer in English.",
},
],
messages: [
{
role: "user",
content: "1. hermes\n2. hermes.example.ts.net\n3. Hermes on agent-001\n4. hermeS",
},
],
};
const before = JSON.stringify(body);
applySystemTransformPipeline(PROVIDER_CLAUDE, body, DEFAULT_SYSTEM_TRANSFORMS_CONFIG);
assert.equal(
JSON.stringify(body),
before,
"user text containing the substring hermes must not receive ZWJ obfuscation"
);
const content = (body.messages[0] as { content: string }).content;
assert.equal(content.includes("\u200d"), false, "no zero-width joiner in user text");
});

View File

@@ -502,8 +502,6 @@ const UI_DEFAULTS_SNAPSHOT = {
"codecompanion",
"openwebui",
"open-webui",
"hermes-agent",
"hermes",
],
targets: ["system", "messages", "tools"],
},