fix(acp): replay loaded session transcript (#30645)
Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com> Co-authored-by: Shoubhit Dash <shoubhit2005@gmail.com>
This commit is contained in:
committed by
GitHub
parent
30ec231aaf
commit
69cfc44dba
@@ -12,6 +12,7 @@ import type {
|
|||||||
import { Effect } from "effect"
|
import { Effect } from "effect"
|
||||||
import { ACPSession } from "./session"
|
import { ACPSession } from "./session"
|
||||||
import { ACPPermission } from "./permission"
|
import { ACPPermission } from "./permission"
|
||||||
|
import { partsToContentChunks, type ReplayPart } from "./content"
|
||||||
import {
|
import {
|
||||||
duplicateRunningToolUpdate,
|
duplicateRunningToolUpdate,
|
||||||
errorToolUpdate,
|
errorToolUpdate,
|
||||||
@@ -87,7 +88,31 @@ export class Subscription {
|
|||||||
await this.recordFetchedPart(message.info.sessionID, message, part)
|
await this.recordFetchedPart(message.info.sessionID, message, part)
|
||||||
if (part.type === "tool") {
|
if (part.type === "tool") {
|
||||||
await this.handleToolPart(message.info.sessionID, part)
|
await this.handleToolPart(message.info.sessionID, part)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
await this.replayContentPart(message, part)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async replayContentPart(message: SessionMessageResponse, part: Part) {
|
||||||
|
if (part.type !== "text" && part.type !== "file" && part.type !== "reasoning") return
|
||||||
|
|
||||||
|
const sessionUpdate =
|
||||||
|
part.type === "reasoning"
|
||||||
|
? "agent_thought_chunk"
|
||||||
|
: message.info.role === "user"
|
||||||
|
? "user_message_chunk"
|
||||||
|
: "agent_message_chunk"
|
||||||
|
|
||||||
|
for (const chunk of partsToContentChunks([part as ReplayPart])) {
|
||||||
|
await this.input.connection.sessionUpdate({
|
||||||
|
sessionId: message.info.sessionID,
|
||||||
|
update: {
|
||||||
|
sessionUpdate,
|
||||||
|
messageId: message.info.id,
|
||||||
|
...chunk,
|
||||||
|
},
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -316,6 +316,46 @@ describe("ACP service sessions", () => {
|
|||||||
expect(result.configOptions?.find((option) => option.id === "mode")?.currentValue).toBe("plan")
|
expect(result.configOptions?.find((option) => option.id === "mode")?.currentValue).toBe("plan")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("replays loaded session transcript chunks", async () => {
|
||||||
|
const { service, updates } = makeService([
|
||||||
|
{
|
||||||
|
info: { id: "msg_user", sessionID: "ses_loaded", role: "user" },
|
||||||
|
parts: [{ id: "part_user", sessionID: "ses_loaded", messageID: "msg_user", type: "text", text: "hello" }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
info: { id: "msg_assistant", sessionID: "ses_loaded", role: "assistant" },
|
||||||
|
parts: [
|
||||||
|
{
|
||||||
|
id: "part_assistant",
|
||||||
|
sessionID: "ses_loaded",
|
||||||
|
messageID: "msg_assistant",
|
||||||
|
type: "text",
|
||||||
|
text: "hi there",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
await Effect.runPromise(service.loadSession({ cwd: "/workspace", sessionId: "ses_loaded", mcpServers: [] }))
|
||||||
|
|
||||||
|
expect(
|
||||||
|
updates
|
||||||
|
.map((item) => item.update)
|
||||||
|
.filter((item) => item.sessionUpdate === "user_message_chunk" || item.sessionUpdate === "agent_message_chunk"),
|
||||||
|
).toEqual([
|
||||||
|
{
|
||||||
|
sessionUpdate: "user_message_chunk",
|
||||||
|
messageId: "msg_user",
|
||||||
|
content: { type: "text", text: "hello" },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
sessionUpdate: "agent_message_chunk",
|
||||||
|
messageId: "msg_assistant",
|
||||||
|
content: { type: "text", text: "hi there" },
|
||||||
|
},
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
it("lists sessions sorted by updated time with cursor support", async () => {
|
it("lists sessions sorted by updated time with cursor support", async () => {
|
||||||
const { service } = makeService()
|
const { service } = makeService()
|
||||||
const first = await Effect.runPromise(service.listSessions({ cwd: "/workspace" }))
|
const first = await Effect.runPromise(service.listSessions({ cwd: "/workspace" }))
|
||||||
|
|||||||
Reference in New Issue
Block a user