fix: harden multi-file response detection so merge can't fail silently (#6516)

Co-authored-by: Reece Browne <[email protected]>
This commit is contained in:
Anthony Stirling
2026-06-04 18:17:36 +01:00
committed by GitHub
co-authored by Reece Browne
parent cb687fbf99
commit bd9ef0586b
9 changed files with 518 additions and 63 deletions
@@ -21,6 +21,7 @@ import {
StirlingFileStub,
} from "@app/types/fileContext";
import { FILE_EVENTS } from "@app/services/errorUtils";
import { zipFileService } from "@app/services/zipFileService";
import { getFilenameWithoutExtension } from "@app/utils/fileUtils";
import {
createChildStub,
@@ -274,29 +275,36 @@ export const useToolOperation = <TParams>(
responseType: "blob",
});
// Multi-file responses are typically ZIP files that need extraction, but some may return single PDFs
const responseBlob: Blob = response.data;
const contentTypeHeader = response.headers?.["content-type"];
if (config.responseHandler) {
// Use custom responseHandler for multi-file (handles ZIP extraction)
processedFiles = await config.responseHandler(
response.data,
responseBlob,
filesForAPI,
);
} else if (
response.data.type === "application/pdf" ||
(response.headers &&
response.headers["content-type"] === "application/pdf")
await zipFileService.isZipResponse(
responseBlob,
typeof contentTypeHeader === "string"
? contentTypeHeader
: undefined,
)
) {
// Single PDF response (e.g. split with merge option) - add prefix to first original filename
const filename = `${config.filePrefix}${filesForAPI[0]?.name || "document.pdf"}`;
const singleFile = new File([response.data], filename, {
type: "application/pdf",
});
processedFiles = [singleFile];
processedFiles = await extractZipFiles(responseBlob);
} else {
// Default: assume ZIP response for multi-file endpoints
// Note: extractZipFiles will check preferences.autoUnzip setting
processedFiles = await extractZipFiles(response.data);
const filename = `${config.filePrefix}${filesForAPI[0]?.name || "document.pdf"}`;
processedFiles = [
new File([responseBlob], filename, { type: "application/pdf" }),
];
}
if (processedFiles.length === 0) {
throw new Error(
"The server processed the request but returned no files.",
);
}
// Assume all inputs succeeded together unless server provided an error earlier
successSourceIds = validFiles.map((f) => f.fileId);
break;