fix: harden prompt optimizer json parsing
This commit is contained in:
parent
cf0b6c72e2
commit
40a1b429ea
@ -299,6 +299,30 @@ const IMAGE_GEN_OPTIMIZER_SYSTEM_PROMPT = `你是一个专业的图片生成提
|
||||
- 细节:一句话补充风格/材质/光线/构图
|
||||
`;
|
||||
|
||||
function parseOptimizerJsonCandidate(raw: string): {
|
||||
optimizedPrompt?: string;
|
||||
negativePrompt?: string;
|
||||
suggestedParams?: {
|
||||
aspectRatio?: string;
|
||||
imageSize?: string;
|
||||
imageCount?: number;
|
||||
promptExtend?: boolean;
|
||||
};
|
||||
} | null {
|
||||
const normalized = raw
|
||||
.trim()
|
||||
.replace(/\uFEFF/g, "")
|
||||
.replace(/[“”]/g, "\"")
|
||||
.replace(/[‘’]/g, "'")
|
||||
.replace(/,\s*([}\]])/g, "$1");
|
||||
if (!normalized) return null;
|
||||
try {
|
||||
return JSON.parse(normalized);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function parseOptimizerJson(responseText: string): {
|
||||
optimizedPrompt?: string;
|
||||
negativePrompt?: string;
|
||||
@ -309,13 +333,40 @@ function parseOptimizerJson(responseText: string): {
|
||||
promptExtend?: boolean;
|
||||
};
|
||||
} | null {
|
||||
const jsonMatch = responseText.match(/\{[\s\S]*\}/);
|
||||
if (!jsonMatch) return null;
|
||||
try {
|
||||
return JSON.parse(jsonMatch[0]);
|
||||
} catch (error) {
|
||||
return null;
|
||||
if (!responseText || typeof responseText !== "string") return null;
|
||||
|
||||
const fencedBlocks = Array.from(
|
||||
responseText.matchAll(/```(?:json)?\s*([\s\S]*?)```/gi)
|
||||
).map((match) => match[1]?.trim() || "");
|
||||
|
||||
for (const block of fencedBlocks) {
|
||||
const parsed = parseOptimizerJsonCandidate(block);
|
||||
if (parsed) return parsed;
|
||||
}
|
||||
|
||||
const text = responseText.trim();
|
||||
const starts: number[] = [];
|
||||
for (let i = 0; i < text.length; i++) {
|
||||
if (text[i] === "{") starts.push(i);
|
||||
}
|
||||
|
||||
for (const start of starts) {
|
||||
let depth = 0;
|
||||
for (let end = start; end < text.length; end++) {
|
||||
if (text[end] === "{") depth += 1;
|
||||
if (text[end] === "}") {
|
||||
depth -= 1;
|
||||
if (depth === 0) {
|
||||
const candidate = text.slice(start, end + 1);
|
||||
const parsed = parseOptimizerJsonCandidate(candidate);
|
||||
if (parsed) return parsed;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function sanitizeSuggestedParams(input?: {
|
||||
@ -590,7 +641,10 @@ export async function optimizePromptWithLLM(params: {
|
||||
}
|
||||
|
||||
// 解析失败,回退到模板优化
|
||||
console.log("[Prompt Optimizer LLM] Parse failed, falling back to template");
|
||||
console.log(
|
||||
"[Prompt Optimizer LLM] Parse failed, falling back to template. raw=",
|
||||
responseText.slice(0, 320)
|
||||
);
|
||||
return optimizePrompt({ originalPrompt, intent, subIntent });
|
||||
|
||||
} catch (error) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user