summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAiden Cline <[email protected]>2025-07-31 05:07:59 -0500
committerGitHub <[email protected]>2025-07-31 05:07:59 -0500
commit3c49a9b7dd552450fc9b5cc64a965da9d6cf1fef (patch)
treebca081b43b373c2410508fbda2efcc02fe945c9e
parentad66b9746345485ceac7839bb1530a534598ea18 (diff)
downloadopencode-3c49a9b7dd552450fc9b5cc64a965da9d6cf1fef.tar.gz
opencode-3c49a9b7dd552450fc9b5cc64a965da9d6cf1fef.zip
fix: process revert cleanup before creating new messages (#1448)
-rw-r--r--packages/opencode/src/session/index.ts59
1 files changed, 30 insertions, 29 deletions
diff --git a/packages/opencode/src/session/index.ts b/packages/opencode/src/session/index.ts
index 097e266a9..dd7c9a523 100644
--- a/packages/opencode/src/session/index.ts
+++ b/packages/opencode/src/session/index.ts
@@ -377,6 +377,36 @@ export namespace Session {
l.info("chatting")
const inputMode = input.mode ?? "build"
+
+ // Process revert cleanup first, before creating new messages
+ const session = await get(input.sessionID)
+ if (session.revert) {
+ let msgs = await messages(input.sessionID)
+ const messageID = session.revert.messageID
+ const [preserve, remove] = splitWhen(msgs, (x) => x.info.id === messageID)
+ msgs = preserve
+ for (const msg of remove) {
+ await Storage.remove(`session/message/${input.sessionID}/${msg.info.id}`)
+ await Bus.publish(MessageV2.Event.Removed, { sessionID: input.sessionID, messageID: msg.info.id })
+ }
+ const last = preserve.at(-1)
+ if (session.revert.partID && last) {
+ const partID = session.revert.partID
+ const [preserveParts, removeParts] = splitWhen(last.parts, (x) => x.id === partID)
+ last.parts = preserveParts
+ for (const part of removeParts) {
+ await Storage.remove(`session/part/${input.sessionID}/${last.info.id}/${part.id}`)
+ await Bus.publish(MessageV2.Event.PartRemoved, {
+ sessionID: input.sessionID,
+ messageID: last.info.id,
+ partID: part.id,
+ })
+ }
+ }
+ await update(input.sessionID, (draft) => {
+ draft.revert = undefined
+ })
+ }
const userMsg: MessageV2.Info = {
id: input.messageID ?? Identifier.ascending("message"),
role: "user",
@@ -560,35 +590,6 @@ export namespace Session {
const model = await Provider.getModel(input.providerID, input.modelID)
let msgs = await messages(input.sessionID)
- const session = await get(input.sessionID)
-
- if (session.revert) {
- const messageID = session.revert.messageID
- const [preserve, remove] = splitWhen(msgs, (x) => x.info.id === messageID)
- msgs = preserve
- for (const msg of remove) {
- if (msg.info.id === userMsg.id) continue
- await Storage.remove(`session/message/${input.sessionID}/${msg.info.id}`)
- await Bus.publish(MessageV2.Event.Removed, { sessionID: input.sessionID, messageID: msg.info.id })
- }
- const last = preserve.at(-1)
- if (session.revert.partID && last) {
- const partID = session.revert.partID
- const [preserveParts, removeParts] = splitWhen(last.parts, (x) => x.id === partID)
- last.parts = preserveParts
- for (const part of removeParts) {
- await Storage.remove(`session/part/${input.sessionID}/${last.info.id}/${part.id}`)
- await Bus.publish(MessageV2.Event.PartRemoved, {
- sessionID: input.sessionID,
- messageID: last.info.id,
- partID: part.id,
- })
- }
- }
- await update(input.sessionID, (draft) => {
- draft.revert = undefined
- })
- }
const previous = msgs.filter((x) => x.info.role === "assistant").at(-1)?.info as MessageV2.Assistant
const outputLimit = Math.min(model.info.limit.output, OUTPUT_TOKEN_MAX) || OUTPUT_TOKEN_MAX