fix(backend): bridge maps real Pi message_update->text_delta for FE streaming
Live end-to-end against real pi --mode rpc revealed Pi streams assistant text as top-level message_update events whose nested assistantMessageEvent carries the incremental delta — not the top-level text_delta the fake-pi-rpc emits. The bridge now maps message_update(assistantMessageEvent.text_delta).delta -> FE text_delta, so the chat shows the model's output during a real session. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -19,6 +19,11 @@ export class SessionBridge {
|
||||
this.fan({ type: "ui_request", ui_request: descriptor });
|
||||
} else if (m.type === "extension_ui_request" && m.method === "notify") {
|
||||
this.fan({ type: "info", level: m.notifyType ?? "info", text: m.message ?? "" });
|
||||
} else if (m.type === "message_update" && m.assistantMessageEvent?.type === "text_delta") {
|
||||
// Real Pi streams assistant text as message_update events whose nested
|
||||
// assistantMessageEvent carries the incremental `delta`. Map it to the FE's
|
||||
// text_delta contract. (Top-level text_delta below is what the fake-pi-rpc emits.)
|
||||
this.fan({ type: "text_delta", text: m.assistantMessageEvent.delta ?? "" });
|
||||
} else if (m.type === "text_delta") {
|
||||
this.fan({ type: "text_delta", text: m.text ?? "" });
|
||||
} else if (m.type === "system_event") {
|
||||
|
||||
@@ -15,6 +15,19 @@ function fakeRpc() {
|
||||
};
|
||||
}
|
||||
|
||||
test("real Pi message_update (assistantMessageEvent text_delta) becomes a text_delta to the FE", () => {
|
||||
const { rpc, fire } = fakeRpc();
|
||||
const b = new SessionBridge(rpc);
|
||||
const seen: any[] = [];
|
||||
b.onClientEvent((e) => seen.push(e));
|
||||
// Shape emitted by real `pi --mode rpc`: text streams inside message_update.assistantMessageEvent.delta
|
||||
fire({ type: "message_update", assistantMessageEvent: { type: "text_delta", contentIndex: 0, delta: "Avvio" } });
|
||||
expect(seen[0]).toEqual({ type: "text_delta", text: "Avvio" });
|
||||
// Non-text message_update events (e.g. text_start) are ignored.
|
||||
fire({ type: "message_update", assistantMessageEvent: { type: "text_start", contentIndex: 0 } });
|
||||
expect(seen).toHaveLength(1);
|
||||
});
|
||||
|
||||
test("extension_ui_request nativo (method:input, title=json) diventa ui_request ed è il pendente", () => {
|
||||
const { rpc, fire } = fakeRpc();
|
||||
const b = new SessionBridge(rpc);
|
||||
|
||||
Reference in New Issue
Block a user