core: prevent duplicate user messages in ACP clients (#22468)

This commit is contained in:
Aiden Cline
2026-04-14 11:37:33 -05:00
committed by GitHub
parent a8f9f6b705
commit b1312a3181
2 changed files with 46 additions and 0 deletions

View File

@@ -453,6 +453,12 @@ export namespace ACP {
return
}
}
// ACP clients already know the prompt they just submitted, so replaying
// live user parts duplicates the message. We still replay user history in
// loadSession() and forkSession() via processMessage().
if (part.type !== "text" && part.type !== "file") return
return
}

View File

@@ -295,6 +295,46 @@ describe("acp.agent event subscription", () => {
})
})
test("does not emit user_message_chunk for live prompt parts", async () => {
await using tmp = await tmpdir()
await Instance.provide({
directory: tmp.path,
fn: async () => {
const { agent, controller, sessionUpdates, stop } = createFakeAgent()
const cwd = "/tmp/opencode-acp-test"
const sessionId = await agent.newSession({ cwd, mcpServers: [] } as any).then((x) => x.sessionId)
controller.push({
directory: cwd,
payload: {
type: "message.part.updated",
properties: {
sessionID: sessionId,
time: Date.now(),
part: {
id: "part_1",
sessionID: sessionId,
messageID: "msg_user",
type: "text",
text: "hello",
},
},
},
} as any)
await new Promise((r) => setTimeout(r, 20))
expect(
sessionUpdates
.filter((u) => u.sessionId === sessionId)
.some((u) => u.update.sessionUpdate === "user_message_chunk"),
).toBe(false)
stop()
},
})
})
test("keeps concurrent sessions isolated when message.part.delta events are interleaved", async () => {
await using tmp = await tmpdir()
await Instance.provide({