diff --git a/apps/sim/app/workspace/[workspaceId]/files/[fileId]/view/file-viewer.tsx b/apps/sim/app/workspace/[workspaceId]/files/[fileId]/view/file-viewer.tsx index a450bd374d..cbed424d13 100644 --- a/apps/sim/app/workspace/[workspaceId]/files/[fileId]/view/file-viewer.tsx +++ b/apps/sim/app/workspace/[workspaceId]/files/[fileId]/view/file-viewer.tsx @@ -17,7 +17,7 @@ export function FileViewer() { return null } - const serveUrl = `/api/files/serve/${encodeURIComponent(file.key)}?context=workspace` + const serveUrl = `/api/files/serve/${encodeURIComponent(file.key)}?context=workspace&t=${file.size}` return (
diff --git a/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/file-viewer.tsx b/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/file-viewer.tsx index 6a90ebacbb..7c59dbbe83 100644 --- a/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/file-viewer.tsx +++ b/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/file-viewer.tsx @@ -502,7 +502,7 @@ const ZOOM_BUTTON_FACTOR = 1.2 const clampZoom = (z: number) => Math.min(Math.max(z, ZOOM_MIN), ZOOM_MAX) const ImagePreview = memo(function ImagePreview({ file }: { file: WorkspaceFileRecord }) { - const serveUrl = `/api/files/serve/${encodeURIComponent(file.key)}?context=workspace` + const serveUrl = `/api/files/serve/${encodeURIComponent(file.key)}?context=workspace&t=${file.size}` const [zoom, setZoom] = useState(1) const [offset, setOffset] = useState({ x: 0, y: 0 }) const isDragging = useRef(false) diff --git a/apps/sim/lib/copilot/tools/server/files/workspace-file.ts b/apps/sim/lib/copilot/tools/server/files/workspace-file.ts index 94f4ec0a3a..afa3b3ff7a 100644 --- a/apps/sim/lib/copilot/tools/server/files/workspace-file.ts +++ b/apps/sim/lib/copilot/tools/server/files/workspace-file.ts @@ -15,6 +15,7 @@ import { deleteWorkspaceFile, downloadWorkspaceFile as downloadWsFile, getWorkspaceFile, + getWorkspaceFileByName, renameWorkspaceFile, updateWorkspaceFileContent, uploadWorkspaceFile, @@ -99,20 +100,76 @@ export const workspaceFileServerTool: BaseServerTool).fileId as string | undefined - const content = (args as Record).content as string | undefined - - if (!fileId) { - return { success: false, message: 'fileId is required for append operation' } - } - if (!content) { - return { success: false, message: 'content is required for append operation' } - } - - const fileRecord = await getWorkspaceFile(workspaceId, fileId) - if (!fileRecord) { - return { success: false, message: `File with ID "${fileId}" not found` } - } - - const currentBuffer = await downloadWsFile(fileRecord) - const combined = `${currentBuffer.toString('utf-8')}\n${content}` - - const appendLowerName = fileRecord.name?.toLowerCase() ?? '' - const isPptxAppend = appendLowerName.endsWith('.pptx') - const isDocxAppend = appendLowerName.endsWith('.docx') - const isPdfAppend = appendLowerName.endsWith('.pdf') - const isDocAppend = isPptxAppend || isDocxAppend || isPdfAppend - - if (isDocAppend) { - const formatName = isPptxAppend ? 'PPTX' : isDocxAppend ? 'DOCX' : 'PDF' - const generator = isPptxAppend - ? generatePptxFromCode - : isDocxAppend - ? generateDocxFromCode - : generatePdfFromCode - try { - await generator(combined, workspaceId) - } catch (err) { - const msg = err instanceof Error ? err.message : String(err) - return { - success: false, - message: `Appended ${formatName} code failed to compile: ${msg}. Fix the content and retry.`, - } - } - } - - const appendSourceMime = isPptxAppend - ? PPTX_SOURCE_MIME - : isDocxAppend - ? DOCX_SOURCE_MIME - : isPdfAppend - ? PDF_SOURCE_MIME - : undefined - const appendBuffer = Buffer.from(combined, 'utf-8') - assertServerToolNotAborted(context) - await updateWorkspaceFileContent( - workspaceId, - fileId, - context.userId, - appendBuffer, - appendSourceMime - ) - - logger.info('Workspace file appended via copilot', { - fileId, - name: fileRecord.name, - appendedSize: content.length, - totalSize: appendBuffer.length, - userId: context.userId, - }) - - return { - success: true, - message: `Content appended to "${fileRecord.name}" (${content.length} bytes added, ${appendBuffer.length} bytes total)`, - data: { - id: fileId, - name: fileRecord.name, - size: appendBuffer.length, - }, - } - } - case 'patch': { const fileId = (args as Record).fileId as string | undefined const edits = (args as Record).edits as diff --git a/apps/sim/lib/copilot/tools/shared/schemas.ts b/apps/sim/lib/copilot/tools/shared/schemas.ts index 579a4b6b85..c59200e846 100644 --- a/apps/sim/lib/copilot/tools/shared/schemas.ts +++ b/apps/sim/lib/copilot/tools/shared/schemas.ts @@ -176,7 +176,7 @@ export type UserTableResult = z.infer // workspace_file - shared schema used by server tool and Go catalog export const WorkspaceFileArgsSchema = z.object({ - operation: z.enum(['write', 'update', 'append', 'delete', 'rename', 'patch']), + operation: z.enum(['write', 'update', 'delete', 'rename', 'patch']), args: z .object({ fileId: z.string().optional(),