Skip to content

Commit c32c82b

Browse files
obostjancicclaude
andcommitted
fix(ai): Address review bot feedback for XML tag renderer
Strip nested XML tags from inline tag content to prevent broken markdown with unmatched asterisks. Remove unused isBlock property from parseXmlTagSegments since preprocessInlineXmlTags handles the distinction. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 13eb77b commit c32c82b

File tree

2 files changed

+19
-20
lines changed

2 files changed

+19
-20
lines changed

static/app/views/performance/newTraceDetails/traceDrawer/details/span/eapSections/aiContentDetection.spec.ts

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -158,40 +158,41 @@ describe('preprocessInlineXmlTags', () => {
158158
const text = 'before <tag> spaced </tag> after';
159159
expect(preprocessInlineXmlTags(text)).toBe('before *tag: spaced* after');
160160
});
161+
162+
it('strips nested XML tags from inline tag content', () => {
163+
const text = 'Text <outer>before <inner>nested</inner> after</outer> more';
164+
expect(preprocessInlineXmlTags(text)).toBe(
165+
'Text *outer: before nested after* more'
166+
);
167+
});
161168
});
162169

163170
describe('parseXmlTagSegments', () => {
164-
it('marks inline XML tags with isBlock false', () => {
171+
it('splits text with XML tags into segments', () => {
165172
const text = 'Before <thinking>inner thought</thinking> After';
166173
const segments = parseXmlTagSegments(text);
167174
expect(segments).toEqual([
168175
{type: 'text', content: 'Before '},
169-
{type: 'xml-tag', tagName: 'thinking', content: 'inner thought', isBlock: false},
176+
{type: 'xml-tag', tagName: 'thinking', content: 'inner thought'},
170177
{type: 'text', content: ' After'},
171178
]);
172179
});
173180

174-
it('marks tag at start of text as block', () => {
181+
it('handles multiple XML tags', () => {
175182
const text = '<plan>step 1</plan> then <result>done</result>';
176183
const segments = parseXmlTagSegments(text);
177184
expect(segments).toEqual([
178-
{type: 'xml-tag', tagName: 'plan', content: 'step 1', isBlock: true},
185+
{type: 'xml-tag', tagName: 'plan', content: 'step 1'},
179186
{type: 'text', content: ' then '},
180-
{type: 'xml-tag', tagName: 'result', content: 'done', isBlock: false},
187+
{type: 'xml-tag', tagName: 'result', content: 'done'},
181188
]);
182189
});
183190

184-
it('marks tag preceded by newline as block', () => {
185-
const text = 'Some text\n<thinking>\nline1\nline2\n</thinking>';
191+
it('handles multiline content inside tags', () => {
192+
const text = '<thinking>\nline1\nline2\n</thinking>';
186193
const segments = parseXmlTagSegments(text);
187194
expect(segments).toEqual([
188-
{type: 'text', content: 'Some text\n'},
189-
{
190-
type: 'xml-tag',
191-
tagName: 'thinking',
192-
content: '\nline1\nline2\n',
193-
isBlock: true,
194-
},
195+
{type: 'xml-tag', tagName: 'thinking', content: '\nline1\nline2\n'},
195196
]);
196197
});
197198

@@ -208,7 +209,7 @@ describe('parseXmlTagSegments', () => {
208209
it('handles tags with hyphens in names', () => {
209210
const text = '<my-tag>content</my-tag>';
210211
expect(parseXmlTagSegments(text)).toEqual([
211-
{type: 'xml-tag', tagName: 'my-tag', content: 'content', isBlock: true},
212+
{type: 'xml-tag', tagName: 'my-tag', content: 'content'},
212213
]);
213214
});
214215

@@ -221,7 +222,6 @@ describe('parseXmlTagSegments', () => {
221222
tagName: 'bug_report',
222223
content:
223224
'\n<location>file.ts</location>\n<description>a bug</description>\n',
224-
isBlock: true,
225225
},
226226
]);
227227
});

static/app/views/performance/newTraceDetails/traceDrawer/details/span/eapSections/aiContentDetection.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ type AIContentType =
1010

1111
type ContentSegment =
1212
| {content: string; type: 'text'}
13-
| {content: string; isBlock: boolean; tagName: string; type: 'xml-tag'};
13+
| {content: string; tagName: string; type: 'xml-tag'};
1414

1515
interface AIContentDetectionResult {
1616
type: AIContentType;
@@ -57,12 +57,10 @@ export function parseXmlTagSegments(text: string): ContentSegment[] {
5757
if (match.index > lastIndex) {
5858
segments.push({type: 'text', content: text.slice(lastIndex, match.index)});
5959
}
60-
const isBlock = match.index === 0 || /\n\s*$/.test(text.slice(0, match.index));
6160
segments.push({
6261
type: 'xml-tag',
6362
tagName: match[1]!,
6463
content: match[2]!,
65-
isBlock,
6664
});
6765
lastIndex = match.index + match[0].length;
6866
}
@@ -82,7 +80,8 @@ export function preprocessInlineXmlTags(text: string): string {
8280
if (isBlock) {
8381
return match;
8482
}
85-
return `*${tagName}: ${content.trim()}*`;
83+
const stripped = content.replace(/<\/?[a-zA-Z][\w-]*>/g, '').trim();
84+
return `*${tagName}: ${stripped}*`;
8685
});
8786
}
8887

0 commit comments

Comments
 (0)