diff --git a/docs/chat-chain-changes/2026-11-05-output-separators.md b/docs/chat-chain-changes/2026-11-05-output-separators.md new file mode 100644 index 0000000..4accd1d --- /dev/null +++ b/docs/chat-chain-changes/2026-11-05-output-separators.md @@ -0,0 +1,9 @@ +--- +date: 2026-11-05 +pr: pending +feature: Separate merged agent output +impact: Individual assistant messages within one run remain in one bubble but have visual dividers; the run completion marker is closer to the message. Stored text and chat events are unchanged. +--- + +Message boundaries are retained as display-only segments. The combined text +used for copying and speech remains unchanged. diff --git a/packages/client/src/components/hermes/chat/MessageItem.vue b/packages/client/src/components/hermes/chat/MessageItem.vue index 658e271..9435be1 100644 --- a/packages/client/src/components/hermes/chat/MessageItem.vue +++ b/packages/client/src/components/hermes/chat/MessageItem.vue @@ -228,6 +228,14 @@ const parsedThinking = computed(() => parseThinking(props.message.content || "", { streaming: !!props.message.isStreaming }), ); +const segmentBoundary = '\uE000hermes-output-boundary\uE001'; +const assistantBodySegments = computed(() => { + const segments = props.message.contentSegments; + if (!segments || segments.length < 2) return parsedThinking.value.body ? [parsedThinking.value.body] : []; + const parsed = parseThinking(segments.join(segmentBoundary), { streaming: !!props.message.isStreaming }); + return parsed.body.split(segmentBoundary).filter(segment => segment.trim()); +}); + // 优先使用来自 reasoning 字段/事件的思考文本;否则回退到从 content 解析的 标签。 // 若两者共存,则拼接展示(罕见,但保持信息不丢)。 const hasReasoningField = computed(() => !!(props.message.reasoning && props.message.reasoning.length > 0)); @@ -1111,11 +1119,12 @@ onBeforeUnmount(() => { - +