diff --git a/strix/core/agents.py b/strix/core/agents.py
index c96204df..dd117b45 100644
--- a/strix/core/agents.py
+++ b/strix/core/agents.py
@@ -5,6 +5,7 @@ from __future__ import annotations
import asyncio
import json
import logging
+import re
import tempfile
from dataclasses import dataclass, field
from pathlib import Path
@@ -29,6 +30,22 @@ Status = Literal["running", "waiting", "completed", "stopped", "crashed", "faile
# on other agents is re-checked on a timer.
WaitKind = Literal["user", "agents", "stalled"]
+_CHATGPT_TRANSCRIPT_TAGS = (
+ "analysis",
+ "assistant",
+ "channel",
+ "final",
+ "user",
+)
+_CHATGPT_TRANSCRIPT_TAG_RE = re.compile(
+ rf"?(?:{'|'.join(_CHATGPT_TRANSCRIPT_TAGS)})\s*>",
+ flags=re.IGNORECASE,
+)
+
+
+def _strip_chatgpt_transcript_tags(content: str) -> str:
+ return _CHATGPT_TRANSCRIPT_TAG_RE.sub("", content)
+
@dataclass(slots=True)
class AgentRuntime:
@@ -372,7 +389,7 @@ class AgentCoordinator:
await self._maybe_snapshot()
async def cancel_descendants(self, agent_id: str) -> None:
- tasks = []
+ tasks: list[asyncio.Task[Any]] = []
async with self._lock:
for aid in reversed(self._subtree_order_locked(agent_id)):
task = self.runtimes.get(aid, AgentRuntime()).task
@@ -437,7 +454,7 @@ class AgentCoordinator:
def _message_to_session_item(self, message: dict[str, Any]) -> TResponseInputItem:
sender = str(message.get("from", "unknown"))
- content = str(message.get("content", ""))
+ content = _strip_chatgpt_transcript_tags(str(message.get("content", "")))
if sender == "user":
return cast("TResponseInputItem", {"role": "user", "content": content})
sender_name = self.names.get(sender, sender)
diff --git a/tests/test_agent_messages.py b/tests/test_agent_messages.py
new file mode 100644
index 00000000..1594c47e
--- /dev/null
+++ b/tests/test_agent_messages.py
@@ -0,0 +1,35 @@
+"""Tests for agent-to-session message conversion."""
+
+from __future__ import annotations
+
+from strix.core.agents import AgentCoordinator
+
+
+CHATGPT_TRANSCRIPT_CONTENT = (
+ "checked target\nfinal\ndone"
+)
+
+
+def test_message_to_session_item_strips_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,
+ }
+ )
+
+ content = str(item["content"])
+
+ assert "" not in content
+ assert "" not in 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