import type { ChatResponse } from "./board-actions"; import type { ParsedCommand } from "./work-package-types"; function extractAssistantMessage(rawText: string) { const trimmed = rawText.trim(); if (!trimmed) return ""; try { const parsed = JSON.parse(trimmed) as | { assistantMessage?: unknown; message?: unknown; content?: unknown; text?: unknown; } | string; if (typeof parsed === "string") { return parsed.trim(); } const candidate = parsed?.assistantMessage ?? parsed?.message ?? parsed?.content ?? parsed?.text; if (typeof candidate === "string" && candidate.trim()) { return candidate.trim(); } } catch { // ignore } return trimmed; } export function recoverInvalidLlmResponse(args: { rawText: string; parsedCommand?: ParsedCommand; fallbackResponse?: ChatResponse; }): ChatResponse { const { rawText, parsedCommand, fallbackResponse } = args; if (parsedCommand?.mode === "ask") { return { assistantMessage: extractAssistantMessage(rawText) || "The model replied, but not in structured JSON. No board changes were applied.", boardAction: { type: "none", workPackageId: null }, }; } if (fallbackResponse) { return fallbackResponse; } return { assistantMessage: rawText.trim() || "The model replied, but not in the required JSON contract. No board changes were applied.", boardAction: { type: "none", workPackageId: null }, }; }