Normalize incoming reasoning at the shared heading boundary and completed extraction, and flatten auxiliary content and reasoning before accumulation. Reuse the existing text flattener with no implicit fragment separators. Combine the earliest related work from zsuroy (#85791), the diagnosis and patch from 2025hcsmile2010-hue (#104711, #104848), and completed extraction work from liuhao1024 (#104717) as a slim redo, not a verbatim cherry-pick. Two invariant tests exercise the real SDK and local HTTP fixture across main streaming, Relay collection, auxiliary sync/async and completed output. The standalone matrix improves from 32/84 to 84/84, preserving answers. Co-authored-by: suroy <suroy@qq.com> Co-authored-by: 2025hcsmile2010-hue <2025hcsmile2010@gmail.com> Co-authored-by: liuhao1024 <sunsky.lau@gmail.com>
32 lines
1.6 KiB
Python
32 lines
1.6 KiB
Python
"""Boundary repair for providers that stream reasoning as discrete summary parts.
|
|
|
|
Reasoning-summary models (OpenAI gpt-5.x and Responses-API relays onto the chat wire) emit one
|
|
``reasoning_content`` delta per *completed* summary part, each opening with a bold heading.
|
|
The chat wire lacks the Responses API's ``summary_index`` delimiter (verified live on Nous
|
|
Portal ``openai/gpt-5.6-sol``), so plain concatenation glues ``**One****Two**`` into one
|
|
half-bold paragraph. The boundary is re-derived from a delta opening a bold heading, matching
|
|
the blank-line join Hermes' own Responses adapter does.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
|
|
from agent.message_content import flatten_message_text
|
|
|
|
__all__ = ["separate_glued_reasoning_blocks"]
|
|
|
|
|
|
def separate_glued_reasoning_blocks(previous: str, delta: Any) -> str:
|
|
"""Return *delta*, prefixed with a paragraph break when it glues onto *previous*.
|
|
|
|
A break is inserted when *delta* opens a *closed* bold heading and *previous* is mid-line
|
|
(heading butting heading, or prose butting heading). Token-streamed reasoning is left
|
|
alone: its deltas carry their own whitespace, and a fragment that merely opens emphasis
|
|
(``**`` alone) is not a part boundary — summary parts carry the whole heading in one delta.
|
|
"""
|
|
# Relays also emit content-part lists/dicts; fragments carry their own whitespace.
|
|
delta = flatten_message_text(delta, sep="")
|
|
glued = previous and delta and not previous[-1].isspace() and delta.startswith("**") and "**" in delta[2:]
|
|
return f"\n\n{delta}" if glued else delta
|