Skip to content

Commit 90f5927

Browse files
fix(file): use file-upload subblock (#3862)
* fix(file): use file-upload subblock * fix preview + logs url for notifs * fix color for profound * remove canonical param from desc
1 parent d091441 commit 90f5927

File tree

7 files changed

+114
-57
lines changed

7 files changed

+114
-57
lines changed

apps/docs/content/docs/en/tools/file.mdx

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: File
3-
description: Read and parse multiple files
3+
description: Read and write workspace files
44
---
55

66
import { BlockInfoCard } from "@/components/ui/block-info-card"
@@ -27,7 +27,7 @@ The File Parser tool is particularly useful for scenarios where your agents need
2727

2828
## Usage Instructions
2929

30-
Upload files directly or import from external URLs to get UserFile objects for use in other blocks.
30+
Read and parse files from uploads or URLs, write new workspace files, or append content to existing files.
3131

3232

3333

@@ -52,4 +52,45 @@ Parse one or more uploaded files or files from URLs (text, PDF, CSV, images, etc
5252
| `files` | file[] | Parsed files as UserFile objects |
5353
| `combinedContent` | string | Combined content of all parsed files |
5454

55+
### `file_write`
56+
57+
Create a new workspace file. If a file with the same name already exists, a numeric suffix is added (e.g.,
58+
59+
#### Input
60+
61+
| Parameter | Type | Required | Description |
62+
| --------- | ---- | -------- | ----------- |
63+
| `fileName` | string | Yes | File name \(e.g., "data.csv"\). If a file with this name exists, a numeric suffix is added automatically. |
64+
| `content` | string | Yes | The text content to write to the file. |
65+
| `contentType` | string | No | MIME type for new files \(e.g., "text/plain"\). Auto-detected from file extension if omitted. |
66+
67+
#### Output
68+
69+
| Parameter | Type | Description |
70+
| --------- | ---- | ----------- |
71+
| `id` | string | File ID |
72+
| `name` | string | File name |
73+
| `size` | number | File size in bytes |
74+
| `url` | string | URL to access the file |
75+
76+
### `file_append`
77+
78+
Append content to an existing workspace file. The file must already exist. Content is added to the end of the file.
79+
80+
#### Input
81+
82+
| Parameter | Type | Required | Description |
83+
| --------- | ---- | -------- | ----------- |
84+
| `fileName` | string | Yes | Name of an existing workspace file to append to. |
85+
| `content` | string | Yes | The text content to append to the file. |
86+
87+
#### Output
88+
89+
| Parameter | Type | Description |
90+
| --------- | ---- | ----------- |
91+
| `id` | string | File ID |
92+
| `name` | string | File name |
93+
| `size` | number | File size in bytes |
94+
| `url` | string | URL to access the file |
95+
5596

apps/docs/content/docs/en/tools/profound.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { BlockInfoCard } from "@/components/ui/block-info-card"
77

88
<BlockInfoCard
99
type="profound"
10-
color="#1A1A2E"
10+
color="#000000"
1111
/>
1212

1313
{/* MANUAL-CONTENT-START:intro */}

apps/sim/app/(landing)/integrations/data/integrations.json

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2993,13 +2993,26 @@
29932993
"type": "file_v3",
29942994
"slug": "file",
29952995
"name": "File",
2996-
"description": "Read and parse multiple files",
2997-
"longDescription": "Upload files directly or import from external URLs to get UserFile objects for use in other blocks.",
2996+
"description": "Read and write workspace files",
2997+
"longDescription": "Read and parse files from uploads or URLs, write new workspace files, or append content to existing files.",
29982998
"bgColor": "#40916C",
29992999
"iconName": "DocumentIcon",
30003000
"docsUrl": "https://docs.sim.ai/tools/file",
3001-
"operations": [],
3002-
"operationCount": 0,
3001+
"operations": [
3002+
{
3003+
"name": "Read",
3004+
"description": "Parse one or more uploaded files or files from URLs (text, PDF, CSV, images, etc.)"
3005+
},
3006+
{
3007+
"name": "Write",
3008+
"description": "Create a new workspace file. If a file with the same name already exists, a numeric suffix is added (e.g., "
3009+
},
3010+
{
3011+
"name": "Append",
3012+
"description": "Append content to an existing workspace file. The file must already exist. Content is added to the end of the file."
3013+
}
3014+
],
3015+
"operationCount": 3,
30033016
"triggers": [],
30043017
"triggerCount": 0,
30053018
"authType": "none",
@@ -8617,7 +8630,7 @@
86178630
"name": "Profound",
86188631
"description": "AI visibility and analytics with Profound",
86198632
"longDescription": "Track how your brand appears across AI platforms. Monitor visibility scores, sentiment, citations, bot traffic, referrals, content optimization, and prompt volumes with Profound.",
8620-
"bgColor": "#1A1A2E",
8633+
"bgColor": "#000000",
86218634
"iconName": "ProfoundIcon",
86228635
"docsUrl": "https://docs.sim.ai/tools/profound",
86238636
"operations": [

apps/sim/app/api/emails/preview/route.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ const emailTemplates = {
100100
trigger: 'api',
101101
duration: '2.3s',
102102
cost: '$0.0042',
103-
logUrl: 'https://sim.ai/workspace/ws_123/logs?search=exec_abc123',
103+
logUrl: 'https://sim.ai/workspace/ws_123/logs?executionId=exec_abc123',
104104
}),
105105
'workflow-notification-error': () =>
106106
renderWorkflowNotificationEmail({
@@ -109,7 +109,7 @@ const emailTemplates = {
109109
trigger: 'webhook',
110110
duration: '1.1s',
111111
cost: '$0.0021',
112-
logUrl: 'https://sim.ai/workspace/ws_123/logs?search=exec_abc123',
112+
logUrl: 'https://sim.ai/workspace/ws_123/logs?executionId=exec_abc123',
113113
}),
114114
'workflow-notification-alert': () =>
115115
renderWorkflowNotificationEmail({
@@ -118,7 +118,7 @@ const emailTemplates = {
118118
trigger: 'schedule',
119119
duration: '45.2s',
120120
cost: '$0.0156',
121-
logUrl: 'https://sim.ai/workspace/ws_123/logs?search=exec_abc123',
121+
logUrl: 'https://sim.ai/workspace/ws_123/logs?executionId=exec_abc123',
122122
alertReason: '3 consecutive failures detected',
123123
}),
124124
'workflow-notification-full': () =>
@@ -128,7 +128,7 @@ const emailTemplates = {
128128
trigger: 'api',
129129
duration: '12.5s',
130130
cost: '$0.0234',
131-
logUrl: 'https://sim.ai/workspace/ws_123/logs?search=exec_abc123',
131+
logUrl: 'https://sim.ai/workspace/ws_123/logs?executionId=exec_abc123',
132132
finalOutput: { processed: 150, skipped: 3, status: 'completed' },
133133
rateLimits: {
134134
sync: { requestsPerMinute: 60, remaining: 45 },

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/file-upload/file-upload.tsx

Lines changed: 11 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ import { useParams } from 'next/navigation'
77
import { Button, Combobox } from '@/components/emcn/components'
88
import { Progress } from '@/components/ui/progress'
99
import { cn } from '@/lib/core/utils/cn'
10-
import type { WorkspaceFileRecord } from '@/lib/uploads/contexts/workspace'
1110
import { getExtensionFromMimeType } from '@/lib/uploads/utils/file-utils'
1211
import { useSubBlockValue } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/hooks/use-sub-block-value'
12+
import { useWorkspaceFiles } from '@/hooks/queries/workspace-files'
1313
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
1414
import { useWorkflowStore } from '@/stores/workflows/workflow/store'
1515

@@ -150,8 +150,6 @@ export function FileUpload({
150150
const [storeValue, setStoreValue] = useSubBlockValue(blockId, subBlockId)
151151
const [uploadingFiles, setUploadingFiles] = useState<UploadingFile[]>([])
152152
const [uploadProgress, setUploadProgress] = useState(0)
153-
const [workspaceFiles, setWorkspaceFiles] = useState<WorkspaceFileRecord[]>([])
154-
const [loadingWorkspaceFiles, setLoadingWorkspaceFiles] = useState(false)
155153
const [uploadError, setUploadError] = useState<string | null>(null)
156154
const [inputValue, setInputValue] = useState('')
157155

@@ -163,25 +161,13 @@ export function FileUpload({
163161
const params = useParams()
164162
const workspaceId = params?.workspaceId as string
165163

166-
const value = isPreview ? previewValue : storeValue
167-
168-
const loadWorkspaceFiles = async () => {
169-
if (!workspaceId || isPreview) return
170-
171-
try {
172-
setLoadingWorkspaceFiles(true)
173-
const response = await fetch(`/api/workspaces/${workspaceId}/files`)
174-
const data = await response.json()
164+
const {
165+
data: workspaceFiles = [],
166+
isLoading: loadingWorkspaceFiles,
167+
refetch: refetchWorkspaceFiles,
168+
} = useWorkspaceFiles(isPreview ? '' : workspaceId)
175169

176-
if (data.success) {
177-
setWorkspaceFiles(data.files || [])
178-
}
179-
} catch (error) {
180-
logger.error('Error loading workspace files:', error)
181-
} finally {
182-
setLoadingWorkspaceFiles(false)
183-
}
184-
}
170+
const value = isPreview ? previewValue : storeValue
185171

186172
/**
187173
* Checks if a file's MIME type matches the accepted types
@@ -226,10 +212,6 @@ export function FileUpload({
226212
return !isAlreadySelected
227213
})
228214

229-
useEffect(() => {
230-
void loadWorkspaceFiles()
231-
}, [workspaceId])
232-
233215
/**
234216
* Opens file dialog
235217
*/
@@ -394,7 +376,7 @@ export function FileUpload({
394376
setUploadError(null)
395377

396378
if (workspaceId) {
397-
void loadWorkspaceFiles()
379+
void refetchWorkspaceFiles()
398380
}
399381

400382
if (uploadedFiles.length === 1) {
@@ -726,7 +708,7 @@ export function FileUpload({
726708
value={inputValue}
727709
onChange={handleComboboxChange}
728710
onOpenChange={(open) => {
729-
if (open) void loadWorkspaceFiles()
711+
if (open) void refetchWorkspaceFiles()
730712
}}
731713
placeholder={loadingWorkspaceFiles ? 'Loading files...' : '+ Add More'}
732714
disabled={disabled || loadingWorkspaceFiles}
@@ -746,7 +728,7 @@ export function FileUpload({
746728
onInputChange={handleComboboxChange}
747729
onClear={(e) => handleRemoveFile(filesArray[0], e)}
748730
onOpenChange={(open) => {
749-
if (open) void loadWorkspaceFiles()
731+
if (open) void refetchWorkspaceFiles()
750732
}}
751733
disabled={disabled}
752734
isLoading={loadingWorkspaceFiles}
@@ -763,7 +745,7 @@ export function FileUpload({
763745
value={inputValue}
764746
onChange={handleComboboxChange}
765747
onOpenChange={(open) => {
766-
if (open) void loadWorkspaceFiles()
748+
if (open) void refetchWorkspaceFiles()
767749
}}
768750
placeholder={loadingWorkspaceFiles ? 'Loading files...' : 'Select or upload file'}
769751
disabled={disabled || loadingWorkspaceFiles}

apps/sim/blocks/blocks/file.ts

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -318,23 +318,26 @@ export const FileV3Block: BlockConfig<FileParserV3Output> = {
318318
condition: { field: 'operation', value: 'file_write' },
319319
mode: 'advanced',
320320
},
321+
{
322+
id: 'appendFile',
323+
title: 'File',
324+
type: 'file-upload' as SubBlockType,
325+
canonicalParamId: 'appendFileInput',
326+
acceptedTypes: '.txt,.md,.json,.csv,.xml,.html,.htm,.yaml,.yml,.log,.rtf',
327+
placeholder: 'Select or upload a workspace file',
328+
mode: 'basic',
329+
condition: { field: 'operation', value: 'file_append' },
330+
required: { field: 'operation', value: 'file_append' },
331+
},
321332
{
322333
id: 'appendFileName',
323334
title: 'File',
324-
type: 'dropdown' as SubBlockType,
325-
placeholder: 'Select a workspace file...',
335+
type: 'short-input' as SubBlockType,
336+
canonicalParamId: 'appendFileInput',
337+
placeholder: 'File name (e.g., notes.md)',
338+
mode: 'advanced',
326339
condition: { field: 'operation', value: 'file_append' },
327340
required: { field: 'operation', value: 'file_append' },
328-
options: [],
329-
fetchOptions: async () => {
330-
const { useWorkflowRegistry } = await import('@/stores/workflows/registry/store')
331-
const workspaceId = useWorkflowRegistry.getState().hydration.workspaceId
332-
if (!workspaceId) return []
333-
const response = await fetch(`/api/workspaces/${workspaceId}/files`)
334-
const data = await response.json()
335-
if (!data.success || !data.files) return []
336-
return data.files.map((f: { name: string }) => ({ label: f.name, id: f.name }))
337-
},
338341
},
339342
{
340343
id: 'appendContent',
@@ -362,8 +365,26 @@ export const FileV3Block: BlockConfig<FileParserV3Output> = {
362365
}
363366

364367
if (operation === 'file_append') {
368+
const appendInput = params.appendFileInput
369+
if (!appendInput) {
370+
throw new Error('File is required for append')
371+
}
372+
373+
let fileName: string
374+
if (typeof appendInput === 'string') {
375+
fileName = appendInput.trim()
376+
} else {
377+
const normalized = normalizeFileInput(appendInput, { single: true })
378+
const file = normalized as Record<string, unknown> | null
379+
fileName = (file?.name as string) ?? ''
380+
}
381+
382+
if (!fileName) {
383+
throw new Error('Could not determine file name')
384+
}
385+
365386
return {
366-
fileName: params.appendFileName,
387+
fileName,
367388
content: params.appendContent,
368389
workspaceId: params._context?.workspaceId,
369390
}
@@ -408,12 +429,12 @@ export const FileV3Block: BlockConfig<FileParserV3Output> = {
408429
},
409430
inputs: {
410431
operation: { type: 'string', description: 'Operation to perform (read, write, or append)' },
411-
fileInput: { type: 'json', description: 'File input for read (canonical param)' },
432+
fileInput: { type: 'json', description: 'File input for read' },
412433
fileType: { type: 'string', description: 'File type for read' },
413434
fileName: { type: 'string', description: 'Name for a new file (write)' },
414435
content: { type: 'string', description: 'File content to write' },
415436
contentType: { type: 'string', description: 'MIME content type for write' },
416-
appendFileName: { type: 'string', description: 'Name of existing file to append to' },
437+
appendFileInput: { type: 'json', description: 'File to append to' },
417438
appendContent: { type: 'string', description: 'Content to append to file' },
418439
},
419440
outputs: {

apps/sim/blocks/blocks/profound.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ export const ProfoundBlock: BlockConfig = {
6868
category: 'tools',
6969
integrationType: IntegrationType.Analytics,
7070
tags: ['seo', 'data-analytics'],
71-
bgColor: '#1A1A2E',
71+
bgColor: '#000000',
7272
icon: ProfoundIcon,
7373
authMode: AuthMode.ApiKey,
7474

0 commit comments

Comments
 (0)