fix(ralph-loop): guard compaction continuation ownership

This commit is contained in:
YeonGyu-Kim
2026-05-14 13:43:47 +09:00
parent d16d47a0b4
commit 9e6185266d
11 changed files with 252 additions and 101 deletions
@@ -2,7 +2,7 @@ import type { PluginInput } from "@opencode-ai/plugin"
import { log } from "../../shared/logger"
import { resolveMessageEventSessionID, resolveSessionEventID } from "../../shared/event-session-id"
import { isSessionActive } from "../shared/session-idle-settle"
import type { RalphLoopOptions, RalphLoopState } from "./types"
import type { IterationCommitExpectation, RalphLoopOptions, RalphLoopState } from "./types"
import { HOOK_NAME } from "./constants"
import { handleDetectedCompletion } from "./completion-handler"
import {
@@ -18,7 +18,7 @@ const RAPID_IDLE_DEDUP_MS = 500
type LoopStateController = {
getState: () => RalphLoopState | null
clear: () => boolean
incrementIteration: () => RalphLoopState | null
incrementIteration: (expected?: IterationCommitExpectation) => RalphLoopState | null
setSessionID: (sessionID: string) => RalphLoopState | null
markVerificationPending: (sessionID: string) => RalphLoopState | null
setVerificationSessionID: (sessionID: string, verificationSessionID: string) => RalphLoopState | null
@@ -377,11 +377,21 @@ export function createRalphLoopEventHandler(
return
}
const committed = options.loopState.incrementIteration()
const committed = options.loopState.incrementIteration({
iteration: stateBeforeCommit.iteration,
sessionID: result.sessionID,
})
if (committed) {
showIterationToast(ctx, committed)
} else {
log(`[${HOOK_NAME}] Dispatch succeeded but iteration commit failed`, { sessionID })
options.loopState.clear()
showToastBestEffort(ctx, {
title: "Ralph Loop Failed",
message: "Dispatch succeeded but iteration commit failed",
variant: "warning",
duration: 5000,
})
}
return
}
@@ -532,12 +542,22 @@ export function createRalphLoopEventHandler(
return
}
const committed = options.loopState.incrementIteration()
const committed = options.loopState.incrementIteration({
iteration: stateBeforeCommit.iteration,
sessionID: result.sessionID,
})
if (committed) {
showIterationToast(ctx, committed)
runtimeErrorRetriedSessions.set(sessionID, committed.iteration)
} else {
log(`[${HOOK_NAME}] Dispatch succeeded but iteration commit failed after runtime error`, { sessionID })
options.loopState.clear()
showToastBestEffort(ctx, {
title: "Ralph Loop Failed",
message: "Dispatch succeeded but iteration commit failed",
variant: "warning",
duration: 5000,
})
}
return
}