fix(ralph-loop): generate transcript path from sessionID instead of relying on event properties (#355)
OpenCode doesn't pass transcriptPath in the session.idle event properties, which caused detectCompletionPromise to always return false (the first check returns early if transcriptPath is undefined). This fix: - Imports getTranscriptPath from claude-code-hooks/transcript - Generates the transcript path from sessionID instead of reading from event - Adds optional getTranscriptPath callback to RalphLoopOptions for testability Fixes #354 Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.com>
This commit is contained in:
@@ -329,17 +329,19 @@ describe("ralph-loop", () => {
|
|||||||
|
|
||||||
test("should detect completion promise and stop loop", async () => {
|
test("should detect completion promise and stop loop", async () => {
|
||||||
// #given - active loop with transcript containing completion
|
// #given - active loop with transcript containing completion
|
||||||
const hook = createRalphLoopHook(createMockPluginInput())
|
const transcriptPath = join(TEST_DIR, "transcript.jsonl")
|
||||||
|
const hook = createRalphLoopHook(createMockPluginInput(), {
|
||||||
|
getTranscriptPath: () => transcriptPath,
|
||||||
|
})
|
||||||
hook.startLoop("session-123", "Build something", { completionPromise: "COMPLETE" })
|
hook.startLoop("session-123", "Build something", { completionPromise: "COMPLETE" })
|
||||||
|
|
||||||
const transcriptPath = join(TEST_DIR, "transcript.jsonl")
|
|
||||||
writeFileSync(transcriptPath, JSON.stringify({ content: "Task done <promise>COMPLETE</promise>" }))
|
writeFileSync(transcriptPath, JSON.stringify({ content: "Task done <promise>COMPLETE</promise>" }))
|
||||||
|
|
||||||
// #when - session goes idle with transcript
|
// #when - session goes idle (transcriptPath now derived from sessionID via getTranscriptPath)
|
||||||
await hook.event({
|
await hook.event({
|
||||||
event: {
|
event: {
|
||||||
type: "session.idle",
|
type: "session.idle",
|
||||||
properties: { sessionID: "session-123", transcriptPath },
|
properties: { sessionID: "session-123" },
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import {
|
|||||||
DEFAULT_COMPLETION_PROMISE,
|
DEFAULT_COMPLETION_PROMISE,
|
||||||
} from "./constants"
|
} from "./constants"
|
||||||
import type { RalphLoopState, RalphLoopOptions } from "./types"
|
import type { RalphLoopState, RalphLoopOptions } from "./types"
|
||||||
|
import { getTranscriptPath as getDefaultTranscriptPath } from "../claude-code-hooks/transcript"
|
||||||
|
|
||||||
export * from "./types"
|
export * from "./types"
|
||||||
export * from "./constants"
|
export * from "./constants"
|
||||||
@@ -48,6 +49,7 @@ export function createRalphLoopHook(
|
|||||||
const sessions = new Map<string, SessionState>()
|
const sessions = new Map<string, SessionState>()
|
||||||
const config = options?.config
|
const config = options?.config
|
||||||
const stateDir = config?.state_dir
|
const stateDir = config?.state_dir
|
||||||
|
const getTranscriptPath = options?.getTranscriptPath ?? getDefaultTranscriptPath
|
||||||
|
|
||||||
function getSessionState(sessionID: string): SessionState {
|
function getSessionState(sessionID: string): SessionState {
|
||||||
let state = sessions.get(sessionID)
|
let state = sessions.get(sessionID)
|
||||||
@@ -149,7 +151,8 @@ export function createRalphLoopHook(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const transcriptPath = props?.transcriptPath as string | undefined
|
// Generate transcript path from sessionID - OpenCode doesn't pass it in event properties
|
||||||
|
const transcriptPath = getTranscriptPath(sessionID)
|
||||||
|
|
||||||
if (detectCompletionPromise(transcriptPath, state.completion_promise)) {
|
if (detectCompletionPromise(transcriptPath, state.completion_promise)) {
|
||||||
log(`[${HOOK_NAME}] Completion detected!`, {
|
log(`[${HOOK_NAME}] Completion detected!`, {
|
||||||
|
|||||||
@@ -12,4 +12,5 @@ export interface RalphLoopState {
|
|||||||
|
|
||||||
export interface RalphLoopOptions {
|
export interface RalphLoopOptions {
|
||||||
config?: RalphLoopConfig
|
config?: RalphLoopConfig
|
||||||
|
getTranscriptPath?: (sessionId: string) => string
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user