Working as well as it was

This commit is contained in:
Connor Yoh 2025-09-05 18:00:00 +01:00
parent 5bf024be48
commit 47a16e71cf
3 changed files with 65 additions and 27 deletions

View File

@ -466,8 +466,21 @@ export async function consumeFiles(
// Process output files with thumbnails and metadata // Process output files with thumbnails and metadata
const outputStirlingFileStubs = await processFilesIntoRecords(outputFiles, filesRef); const outputStirlingFileStubs = await processFilesIntoRecords(outputFiles, filesRef);
// Mark input files as processed in IndexedDB (no longer leaf nodes) // Mark input files as processed in IndexedDB (no longer leaf nodes) and save output files
if (indexedDB) { if (indexedDB) {
// Mark input files as processed (isLeaf = false)
await Promise.all(
inputFileIds.map(async (fileId) => {
try {
await indexedDB.markFileAsProcessed(fileId);
if (DEBUG) console.log(`📄 Marked file ${fileId} as processed (no longer leaf)`);
} catch (error) {
if (DEBUG) console.warn(`📄 Failed to mark file ${fileId} as processed:`, error);
}
})
);
// Save output files to IndexedDB
await persistFilesToIndexedDB(outputStirlingFileStubs, indexedDB); await persistFilesToIndexedDB(outputStirlingFileStubs, indexedDB);
} }

View File

@ -8,7 +8,7 @@ import { useToolResources } from './useToolResources';
import { extractErrorMessage } from '../../../utils/toolErrorHandler'; import { extractErrorMessage } from '../../../utils/toolErrorHandler';
import { StirlingFile, extractFiles, FileId, StirlingFileStub } from '../../../types/fileContext'; import { StirlingFile, extractFiles, FileId, StirlingFileStub } from '../../../types/fileContext';
import { ResponseHandler } from '../../../utils/toolResponseProcessor'; import { ResponseHandler } from '../../../utils/toolResponseProcessor';
import { prepareFilesWithHistory, verifyToolMetadataPreservation } from '../../../utils/fileHistoryUtils'; import { prepareStirlingFilesWithHistory, verifyToolMetadataPreservation } from '../../../utils/fileHistoryUtils';
// Re-export for backwards compatibility // Re-export for backwards compatibility
export type { ProcessingProgress, ResponseHandler }; export type { ProcessingProgress, ResponseHandler };
@ -159,7 +159,6 @@ export const useToolOperation = <TParams>(
return; return;
} }
// Reset state // Reset state
actions.setLoading(true); actions.setLoading(true);
actions.setError(null); actions.setError(null);
@ -168,14 +167,13 @@ export const useToolOperation = <TParams>(
// Prepare files with history metadata injection (for PDFs) // Prepare files with history metadata injection (for PDFs)
actions.setStatus('Preparing files...'); actions.setStatus('Preparing files...');
const getFileStub = (file: File) => { const getFileStubById = (fileId: FileId) => {
const fileId = findFileId(file); return selectors.getStirlingFileStub(fileId);
return fileId ? selectors.getStirlingFileStub(fileId) : undefined;
}; };
const filesWithHistory = await prepareFilesWithHistory( const filesWithHistory = await prepareStirlingFilesWithHistory(
validFiles, validFiles,
getFileStub, getFileStubById,
config.operationType, config.operationType,
params as Record<string, any> params as Record<string, any>
); );
@ -183,8 +181,9 @@ export const useToolOperation = <TParams>(
try { try {
let processedFiles: File[]; let processedFiles: File[];
// Convert StirlingFile to regular File objects for API processing // Convert StirlingFiles with history to regular Files for API processing
const validRegularFiles = extractFiles(validFiles); // The history is already injected into the File data, we just need to extract the File objects
const filesForAPI = extractFiles(filesWithHistory);
switch (config.toolType) { switch (config.toolType) {
case ToolType.singleFile: { case ToolType.singleFile: {
@ -197,7 +196,7 @@ export const useToolOperation = <TParams>(
}; };
processedFiles = await processFiles( processedFiles = await processFiles(
params, params,
validRegularFiles, filesForAPI,
apiCallsConfig, apiCallsConfig,
actions.setProgress, actions.setProgress,
actions.setStatus actions.setStatus
@ -207,7 +206,7 @@ export const useToolOperation = <TParams>(
case ToolType.multiFile: { case ToolType.multiFile: {
// Multi-file processing - single API call with all files // Multi-file processing - single API call with all files
actions.setStatus('Processing files...'); actions.setStatus('Processing files...');
const formData = config.buildFormData(params, validRegularFiles); const formData = config.buildFormData(params, filesForAPI);
const endpoint = typeof config.endpoint === 'function' ? config.endpoint(params) : config.endpoint; const endpoint = typeof config.endpoint === 'function' ? config.endpoint(params) : config.endpoint;
const response = await axios.post(endpoint, formData, { responseType: 'blob' }); const response = await axios.post(endpoint, formData, { responseType: 'blob' });
@ -215,11 +214,11 @@ export const useToolOperation = <TParams>(
// Multi-file responses are typically ZIP files that need extraction, but some may return single PDFs // Multi-file responses are typically ZIP files that need extraction, but some may return single PDFs
if (config.responseHandler) { if (config.responseHandler) {
// Use custom responseHandler for multi-file (handles ZIP extraction) // Use custom responseHandler for multi-file (handles ZIP extraction)
processedFiles = await config.responseHandler(response.data, validRegularFiles); processedFiles = await config.responseHandler(response.data, filesForAPI);
} else if (response.data.type === 'application/pdf' || } else if (response.data.type === 'application/pdf' ||
(response.headers && response.headers['content-type'] === 'application/pdf')) { (response.headers && response.headers['content-type'] === 'application/pdf')) {
// Single PDF response (e.g. split with merge option) - use original filename // Single PDF response (e.g. split with merge option) - use original filename
const originalFileName = validRegularFiles[0]?.name || 'document.pdf'; const originalFileName = filesForAPI[0]?.name || 'document.pdf';
const singleFile = new File([response.data], originalFileName, { type: 'application/pdf' }); const singleFile = new File([response.data], originalFileName, { type: 'application/pdf' });
processedFiles = [singleFile]; processedFiles = [singleFile];
} else { } else {
@ -236,7 +235,7 @@ export const useToolOperation = <TParams>(
case ToolType.custom: case ToolType.custom:
actions.setStatus('Processing files...'); actions.setStatus('Processing files...');
processedFiles = await config.customProcessor(params, validRegularFiles); processedFiles = await config.customProcessor(params, filesForAPI);
break; break;
} }

View File

@ -123,25 +123,51 @@ export async function injectHistoryForTool(
} }
/** /**
* Prepare FormData with history-injected PDFs for tool operations * Prepare StirlingFiles with history-injected PDFs for tool operations
* Preserves fileId and all StirlingFile metadata while injecting history
*/ */
export async function prepareFilesWithHistory( export async function prepareStirlingFilesWithHistory(
files: File[], stirlingFiles: import('../types/fileContext').StirlingFile[],
getStirlingFileStub: (file: File) => StirlingFileStub | undefined, getStirlingFileStub: (fileId: import('../types/file').FileId) => StirlingFileStub | undefined,
toolName: string, toolName: string,
parameters?: Record<string, any> parameters?: Record<string, any>
): Promise<File[]> { ): Promise<import('../types/fileContext').StirlingFile[]> {
const processedFiles: File[] = []; const processedFiles: import('../types/fileContext').StirlingFile[] = [];
for (const file of files) { for (const stirlingFile of stirlingFiles) {
const record = getStirlingFileStub(file); const fileStub = getStirlingFileStub(stirlingFile.fileId);
if (!record) {
processedFiles.push(file); if (!fileStub) {
// If no stub found, keep original file
processedFiles.push(stirlingFile);
continue; continue;
} }
const fileWithHistory = await injectHistoryForTool(file, record, toolName, parameters); // Inject history into the file data
processedFiles.push(fileWithHistory); const fileWithHistory = await injectHistoryForTool(stirlingFile, fileStub, toolName, parameters);
// Create new StirlingFile with the updated file data but preserve fileId and quickKey
const updatedStirlingFile = new File([fileWithHistory], fileWithHistory.name, {
type: fileWithHistory.type,
lastModified: fileWithHistory.lastModified
}) as import('../types/fileContext').StirlingFile;
// Preserve the original fileId and quickKey
Object.defineProperty(updatedStirlingFile, 'fileId', {
value: stirlingFile.fileId,
writable: false,
enumerable: true,
configurable: false
});
Object.defineProperty(updatedStirlingFile, 'quickKey', {
value: stirlingFile.quickKey,
writable: false,
enumerable: true,
configurable: false
});
processedFiles.push(updatedStirlingFile);
} }
return processedFiles; return processedFiles;