{"repo":"NousResearch/hermes-agent","public_id":"6576","display_label":"Azure content filter workaround via prompt marker rename","summary":"These items address Azure OpenAI content filter blocks triggered by the '[SYSTEM:' marker in user-injected prompts, proposing or applying a rename to '[IMPORTANT:' as a workaround. The bug report and fixes all center on the same specific trigger-word issue.","subsystem":null,"counts":{"members":4,"open_issues":0,"open_issues_distinct":0,"open_prs":0,"closed_issues":1,"merged_prs":1,"attempt_prs":2},"landed_fix":{"status":"merged_to_main","basis":"structural","pr":16114,"merged_at":"2026-04-26T15:44:59+00:00"},"resolution":{"state":"resolved","by":"pr-16114"},"freshness":{"state":"stale","last_verified_at":"2026-04-26T15:44:59+00:00","is_stale":true},"grouping":{"backbone":"STRUCTURAL_SPANNING","link_density":0.5},"fix_edges":[{"issue_number":6576,"pr_number":16114,"tier":"verified","basis":"closing_ref","confidence":0.95,"recoverable_from_timeline":true,"pr_merged_at":"2026-04-26T15:44:59+00:00"}],"members":[{"kind":"issue","number":6576,"title":"[Bug]: Azure OpenAI security filters block some Hermes requests due to trigger word","url":null,"state":"closed"},{"kind":"pr","number":6583,"title":"fix(prompts): replace [SYSTEM: with [IMPORTANT: to avoid Azure content filter","url":null,"state":"closed","close_reason":{"category":"silent_close","implication":"active"},"merged":false},{"kind":"pr","number":6616,"title":"fix(prompts): replace [SYSTEM: with [IMPORTANT: to avoid Azure content filter","url":null,"state":"closed","close_reason":{"refs":[{"kind":"commit","value":"bed192135","number":0},{"kind":"pr","value":"#16114","number":16114},{"kind":"pr","value":"#6576","number":6576}],"category":"merged_via","implication":"superseded"},"merged":false},{"kind":"pr","number":16114,"title":"fix(prompts): rename [SYSTEM: → [IMPORTANT: in all user-injected markers (Azure content filter)","url":null,"state":"merged","close_reason":{"category":"merged"},"merged":true,"is_fix_pr":true,"fix_tier":"verified","files_changed":["agent/skill_commands.py","cli.py","cron/scheduler.py","gateway/run.py","scripts/release.py","tools/process_registry.py"],"fix_hunks":[{"file":"agent/skill_commands.py","hunks":["@@ -329,7 +329,7 @@ def build_skill_invocation_message(\n \n     loaded_skill, skill_dir, skill_name = loaded\n     activation_note = (\n-        f'[SYSTEM: The user has invoked the \"{skill_name}\" skill, indicating they want '\n+        f'[IMPORTANT: The user has invoked the \"{skill_name}\" skill, indicating they want '\n         \"you to follow its instructions. The full skill content is loaded below.]\"\n     )\n     return _build_skill_message(","@@ -368,7 +368,7 @@ def build_preloaded_skills_prompt(\n \n         loaded_skill, skill_dir, skill_name = loaded\n         activation_note = (\n-            f'[SYSTEM: The user launched this CLI session with the \"{skill_name}\" skill '\n+            f'[IMPORTANT: The user launched this CLI session with the \"{skill_name}\" skill '\n             \"preloaded. Treat its instructions as active guidance for the duration of this \"\n             \"session unless the user overrides them.]\"\n         )"]},{"file":"cli.py","hunks":["@@ -1378,7 +1378,7 @@ def _resolve_attachment_path(raw_path: str) -> Path | None:\n \n \n def _format_process_notification(evt: dict) -> \"str | None\":\n-    \"\"\"Format a process notification event into a [SYSTEM: ...] message.\n+    \"\"\"Format a process notification event into a [IMPORTANT: ...] message.\n \n     Handles both completion events (notify_on_complete) and watch pattern\n     match events from the unified completion_queue.","@@ -1388,14 +1388,14 @@ def _format_process_notification(evt: dict) -> \"str | None\":\n     _cmd = evt.get(\"command\", \"unknown\")\n \n     if evt_type == \"watch_disabled\":\n-        return f\"[SYSTEM: {evt.get('message', '')}]\"\n+        return f\"[IMPORTANT: {evt.get('message', '')}]\"\n \n     if evt_type == \"watch_match\":\n         _pat = evt.get(\"pattern\", \"?\")\n         _out = evt.get(\"output\", \"\")\n         _sup = evt.get(\"suppressed\", 0)\n         text = (\n-            f\"[SYSTEM: Background process {_sid} matched \"\n+            f\"[IMPORTANT: Background process {_sid} matched \"\n             f\"watch pattern \\\"{_pat}\\\".\\n\"\n             f\"Command: {_cmd}\\n\"\n             f\"Matched output:\\n{_out}\"","@@ -1409,7 +1409,7 @@ def _format_process_notification(evt: dict) -> \"str | None\":\n     _exit = evt.get(\"exit_code\", \"?\")\n     _out = evt.get(\"output\", \"\")\n     return (\n-        f\"[SYSTEM: Background process {_sid} completed \"\n+        f\"[IMPORTANT: Background process {_sid} completed \"\n         f\"(exit code {_exit}).\\n\"\n         f\"Command: {_cmd}\\n\"\n         f\"Output:\\n{_out}]\"","@@ -7217,7 +7217,7 @@ def _reload_mcp(self):\n             change_detail = \". \".join(change_parts) + \". \" if change_parts else \"\"\n             self.conversation_history.append({\n                 \"role\": \"user\",\n-                \"content\": f\"[SYSTEM: MCP servers have been reloaded. {change_detail}{tool_summary}. The tool list for this conversation has been updated accordingly.]\",\n+                \"content\": f\"[IMPORTANT: MCP servers have been reloaded. {change_detail}{tool_summary}. The tool list for this conversation has been updated accordingly.]\",\n             })\n \n             # Persist session immediately so the session log reflects the"]},{"file":"cron/scheduler.py","hunks":["@@ -715,7 +715,7 @@ def _build_job_prompt(job: dict, prerun_script: Optional[tuple] = None) -> str:\n     # Always prepend cron execution guidance so the agent knows how\n     # delivery works and can suppress delivery when appropriate.\n     cron_hint = (\n-        \"[SYSTEM: You are running as a scheduled cron job. \"\n+        \"[IMPORTANT: You are running as a scheduled cron job. \"\n         \"DELIVERY: Your final response will be automatically delivered \"\n         \"to the user — do NOT use send_message or try to deliver \"\n         \"the output yourself. Just produce your report/output as your \"","@@ -751,7 +751,7 @@ def _build_job_prompt(job: dict, prerun_script: Optional[tuple] = None) -> str:\n             parts.append(\"\")\n         parts.extend(\n             [\n-                f'[SYSTEM: The user has invoked the \"{skill_name}\" skill, indicating they want you to follow its instructions. The full skill content is loaded below.]',\n+                f'[IMPORTANT: The user has invoked the \"{skill_name}\" skill, indicating they want you to follow its instructions. The full skill content is loaded below.]',\n                 \"\",\n                 content,\n             ]","@@ -759,7 +759,7 @@ def _build_job_prompt(job: dict, prerun_script: Optional[tuple] = None) -> str:\n \n     if skipped:\n         notice = (\n-            f\"[SYSTEM: The following skill(s) were listed for this job but could not be found \"\n+            f\"[IMPORTANT: The following skill(s) were listed for this job but could not be found \"\n             f\"and were skipped: {', '.join(skipped)}. \"\n             f\"Start your response with a brief notice so the user is aware, e.g.: \"\n             f\"'⚠️ Skill(s) not found and skipped: {', '.join(skipped)}']\""]},{"file":"gateway/run.py","hunks":["@@ -591,20 +591,20 @@ def _parse_session_key(session_key: str) -> \"dict | None\":\n \n \n def _format_gateway_process_notification(evt: dict) -> \"str | None\":\n-    \"\"\"Format a watch pattern event from completion_queue into a [SYSTEM:] message.\"\"\"\n+    \"\"\"Format a watch pattern event from completion_queue into a [IMPORTANT:] message.\"\"\"\n     evt_type = evt.get(\"type\", \"completion\")\n     _sid = evt.get(\"session_id\", \"unknown\")\n     _cmd = evt.get(\"command\", \"unknown\")\n \n     if evt_type == \"watch_disabled\":\n-        return f\"[SYSTEM: {evt.get('message', '')}]\"\n+        return f\"[IMPORTANT: {evt.get('message', '')}]\"\n \n     if evt_type == \"watch_match\":\n         _pat = evt.get(\"pattern\", \"?\")\n         _out = evt.get(\"output\", \"\")\n         _sup = evt.get(\"suppressed\", 0)\n         text = (\n-            f\"[SYSTEM: Background process {_sid} matched \"\n+            f\"[IMPORTANT: Background process {_sid} matched \"\n             f\"watch pattern \\\"{_pat}\\\".\\n\"\n             f\"Command: {_cmd}\\n\"\n             f\"Matched output:\\n{_out}\"","@@ -4232,7 +4232,7 @@ async def _handle_message_with_agent(self, event, source, _quick_key: str, run_g\n                     if _loaded:\n                         _loaded_skill, _skill_dir, _display_name = _loaded\n                         _note = (\n-                            f'[SYSTEM: The \"{_display_name}\" skill is auto-loaded. '\n+                            f'[IMPORTANT: The \"{_display_name}\" skill is auto-loaded. '\n                             f\"Follow its instructions for this session.]\"\n                         )\n                         _part = _build_skill_message(_loaded_skill, _skill_dir, _note)","@@ -7473,7 +7473,7 @@ async def _handle_reload_mcp_command(self, event: MessageEvent) -> str:\n             change_detail = \". \".join(change_parts) + \". \" if change_parts else \"\"\n             reload_msg = {\n                 \"role\": \"user\",\n-                \"content\": f\"[SYSTEM: MCP servers have been reloaded. {change_detail}{tool_summary}. The tool list for this conversation has been updated accordingly.]\",\n+                \"content\": f\"[IMPORTANT: MCP servers have been reloaded. {change_detail}{tool_summary}. The tool list for this conversation has been updated accordingly.]\",\n             }\n             try:\n                 session_entry = self.session_store.get_or_create_session(event.source)","@@ -8412,7 +8412,7 @@ async def _run_process_watcher(self, watcher: dict) -> None:\n                     from tools.ansi_strip import strip_ansi\n                     _out = strip_ansi(session.output_buffer[-2000:]) if session.output_buffer else \"\"\n                     synth_text = (\n-                        f\"[SYSTEM: Background process {session_id} completed \"\n+                        f\"[IMPORTANT: Background process {session_id} completed \"\n                         f\"(exit code {session.exit_code}).\\n\"\n                         f\"Command: {session.command}\\n\"\n                         f\"Output:\\n{_out}]\""]},{"file":"scripts/release.py","hunks":["@@ -119,6 +119,7 @@\n     \"nocoo@users.noreply.github.com\": \"nocoo\",\n     \"30841158+n-WN@users.noreply.github.com\": \"n-WN\",\n     \"[redacted:email]\": \"hiddenpuppy\",\n+    \"[redacted:email]\": \"ygd58\",\n     \"[redacted:email]\": \"HiddenPuppy\",\n     \"[redacted:email]\": \"jerome-benoit\",\n     \"wysie@users.noreply.github.com\": \"Wysie\","]},{"file":"tools/process_registry.py","hunks":["@@ -776,7 +776,7 @@ def _move_to_finished(self, session: ProcessSession):\n \n         # Only enqueue completion notification on the FIRST move.  Without\n         # this guard, kill_process() and the reader thread can both call\n-        # _move_to_finished(), producing duplicate [SYSTEM: ...] messages.\n+        # _move_to_finished(), producing duplicate [IMPORTANT: ...] messages.\n         if was_running and session.notify_on_complete:\n             from tools.ansi_strip import strip_ansi\n             output_tail = strip_ansi(session.output_buffer[-2000:]) if session.output_buffer else \"\"\n"]}]}],"trust":{"default_tier":"verified","includes_suggested":false}}