fix(opencode): remove automatic full session diffs (#30127)
This commit is contained in:
@@ -4,16 +4,20 @@
|
||||
* the response was Schema-encoded against `Snapshot.FileDiff` with
|
||||
* `patch: Schema.String` (required), so any session whose stored
|
||||
* `summary_diffs` had a row without `patch` returned HTTP 400 and the
|
||||
* session never loaded.
|
||||
* session never loaded. Legacy session-level diffs are no longer surfaced,
|
||||
* but the endpoint remains compatible and must still return successfully.
|
||||
*
|
||||
* This test inserts a session row with a missing-patch diff entry and
|
||||
* asserts that GET /session/<id>/diff returns 200 with the row intact.
|
||||
* asserts that GET /session/<id>/diff returns 200 with empty data.
|
||||
*/
|
||||
import { afterEach, describe, expect } from "bun:test"
|
||||
import { Effect, Layer } from "effect"
|
||||
import { SessionPaths } from "@/server/routes/instance/httpapi/groups/session"
|
||||
import { Session } from "@/session/session"
|
||||
import { Storage } from "@/storage/storage"
|
||||
import { SessionLegacy } from "@opencode-ai/core/session/legacy"
|
||||
import { MessageID } from "@/session/schema"
|
||||
import { ProviderV2 } from "@opencode-ai/core/provider"
|
||||
import { resetDatabase } from "../fixture/db"
|
||||
import { disposeAllInstances, TestInstance } from "../fixture/fixture"
|
||||
import { testEffect } from "../lib/effect"
|
||||
@@ -38,7 +42,7 @@ const withSession = (input?: Parameters<Session.Interface["create"]>[0]) =>
|
||||
|
||||
describe("session diff with missing patch (#26574)", () => {
|
||||
it.instance(
|
||||
"GET /session/<id>/diff returns 200 when summary_diffs row has no patch",
|
||||
"GET /session/<id>/diff ignores legacy session-level diff storage",
|
||||
() =>
|
||||
Effect.gen(function* () {
|
||||
const test = yield* TestInstance
|
||||
@@ -57,15 +61,37 @@ describe("session diff with missing patch (#26574)", () => {
|
||||
)
|
||||
|
||||
expect(response.status).toBe(200)
|
||||
const body = (yield* response.json) as Array<{
|
||||
file: string
|
||||
patch?: string
|
||||
additions: number
|
||||
}>
|
||||
expect(body).toHaveLength(1)
|
||||
expect(body[0]?.file).toBe("legacy.txt")
|
||||
expect(body[0]?.additions).toBe(1)
|
||||
expect(body[0]?.patch).toBeUndefined()
|
||||
expect(yield* response.json).toEqual([])
|
||||
}),
|
||||
{ git: true, config: { formatter: false, lsp: false } },
|
||||
)
|
||||
|
||||
it.instance(
|
||||
"GET /session/<id>/diff returns requested turn diffs",
|
||||
() =>
|
||||
Effect.gen(function* () {
|
||||
const test = yield* TestInstance
|
||||
const session = yield* withSession({ title: "turn-diff" })
|
||||
const messageID = MessageID.ascending()
|
||||
yield* Session.use.updateMessage({
|
||||
id: messageID,
|
||||
sessionID: session.id,
|
||||
role: "user",
|
||||
time: { created: Date.now() },
|
||||
agent: "build",
|
||||
model: { providerID: ProviderV2.ID.make("test"), modelID: ProviderV2.ModelID.make("model") },
|
||||
summary: {
|
||||
diffs: [{ file: "turn.ts", additions: 1, deletions: 0, status: "modified" }],
|
||||
},
|
||||
} satisfies SessionLegacy.User)
|
||||
|
||||
const response = yield* requestInDirectory(
|
||||
`${pathFor(SessionPaths.diff, { sessionID: session.id })}?messageID=${messageID}`,
|
||||
test.directory,
|
||||
)
|
||||
|
||||
expect(response.status).toBe(200)
|
||||
expect(yield* response.json).toEqual([{ file: "turn.ts", additions: 1, deletions: 0, status: "modified" }])
|
||||
}),
|
||||
{ git: true, config: { formatter: false, lsp: false } },
|
||||
)
|
||||
|
||||
@@ -257,15 +257,17 @@ it.live("tool execution produces non-empty session diff (snapshot race)", () =>
|
||||
|
||||
// Verify the tool call completed (in the first assistant message)
|
||||
const allMsgs = yield* MessageV2.filterCompactedEffect(session.id)
|
||||
const user = allMsgs.find((msg): msg is SessionLegacy.WithParts & { info: SessionLegacy.User } => msg.info.role === "user")
|
||||
const tool = allMsgs
|
||||
.flatMap((m) => m.parts)
|
||||
.find((p): p is SessionLegacy.ToolPart => p.type === "tool" && p.tool === "bash")
|
||||
expect(tool?.state.status).toBe("completed")
|
||||
if (!user) throw new Error("Expected user message")
|
||||
|
||||
// Poll for diff — summarize() is fire-and-forget
|
||||
// Poll for the turn diff — summarize() is fire-and-forget.
|
||||
let diff: Array<{ file?: string }> = []
|
||||
for (let i = 0; i < 50; i++) {
|
||||
diff = yield* summary.diff({ sessionID: session.id })
|
||||
diff = yield* summary.diff({ sessionID: session.id, messageID: user.info.id })
|
||||
if (diff.length > 0) break
|
||||
yield* Effect.sleep("100 millis")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user