@@ -250,16 +250,27 @@ export const FileV2Block: BlockConfig<FileParserOutput> = {
250250export const FileV3Block : BlockConfig < FileParserV3Output > = {
251251 type : 'file_v3' ,
252252 name : 'File' ,
253- description : 'Read and parse multiple files' ,
253+ description : 'Read and write workspace files' ,
254254 longDescription :
255- 'Upload files directly or import from external URLs to get UserFile objects for use in other blocks .' ,
255+ 'Read and parse files from uploads or URLs, write new workspace files, or append content to existing files .' ,
256256 docsLink : 'https://docs.sim.ai/tools/file' ,
257257 category : 'tools' ,
258258 integrationType : IntegrationType . FileStorage ,
259259 tags : [ 'document-processing' ] ,
260260 bgColor : '#40916C' ,
261261 icon : DocumentIcon ,
262262 subBlocks : [
263+ {
264+ id : 'operation' ,
265+ title : 'Operation' ,
266+ type : 'dropdown' as SubBlockType ,
267+ options : [
268+ { label : 'Read' , id : 'file_parser_v3' } ,
269+ { label : 'Write' , id : 'file_write' } ,
270+ { label : 'Append' , id : 'file_append' } ,
271+ ] ,
272+ value : ( ) => 'file_parser_v3' ,
273+ } ,
263274 {
264275 id : 'file' ,
265276 title : 'Files' ,
@@ -270,7 +281,8 @@ export const FileV3Block: BlockConfig<FileParserV3Output> = {
270281 multiple : true ,
271282 mode : 'basic' ,
272283 maxSize : 100 ,
273- required : true ,
284+ required : { field : 'operation' , value : 'file_parser_v3' } ,
285+ condition : { field : 'operation' , value : 'file_parser_v3' } ,
274286 } ,
275287 {
276288 id : 'fileUrl' ,
@@ -279,15 +291,84 @@ export const FileV3Block: BlockConfig<FileParserV3Output> = {
279291 canonicalParamId : 'fileInput' ,
280292 placeholder : 'https://example.com/document.pdf' ,
281293 mode : 'advanced' ,
282- required : true ,
294+ required : { field : 'operation' , value : 'file_parser_v3' } ,
295+ condition : { field : 'operation' , value : 'file_parser_v3' } ,
296+ } ,
297+ {
298+ id : 'fileName' ,
299+ title : 'File Name' ,
300+ type : 'short-input' as SubBlockType ,
301+ placeholder : 'File name (e.g., data.csv)' ,
302+ condition : { field : 'operation' , value : 'file_write' } ,
303+ required : { field : 'operation' , value : 'file_write' } ,
304+ } ,
305+ {
306+ id : 'content' ,
307+ title : 'Content' ,
308+ type : 'long-input' as SubBlockType ,
309+ placeholder : 'File content to write...' ,
310+ condition : { field : 'operation' , value : 'file_write' } ,
311+ required : { field : 'operation' , value : 'file_write' } ,
312+ } ,
313+ {
314+ id : 'contentType' ,
315+ title : 'Content Type' ,
316+ type : 'short-input' as SubBlockType ,
317+ placeholder : 'text/plain (auto-detected from extension)' ,
318+ condition : { field : 'operation' , value : 'file_write' } ,
319+ mode : 'advanced' ,
320+ } ,
321+ {
322+ id : 'appendFileName' ,
323+ title : 'File' ,
324+ type : 'dropdown' as SubBlockType ,
325+ placeholder : 'Select a workspace file...' ,
326+ condition : { field : 'operation' , value : 'file_append' } ,
327+ 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+ } ,
338+ } ,
339+ {
340+ id : 'appendContent' ,
341+ title : 'Content' ,
342+ type : 'long-input' as SubBlockType ,
343+ placeholder : 'Content to append...' ,
344+ condition : { field : 'operation' , value : 'file_append' } ,
345+ required : { field : 'operation' , value : 'file_append' } ,
283346 } ,
284347 ] ,
285348 tools : {
286- access : [ 'file_parser_v3' ] ,
349+ access : [ 'file_parser_v3' , 'file_write' , 'file_append' ] ,
287350 config : {
288- tool : ( ) => 'file_parser_v3' ,
351+ tool : ( params ) => params . operation || 'file_parser_v3' ,
289352 params : ( params ) => {
290- // Use canonical 'fileInput' param directly
353+ const operation = params . operation || 'file_parser_v3'
354+
355+ if ( operation === 'file_write' ) {
356+ return {
357+ fileName : params . fileName ,
358+ content : params . content ,
359+ contentType : params . contentType ,
360+ workspaceId : params . _context ?. workspaceId ,
361+ }
362+ }
363+
364+ if ( operation === 'file_append' ) {
365+ return {
366+ fileName : params . appendFileName ,
367+ content : params . appendContent ,
368+ workspaceId : params . _context ?. workspaceId ,
369+ }
370+ }
371+
291372 const fileInput = params . fileInput
292373 if ( ! fileInput ) {
293374 logger . error ( 'No file input provided' )
@@ -326,17 +407,39 @@ export const FileV3Block: BlockConfig<FileParserV3Output> = {
326407 } ,
327408 } ,
328409 inputs : {
329- fileInput : { type : 'json' , description : 'File input (canonical param)' } ,
330- fileType : { type : 'string' , description : 'File type' } ,
410+ operation : { type : 'string' , description : 'Operation to perform (read, write, or append)' } ,
411+ fileInput : { type : 'json' , description : 'File input for read (canonical param)' } ,
412+ fileType : { type : 'string' , description : 'File type for read' } ,
413+ fileName : { type : 'string' , description : 'Name for a new file (write)' } ,
414+ content : { type : 'string' , description : 'File content to write' } ,
415+ contentType : { type : 'string' , description : 'MIME content type for write' } ,
416+ appendFileName : { type : 'string' , description : 'Name of existing file to append to' } ,
417+ appendContent : { type : 'string' , description : 'Content to append to file' } ,
331418 } ,
332419 outputs : {
333420 files : {
334421 type : 'file[]' ,
335- description : 'Parsed files as UserFile objects' ,
422+ description : 'Parsed files as UserFile objects (read) ' ,
336423 } ,
337424 combinedContent : {
338425 type : 'string' ,
339- description : 'All file contents merged into a single text string' ,
426+ description : 'All file contents merged into a single text string (read)' ,
427+ } ,
428+ id : {
429+ type : 'string' ,
430+ description : 'File ID (write)' ,
431+ } ,
432+ name : {
433+ type : 'string' ,
434+ description : 'File name (write)' ,
435+ } ,
436+ size : {
437+ type : 'number' ,
438+ description : 'File size in bytes (write)' ,
439+ } ,
440+ url : {
441+ type : 'string' ,
442+ description : 'URL to access the file (write)' ,
340443 } ,
341444 } ,
342445}
0 commit comments