Pi: stream assistant text during RPC runs

This commit is contained in:
Peter Steinberger
2025-12-03 11:50:49 +00:00
parent 3958450223
commit 9253702966

View File

@@ -356,6 +356,29 @@ export async function runCommandReply(
pendingTimer = null;
}
};
let lastStreamedAssistant: string | undefined;
const streamAssistant = (msg?: {
role?: string;
content?: unknown[];
}) => {
if (!onPartialReply || msg?.role !== "assistant") return;
const textBlocks = Array.isArray(msg.content)
? (msg.content as Array<{ type?: string; text?: string }>)
.filter((c) => c?.type === "text" && typeof c.text === "string")
.map((c) => c.text.trim())
.filter(Boolean)
: [];
if (textBlocks.length === 0) return;
const combined = textBlocks.join("\n").trim();
if (!combined || combined === lastStreamedAssistant) return;
lastStreamedAssistant = combined;
const { text: cleanedText, mediaUrls: mediaFound } =
splitMediaFromOutput(combined);
void onPartialReply({
text: cleanedText,
mediaUrls: mediaFound?.length ? mediaFound : undefined,
} as ReplyPayload);
};
const run = async () => {
// Prefer long-lived tau RPC for pi agent to avoid cold starts.
@@ -380,7 +403,7 @@ export async function runCommandReply(
prompt: body,
timeoutMs,
onEvent:
verboseLevel === "on" && onPartialReply
onPartialReply
? (line: string) => {
try {
const ev = JSON.parse(line) as {
@@ -414,6 +437,13 @@ export async function runCommandReply(
TOOL_RESULT_DEBOUNCE_MS,
);
}
if (
ev.type === "message_end" ||
ev.type === "message_update" ||
ev.type === "message"
) {
streamAssistant(ev.message);
}
} catch {
// ignore malformed lines
}