Codex/generation task reliability #20
@@ -107,6 +107,17 @@ function isRecord(value: unknown): value is Record<string, unknown> {
|
||||
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
||||
}
|
||||
|
||||
function normalizeEvidenceItems(source: unknown[], limit: number): string[] {
|
||||
const items: string[] = [];
|
||||
for (const item of source) {
|
||||
const value = String(item).trim();
|
||||
if (!value) continue;
|
||||
items.push(value);
|
||||
if (items.length >= limit) break;
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
function normalizeNestedScores(value: unknown): Record<string, Record<string, number>> {
|
||||
if (!isRecord(value)) return {};
|
||||
|
||||
@@ -132,7 +143,7 @@ function normalizeEvidence(value: unknown): Record<string, string[]> {
|
||||
const source = value[dimensionKey] ?? (dimensionKey === "logic" ? value.dialogue : undefined);
|
||||
if (!Array.isArray(source)) continue;
|
||||
|
||||
const items = source.map(String).map((item) => item.trim()).filter(Boolean).slice(0, 3);
|
||||
const items = normalizeEvidenceItems(source, 3);
|
||||
if (items.length > 0) normalized[dimensionKey] = items;
|
||||
}
|
||||
|
||||
|
||||
@@ -82,11 +82,16 @@ export function useCanvasNodeDrag(params: UseCanvasNodeDragParams) {
|
||||
const cy = pos.y + size.height / 2;
|
||||
const right = pos.x + size.width;
|
||||
const bottom = pos.y + size.height;
|
||||
const others = [
|
||||
...textNodesRef.current.filter((n) => n.id !== draggedId).map((n) => ({ pos: n.position, size: n.size })),
|
||||
...imageNodesRef.current.filter((n) => n.id !== draggedId).map((n) => ({ pos: n.position, size: n.size })),
|
||||
...videoNodesRef.current.filter((n) => n.id !== draggedId).map((n) => ({ pos: n.position, size: n.size })),
|
||||
];
|
||||
const others: Array<{ pos: CanvasPoint; size: CanvasNodeSize }> = [];
|
||||
for (const node of textNodesRef.current) {
|
||||
if (node.id !== draggedId) others.push({ pos: node.position, size: node.size });
|
||||
}
|
||||
for (const node of imageNodesRef.current) {
|
||||
if (node.id !== draggedId) others.push({ pos: node.position, size: node.size });
|
||||
}
|
||||
for (const node of videoNodesRef.current) {
|
||||
if (node.id !== draggedId) others.push({ pos: node.position, size: node.size });
|
||||
}
|
||||
for (const other of others) {
|
||||
const ocx = other.pos.x + other.size.width / 2;
|
||||
const ocy = other.pos.y + other.size.height / 2;
|
||||
|
||||
@@ -81,6 +81,20 @@ const CAMERA_EFFECT_PRESETS = [
|
||||
{ key: "hdr", label: "HDR", prompt: "HDR高动态范围,明暗细节丰富,色彩饱和" },
|
||||
] as const;
|
||||
|
||||
const CAMERA_EFFECT_PROMPT_BY_KEY = new Map<string, string>(
|
||||
CAMERA_EFFECT_PRESETS.map((effect) => [effect.key, effect.prompt]),
|
||||
);
|
||||
|
||||
function getCameraEffectsPrompt(effectKeys: Set<string>): string {
|
||||
if (effectKeys.size === 0) return "";
|
||||
const prompts: string[] = [];
|
||||
for (const key of effectKeys) {
|
||||
const prompt = CAMERA_EFFECT_PROMPT_BY_KEY.get(key);
|
||||
if (prompt) prompts.push(prompt);
|
||||
}
|
||||
return prompts.join(",");
|
||||
}
|
||||
|
||||
function shotScaleToZoom(shotScale: number): number {
|
||||
const map: Record<number, number> = { 1: 24, 2: 28, 3: 32, 4: 35, 5: 40, 6: 50, 7: 60, 8: 75, 9: 85, 10: 100 };
|
||||
return map[Math.round(Math.max(1, Math.min(10, shotScale)))] || 40;
|
||||
@@ -400,9 +414,7 @@ function ImageWorkbenchPage({ initialTool = "workbench", onOpenMore, onSelectVie
|
||||
const refUrls = await uploadReferenceImages([cameraImage]);
|
||||
const model = "wan2.7-image-pro";
|
||||
const cameraDesc = `镜头预设: ${cameraPreset}, 方向: ${cameraDirection}, 水平: ${cameraHorizontal}°, 垂直: ${cameraVertical}°, 倾斜: ${cameraRoll}°, 焦距: ${cameraZoom}mm`;
|
||||
const effectsDesc = cameraEffects.size > 0
|
||||
? Array.from(cameraEffects).map((key) => CAMERA_EFFECT_PRESETS.find((e) => e.key === key)?.prompt).filter(Boolean).join(",")
|
||||
: "";
|
||||
const effectsDesc = getCameraEffectsPrompt(cameraEffects);
|
||||
const fullPrompt = cameraPromptEnabled && cameraPrompt.trim()
|
||||
? `${cameraDesc}${effectsDesc ? `。视觉效果: ${effectsDesc}` : ""}。${cameraPrompt}`
|
||||
: `${cameraDesc}${effectsDesc ? `。视觉效果: ${effectsDesc}` : ""}。保持人物和场景一致,按照镜头参数重新构图。`;
|
||||
|
||||
@@ -245,9 +245,21 @@ function getDimensionSubScores(result: EvalResult, dim: ScoreDimension): Array<[
|
||||
.slice(0, 5);
|
||||
}
|
||||
|
||||
function normalizeEvidenceItems(evidence: unknown[] | undefined, limit: number): string[] {
|
||||
if (!Array.isArray(evidence)) return [];
|
||||
const items: string[] = [];
|
||||
for (const item of evidence) {
|
||||
const value = String(item).trim();
|
||||
if (!value) continue;
|
||||
items.push(value);
|
||||
if (items.length >= limit) break;
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
function getDimensionEvidence(result: EvalResult, dim: ScoreDimension): string[] {
|
||||
const evidence = result.evidence?.[dim.key] ?? (dim.key === "logic" ? result.evidence?.dialogue : undefined);
|
||||
return Array.isArray(evidence) ? evidence.map(String).map((item) => item.trim()).filter(Boolean).slice(0, 3) : [];
|
||||
return normalizeEvidenceItems(evidence, 3);
|
||||
}
|
||||
|
||||
function formatReportMarkdown(result: EvalResult, script: string): string {
|
||||
|
||||
Reference in New Issue
Block a user