auto-reply: support multi-text RPC outputs
This commit is contained in:
@@ -13,36 +13,50 @@ type PiAssistantMessage = {
|
||||
|
||||
function parsePiJson(raw: string): AgentParseResult {
|
||||
const lines = raw.split(/\n+/).filter((l) => l.trim().startsWith("{"));
|
||||
let lastMessage: PiAssistantMessage | undefined;
|
||||
|
||||
// Collect every assistant message we see; Tau in RPC mode can emit multiple
|
||||
// assistant payloads in one run (e.g., queued turns, heartbeats). We concatenate
|
||||
// all text blocks so users see everything instead of only the last message_end.
|
||||
const texts: string[] = [];
|
||||
let lastAssistant: PiAssistantMessage | undefined;
|
||||
|
||||
for (const line of lines) {
|
||||
try {
|
||||
const ev = JSON.parse(line) as {
|
||||
type?: string;
|
||||
message?: PiAssistantMessage;
|
||||
};
|
||||
// Pi emits a stream; we only care about the terminal assistant message_end.
|
||||
if (ev.type === "message_end" && ev.message?.role === "assistant") {
|
||||
lastMessage = ev.message;
|
||||
const msg = ev.message;
|
||||
if (msg?.role === "assistant" && Array.isArray(msg.content)) {
|
||||
const msgText = msg.content
|
||||
.filter((c) => c?.type === "text" && typeof c.text === "string")
|
||||
.map((c) => c.text)
|
||||
.join("\n")
|
||||
.trim();
|
||||
if (msgText) texts.push(msgText);
|
||||
// keep meta from the most recent assistant message
|
||||
lastAssistant = msg;
|
||||
}
|
||||
} catch {
|
||||
// ignore
|
||||
// ignore malformed lines
|
||||
}
|
||||
}
|
||||
const text =
|
||||
lastMessage?.content
|
||||
?.filter((c) => c?.type === "text" && typeof c.text === "string")
|
||||
.map((c) => c.text)
|
||||
.join("\n")
|
||||
?.trim() ?? undefined;
|
||||
const meta: AgentMeta | undefined = lastMessage
|
||||
? {
|
||||
model: lastMessage.model,
|
||||
provider: lastMessage.provider,
|
||||
stopReason: lastMessage.stopReason,
|
||||
usage: lastMessage.usage,
|
||||
}
|
||||
: undefined;
|
||||
return { text, meta };
|
||||
|
||||
// Combine all assistant text messages (ignore tool calls/partials). This keeps
|
||||
// multi-message replies intact while dropping non-text events.
|
||||
const text = texts.length ? texts.join("\n\n").trim() : undefined;
|
||||
|
||||
const meta: AgentMeta | undefined =
|
||||
text && lastAssistant
|
||||
? {
|
||||
model: lastAssistant.model,
|
||||
provider: lastAssistant.provider,
|
||||
stopReason: lastAssistant.stopReason,
|
||||
usage: lastAssistant.usage,
|
||||
}
|
||||
: undefined;
|
||||
|
||||
return { texts, meta };
|
||||
}
|
||||
|
||||
export const piSpec: AgentSpec = {
|
||||
|
||||
Reference in New Issue
Block a user