import { test, expect, vi } from "vitest"; import { SessionBridge } from "../src/bridge/session-bridge.js"; function fakeRpc() { const sent: any[] = []; let evcb: any; return { rpc: { send: (c: any) => sent.push(c), on: (_: any, cb: any) => { evcb = cb; }, request: vi.fn(), } as any, sent, fire: (m: any) => evcb(m), }; } 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); const seen: any[] = []; b.onClientEvent((e) => seen.push(e)); const descriptor = { id: "u1", widget: "select" }; fire({ type: "extension_ui_request", id: "u1", method: "input", title: JSON.stringify(descriptor) }); expect(seen[0]).toEqual({ type: "ui_request", ui_request: descriptor }); expect(b.pendingWidget()).toEqual(descriptor); }); test("respond invia extension_ui_response con payload in value e azzera il pendente", () => { const { rpc, sent, fire } = fakeRpc(); const b = new SessionBridge(rpc); fire({ type: "extension_ui_request", id: "u1", method: "input", title: JSON.stringify({ id: "u1", widget: "select" }) }); b.respond({ id: "u1", choices: ["a"] }); expect(sent.at(-1)).toEqual({ type: "extension_ui_response", id: "u1", value: JSON.stringify({ id: "u1", choices: ["a"] }) }); expect(b.pendingWidget()).toBeNull(); }); test("steer invia un comando steer", () => { const { rpc, sent } = fakeRpc(); new SessionBridge(rpc).steer("considera solo il 2024"); expect(sent.at(-1)).toEqual({ type: "steer", message: "considera solo il 2024" }); });