



























@@ -200,6 +200,47 @@ function resolveAssistantTextChunk(params: {
200200return "";
201201}
202202203+const REASONING_TAG_RE = /<\s*\/?\s*(?:(?:antml:)?(?:think(?:ing)?|thought)|antthinking)\b/i;
204+205+function resolveStreamVisibleText(params: {
206+previousRawText: string;
207+visibleDelta: string;
208+finalText?: string;
209+}): { rawText: string; visibleText: string } {
210+if (params.finalText !== undefined) {
211+const rawText = params.finalText;
212+return { rawText, visibleText: rawText.trim() };
213+}
214+const rawText = `${params.previousRawText}${params.visibleDelta}`;
215+return { rawText, visibleText: rawText.trim() };
216+}
217+218+function copyPartialBlockState(
219+target: EmbeddedAgentSubscribeState["partialBlockState"],
220+source: EmbeddedAgentSubscribeState["partialBlockState"],
221+) {
222+const copyFenceState = (fence?: typeof source.fence) =>
223+fence
224+ ? {
225+atLineStart: fence.atLineStart,
226+ ...(fence.open ? { open: { ...fence.open } } : {}),
227+}
228+ : undefined;
229+target.thinking = source.thinking;
230+target.final = source.final;
231+target.inlineCode = { ...source.inlineCode };
232+target.fence = copyFenceState(source.fence);
233+target.reasoningInlineCode = source.reasoningInlineCode
234+ ? { ...source.reasoningInlineCode }
235+ : undefined;
236+target.reasoningFence = copyFenceState(source.reasoningFence);
237+target.reasoningPendingFenceFragment = source.reasoningPendingFenceFragment;
238+target.finalInlineCode = source.finalInlineCode ? { ...source.finalInlineCode } : undefined;
239+target.finalFence = copyFenceState(source.finalFence);
240+target.pendingFenceFragment = source.pendingFenceFragment;
241+target.pendingTagFragment = source.pendingTagFragment;
242+}
243+203244export function resolveSilentReplyFallbackText(params: {
204245text: unknown;
205246messagingToolSentTexts: string[];
@@ -551,9 +592,6 @@ export function handleMessageUpdate(
551592if (isPhasePendingOpenAiResponsesTextItem) {
552593return;
553594}
554-const phaseAwareVisibleText = coerceChatContentText(
555-extractAssistantVisibleText(partialAssistant),
556-).trim();
557595const shouldUsePhaseAwareBlockReply = Boolean(deliveryPhase);
558596559597if (chunk) {
@@ -567,27 +605,58 @@ export function handleMessageUpdate(
567605// Handle partial <think> tags: stream whatever reasoning is visible so far.
568606ctx.emitReasoningStream(extractThinkingFromTaggedStream(ctx.state.deltaBuffer));
569607}
570-const next =
571-phaseAwareVisibleText ||
572-(deliveryPhase === "final_answer"
573- ? ""
574- : ctx
575-.stripBlockTags(
576-ctx.state.deltaBuffer,
577-{
578-thinking: false,
579-final: false,
580-inlineCode: createInlineCodeState(),
581-},
582-{ final: evtType === "text_end" },
583-)
584-.trim());
608+const wasThinking = ctx.state.partialBlockState.thinking;
609+let visibleDelta = "";
610+let next = shouldUsePhaseAwareBlockReply
611+ ? coerceChatContentText(extractAssistantVisibleText(partialAssistant)).trim()
612+ : "";
613+let nextRawStreamText = next;
614+if (!next && deliveryPhase !== "final_answer") {
615+const pendingTagFragment = ctx.state.partialBlockState.pendingTagFragment;
616+const shouldRecomputeFullStream = Boolean(pendingTagFragment) || REASONING_TAG_RE.test(chunk);
617+if (shouldRecomputeFullStream) {
618+const recomputeState: EmbeddedAgentSubscribeState["partialBlockState"] = {
619+thinking: false,
620+final: false,
621+inlineCode: createInlineCodeState(),
622+};
623+const recomputedRawText = ctx.stripBlockTags(ctx.state.deltaBuffer, recomputeState, {
624+final: evtType === "text_end",
625+});
626+const previousRawText = ctx.state.lastStreamedAssistant ?? "";
627+const isFullStreamReplacement = !recomputedRawText.startsWith(previousRawText);
628+next = recomputedRawText.trim();
629+visibleDelta = isFullStreamReplacement
630+ ? recomputedRawText
631+ : recomputedRawText.slice(previousRawText.length);
632+nextRawStreamText = recomputedRawText;
633+copyPartialBlockState(ctx.state.partialBlockState, recomputeState);
634+} else {
635+visibleDelta =
636+chunk || evtType === "text_end"
637+ ? ctx.stripBlockTags(chunk, ctx.state.partialBlockState, {
638+final: evtType === "text_end",
639+})
640+ : "";
641+if (ctx.state.partialBlockState.pendingTagFragment) {
642+visibleDelta = "";
643+next = ctx.state.lastStreamedAssistantCleaned ?? "";
644+nextRawStreamText = ctx.state.lastStreamedAssistant ?? "";
645+} else {
646+const streamVisibleText = resolveStreamVisibleText({
647+previousRawText: ctx.state.lastStreamedAssistant ?? "",
648+ visibleDelta,
649+});
650+next = streamVisibleText.visibleText;
651+nextRawStreamText = streamVisibleText.rawText;
652+}
653+}
654+} else if (next && (chunk || evtType === "text_end")) {
655+visibleDelta = ctx.stripBlockTags(chunk, ctx.state.partialBlockState, {
656+final: evtType === "text_end",
657+});
658+}
585659if (next) {
586-const wasThinking = ctx.state.partialBlockState.thinking;
587-const visibleDelta =
588-chunk || evtType === "text_end"
589- ? ctx.stripBlockTags(chunk, ctx.state.partialBlockState, { final: evtType === "text_end" })
590- : "";
591660if (!wasThinking && ctx.state.partialBlockState.thinking) {
592661openReasoningStream(ctx);
593662}
@@ -636,7 +705,7 @@ export function handleMessageUpdate(
636705}
637706}
638707639-ctx.state.lastStreamedAssistant = next;
708+ctx.state.lastStreamedAssistant = nextRawStreamText;
640709ctx.state.lastStreamedAssistantCleaned = cleanedText;
641710642711if (ctx.params.silentExpected || suppressDeterministicApprovalOutput) {
@@ -755,7 +824,21 @@ export function handleMessageEnd(
755824ctx.state.blockState.thinking = false;
756825ctx.state.blockState.final = false;
757826ctx.state.blockState.inlineCode = createInlineCodeState();
827+ctx.state.blockState.fence = undefined;
828+ctx.state.blockState.reasoningInlineCode = undefined;
829+ctx.state.blockState.reasoningFence = undefined;
830+ctx.state.blockState.reasoningPendingFenceFragment = undefined;
831+ctx.state.blockState.finalInlineCode = undefined;
832+ctx.state.blockState.finalFence = undefined;
833+ctx.state.blockState.pendingFenceFragment = undefined;
758834ctx.state.blockState.pendingTagFragment = undefined;
835+ctx.state.partialBlockState.fence = undefined;
836+ctx.state.partialBlockState.reasoningInlineCode = undefined;
837+ctx.state.partialBlockState.reasoningFence = undefined;
838+ctx.state.partialBlockState.reasoningPendingFenceFragment = undefined;
839+ctx.state.partialBlockState.finalInlineCode = undefined;
840+ctx.state.partialBlockState.finalFence = undefined;
841+ctx.state.partialBlockState.pendingFenceFragment = undefined;
759842ctx.state.partialBlockState.pendingTagFragment = undefined;
760843ctx.state.lastStreamedAssistant = undefined;
761844ctx.state.lastStreamedAssistantCleaned = undefined;
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。