|
| 1 | +import { createLogger } from '@sim/logger' |
1 | 2 | import type { GoogleDriveToolParams, GoogleDriveUploadResponse } from '@/tools/google_drive/types' |
| 3 | +import { ALL_FILE_FIELDS } from '@/tools/google_drive/utils' |
2 | 4 | import type { ToolConfig } from '@/tools/types' |
3 | 5 |
|
| 6 | +const logger = createLogger('GoogleDriveCreateFolderTool') |
| 7 | + |
4 | 8 | export const createFolderTool: ToolConfig<GoogleDriveToolParams, GoogleDriveUploadResponse> = { |
5 | 9 | id: 'google_drive_create_folder', |
6 | 10 | name: 'Create Folder in Google Drive', |
7 | | - description: 'Create a new folder in Google Drive', |
| 11 | + description: 'Create a new folder in Google Drive with complete metadata returned', |
8 | 12 | version: '1.0', |
9 | 13 |
|
10 | 14 | oauth: { |
@@ -66,35 +70,120 @@ export const createFolderTool: ToolConfig<GoogleDriveToolParams, GoogleDriveUplo |
66 | 70 | }, |
67 | 71 | }, |
68 | 72 |
|
69 | | - transformResponse: async (response: Response) => { |
| 73 | + transformResponse: async (response: Response, params?: GoogleDriveToolParams) => { |
70 | 74 | if (!response.ok) { |
71 | 75 | const data = await response.json().catch(() => ({})) |
| 76 | + logger.error('Failed to create folder in Google Drive', { |
| 77 | + status: response.status, |
| 78 | + statusText: response.statusText, |
| 79 | + error: data, |
| 80 | + }) |
72 | 81 | throw new Error(data.error?.message || 'Failed to create folder in Google Drive') |
73 | 82 | } |
| 83 | + |
74 | 84 | const data = await response.json() |
| 85 | + const folderId = data.id |
| 86 | + const authHeader = `Bearer ${params?.accessToken || ''}` |
| 87 | + |
| 88 | + // Fetch complete folder metadata with all fields |
| 89 | + const metadataResponse = await fetch( |
| 90 | + `https://www.googleapis.com/drive/v3/files/${folderId}?supportsAllDrives=true&fields=${ALL_FILE_FIELDS}`, |
| 91 | + { |
| 92 | + headers: { |
| 93 | + Authorization: authHeader, |
| 94 | + }, |
| 95 | + } |
| 96 | + ) |
| 97 | + |
| 98 | + if (!metadataResponse.ok) { |
| 99 | + logger.warn('Failed to fetch complete metadata, returning basic response', { |
| 100 | + status: metadataResponse.status, |
| 101 | + statusText: metadataResponse.statusText, |
| 102 | + }) |
| 103 | + // Return basic response if metadata fetch fails |
| 104 | + return { |
| 105 | + success: true, |
| 106 | + output: { |
| 107 | + file: data, |
| 108 | + }, |
| 109 | + } |
| 110 | + } |
| 111 | + |
| 112 | + const fullMetadata = await metadataResponse.json() |
| 113 | + |
| 114 | + logger.info('Folder created successfully', { |
| 115 | + folderId: fullMetadata.id, |
| 116 | + name: fullMetadata.name, |
| 117 | + mimeType: fullMetadata.mimeType, |
| 118 | + hasOwners: !!fullMetadata.owners?.length, |
| 119 | + hasPermissions: !!fullMetadata.permissions?.length, |
| 120 | + }) |
75 | 121 |
|
76 | 122 | return { |
77 | 123 | success: true, |
78 | 124 | output: { |
79 | | - file: { |
80 | | - id: data.id, |
81 | | - name: data.name, |
82 | | - mimeType: data.mimeType, |
83 | | - webViewLink: data.webViewLink, |
84 | | - webContentLink: data.webContentLink, |
85 | | - size: data.size, |
86 | | - createdTime: data.createdTime, |
87 | | - modifiedTime: data.modifiedTime, |
88 | | - parents: data.parents, |
89 | | - }, |
| 125 | + file: fullMetadata, |
90 | 126 | }, |
91 | 127 | } |
92 | 128 | }, |
93 | 129 |
|
94 | 130 | outputs: { |
95 | 131 | file: { |
96 | | - type: 'json', |
97 | | - description: 'Created folder metadata including ID, name, and parent information', |
| 132 | + type: 'object', |
| 133 | + description: 'Complete created folder metadata from Google Drive', |
| 134 | + properties: { |
| 135 | + // Basic Info |
| 136 | + id: { type: 'string', description: 'Google Drive folder ID' }, |
| 137 | + name: { type: 'string', description: 'Folder name' }, |
| 138 | + mimeType: { type: 'string', description: 'MIME type (application/vnd.google-apps.folder)' }, |
| 139 | + kind: { type: 'string', description: 'Resource type identifier' }, |
| 140 | + description: { type: 'string', description: 'Folder description' }, |
| 141 | + // Ownership & Sharing |
| 142 | + owners: { type: 'json', description: 'List of folder owners' }, |
| 143 | + permissions: { type: 'json', description: 'Folder permissions' }, |
| 144 | + permissionIds: { type: 'json', description: 'Permission IDs' }, |
| 145 | + shared: { type: 'boolean', description: 'Whether folder is shared' }, |
| 146 | + ownedByMe: { type: 'boolean', description: 'Whether owned by current user' }, |
| 147 | + writersCanShare: { type: 'boolean', description: 'Whether writers can share' }, |
| 148 | + viewersCanCopyContent: { type: 'boolean', description: 'Whether viewers can copy' }, |
| 149 | + copyRequiresWriterPermission: { |
| 150 | + type: 'boolean', |
| 151 | + description: 'Whether copy requires writer permission', |
| 152 | + }, |
| 153 | + sharingUser: { type: 'json', description: 'User who shared the folder' }, |
| 154 | + // Labels/Tags |
| 155 | + starred: { type: 'boolean', description: 'Whether folder is starred' }, |
| 156 | + trashed: { type: 'boolean', description: 'Whether folder is in trash' }, |
| 157 | + explicitlyTrashed: { type: 'boolean', description: 'Whether explicitly trashed' }, |
| 158 | + properties: { type: 'json', description: 'Custom properties' }, |
| 159 | + appProperties: { type: 'json', description: 'App-specific properties' }, |
| 160 | + folderColorRgb: { type: 'string', description: 'Folder color' }, |
| 161 | + // Timestamps |
| 162 | + createdTime: { type: 'string', description: 'Folder creation time' }, |
| 163 | + modifiedTime: { type: 'string', description: 'Last modification time' }, |
| 164 | + modifiedByMeTime: { type: 'string', description: 'When modified by current user' }, |
| 165 | + viewedByMeTime: { type: 'string', description: 'When last viewed by current user' }, |
| 166 | + sharedWithMeTime: { type: 'string', description: 'When shared with current user' }, |
| 167 | + // User Info |
| 168 | + lastModifyingUser: { type: 'json', description: 'User who last modified the folder' }, |
| 169 | + viewedByMe: { type: 'boolean', description: 'Whether viewed by current user' }, |
| 170 | + modifiedByMe: { type: 'boolean', description: 'Whether modified by current user' }, |
| 171 | + // Links |
| 172 | + webViewLink: { type: 'string', description: 'URL to view in browser' }, |
| 173 | + iconLink: { type: 'string', description: 'URL to folder icon' }, |
| 174 | + // Hierarchy & Location |
| 175 | + parents: { type: 'json', description: 'Parent folder IDs' }, |
| 176 | + spaces: { type: 'json', description: 'Spaces containing folder' }, |
| 177 | + driveId: { type: 'string', description: 'Shared drive ID' }, |
| 178 | + // Capabilities |
| 179 | + capabilities: { type: 'json', description: 'User capabilities on folder' }, |
| 180 | + // Versions |
| 181 | + version: { type: 'string', description: 'Version number' }, |
| 182 | + // Other |
| 183 | + isAppAuthorized: { type: 'boolean', description: 'Whether created by requesting app' }, |
| 184 | + contentRestrictions: { type: 'json', description: 'Content restrictions' }, |
| 185 | + linkShareMetadata: { type: 'json', description: 'Link share metadata' }, |
| 186 | + }, |
98 | 187 | }, |
99 | 188 | }, |
100 | 189 | } |
0 commit comments