feat: make block streaming break configurable

This commit is contained in:
Peter Steinberger
2026-01-03 00:52:02 +01:00
parent ea7d967625
commit 2d28fa34f5
8 changed files with 138 additions and 31 deletions

View File

@@ -61,6 +61,7 @@ export function subscribeEmbeddedPiSession(params: {
text?: string;
mediaUrls?: string[];
}) => void | Promise<void>;
blockReplyBreak?: "text_end" | "message_end";
onPartialReply?: (payload: {
text?: string;
mediaUrls?: string[];
@@ -74,8 +75,10 @@ export function subscribeEmbeddedPiSession(params: {
const assistantTexts: string[] = [];
const toolMetas: Array<{ toolName?: string; meta?: string }> = [];
const toolMetaById = new Map<string, string | undefined>();
const blockReplyBreak = params.blockReplyBreak ?? "text_end";
let deltaBuffer = "";
let lastStreamedAssistant: string | undefined;
let assistantTextBaseline = 0;
let compactionInFlight = false;
let pendingCompactionRetry = 0;
let compactionRetryResolve: (() => void) | undefined;
@@ -149,6 +152,7 @@ export function subscribeEmbeddedPiSession(params: {
toolMetaById.clear();
deltaBuffer = "";
lastStreamedAssistant = undefined;
assistantTextBaseline = 0;
toolDebouncer.flush();
};
@@ -264,38 +268,55 @@ export function subscribeEmbeddedPiSession(params: {
: "";
if (chunk) {
deltaBuffer += chunk;
const cleaned = params.enforceFinalTag
? stripThinkingSegments(stripUnpairedThinkingTags(deltaBuffer))
: stripThinkingSegments(deltaBuffer);
const next = params.enforceFinalTag
? (extractFinalText(cleaned)?.trim() ?? cleaned.trim())
: cleaned.trim();
if (next && next !== lastStreamedAssistant) {
lastStreamedAssistant = next;
}
const cleaned = params.enforceFinalTag
? stripThinkingSegments(stripUnpairedThinkingTags(deltaBuffer))
: stripThinkingSegments(deltaBuffer);
const next = params.enforceFinalTag
? (extractFinalText(cleaned)?.trim() ?? cleaned.trim())
: cleaned.trim();
if (next && next !== lastStreamedAssistant) {
lastStreamedAssistant = next;
const { text: cleanedText, mediaUrls } =
splitMediaFromOutput(next);
emitAgentEvent({
runId: params.runId,
stream: "assistant",
data: {
text: cleanedText,
mediaUrls: mediaUrls?.length ? mediaUrls : undefined,
},
});
params.onAgentEvent?.({
stream: "assistant",
data: {
text: cleanedText,
mediaUrls: mediaUrls?.length ? mediaUrls : undefined,
},
});
if (params.onPartialReply) {
void params.onPartialReply({
text: cleanedText,
mediaUrls: mediaUrls?.length ? mediaUrls : undefined,
});
}
}
if (evtType === "text_end" && blockReplyBreak === "text_end") {
if (next) assistantTexts.push(next);
if (next && params.onBlockReply) {
const { text: cleanedText, mediaUrls } =
splitMediaFromOutput(next);
emitAgentEvent({
runId: params.runId,
stream: "assistant",
data: {
text: cleanedText,
mediaUrls: mediaUrls?.length ? mediaUrls : undefined,
},
});
params.onAgentEvent?.({
stream: "assistant",
data: {
text: cleanedText,
mediaUrls: mediaUrls?.length ? mediaUrls : undefined,
},
});
if (params.onPartialReply) {
void params.onPartialReply({
if (cleanedText || (mediaUrls && mediaUrls.length > 0)) {
void params.onBlockReply({
text: cleanedText,
mediaUrls: mediaUrls?.length ? mediaUrls : undefined,
});
}
}
deltaBuffer = "";
lastStreamedAssistant = undefined;
}
}
}
@@ -317,8 +338,17 @@ export function subscribeEmbeddedPiSession(params: {
params.enforceFinalTag && cleaned
? (extractFinalText(cleaned)?.trim() ?? cleaned)
: cleaned;
if (text) assistantTexts.push(text);
if (text && params.onBlockReply) {
const addedDuringMessage =
assistantTexts.length > assistantTextBaseline;
if (!addedDuringMessage && text) assistantTexts.push(text);
assistantTextBaseline = assistantTexts.length;
if (
blockReplyBreak === "message_end" &&
text &&
params.onBlockReply
) {
const { text: cleanedText, mediaUrls } = splitMediaFromOutput(text);
if (cleanedText || (mediaUrls && mediaUrls.length > 0)) {
void params.onBlockReply({
@@ -328,6 +358,7 @@ export function subscribeEmbeddedPiSession(params: {
}
}
deltaBuffer = "";
lastStreamedAssistant = undefined;
}
}