diff --git a/apps/sim/app/api/tools/dropbox/upload/route.ts b/apps/sim/app/api/tools/dropbox/upload/route.ts index c68967b839b..58873c334bc 100644 --- a/apps/sim/app/api/tools/dropbox/upload/route.ts +++ b/apps/sim/app/api/tools/dropbox/upload/route.ts @@ -89,7 +89,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => { const dropboxApiArg = { path: finalPath, mode: validatedData.mode || 'add', - autorename: validatedData.autorename ?? true, + autorename: validatedData.autorename ?? false, mute: validatedData.mute ?? false, } diff --git a/apps/sim/blocks/blocks/dropbox.ts b/apps/sim/blocks/blocks/dropbox.ts index e18b895a6b9..f162ce89c6c 100644 --- a/apps/sim/blocks/blocks/dropbox.ts +++ b/apps/sim/blocks/blocks/dropbox.ts @@ -33,7 +33,10 @@ export const DropboxBlock: BlockConfig = { { label: 'Move File/Folder', id: 'dropbox_move' }, { label: 'Get Metadata', id: 'dropbox_get_metadata' }, { label: 'Create Shared Link', id: 'dropbox_create_shared_link' }, + { label: 'List Shared Links', id: 'dropbox_list_shared_links' }, { label: 'Search Files', id: 'dropbox_search' }, + { label: 'List Revisions', id: 'dropbox_list_revisions' }, + { label: 'Restore File', id: 'dropbox_restore' }, ], value: () => 'dropbox_upload', }, @@ -299,6 +302,71 @@ Return ONLY the timestamp string - no explanations, no quotes, no extra text.`, placeholder: '100', condition: { field: 'operation', value: 'dropbox_search' }, }, + // List shared links operation inputs + { + id: 'path', + title: 'Path', + type: 'short-input', + placeholder: '/ (all links) or /folder', + condition: { field: 'operation', value: 'dropbox_list_shared_links' }, + }, + { + id: 'directOnly', + title: 'Direct Links Only', + type: 'switch', + condition: { field: 'operation', value: 'dropbox_list_shared_links' }, + mode: 'advanced', + }, + { + id: 'cursor', + title: 'Cursor', + type: 'short-input', + placeholder: 'Cursor from a previous call, to fetch the next page', + condition: { field: 'operation', value: 'dropbox_list_shared_links' }, + mode: 'advanced', + }, + // List revisions operation inputs + { + id: 'path', + title: 'File Path', + type: 'short-input', + placeholder: '/folder/document.pdf', + condition: { field: 'operation', value: 'dropbox_list_revisions' }, + required: true, + }, + { + id: 'limit', + title: 'Maximum Revisions', + type: 'short-input', + placeholder: '10', + condition: { field: 'operation', value: 'dropbox_list_revisions' }, + mode: 'advanced', + }, + { + id: 'beforeRev', + title: 'Before Revision', + type: 'short-input', + placeholder: 'Revision from a previous call, to fetch the next page', + condition: { field: 'operation', value: 'dropbox_list_revisions' }, + mode: 'advanced', + }, + // Restore operation inputs + { + id: 'path', + title: 'File Path', + type: 'short-input', + placeholder: '/folder/document.pdf', + condition: { field: 'operation', value: 'dropbox_restore' }, + required: true, + }, + { + id: 'rev', + title: 'Revision', + type: 'short-input', + placeholder: 'a1c10ce0dd78', + condition: { field: 'operation', value: 'dropbox_restore' }, + required: true, + }, ], tools: { access: [ @@ -311,7 +379,10 @@ Return ONLY the timestamp string - no explanations, no quotes, no extra text.`, 'dropbox_move', 'dropbox_get_metadata', 'dropbox_create_shared_link', + 'dropbox_list_shared_links', 'dropbox_search', + 'dropbox_list_revisions', + 'dropbox_restore', ], config: { tool: (params) => { @@ -334,8 +405,14 @@ Return ONLY the timestamp string - no explanations, no quotes, no extra text.`, return 'dropbox_get_metadata' case 'dropbox_create_shared_link': return 'dropbox_create_shared_link' + case 'dropbox_list_shared_links': + return 'dropbox_list_shared_links' case 'dropbox_search': return 'dropbox_search' + case 'dropbox_list_revisions': + return 'dropbox_list_revisions' + case 'dropbox_restore': + return 'dropbox_restore' default: return 'dropbox_upload' } @@ -379,14 +456,24 @@ Return ONLY the timestamp string - no explanations, no quotes, no extra text.`, query: { type: 'string', description: 'Search query' }, fileExtensions: { type: 'string', description: 'File extensions filter' }, maxResults: { type: 'number', description: 'Maximum search results' }, + // List shared links inputs + directOnly: { type: 'boolean', description: 'Only return direct links, not parent folders' }, + cursor: { type: 'string', description: 'Fetch the next page of shared links (pagination)' }, + // List revisions input + beforeRev: { type: 'string', description: 'Fetch revisions before this one (pagination)' }, + // Restore input + rev: { type: 'string', description: 'Revision identifier to restore' }, }, outputs: { // Upload/Download outputs file: { type: 'file', description: 'Downloaded file stored in execution files' }, content: { type: 'string', description: 'File content (base64)' }, temporaryLink: { type: 'string', description: 'Temporary download link' }, - // List folder outputs - entries: { type: 'json', description: 'List of files and folders' }, + // List folder / List revisions outputs + entries: { + type: 'json', + description: 'List of files and folders (List Folder), or file revisions (List Revisions)', + }, cursor: { type: 'string', description: 'Pagination cursor' }, hasMore: { type: 'boolean', description: 'Whether more results exist' }, // Create folder output @@ -399,6 +486,10 @@ Return ONLY the timestamp string - no explanations, no quotes, no extra text.`, sharedLink: { type: 'json', description: 'Shared link details' }, // Search outputs matches: { type: 'json', description: 'Search results' }, + // List shared links outputs + links: { type: 'json', description: 'List of shared links (url, name, path_lower, expires)' }, + // List revisions output + isDeleted: { type: 'boolean', description: 'Whether the latest revision is deleted or moved' }, }, } @@ -501,5 +592,12 @@ export const DropboxBlockMeta = { content: '# Share Dropbox Link\n\nGenerate a shareable link for an existing Dropbox item with the right access controls.\n\n## Steps\n1. Confirm the exact path of the file or folder. Use Get Metadata to verify it exists.\n2. Call Create Shared Link with the path and the requested visibility — public for anyone, team-only for internal sharing, or password-protected with a supplied password.\n3. Set an expiration date if the link should not be permanent.\n\n## Output\nReturn the shared link URL, its visibility setting, and the expiration date if one was applied.', }, + { + name: 'recover-dropbox-file-version', + description: + 'Recover an earlier version of a Dropbox file after an unwanted overwrite or edit.', + content: + '# Recover Dropbox File Version\n\nRoll a file back to an earlier saved revision.\n\n## Steps\n1. Call List Revisions on the file path to see prior versions, each with a revision identifier and modification time.\n2. Identify the revision to recover based on its timestamp or size.\n3. Call Restore File with the file path and the chosen revision identifier. This saves that revision as the new current version — it does not delete history.\n\n## Output\nReturn the restored file metadata, including its path and the revision that was restored.', + }, ], } as const satisfies BlockMeta diff --git a/apps/sim/tools/dropbox/copy.ts b/apps/sim/tools/dropbox/copy.ts index 8a6471f0314..16fc7b27610 100644 --- a/apps/sim/tools/dropbox/copy.ts +++ b/apps/sim/tools/dropbox/copy.ts @@ -46,8 +46,8 @@ export const dropboxCopyTool: ToolConfig } }, body: (params) => ({ - from_path: params.fromPath, - to_path: params.toPath, + from_path: params.fromPath.trim(), + to_path: params.toPath.trim(), autorename: params.autorename ?? false, }), }, @@ -77,10 +77,10 @@ export const dropboxCopyTool: ToolConfig description: 'Metadata of the copied item', properties: { '.tag': { type: 'string', description: 'Type: file or folder' }, - id: { type: 'string', description: 'Unique identifier' }, + id: { type: 'string', description: 'Unique identifier', optional: true }, name: { type: 'string', description: 'Name of the copied item' }, - path_display: { type: 'string', description: 'Display path' }, - size: { type: 'number', description: 'Size in bytes (files only)' }, + path_display: { type: 'string', description: 'Display path', optional: true }, + size: { type: 'number', description: 'Size in bytes (files only)', optional: true }, }, }, }, diff --git a/apps/sim/tools/dropbox/create_folder.ts b/apps/sim/tools/dropbox/create_folder.ts index a107747c7d4..b57711591e3 100644 --- a/apps/sim/tools/dropbox/create_folder.ts +++ b/apps/sim/tools/dropbox/create_folder.ts @@ -43,7 +43,7 @@ export const dropboxCreateFolderTool: ToolConfig< } }, body: (params) => ({ - path: params.path, + path: params.path.trim(), autorename: params.autorename ?? false, }), }, @@ -74,8 +74,8 @@ export const dropboxCreateFolderTool: ToolConfig< properties: { id: { type: 'string', description: 'Unique identifier for the folder' }, name: { type: 'string', description: 'Name of the folder' }, - path_display: { type: 'string', description: 'Display path of the folder' }, - path_lower: { type: 'string', description: 'Lowercase path of the folder' }, + path_display: { type: 'string', description: 'Display path of the folder', optional: true }, + path_lower: { type: 'string', description: 'Lowercase path of the folder', optional: true }, }, }, }, diff --git a/apps/sim/tools/dropbox/create_shared_link.ts b/apps/sim/tools/dropbox/create_shared_link.ts index e27df0451a5..b7b05be3845 100644 --- a/apps/sim/tools/dropbox/create_shared_link.ts +++ b/apps/sim/tools/dropbox/create_shared_link.ts @@ -59,7 +59,7 @@ export const dropboxCreateSharedLinkTool: ToolConfig< }, body: (params) => { const body: Record = { - path: params.path, + path: params.path.trim(), } const settings: Record = {} @@ -88,12 +88,24 @@ export const dropboxCreateSharedLinkTool: ToolConfig< const data = await response.json() if (!response.ok) { - // Check if a shared link already exists + // A link may already exist for this path - Dropbox includes its metadata in the error + // when the requested settings match the existing link, so surface it as a success. + // Per Stone's JSON rules, a union member whose payload is a struct (SharedLinkMetadata) + // flattens that struct's fields alongside ".tag" - there is no nested "metadata" key. + const existingLink = data.error?.shared_link_already_exists + if (existingLink) { + return { + success: true, + output: { + sharedLink: existingLink, + }, + } + } if (data.error_summary?.includes('shared_link_already_exists')) { return { success: false, error: - 'A shared link already exists for this path. Use list_shared_links to get the existing link.', + 'A shared link already exists for this path with different settings. Use Dropbox List Shared Links to retrieve it.', output: {}, } } @@ -119,8 +131,12 @@ export const dropboxCreateSharedLinkTool: ToolConfig< properties: { url: { type: 'string', description: 'The shared link URL' }, name: { type: 'string', description: 'Name of the shared item' }, - path_lower: { type: 'string', description: 'Lowercase path of the shared item' }, - expires: { type: 'string', description: 'Expiration date if set' }, + path_lower: { + type: 'string', + description: 'Lowercase path of the shared item', + optional: true, + }, + expires: { type: 'string', description: 'Expiration date if set', optional: true }, link_permissions: { type: 'object', description: 'Permissions for the shared link', diff --git a/apps/sim/tools/dropbox/delete.ts b/apps/sim/tools/dropbox/delete.ts index d1e6a67c86d..1e700eb4dd3 100644 --- a/apps/sim/tools/dropbox/delete.ts +++ b/apps/sim/tools/dropbox/delete.ts @@ -34,7 +34,7 @@ export const dropboxDeleteTool: ToolConfig ({ - path: params.path, + path: params.path.trim(), }), }, @@ -65,7 +65,7 @@ export const dropboxDeleteTool: ToolConfig ({ - path: params.path, + path: params.path.trim(), include_media_info: params.includeMediaInfo ?? false, include_deleted: params.includeDeleted ?? false, }), @@ -80,15 +80,27 @@ export const dropboxGetMetadataTool: ToolConfig< description: 'Metadata for the file or folder', properties: { '.tag': { type: 'string', description: 'Type: file, folder, or deleted' }, - id: { type: 'string', description: 'Unique identifier' }, + id: { type: 'string', description: 'Unique identifier', optional: true }, name: { type: 'string', description: 'Name of the item' }, - path_display: { type: 'string', description: 'Display path' }, - path_lower: { type: 'string', description: 'Lowercase path' }, - size: { type: 'number', description: 'Size in bytes (files only)' }, - client_modified: { type: 'string', description: 'Client modification time' }, - server_modified: { type: 'string', description: 'Server modification time' }, - rev: { type: 'string', description: 'Revision identifier' }, - content_hash: { type: 'string', description: 'Content hash' }, + path_display: { type: 'string', description: 'Display path', optional: true }, + path_lower: { type: 'string', description: 'Lowercase path', optional: true }, + size: { type: 'number', description: 'Size in bytes (files only)', optional: true }, + client_modified: { + type: 'string', + description: 'Client modification time (files only)', + optional: true, + }, + server_modified: { + type: 'string', + description: 'Server modification time (files only)', + optional: true, + }, + rev: { type: 'string', description: 'Revision identifier (files only)', optional: true }, + content_hash: { + type: 'string', + description: 'Content hash (files only)', + optional: true, + }, }, }, }, diff --git a/apps/sim/tools/dropbox/index.ts b/apps/sim/tools/dropbox/index.ts index 6fea8749700..c113cc121af 100644 --- a/apps/sim/tools/dropbox/index.ts +++ b/apps/sim/tools/dropbox/index.ts @@ -5,7 +5,10 @@ import { dropboxDeleteTool } from '@/tools/dropbox/delete' import { dropboxDownloadTool } from '@/tools/dropbox/download' import { dropboxGetMetadataTool } from '@/tools/dropbox/get_metadata' import { dropboxListFolderTool } from '@/tools/dropbox/list_folder' +import { dropboxListRevisionsTool } from '@/tools/dropbox/list_revisions' +import { dropboxListSharedLinksTool } from '@/tools/dropbox/list_shared_links' import { dropboxMoveTool } from '@/tools/dropbox/move' +import { dropboxRestoreTool } from '@/tools/dropbox/restore' import { dropboxSearchTool } from '@/tools/dropbox/search' import { dropboxUploadTool } from '@/tools/dropbox/upload' @@ -17,7 +20,10 @@ export { dropboxDownloadTool, dropboxGetMetadataTool, dropboxListFolderTool, + dropboxListRevisionsTool, + dropboxListSharedLinksTool, dropboxMoveTool, + dropboxRestoreTool, dropboxSearchTool, dropboxUploadTool, } diff --git a/apps/sim/tools/dropbox/list_folder.ts b/apps/sim/tools/dropbox/list_folder.ts index 19e30158f67..a0a31ba9f1b 100644 --- a/apps/sim/tools/dropbox/list_folder.ts +++ b/apps/sim/tools/dropbox/list_folder.ts @@ -59,7 +59,7 @@ export const dropboxListFolderTool: ToolConfig ({ - path: params.path === '/' ? '' : params.path, + path: params.path.trim() === '/' ? '' : params.path.trim(), recursive: params.recursive ?? false, include_deleted: params.includeDeleted ?? false, include_media_info: params.includeMediaInfo ?? false, @@ -96,10 +96,10 @@ export const dropboxListFolderTool: ToolConfig = { + id: 'dropbox_list_revisions', + name: 'Dropbox List Revisions', + description: 'List the revision history for a file in Dropbox (files only, not folders)', + version: '1.0.0', + + oauth: { + required: true, + provider: 'dropbox', + }, + + params: { + path: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'The path of the file to list revisions for', + }, + limit: { + type: 'number', + required: false, + visibility: 'user-only', + description: 'Maximum number of revisions to return, 1-100 (default: 10)', + }, + beforeRev: { + type: 'string', + required: false, + visibility: 'user-only', + description: + 'Only return revisions before this one. Pass the rev of the last revision from a previous call to fetch the next page.', + }, + }, + + request: { + url: 'https://api.dropboxapi.com/2/files/list_revisions', + method: 'POST', + headers: (params) => { + if (!params.accessToken) { + throw new Error('Missing access token for Dropbox API request') + } + return { + Authorization: `Bearer ${params.accessToken}`, + 'Content-Type': 'application/json', + } + }, + body: (params) => { + const body: Record = { + path: params.path.trim(), + mode: 'path', + limit: params.limit ?? 10, + } + if (params.beforeRev) { + body.before_rev = params.beforeRev.trim() + } + return body + }, + }, + + transformResponse: async (response) => { + const data = await response.json() + + if (!response.ok) { + return { + success: false, + error: data.error_summary || data.error?.message || 'Failed to list revisions', + output: {}, + } + } + + return { + success: true, + output: { + entries: data.entries || [], + isDeleted: data.is_deleted ?? false, + hasMore: data.has_more ?? false, + }, + } + }, + + outputs: { + entries: { + type: 'array', + description: 'The revisions for the file, most recent first', + items: { + type: 'object', + properties: { + id: { type: 'string', description: 'Unique identifier for this revision' }, + name: { type: 'string', description: 'Name of the file' }, + path_display: { type: 'string', description: 'Display path', optional: true }, + rev: { type: 'string', description: 'Revision identifier, pass to Restore' }, + size: { type: 'number', description: 'Size of this revision in bytes' }, + server_modified: { type: 'string', description: 'Server modification time' }, + }, + }, + }, + isDeleted: { + type: 'boolean', + description: 'Whether the file identified by the latest revision is deleted or moved', + }, + hasMore: { + type: 'boolean', + description: 'Whether there are more revisions available', + }, + }, +} diff --git a/apps/sim/tools/dropbox/list_shared_links.ts b/apps/sim/tools/dropbox/list_shared_links.ts new file mode 100644 index 00000000000..1459424821a --- /dev/null +++ b/apps/sim/tools/dropbox/list_shared_links.ts @@ -0,0 +1,120 @@ +import type { + DropboxListSharedLinksParams, + DropboxListSharedLinksResponse, +} from '@/tools/dropbox/types' +import type { ToolConfig } from '@/tools/types' + +export const dropboxListSharedLinksTool: ToolConfig< + DropboxListSharedLinksParams, + DropboxListSharedLinksResponse +> = { + id: 'dropbox_list_shared_links', + name: 'Dropbox List Shared Links', + description: 'List shared links for a path, or for the entire account if no path is given', + version: '1.0.0', + + oauth: { + required: true, + provider: 'dropbox', + }, + + params: { + path: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Path to list shared links for. If omitted, lists all shared links.', + }, + directOnly: { + type: 'boolean', + required: false, + visibility: 'user-only', + description: 'If true, only return links directly to the path, not parent folder links', + }, + cursor: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Cursor from a previous call to fetch the next page of results', + }, + }, + + request: { + url: 'https://api.dropboxapi.com/2/sharing/list_shared_links', + method: 'POST', + headers: (params) => { + if (!params.accessToken) { + throw new Error('Missing access token for Dropbox API request') + } + return { + Authorization: `Bearer ${params.accessToken}`, + 'Content-Type': 'application/json', + } + }, + body: (params) => { + const body: Record = {} + if (params.path) { + const trimmedPath = params.path.trim() + // Dropbox only returns every shared link on the account when `path` is omitted + // entirely; sending "" scopes the results to the root folder instead. Since our UI + // tells users "/" means "list all links", omit the field rather than sending "". + if (trimmedPath !== '/' && trimmedPath !== '') { + body.path = trimmedPath + } + } + if (params.directOnly !== undefined) body.direct_only = params.directOnly + if (params.cursor) body.cursor = params.cursor + return body + }, + }, + + transformResponse: async (response) => { + const data = await response.json() + + if (!response.ok) { + return { + success: false, + error: data.error_summary || data.error?.message || 'Failed to list shared links', + output: {}, + } + } + + return { + success: true, + output: { + links: data.links ?? [], + hasMore: data.has_more ?? false, + cursor: data.cursor, + }, + } + }, + + outputs: { + links: { + type: 'array', + description: 'Shared links applicable to the path argument', + items: { + type: 'object', + properties: { + '.tag': { type: 'string', description: 'Type: file or folder' }, + url: { type: 'string', description: 'The shared link URL' }, + name: { type: 'string', description: 'Name of the shared item' }, + path_lower: { + type: 'string', + description: 'Lowercase path of the shared item', + optional: true, + }, + expires: { type: 'string', description: 'Expiration date if set', optional: true }, + }, + }, + }, + hasMore: { + type: 'boolean', + description: 'Whether there are more results', + }, + cursor: { + type: 'string', + description: 'Cursor for pagination (only returned when no path is given)', + }, + }, +} diff --git a/apps/sim/tools/dropbox/move.ts b/apps/sim/tools/dropbox/move.ts index bbdf57081f4..3d11c5a53d0 100644 --- a/apps/sim/tools/dropbox/move.ts +++ b/apps/sim/tools/dropbox/move.ts @@ -46,8 +46,8 @@ export const dropboxMoveTool: ToolConfig } }, body: (params) => ({ - from_path: params.fromPath, - to_path: params.toPath, + from_path: params.fromPath.trim(), + to_path: params.toPath.trim(), autorename: params.autorename ?? false, }), }, @@ -77,10 +77,10 @@ export const dropboxMoveTool: ToolConfig description: 'Metadata of the moved item', properties: { '.tag': { type: 'string', description: 'Type: file or folder' }, - id: { type: 'string', description: 'Unique identifier' }, + id: { type: 'string', description: 'Unique identifier', optional: true }, name: { type: 'string', description: 'Name of the moved item' }, - path_display: { type: 'string', description: 'Display path' }, - size: { type: 'number', description: 'Size in bytes (files only)' }, + path_display: { type: 'string', description: 'Display path', optional: true }, + size: { type: 'number', description: 'Size in bytes (files only)', optional: true }, }, }, }, diff --git a/apps/sim/tools/dropbox/restore.ts b/apps/sim/tools/dropbox/restore.ts new file mode 100644 index 00000000000..3cbb2259330 --- /dev/null +++ b/apps/sim/tools/dropbox/restore.ts @@ -0,0 +1,82 @@ +import type { DropboxRestoreParams, DropboxRestoreResponse } from '@/tools/dropbox/types' +import type { ToolConfig } from '@/tools/types' + +export const dropboxRestoreTool: ToolConfig = { + id: 'dropbox_restore', + name: 'Dropbox Restore', + description: 'Restore a specific revision of a file to the given path', + version: '1.0.0', + + oauth: { + required: true, + provider: 'dropbox', + }, + + params: { + path: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'The path to save the restored file to', + }, + rev: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'The revision identifier to restore (from Dropbox List Revisions)', + }, + }, + + request: { + url: 'https://api.dropboxapi.com/2/files/restore', + method: 'POST', + headers: (params) => { + if (!params.accessToken) { + throw new Error('Missing access token for Dropbox API request') + } + return { + Authorization: `Bearer ${params.accessToken}`, + 'Content-Type': 'application/json', + } + }, + body: (params) => ({ + path: params.path.trim(), + rev: params.rev.trim(), + }), + }, + + transformResponse: async (response) => { + const data = await response.json() + + if (!response.ok) { + return { + success: false, + error: data.error_summary || data.error?.message || 'Failed to restore file', + output: {}, + } + } + + return { + success: true, + output: { + metadata: data, + }, + } + }, + + outputs: { + metadata: { + type: 'object', + description: 'Metadata of the restored file', + properties: { + id: { type: 'string', description: 'Unique identifier for the file' }, + name: { type: 'string', description: 'Name of the file' }, + path_display: { type: 'string', description: 'Display path of the file', optional: true }, + path_lower: { type: 'string', description: 'Lowercase path of the file', optional: true }, + size: { type: 'number', description: 'Size of the file in bytes' }, + rev: { type: 'string', description: 'Revision identifier of the restored file' }, + server_modified: { type: 'string', description: 'Server modification time' }, + }, + }, + }, +} diff --git a/apps/sim/tools/dropbox/search.ts b/apps/sim/tools/dropbox/search.ts index 558f89fc186..4498a44d31a 100644 --- a/apps/sim/tools/dropbox/search.ts +++ b/apps/sim/tools/dropbox/search.ts @@ -59,7 +59,8 @@ export const dropboxSearchTool: ToolConfig = {} if (params.path) { - options.path = params.path + const trimmedPath = params.path.trim() + options.path = trimmedPath === '/' ? '' : trimmedPath } if (params.fileExtensions) { diff --git a/apps/sim/tools/dropbox/types.ts b/apps/sim/tools/dropbox/types.ts index 94d8bd20054..2b9440e6359 100644 --- a/apps/sim/tools/dropbox/types.ts +++ b/apps/sim/tools/dropbox/types.ts @@ -7,8 +7,8 @@ interface DropboxFileMetadata { '.tag': 'file' id: string name: string - path_display: string - path_lower: string + path_display?: string + path_lower?: string size: number client_modified: string server_modified: string @@ -21,15 +21,15 @@ interface DropboxFolderMetadata { '.tag': 'folder' id: string name: string - path_display: string - path_lower: string + path_display?: string + path_lower?: string } interface DropboxDeletedMetadata { '.tag': 'deleted' name: string - path_display: string - path_lower: string + path_display?: string + path_lower?: string } export type DropboxMetadata = DropboxFileMetadata | DropboxFolderMetadata | DropboxDeletedMetadata @@ -232,6 +232,62 @@ interface DropboxGetTemporaryLinkResponse extends ToolResponse { } } +// ===== List Shared Links Params ===== + +export interface DropboxListSharedLinksParams extends DropboxBaseParams { + path?: string + directOnly?: boolean + cursor?: string +} + +export interface DropboxListSharedLinksResponse extends ToolResponse { + output: { + links?: DropboxSharedLinkMetadata[] + hasMore?: boolean + cursor?: string + } +} + +// ===== List Revisions Params ===== + +interface DropboxFileRevision { + '.tag': 'file' + id: string + name: string + path_display?: string + path_lower?: string + size: number + rev: string + server_modified: string +} + +export interface DropboxListRevisionsParams extends DropboxBaseParams { + path: string + limit?: number + beforeRev?: string +} + +export interface DropboxListRevisionsResponse extends ToolResponse { + output: { + entries?: DropboxFileRevision[] + isDeleted?: boolean + hasMore?: boolean + } +} + +// ===== Restore Params ===== + +export interface DropboxRestoreParams extends DropboxBaseParams { + path: string + rev: string +} + +export interface DropboxRestoreResponse extends ToolResponse { + output: { + metadata?: DropboxFileMetadata + } +} + // ===== Combined Response Type ===== export type DropboxResponse = @@ -246,3 +302,6 @@ export type DropboxResponse = | DropboxCreateSharedLinkResponse | DropboxSearchResponse | DropboxGetTemporaryLinkResponse + | DropboxListSharedLinksResponse + | DropboxListRevisionsResponse + | DropboxRestoreResponse diff --git a/apps/sim/tools/dropbox/upload.ts b/apps/sim/tools/dropbox/upload.ts index 1a8914bc439..1fa507b517d 100644 --- a/apps/sim/tools/dropbox/upload.ts +++ b/apps/sim/tools/dropbox/upload.ts @@ -67,7 +67,7 @@ export const dropboxUploadTool: ToolConfig ({ accessToken: params.accessToken, - path: params.path, + path: params.path.trim(), file: params.file, fileContent: params.fileContent, fileName: params.fileName, @@ -101,13 +101,17 @@ export const dropboxUploadTool: ToolConfig = { dropbox_get_metadata: dropboxGetMetadataTool, dropbox_create_shared_link: dropboxCreateSharedLinkTool, dropbox_search: dropboxSearchTool, + dropbox_list_shared_links: dropboxListSharedLinksTool, + dropbox_list_revisions: dropboxListRevisionsTool, + dropbox_restore: dropboxRestoreTool, devin_create_session: devinCreateSessionTool, devin_get_session: devinGetSessionTool, devin_list_sessions: devinListSessionsTool,