Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions packages/app/e2e/regression/message-diff-expansion.spec.ts
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
import { expect, test } from "@playwright/test"
import { sessionID, setupTimeline, userMessage } from "../performance/timeline-stability/fixture"

test("loads a patch only when an inline summary diff is expanded", async ({ page }) => {
let requests = 0
const diffRequests: string[] = []
page.on("request", (request) => {
if (request.url().includes("diff")) diffRequests.push(request.url())
})
await setupTimeline(page, {
messages: [
userMessage(undefined, {
summary: {
additions: 1,
deletions: 1,
files: 1,
diffs: [{ file: "src/changed.ts", additions: 1, deletions: 1, status: "modified" }],
},
}),
],
})
await page.route("**/*", async (route) => {
if (!new URL(route.request().url()).pathname.endsWith(`/session/${sessionID}/diff`)) return route.fallback()
requests++
await route.fulfill({
contentType: "application/json",
body: JSON.stringify([
{
file: "src/changed.ts",
patch: "@@ -1 +1 @@\n-before\n+from side table\n",
additions: 1,
deletions: 1,
status: "modified",
},
]),
})
})

const trigger = page.locator('[data-slot="session-turn-diff-trigger"]').first()
await expect(trigger).toBeVisible()
expect(requests).toBe(0)

await trigger.click()
await expect.poll(() => ({ requests, diffRequests })).toEqual({ requests: 1, diffRequests: expect.any(Array) })
await expect(page.getByText("from side table", { exact: true })).toBeVisible()
})
2 changes: 2 additions & 0 deletions packages/app/src/context/directory-sync.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -12,6 +12,7 @@ const sessionFields = new Set([
"session_status",
"session_working",
"session_diff",
"message_diff",
"todo",
"permission",
"question",
Expand DownExpand Up@@ -118,6 +119,7 @@ export const createDirSyncContext = (
},
todo: serverSync.session.todo,
history: serverSync.session.history,
fetchMessageDiff: serverSync.session.fetchMessageDiff,
evict(sessionID: string) {
serverSync.session.evict(sessionID)
},
Expand Down
2 changes: 2 additions & 0 deletions packages/app/src/context/global-sync/bootstrap.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -58,6 +58,8 @@ function directoryState() {
return this.session_status[id]?.type !== "idle"
},
session_diff: {},
message_diff: {},
message_diff_status: {},
todo: {},
permission: {},
question: {},
Expand Down
2 changes: 2 additions & 0 deletions packages/app/src/context/global-sync/child-store.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -234,6 +234,8 @@ export function createChildStoreManager(input: {
return (type ?? "idle") !== "idle"
},
session_diff: {},
message_diff: {},
message_diff_status: {},
todo: {},
permission: {},
question: {},
Expand Down
2 changes: 2 additions & 0 deletions packages/app/src/context/global-sync/event-reducer.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -72,6 +72,8 @@ const baseState = (input: Partial<State> = {}) =>
sessionTotal: 0,
session_status: {},
session_diff: {},
message_diff: {},
message_diff_status: {},
todo: {},
permission: {},
question: {},
Expand Down
12 changes: 11 additions & 1 deletion packages/app/src/context/global-sync/session-cache.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -27,6 +27,8 @@ describe("app session cache", () => {
const store: {
session_status: Record<string, SessionStatus | undefined>
session_diff: Record<string, FileDiffInfo[] | undefined>
message_diff: Record<string, FileDiffInfo[] | undefined>
message_diff_status: Record<string, "pending" | "failed" | "absent" | undefined>
todo: Record<string, Todo[] | undefined>
message: Record<string, Message[] | undefined>
session_message: Record<string, never[] | undefined>
Expand All@@ -37,8 +39,10 @@ describe("app session cache", () => {
} = {
session_status: { ses_1: { type: "busy" } as SessionStatus },
session_diff: { ses_1: [] },
message_diff: { msg_dropped: [] },
message_diff_status: { msg_dropped: "failed" },
todo: { ses_1: [] as Todo[] },
message: {},
message: { ses_1: [msg("msg_dropped", "ses_1")] },
session_message: {},
part: { msg_1: [part("prt_1", "ses_1", "msg_1")] },
permission: { ses_1: [] as PermissionRequest[] },
Expand All@@ -49,6 +53,8 @@ describe("app session cache", () => {
dropSessionCaches(store, ["ses_1"])

expect(store.message.ses_1).toBeUndefined()
expect(store.message_diff.msg_dropped).toBeUndefined()
expect(store.message_diff_status.msg_dropped).toBeUndefined()
expect(store.part.msg_1).toBeUndefined()
expect(store.part_text_accum_delta.prt_1).toBeUndefined()
expect(store.todo.ses_1).toBeUndefined()
Expand All@@ -63,6 +69,8 @@ describe("app session cache", () => {
const store: {
session_status: Record<string, SessionStatus | undefined>
session_diff: Record<string, FileDiffInfo[] | undefined>
message_diff: Record<string, FileDiffInfo[] | undefined>
message_diff_status: Record<string, "pending" | "failed" | "absent" | undefined>
todo: Record<string, Todo[] | undefined>
message: Record<string, Message[] | undefined>
session_message: Record<string, never[] | undefined>
Expand All@@ -73,6 +81,8 @@ describe("app session cache", () => {
} = {
session_status: {},
session_diff: {},
message_diff: {},
message_diff_status: {},
todo: {},
message: { ses_1: [m] },
session_message: {},
Expand Down
6 changes: 6 additions & 0 deletions packages/app/src/context/global-sync/session-cache.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,6 +7,8 @@ export const SESSION_CACHE_LIMIT = 40
type SessionCache = {
session_status: Record<string, SessionStatus | undefined>
session_diff: Record<string, FileDiffInfo[] | undefined>
message_diff: Record<string, FileDiffInfo[] | undefined>
message_diff_status: Record<string, "pending" | "failed" | "absent" | undefined>
todo: Record<string, Todo[] | undefined>
message: Record<string, Message[] | undefined>
session_message: Record<string, SessionMessageInfo[] | undefined>
Expand All@@ -30,6 +32,10 @@ export function dropSessionCaches(store: SessionCache, sessionIDs: Iterable<stri
}

for (const sessionID of stale) {
for (const message of store.message[sessionID] ?? []) {
delete store.message_diff[message.id]
delete store.message_diff_status[message.id]
}
delete store.message[sessionID]
delete store.todo[sessionID]
delete store.session_message[sessionID]
Expand Down
6 changes: 6 additions & 0 deletions packages/app/src/context/global-sync/types.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -51,6 +51,12 @@ export type State = {
session_diff: {
[sessionID: string]: FileDiffInfo[]
}
message_diff: {
[messageID: string]: FileDiffInfo[] | undefined
}
message_diff_status: {
[messageID: string]: "pending" | "failed" | "absent" | undefined
}
todo: {
[sessionID: string]: Todo[]
}
Expand Down
Loading
Loading