fix: restore ai-cad model outputs

This commit is contained in:
134 2026-07-13 11:57:48 +08:00
parent aedf590e1d
commit cb47ebf568

View File

@ -19,6 +19,10 @@ type KittyCadTaskResponse = {
output_format?: string | null;
};
type KittyCadAsyncOperationResponse = KittyCadTaskResponse & {
type?: string | null;
};
type ArchivedFile = {
sourceHash: string;
archivedUrl: string;
@ -134,6 +138,78 @@ function pickPreviewImageFile(files: Array<{ name: string; url: string }>) {
);
}
function extractOutputEntries(task: KittyCadTaskResponse) {
return Object.entries(task.outputs || {}).filter(
(entry): entry is [string, string] =>
typeof entry[0] === "string" &&
entry[0].trim().length > 0 &&
typeof entry[1] === "string" &&
entry[1].trim().length > 0
);
}
async function enrichTextToCadOutputs(params: {
config: Awaited<ReturnType<typeof getKittyCadProviderConfig>>;
task: KittyCadTaskResponse;
taskId: string;
}) {
if (extractOutputEntries(params.task).length > 0) {
return params.task;
}
try {
const asyncOperation = await kittyCadRequest<KittyCadAsyncOperationResponse>(
params.config,
{
method: "GET",
path: `/async/operations/${encodeURIComponent(params.taskId)}`,
}
);
if (extractOutputEntries(asyncOperation).length === 0) {
return params.task;
}
return {
...params.task,
...asyncOperation,
code: asyncOperation.code || params.task.code || null,
conversation_id:
asyncOperation.conversation_id || params.task.conversation_id || null,
model_version:
asyncOperation.model_version || params.task.model_version || null,
output_format:
asyncOperation.output_format || params.task.output_format || null,
outputs: asyncOperation.outputs,
prompt: asyncOperation.prompt || params.task.prompt || null,
} satisfies KittyCadTaskResponse;
} catch (error) {
console.warn("[KittyCADStatus] async output fallback failed", {
taskId: params.taskId,
error: error instanceof Error ? error.message : String(error),
});
return params.task;
}
}
function createClientSafeTaskOutput(task: KittyCadTaskResponse) {
const outputEntries = extractOutputEntries(task);
const outputSummary = Object.fromEntries(
outputEntries.map(([name, base64]) => [
name,
{
base64Length: base64.length,
extension: getFileExtension(name) || null,
},
])
);
return {
...task,
outputs: outputSummary,
};
}
async function archiveOutputIfNeeded(params: {
taskId: string;
filename: string;
@ -269,7 +345,7 @@ export async function GET(_request: Request, { params }: RouteParams) {
}
const config = await getKittyCadProviderConfig();
const result = await kittyCadRequest<KittyCadTaskResponse>(config, {
let result = await kittyCadRequest<KittyCadTaskResponse>(config, {
method: "GET",
path: `/user/text-to-cad/${encodeURIComponent(normalizedTaskId)}`,
});
@ -287,18 +363,18 @@ export async function GET(_request: Request, { params }: RouteParams) {
conversationId: result.conversation_id || null,
modelVersion: result.model_version || null,
outputFormat: result.output_format || null,
output: result,
output: createClientSafeTaskOutput(result),
},
});
}
const outputEntries = Object.entries(result.outputs || {}).filter(
(entry): entry is [string, string] =>
typeof entry[0] === "string" &&
entry[0].trim().length > 0 &&
typeof entry[1] === "string" &&
entry[1].trim().length > 0
);
result = await enrichTextToCadOutputs({
config,
task: result,
taskId: normalizedTaskId,
});
const outputEntries = extractOutputEntries(result);
const archivedEntries = await Promise.all(
outputEntries.map(async ([name, base64]) => {
@ -365,7 +441,7 @@ export async function GET(_request: Request, { params }: RouteParams) {
outputFormat: result.output_format || null,
codeUrl: codeFile?.url || null,
downloadUrls,
output: result,
output: createClientSafeTaskOutput(result),
},
});
} catch (error) {