-
Notifications
You must be signed in to change notification settings - Fork 103
Standalone </think> close tags are rendered as assistant text during streaming #47
Copy link
Copy link
Open
Labels
comp/docsPublic docs, README, security/privacy/data-flow docsPublic docs, README, security/privacy/data-flow docscomp/gatewayHermes gateway lifecycle, runtime connection, logs, local service behaviorHermes gateway lifecycle, runtime connection, logs, local service behaviorcomp/modelsModel discovery, model picker, provider routing, runtime optionsModel discovery, model picker, provider routing, runtime optionscomp/sidepanelSide panel UI, composer, messages, menus, settings shellSide panel UI, composer, messages, menus, settings shellneeds/browser-consoleNeeds sidepanel/service-worker console logs or network failure detailsNeeds sidepanel/service-worker console logs or network failure detailsp3Low: minor bug, polish, docs, duplicate, or follow-upLow: minor bug, polish, docs, duplicate, or follow-upplatform/chromeChrome-specific behavior or extension runtime issueChrome-specific behavior or extension runtime issuestatus/needs-infoNeeds more user/reporter information before actionNeeds more user/reporter information before actionsweep:risk-releaseAutomation/review risk: release, package, manifest, tag, or asset driftAutomation/review risk: release, package, manifest, tag, or asset drifttype/docsDocumentation improvementsDocumentation improvementstype/supportSupport, setup, usage, or compatibility questionSupport, setup, usage, or compatibility question
Description
Metadata
Metadata
Assignees
Labels
comp/docsPublic docs, README, security/privacy/data-flow docsPublic docs, README, security/privacy/data-flow docscomp/gatewayHermes gateway lifecycle, runtime connection, logs, local service behaviorHermes gateway lifecycle, runtime connection, logs, local service behaviorcomp/modelsModel discovery, model picker, provider routing, runtime optionsModel discovery, model picker, provider routing, runtime optionscomp/sidepanelSide panel UI, composer, messages, menus, settings shellSide panel UI, composer, messages, menus, settings shellneeds/browser-consoleNeeds sidepanel/service-worker console logs or network failure detailsNeeds sidepanel/service-worker console logs or network failure detailsp3Low: minor bug, polish, docs, duplicate, or follow-upLow: minor bug, polish, docs, duplicate, or follow-upplatform/chromeChrome-specific behavior or extension runtime issueChrome-specific behavior or extension runtime issuestatus/needs-infoNeeds more user/reporter information before actionNeeds more user/reporter information before actionsweep:risk-releaseAutomation/review risk: release, package, manifest, tag, or asset driftAutomation/review risk: release, package, manifest, tag, or asset drifttype/docsDocumentation improvementsDocumentation improvementstype/supportSupport, setup, usage, or compatibility questionSupport, setup, usage, or compatibility question
Summary
During some multi-tool runs, the Browser Extension renders repeated standalone
</think>lines inside the assistant message while the response is streaming.These lines are reasoning/protocol boundary markers and should not be displayed as assistant text.
The persisted final assistant content may be clean, while the temporary streaming UI still contains the leaked markers.
Environment
mainUser-visible behavior
The assistant card can temporarily look like this:
The actual answer may appear only after additional tool calls finish.
Deterministic reproduction
The behavior can be reproduced directly with the stream reducer:
Expected behavior
Standalone reasoning close-tag lines should not be rendered as assistant text.
Normal assistant content must remain unchanged, including legitimate inline references such as:
Actual behavior
reduceAssistantStreamText()appends everyassistant.deltadirectly to the current display text. Standalone closing tags are therefore rendered like normal assistant output.The
assistant.completedandrun.completedreconciliation paths may also restore unsanitized content.Affected file:
extension/lib/runtime-events.mjsSuggested fix
Add a narrow display-boundary sanitizer that removes only complete lines composed entirely of orphan reasoning closing tags, for example:
</think></thinking></reasoning></thought></REASONING_SCRATCHPAD>Apply it to the accumulated display text after:
assistant.deltaassistant.completedrun.completedreconciliationThe filter should not remove inline text or code containing a literal tag.
This client-side guard is useful even if the malformed or unmatched close tag originally comes from the upstream Gateway stream: protocol markers should not leak into the user-facing assistant card.
Regression tests
Please add tests covering:
assistant.completed.</think>remain unchanged.This repo is using Opire - what does it mean? 👇
💵 Everyone can add rewards for this issue commenting
/reward 100(replace100with the amount).🕵️♂️ If someone starts working on this issue to earn the rewards, they can comment
/tryto let everyone know!🙌 And when they open the PR, they can comment
/claim #47either in the PR description or in a PR's comment.🪙 Also, everyone can tip any user commenting
/tip 20 @abstramagic27(replace20with the amount, and@abstramagic27with the user to tip).📖 If you want to learn more, check out our documentation.