You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
refactor(copilot): resolve each special tag through four named outcomes
parseSpecialTags had grown five inline branches, each added for a specific
malformation found in a trace. The shape made "drop it" the implicit
fallback, which is how spans that were never malformed payloads ended up
silently swallowed.
Extracts resolveTagAt, returning one of four named outcomes — segment,
literal, discard, pending — so each decision is explicit and the main loop
just dispatches on it.
Fixes a latent bug the old shape hid: rejecting an unclosed tag ran `break`,
abandoning the rest of the message, so a genuinely valid tag after a literal
mention was never parsed. Resolution now resumes just past the rejected
opener and scanning continues. Test added.
Two behavior notes:
- Rejected spans are emitted in smaller pieces. The renderer concatenates
adjacent text segments into one markdown string, so this is display-neutral;
the two tests that asserted exact segment arrays now assert joined text.
- Each opener is judged on its own evidence. Previously one verdict ended the
whole parse, so a nested opener released everything; now the outer is
released immediately and the inner is a fresh candidate that can still hold
mid-stream. It resolves at end of stream either way.
Copy file name to clipboardExpand all lines: apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/special-tags/special-tags.test.ts
+33-11Lines changed: 33 additions & 11 deletions
Original file line number
Diff line number
Diff line change
@@ -176,6 +176,16 @@ describe('parseSpecialTags with <question>', () => {
176
176
)
177
177
})
178
178
179
+
it('still parses a valid tag that follows a rejected one',()=>{
180
+
// Before the rewrite, rejecting an unclosed tag abandoned the rest of the
181
+
// message, so this <options> tag was never parsed at all.
182
+
const{ segments }=parseSpecialTags(
183
+
'I use <thinking> loosely here. Anyway: <options>[{"title":"A","description":"d"}]</options> done.',
Copy file name to clipboardExpand all lines: apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/special-tags/special-tags.tsx
+85-61Lines changed: 85 additions & 61 deletions
Original file line number
Diff line number
Diff line change
@@ -604,11 +604,83 @@ function unclosedTagCannotResolve(
604
604
returnfalse
605
605
}
606
606
607
+
/**
608
+
* How one opening tag resolved. Naming the four outcomes is the point: the
609
+
* parser previously decided each case inline, which is how "drop it" quietly
610
+
* became the fallback for situations that were never malformed payloads.
611
+
*/
612
+
typeTagResolution=
613
+
/** Body parsed; emit the typed segment and resume after the closing tag. */
0 commit comments