feat: extend logging for chatData

This commit is contained in:
Alpha Nerd 2026-06-08 11:21:52 +02:00
parent ccd418084e
commit 3434813325
Signed by: alpha-nerd
SSH key fingerprint: SHA256:QkkAgVoYi9TQ0UKPkiKSfnerZy2h4qhi3SVPXJmBN+M

View file

@ -955,19 +955,35 @@ async function chat(text: string, files: PromptFiles = []) {
if (!chatRes.ok) {
throw new Error(`opencode /chat returned ${chatRes.status} ${chatRes.statusText}: ${rawText.slice(0, 1000)}`)
}
let chatData: { parts?: unknown[]; data?: { parts?: unknown[] } }
let chatData: any
try {
chatData = JSON.parse(rawText)
} catch (e) {
throw new Error(`opencode /chat returned non-JSON (status ${chatRes.status}, content-type ${chatRes.headers.get("content-type")}): ${rawText.slice(0, 1000)}`)
}
// Find the last text part in the response
const info = chatData?.info ?? chatData?.data?.info
const parts = chatData?.parts || chatData?.data?.parts || []
const match = parts.findLast((p: any) => p.type === "text") as { text: string } | undefined
if (!match) throw new Error("Failed to parse the text response")
return match.text
// Surface a provider/model error instead of the generic parse failure.
if (info?.error) {
throw new Error(`opencode model error: ${JSON.stringify(info.error).slice(0, 2000)}`)
}
// Prefer the last non-empty text part.
const textParts = parts.filter((p: any) => p.type === "text" && p.text?.trim())
const last = textParts[textParts.length - 1] as { text: string } | undefined
if (last) return last.text
// The agent may have done work (edited files) without a closing text message.
// Don't hard-fail in that case; report what happened instead.
console.error("No text part. Part types:", parts.map((p: any) => p.type).join(", ") || "none")
const ranTools = parts.some((p: any) => p.type === "tool")
if (ranTools) return "_(opencode completed the run but produced no summary message.)_"
throw new Error(
`Failed to parse the text response (parts: ${parts.map((p: any) => p.type).join(", ") || "none"}; raw: ${rawText.slice(0, 1000)})`,
)
}
// ─── Prompt building ────────────────────────────────────────────────────────