fix(ulw-loop): retry parent session after failed verification

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
YeonGyu-Kim
2026-03-07 04:54:37 +09:00
parent fade6740ae
commit 8ec2c44615
5 changed files with 300 additions and 4 deletions
@@ -9,6 +9,7 @@ import {
} from "./completion-promise-detector"
import { continueIteration } from "./iteration-continuation"
import { handleDeletedLoopSession, handleErroredLoopSession } from "./session-event-handler"
import { handleFailedVerification } from "./verification-failure-handler"
type SessionRecovery = {
isRecovering: (sessionID: string) => boolean
@@ -22,6 +23,7 @@ type LoopStateController = {
setSessionID: (sessionID: string) => RalphLoopState | null
markVerificationPending: (sessionID: string) => RalphLoopState | null
setVerificationSessionID: (sessionID: string, verificationSessionID: string) => RalphLoopState | null
restartAfterFailedVerification: (sessionID: string, messageCountAtStart?: number) => RalphLoopState | null
}
type RalphLoopEventHandlerOptions = { directory: string; apiTimeoutMs: number; getTranscriptPath: (sessionID: string) => string | undefined; checkSessionExists?: RalphLoopOptions["checkSessionExists"]; sessionRecovery: SessionRecovery; loopState: LoopStateController }
@@ -57,7 +59,13 @@ export function createRalphLoopEventHandler(
return
}
if (state.session_id && state.session_id !== sessionID) {
const verificationSessionID = state.verification_pending
? state.verification_session_id
: undefined
const matchesParentSession = state.session_id === undefined || state.session_id === sessionID
const matchesVerificationSession = verificationSessionID === sessionID
if (!matchesParentSession && !matchesVerificationSession && state.session_id) {
if (options.checkSessionExists) {
try {
const exists = await options.checkSessionExists(state.session_id)
@@ -79,9 +87,6 @@ export function createRalphLoopEventHandler(
return
}
const verificationSessionID = state.verification_pending
? state.verification_session_id
: undefined
const completionSessionID = verificationSessionID ?? (state.verification_pending ? undefined : sessionID)
const transcriptPath = completionSessionID ? options.getTranscriptPath(completionSessionID) : undefined
const completionViaTranscript = completionSessionID
@@ -130,6 +135,27 @@ export function createRalphLoopEventHandler(
return
}
if (state.verification_pending) {
if (verificationSessionID && matchesVerificationSession) {
const restarted = await handleFailedVerification(ctx, {
state,
loopState: options.loopState,
directory: options.directory,
apiTimeoutMs: options.apiTimeoutMs,
})
if (restarted) {
return
}
}
log(`[${HOOK_NAME}] Waiting for oracle verification`, {
sessionID,
verificationSessionID,
iteration: state.iteration,
})
return
}
if (
typeof state.max_iterations === "number"
&& state.iteration >= state.max_iterations