feat: soften block streaming chunking

This commit is contained in:
Peter Steinberger
2026-01-03 16:45:53 +01:00
parent 53baba71fa
commit 9f8eeceae7
7 changed files with 270 additions and 29 deletions

View File

@@ -231,6 +231,58 @@ describe("subscribeEmbeddedPiSession", () => {
expect(subscription.assistantTexts).toEqual(["Hello block"]);
});
it("streams soft chunks with paragraph preference", () => {
let handler: ((evt: unknown) => void) | undefined;
const session: StubSession = {
subscribe: (fn) => {
handler = fn;
return () => {};
},
};
const onBlockReply = vi.fn();
const subscription = subscribeEmbeddedPiSession({
session: session as unknown as Parameters<
typeof subscribeEmbeddedPiSession
>[0]["session"],
runId: "run",
onBlockReply,
blockReplyBreak: "message_end",
blockReplyChunking: {
minChars: 5,
maxChars: 40,
breakPreference: "paragraph",
},
});
const text = "First block line\n\nSecond block line";
handler?.({
type: "message_update",
message: { role: "assistant" },
assistantMessageEvent: {
type: "text_delta",
delta: text,
},
});
const assistantMessage = {
role: "assistant",
content: [{ type: "text", text }],
} as AssistantMessage;
handler?.({ type: "message_end", message: assistantMessage });
expect(onBlockReply).toHaveBeenCalledTimes(2);
expect(onBlockReply.mock.calls[0][0].text).toBe("First block line");
expect(onBlockReply.mock.calls[1][0].text).toBe("Second block line");
expect(subscription.assistantTexts).toEqual([
"First block line",
"Second block line",
]);
});
it("waits for auto-compaction retry and clears buffered text", async () => {
const listeners: SessionEventHandler[] = [];
const session = {