fix(ralph-loop): only scan text parts for completion tags and handle both API shapes

Reasoning parts could contain completion-like text triggering false
positives. Also handles session.messages returning either an array
or {data: [...]} shape.
This commit is contained in:
YeonGyu-Kim
2026-02-11 00:44:21 +09:00
parent 11d1e70067
commit 88e1e3d0fa
2 changed files with 60 additions and 13 deletions
@@ -63,10 +63,19 @@ export async function detectCompletionInSessionMessages(
options.apiTimeoutMs,
)
const messages = (response as { data?: unknown[] }).data ?? []
if (!Array.isArray(messages)) return false
const messagesResponse: unknown = response
const responseData =
typeof messagesResponse === "object" && messagesResponse !== null && "data" in messagesResponse
? (messagesResponse as { data?: unknown }).data
: undefined
const assistantMessages = (messages as OpenCodeSessionMessage[]).filter((msg) => msg.info?.role === "assistant")
const messageArray: unknown[] = Array.isArray(messagesResponse)
? messagesResponse
: Array.isArray(responseData)
? responseData
: []
const assistantMessages = (messageArray as OpenCodeSessionMessage[]).filter((msg) => msg.info?.role === "assistant")
if (assistantMessages.length === 0) return false
const pattern = buildPromisePattern(options.promise)
@@ -74,10 +83,11 @@ export async function detectCompletionInSessionMessages(
for (const assistant of recentAssistants) {
if (!assistant.parts) continue
const responseText = assistant.parts
.filter((p) => p.type === "text" || p.type === "reasoning")
.map((p) => p.text ?? "")
.join("\n")
let responseText = ""
for (const part of assistant.parts) {
if (part.type !== "text") continue
responseText += `${responseText ? "\n" : ""}${part.text ?? ""}`
}
if (pattern.test(responseText)) {
return true