diff --git a/strix/core/agents.py b/strix/core/agents.py
index dd117b45..bba2bc54 100644
--- a/strix/core/agents.py
+++ b/strix/core/agents.py
@@ -37,8 +37,10 @@ _CHATGPT_TRANSCRIPT_TAGS = (
"final",
"user",
)
+_CHATGPT_TRANSCRIPT_TAG_ALTERNATION = "|".join(re.escape(tag) for tag in _CHATGPT_TRANSCRIPT_TAGS)
+_OPTIONAL_TAG_ATTRIBUTES_PATTERN = r"(?:\s+[^>]*)?"
_CHATGPT_TRANSCRIPT_TAG_RE = re.compile(
- rf"?(?:{'|'.join(_CHATGPT_TRANSCRIPT_TAGS)})\s*>",
+ rf"?(?:{_CHATGPT_TRANSCRIPT_TAG_ALTERNATION}){_OPTIONAL_TAG_ATTRIBUTES_PATTERN}\s*/?>",
flags=re.IGNORECASE,
)
@@ -454,9 +456,10 @@ class AgentCoordinator:
def _message_to_session_item(self, message: dict[str, Any]) -> TResponseInputItem:
sender = str(message.get("from", "unknown"))
- content = _strip_chatgpt_transcript_tags(str(message.get("content", "")))
+ content = str(message.get("content", ""))
if sender == "user":
return cast("TResponseInputItem", {"role": "user", "content": content})
+ content = _strip_chatgpt_transcript_tags(content)
sender_name = self.names.get(sender, sender)
msg_type = message.get("type", "information")
priority = message.get("priority", "normal")
diff --git a/tests/test_agent_messages.py b/tests/test_agent_messages.py
index 1594c47e..76e8f2d0 100644
--- a/tests/test_agent_messages.py
+++ b/tests/test_agent_messages.py
@@ -8,6 +8,16 @@ from strix.core.agents import AgentCoordinator
CHATGPT_TRANSCRIPT_CONTENT = (
"checked target\nfinal\ndone"
)
+CHATGPT_TRANSCRIPT_CONTENT_WITH_ATTRIBUTES = (
+ 'checked target\n'
+ 'final\n'
+ 'done\n'
+ ""
+)
+USER_LITERAL_TAG_CONTENT = (
+ "Please preserve this XML-like snippet: "
+ 'literal user content and done'
+)
def test_message_to_session_item_strips_chatgpt_transcript_tags() -> None:
@@ -33,3 +43,39 @@ def test_message_to_session_item_strips_chatgpt_transcript_tags() -> None:
assert "" not in content
assert "checked target" in content
assert "done" in content
+
+
+def test_message_to_session_item_preserves_user_literal_tags() -> None:
+ coordinator = AgentCoordinator()
+
+ item = coordinator._message_to_session_item(
+ {
+ "from": "user",
+ "content": USER_LITERAL_TAG_CONTENT,
+ }
+ )
+
+ assert item["content"] == USER_LITERAL_TAG_CONTENT
+
+
+def test_message_to_session_item_strips_attributed_chatgpt_transcript_tags() -> None:
+ coordinator = AgentCoordinator()
+ coordinator.names["child"] = "Researcher"
+
+ item = coordinator._message_to_session_item(
+ {
+ "from": "child",
+ "type": "information",
+ "priority": "normal",
+ "content": CHATGPT_TRANSCRIPT_CONTENT_WITH_ATTRIBUTES,
+ }
+ )
+
+ content = str(item["content"])
+
+ assert '' not in content
+ assert '' not in content
+ assert '' not in content
+ assert "" not in content
+ assert "checked target" in content
+ assert "done" in content