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(),