mirror of
https://gitea.toothfairyai.com/ToothFairyAI/tf_code.git
synced 2026-04-15 21:24:48 +00:00
fix(app): better optimistic prompt submit (#17337)
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
import { describe, expect, test } from "bun:test"
|
||||
import type { Message, Part } from "@opencode-ai/sdk/v2/client"
|
||||
import { applyOptimisticAdd, applyOptimisticRemove } from "./sync"
|
||||
import { applyOptimisticAdd, applyOptimisticRemove, mergeOptimisticPage } from "./sync"
|
||||
|
||||
type Text = Extract<Part, { type: "text" }>
|
||||
|
||||
const userMessage = (id: string, sessionID: string): Message => ({
|
||||
id,
|
||||
@@ -11,7 +13,7 @@ const userMessage = (id: string, sessionID: string): Message => ({
|
||||
model: { providerID: "openai", modelID: "gpt" },
|
||||
})
|
||||
|
||||
const textPart = (id: string, sessionID: string, messageID: string): Part => ({
|
||||
const textPart = (id: string, sessionID: string, messageID: string): Text => ({
|
||||
id,
|
||||
sessionID,
|
||||
messageID,
|
||||
@@ -53,4 +55,69 @@ describe("sync optimistic reducers", () => {
|
||||
expect(draft.part.msg_1).toBeUndefined()
|
||||
expect(draft.part.msg_2).toHaveLength(1)
|
||||
})
|
||||
|
||||
test("mergeOptimisticPage keeps pending messages in fetched timelines", () => {
|
||||
const sessionID = "ses_1"
|
||||
const page = mergeOptimisticPage(
|
||||
{
|
||||
session: [userMessage("msg_1", sessionID)],
|
||||
part: [{ id: "msg_1", part: [textPart("prt_1", sessionID, "msg_1")] }],
|
||||
complete: true,
|
||||
},
|
||||
[{ message: userMessage("msg_2", sessionID), parts: [textPart("prt_2", sessionID, "msg_2")] }],
|
||||
)
|
||||
|
||||
expect(page.session.map((x) => x.id)).toEqual(["msg_1", "msg_2"])
|
||||
expect(page.part.find((x) => x.id === "msg_2")?.part.map((x) => x.id)).toEqual(["prt_2"])
|
||||
expect(page.confirmed).toEqual([])
|
||||
expect(page.complete).toBe(true)
|
||||
})
|
||||
|
||||
test("mergeOptimisticPage keeps missing optimistic parts until the server has them", () => {
|
||||
const sessionID = "ses_1"
|
||||
const page = mergeOptimisticPage(
|
||||
{
|
||||
session: [userMessage("msg_2", sessionID)],
|
||||
part: [{ id: "msg_2", part: [textPart("prt_2", sessionID, "msg_2")] }],
|
||||
complete: true,
|
||||
},
|
||||
[
|
||||
{
|
||||
message: userMessage("msg_2", sessionID),
|
||||
parts: [textPart("prt_1", sessionID, "msg_2"), textPart("prt_2", sessionID, "msg_2")],
|
||||
},
|
||||
],
|
||||
)
|
||||
|
||||
expect(page.part.find((x) => x.id === "msg_2")?.part.map((x) => x.id)).toEqual(["prt_1", "prt_2"])
|
||||
expect(page.confirmed).toEqual([])
|
||||
})
|
||||
|
||||
test("mergeOptimisticPage confirms echoed messages once all parts arrive", () => {
|
||||
const sessionID = "ses_1"
|
||||
const page = mergeOptimisticPage(
|
||||
{
|
||||
session: [userMessage("msg_2", sessionID)],
|
||||
part: [
|
||||
{
|
||||
id: "msg_2",
|
||||
part: [{ ...textPart("prt_1", sessionID, "msg_2"), text: "server" }, textPart("prt_2", sessionID, "msg_2")],
|
||||
},
|
||||
],
|
||||
complete: true,
|
||||
},
|
||||
[
|
||||
{
|
||||
message: userMessage("msg_2", sessionID),
|
||||
parts: [textPart("prt_1", sessionID, "msg_2"), textPart("prt_2", sessionID, "msg_2")],
|
||||
},
|
||||
],
|
||||
)
|
||||
|
||||
expect(page.confirmed).toEqual(["msg_2"])
|
||||
expect(page.part.find((x) => x.id === "msg_2")?.part).toMatchObject([
|
||||
{ id: "prt_1", type: "text", text: "server" },
|
||||
{ id: "prt_2", type: "text", text: "prt_2" },
|
||||
])
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user