Skip to content

fix: strip chatgpt transcript tags from agent messages#735

Open
ousamabenyounes wants to merge 2 commits into
usestrix:mainfrom
ousamabenyounes:fix/issue-118
Open

fix: strip chatgpt transcript tags from agent messages#735
ousamabenyounes wants to merge 2 commits into
usestrix:mainfrom
ousamabenyounes:fix/issue-118

Conversation

@ousamabenyounes

@ousamabenyounes ousamabenyounes commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Summary

Fix #118

Strip ChatGPT-style transcript tags from messages before appending them to the SDK session, so agent-originated content cannot be resent to OpenAI-compatible providers with rejected tags like <analysis>, <channel>, or <final>.

Follow-up review fixes:

  • Preserve literal transcript-like tags in user prompts instead of sanitizing user-provided content.
  • Strip attributed and self-closing transcript tags such as <final reason="done"> and <analysis/> from non-user messages.

Also annotates the descendant task list in the same module so the touched file passes pyright.

Test verification (RED -> GREEN)

RED with the follow-up production fix reverted, while keeping the new regression tests:

uv run pytest tests/test_agent_messages.py -q
FAILED tests/test_agent_messages.py::test_message_to_session_item_preserves_user_literal_tags
FAILED tests/test_agent_messages.py::test_message_to_session_item_strips_attributed_chatgpt_transcript_tags
2 failed, 1 passed

GREEN with the follow-up fix applied:

uv run pytest tests/test_agent_messages.py -q
3 passed

Full suite:

uv run pytest -q
145 passed, 2 warnings

Additional targeted validation:

uv run ruff check strix/core/agents.py tests/test_agent_messages.py
All checks passed!

uv run ruff format --check strix/core/agents.py tests/test_agent_messages.py
2 files already formatted

uv run mypy strix/core/agents.py
Success: no issues found in 1 source file

uv run pyright strix/core/agents.py
0 errors, 0 warnings, 0 informations

Global quality baseline notes, not introduced by this PR:

uv run ruff format --check .
Would reformat: strix/core/hooks.py, strix/interface/utils.py, tests/test_cli_target_list.py, tests/test_local_sources.py

uv run ruff check .
4 existing errors in strix/core/hooks.py, strix/runtime/docker_client.py, strix/telemetry/logging.py

uv run mypy strix/
69 existing errors in TUI/Pygments-related files

@greptile-apps

greptile-apps Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR strips ChatGPT-style transcript tags before messages are appended to the SDK session. The main changes are:

  • Added a compiled regex and helper for transcript-tag stripping.
  • Applied the helper in agent message conversion.
  • Added a focused regression test for simple transcript tags.
  • Added a task-list type annotation in descendant cancellation.

Confidence Score: 4/5

The changed message conversion path needs a fix before merging.

  • User-provided prompts can lose literal XML-like tags before they reach the SDK session.
  • The new pattern handles the tested bare tags, but not attributed or self-closing forms.
  • The import and task annotation changes look compatible with the project target.

strix/core/agents.py

Important Files Changed

Filename Overview
strix/core/agents.py Adds transcript-tag stripping in session message conversion and a compatible task-list annotation.
tests/test_agent_messages.py Adds coverage for stripping simple <analysis>, <channel>, and <final> tags while preserving inner text.
Prompt To Fix All With AI
Fix the following 2 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 2
strix/core/agents.py:268-271
**User Prompts Lose Literal Tags**

When a user sends text through the CLI, TUI, or resume instruction path, this line strips `<user>`, `<final>`, `<analysis>`, and the other transcript tags before the sender check. A prompt that asks the agent to inspect XML/HTML or preserve a snippet containing those literal tags is changed before it reaches the SDK session, so the model receives different input than the user provided.

```suggestion
        sender = str(message.get("from", "unknown"))
        content = str(message.get("content", ""))
        if sender == "user":
            return cast("TResponseInputItem", {"role": "user", "content": content})
        content = _strip_chatgpt_transcript_tags(content)
```

### Issue 2 of 2
strix/core/agents.py:31-34
**Attributed Transcript Tags Survive**

This pattern only removes bare tags such as `<final>` and `</final>`. If an agent message contains the same transcript tags with attributes or self-closing syntax, such as `<final reason="done">` or `<analysis/>`, those tags stay in the session item and can still be resent to an OpenAI-compatible provider that rejects transcript markup.

```suggestion
_CHATGPT_TRANSCRIPT_TAG_RE = re.compile(
    rf"</?(?:{'|'.join(_CHATGPT_TRANSCRIPT_TAGS)})(?:\s+[^>]*)?\s*/?>",
    flags=re.IGNORECASE,
)
```

Reviews (1): Last reviewed commit: "fix: strip chatgpt transcript tags from ..." | Re-trigger Greptile

Comment thread strix/core/agents.py
Comment thread strix/core/agents.py
@ousamabenyounes

Copy link
Copy Markdown
Contributor Author

Addressed the two Greptile review comments in a23be85.

  • User prompts now bypass transcript-tag stripping so literal XML/transcript-like snippets are preserved. Covered by test_message_to_session_item_preserves_user_literal_tags.
  • Non-user transcript stripping now handles optional attributes and self-closing syntax. Covered by test_message_to_session_item_strips_attributed_chatgpt_transcript_tags.

Verification:

uv run pytest tests/test_agent_messages.py -q
3 passed

uv run pytest -q
145 passed, 2 warnings

Revert proof: with the production fix reverted and the new tests kept, the targeted file fails with 2 failed / 1 passed.

@0xallam
0xallam force-pushed the main branch 3 times, most recently from 44e87ca to daf39a2 Compare July 13, 2026 23:50
Preserve literal transcript-like tags in user prompts.

Strip attributed and self-closing transcript tags from non-user session messages.

RED->GREEN: new regression tests fail with the production fix reverted, then pass with 3 passed. Full suite: 145 passed, 2 warnings.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG]litellm.BadRequestError - LLM API Rejects Messages Containing <channel> Tags

1 participant