← Back to PRs

#18876: fix(outbound): strip DSML function-call markup before delivery

by BinHPdev open 2026-02-17 04:57 View on GitHub →
channel: mattermost size: S
## Summary <!-- One-liner: what and why --> DeepSeek models emit `<|DSML|function_calls>` markup inline with user-visible text. This raw XML leaked into Discord (and other channel) messages, confusing end users. ## Problem When a DeepSeek model response contains both text and function calls, the DSML markup is included in the text content block. The outbound delivery pipeline had no stripping for this format, so it was sent verbatim to channels. Example user-visible message: ``` Perfect! I'll post the tweet now. <|DSML|function_calls> <|DSML|invoke name="exec"> … ``` ## Solution - Add `stripDsmlMarkup()` to `src/shared/text/reasoning-tags.ts` that removes everything from the first `<|DSML|` occurrence to end-of-string (DSML blocks always trail user-visible content) - Call it in `parseReplyDirectives()` which processes all outbound reply text, so all channels benefit ## Changes - `src/shared/text/reasoning-tags.ts` — new `stripDsmlMarkup()` export - `src/auto-reply/reply/reply-directives.ts` — call `stripDsmlMarkup()` on text before directive parsing - `src/shared/text/reasoning-tags.test.ts` — 5 new tests for DSML stripping ## Test plan - [x] All 49 reasoning-tags tests pass (39 existing + 5 new DSML + 5 new) - [x] `pnpm build` passes Closes #18644 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- greptile_comment --> <h3>Greptile Summary</h3> Adds `stripDsmlMarkup()` to strip DeepSeek DSML function-call markup (`<|DSML|...>`) from outbound messages before they reach users. The function is called within `parseReplyDirectives()`, which is the shared entry point for all outbound delivery paths (Discord, Telegram, Slack, and others). - `stripDsmlMarkup()` in `src/shared/text/reasoning-tags.ts` uses `indexOf` to find the first `<|DSML|` occurrence and slices everything from there to end-of-string, with `trimEnd()` cleanup. Clean and efficient. - Integration in `src/auto-reply/reply/reply-directives.ts` is minimal and well-placed — applied immediately after media splitting, before directive parsing. - Test file has a **duplicate `describe` block** — the same 5 tests appear twice (once with `\uFF5C` unicode escapes, once with literal `|` characters). One should be removed. <h3>Confidence Score: 4/5</h3> - This PR is safe to merge — the core logic is correct, minimal, and well-tested; only a non-critical test duplication needs cleanup. - The stripping logic is straightforward (indexOf + slice) and correctly handles edge cases. The integration point in parseReplyDirectives covers all major outbound delivery paths. Score of 4 rather than 5 due to the duplicated test describe block which, while not a runtime issue, indicates insufficient review of the test file before submission. - `src/shared/text/reasoning-tags.test.ts` has a fully duplicated describe block that should be removed. <sub>Last reviewed commit: f74888b</sub> <!-- greptile_other_comments_section --> <!-- /greptile_comment -->

Most Similar PRs