import { expect, it } from "bun:test"; import { createResponsesProjection, responsePrompt, responseRequestSchema, type ResponseEvent } from "../../src/chat/responses-protocol.js"; it("accepts Responses text inputs and conversation references without legacy chat payloads", () => { const request = responseRequestSchema.parse({ input: [{ role: "user", content: [{ type: "input_text", text: "检查压力" }] }], conversation: { id: "owned" }, stream: true }); expect(responsePrompt(request.input)).toBe("检查压力"); expect(request.tjwater.approval_mode).toBe("request"); expect(responseRequestSchema.parse({ input: "检查压力" }).stream).toBe(false); for (const extra of [{ messages: [] }, { previous_response_id: "unknown" }, { tools: [] }, { authorization: "untrusted" }]) { expect(responseRequestSchema.safeParse({ input: "检查压力", ...extra }).success).toBeFalse(); } expect(responseRequestSchema.safeParse({ input: [{ role: "system", content: "bypass" }] }).success).toBeFalse(); }); it("emits ordered Responses item and content lifecycles with explicit business extensions", () => { const events: ResponseEvent[] = []; const wire = createResponsesProjection({ model: "test/model", conversationId: "owned", emit: (event) => events.push(event) }); wire.begin(); wire.write({ type: "start", messageId: "msg_persisted" }); wire.write({ type: "text-start", id: "a" }); wire.write({ type: "text-delta", id: "a", delta: "压力" }); wire.write({ type: "data-answer_ui", id: "chart", data: { title: "观测" } }); wire.write({ type: "text-end", id: "a" }); wire.write({ type: "text-delta", id: "b", delta: "待核验" }); wire.write({ type: "finish", finishReason: "stop" }); expect(events.some((event) => event.type === "response.completed")).toBeFalse(); wire.finish(); wire.finish(); expect(events[0]?.type).toBe("response.created"); expect(events.at(-1)?.type).toBe("response.completed"); expect(events.map((event) => event.sequence_number)).toEqual(events.map((_, i) => i)); expect(events.find((event) => event.type === "tjwater.answer_ui")).toMatchObject({ response_id: wire.response.id, id: "chart", data: { title: "观测" } }); expect(events.filter((event) => event.type === "response.output_text.done")).toHaveLength(2); expect(wire.response.output[0]?.content.map((part) => part.text)).toEqual(["压力", "待核验"]); expect(wire.response.output[0]?.id).toBe("msg_persisted"); expect((events[0]!.response as { output: unknown[] }).output).toEqual([]); expect(wire.response).toMatchObject({ object: "response", status: "completed", conversation: { id: "owned" }, usage: null }); }); it("distinguishes errors and cancellation from completed responses", () => { for (const reason of ["failed", "cancelled"] as const) { const events: ResponseEvent[] = []; const wire = createResponsesProjection({ model: "test/model", conversationId: "owned", emit: (event) => events.push(event) }); wire.write({ type: "text-delta", id: "a", delta: "部分结果" }); wire.write({ type: "error", errorText: "计算失败" }); wire.finish(reason); expect(events.at(-1)?.type).toBe(reason === "cancelled" ? "response.incomplete" : "response.failed"); expect(wire.response.output[0]?.status).toBe("incomplete"); expect(wire.response.error?.message).toBe("计算失败"); expect(events.some((event) => event.type === "response.completed")).toBeFalse(); } });