Files
OmniRoute/open-sse/utils/reasoningPlaceholder.ts
Austin Liu 07dada6b81 fix: strip internal reasoning placeholder from user-visible content (#8081) (#8162)
* fix: strip internal reasoning placeholder from user-visible content (#8081)

The internal reasoning replay sentinel '(prior reasoning summary unavailable)'
can leak into user-visible assistant content when a model echoes it through
ordinary message.content / delta.content. Existing suppression only checked
reasoning_content fields and reasoning-specific events.

Changes:
- Add stripInternalReasoningPlaceholder() to reasoningPlaceholder.ts —
  removes all occurrences of the sentinel and trims; returns '' when
  nothing meaningful remains
- Streaming: strip in responsesTransformer.ts, openai-responses.ts, and
  openai-to-claude.ts at the delta.content entry point; skip emission
  entirely when only the placeholder was present
- Non-streaming: strip in responseSanitizer.ts sanitizeMessageContent()
  and sanitizeResponsesMessageContent() (all three text paths)

translateText is unaffected (uses mode='translate' via plain newsClient).
The per-provider reasoning_content check remains as defense-in-depth.

* fix: skip only empty content block on reasoning-placeholder, keep finish_reason/tool_calls (#8081)

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>

* chore(quality): rebaseline openai-responses.ts own-growth (#8081 guard)

---------

Co-authored-by: Austin Liu <austinliu@Austins-MacBook-Air-3.local>
Co-authored-by: Probe Test <probe@example.com>
Co-authored-by: Dingding-leo <Dingding-leo@users.noreply.github.com>
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
2026-07-22 19:04:51 -03:00

21 lines
997 B
TypeScript

/**
* Internal replay sentinel used when an upstream requires non-empty reasoning content but the
* original reasoning summary is unavailable. It is valid request scaffolding, never user-visible
* reasoning, so response translators must suppress it before emitting client-facing events.
*/
export const NON_ANTHROPIC_THINKING_PLACEHOLDER = "(prior reasoning summary unavailable)";
export function isInternalReasoningPlaceholder(value: unknown): boolean {
return typeof value === "string" && value.trim() === NON_ANTHROPIC_THINKING_PLACEHOLDER;
}
/**
* Strip the internal placeholder from user-visible content. Models sometimes
* echo the sentinel through ordinary `message.content` / `delta.content`
* (#8081). Removes all occurrences and trims; returns "" when nothing
* meaningful remains so callers can skip emission entirely.
*/
export function stripInternalReasoningPlaceholder(value: string): string {
return value.replaceAll(NON_ANTHROPIC_THINKING_PLACEHOLDER, "").trim();
}