-
Notifications
You must be signed in to change notification settings - Fork 3.2k
fix(google-vault): error handling improvement and more params #2735
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: staging
Are you sure you want to change the base?
Changes from all commits
ff1af41
3beb18b
1fee00a
a00ec62
59aca33
53cfd70
58417eb
79a93ed
3979d09
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -159,6 +159,167 @@ Return ONLY the hold name - no explanations, no quotes, no extra text.`, | |
| placeholder: 'Org Unit ID (alternative to emails)', | ||
| condition: { field: 'operation', value: ['create_matters_holds', 'create_matters_export'] }, | ||
| }, | ||
| // Date filtering for exports (works with all corpus types) | ||
| { | ||
| id: 'startTime', | ||
| title: 'Start Time', | ||
| type: 'short-input', | ||
| placeholder: 'YYYY-MM-DDTHH:mm:ssZ', | ||
| condition: { field: 'operation', value: 'create_matters_export' }, | ||
| wandConfig: { | ||
| enabled: true, | ||
| prompt: `Generate an ISO 8601 timestamp in GMT based on the user's description for Google Vault date filtering. | ||
| The timestamp should be in the format: YYYY-MM-DDTHH:mm:ssZ (UTC timezone). | ||
| Note: Google Vault rounds times to 12 AM on the specified date. | ||
| Examples: | ||
| - "yesterday" -> Calculate yesterday's date at 00:00:00Z | ||
| - "last week" -> Calculate 7 days ago at 00:00:00Z | ||
| - "beginning of this month" -> Calculate the 1st of current month at 00:00:00Z | ||
| - "January 1, 2024" -> 2024-01-01T00:00:00Z | ||
|
|
||
| Return ONLY the timestamp string - no explanations, no quotes, no extra text.`, | ||
| placeholder: 'Describe the start date (e.g., "last month", "January 1, 2024")...', | ||
| generationType: 'timestamp', | ||
| }, | ||
| }, | ||
| { | ||
| id: 'endTime', | ||
| title: 'End Time', | ||
| type: 'short-input', | ||
| placeholder: 'YYYY-MM-DDTHH:mm:ssZ', | ||
| condition: { field: 'operation', value: 'create_matters_export' }, | ||
| wandConfig: { | ||
| enabled: true, | ||
| prompt: `Generate an ISO 8601 timestamp in GMT based on the user's description for Google Vault date filtering. | ||
| The timestamp should be in the format: YYYY-MM-DDTHH:mm:ssZ (UTC timezone). | ||
| Note: Google Vault rounds times to 12 AM on the specified date. | ||
| Examples: | ||
| - "now" -> Current timestamp | ||
| - "today" -> Today's date at 23:59:59Z | ||
| - "end of last month" -> Last day of previous month at 23:59:59Z | ||
| - "December 31, 2024" -> 2024-12-31T23:59:59Z | ||
|
|
||
| Return ONLY the timestamp string - no explanations, no quotes, no extra text.`, | ||
| placeholder: 'Describe the end date (e.g., "today", "end of last quarter")...', | ||
| generationType: 'timestamp', | ||
| }, | ||
| }, | ||
| // Date filtering for holds (only works with MAIL and GROUPS corpus) | ||
| { | ||
|
Comment on lines
+186
to
+208
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Duplicate field ID Consider using unique field IDs to avoid potential conflicts. Prompt To Fix With AIThis is a comment left during a code review.
Path: apps/sim/blocks/blocks/google_vault.ts
Line: 186:208
Comment:
Duplicate field ID `endTime` defined. This field is already defined for create_matters_export (lines 186-208) and is redefined for create_matters_holds (lines 210-232). Similar to `startTime`, duplicate IDs may cause issues with the form rendering system.
Consider using unique field IDs to avoid potential conflicts.
How can I resolve this? If you propose a fix, please make it concise. |
||
| id: 'startTime', | ||
| title: 'Start Time', | ||
| type: 'short-input', | ||
| placeholder: 'YYYY-MM-DDTHH:mm:ssZ', | ||
| condition: { | ||
| field: 'operation', | ||
| value: 'create_matters_holds', | ||
| and: { field: 'corpus', value: ['MAIL', 'GROUPS'] }, | ||
| }, | ||
| wandConfig: { | ||
| enabled: true, | ||
| prompt: `Generate an ISO 8601 timestamp in GMT based on the user's description for Google Vault date filtering. | ||
| The timestamp should be in the format: YYYY-MM-DDTHH:mm:ssZ (UTC timezone). | ||
| Note: Google Vault rounds times to 12 AM on the specified date. | ||
| Examples: | ||
| - "yesterday" -> Calculate yesterday's date at 00:00:00Z | ||
| - "last week" -> Calculate 7 days ago at 00:00:00Z | ||
| - "beginning of this month" -> Calculate the 1st of current month at 00:00:00Z | ||
| - "January 1, 2024" -> 2024-01-01T00:00:00Z | ||
|
|
||
| Return ONLY the timestamp string - no explanations, no quotes, no extra text.`, | ||
| placeholder: 'Describe the start date (e.g., "last month", "January 1, 2024")...', | ||
| generationType: 'timestamp', | ||
| }, | ||
| }, | ||
| { | ||
| id: 'endTime', | ||
| title: 'End Time', | ||
| type: 'short-input', | ||
| placeholder: 'YYYY-MM-DDTHH:mm:ssZ', | ||
| condition: { | ||
| field: 'operation', | ||
| value: 'create_matters_holds', | ||
| and: { field: 'corpus', value: ['MAIL', 'GROUPS'] }, | ||
| }, | ||
| wandConfig: { | ||
| enabled: true, | ||
| prompt: `Generate an ISO 8601 timestamp in GMT based on the user's description for Google Vault date filtering. | ||
| The timestamp should be in the format: YYYY-MM-DDTHH:mm:ssZ (UTC timezone). | ||
| Note: Google Vault rounds times to 12 AM on the specified date. | ||
| Examples: | ||
| - "now" -> Current timestamp | ||
| - "today" -> Today's date at 23:59:59Z | ||
| - "end of last month" -> Last day of previous month at 23:59:59Z | ||
| - "December 31, 2024" -> 2024-12-31T23:59:59Z | ||
|
|
||
| Return ONLY the timestamp string - no explanations, no quotes, no extra text.`, | ||
| placeholder: 'Describe the end date (e.g., "today", "end of last quarter")...', | ||
|
Comment on lines
+234
to
+256
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Duplicate field ID Consider using unique identifiers for each operation's search terms field. Prompt To Fix With AIThis is a comment left during a code review.
Path: apps/sim/blocks/blocks/google_vault.ts
Line: 234:256
Comment:
Duplicate field ID `terms` defined. This field appears twice - once for exports (lines 234-256) and once for holds (lines 258-278). Like the date fields, duplicate field IDs may cause form rendering or data binding issues.
Consider using unique identifiers for each operation's search terms field.
How can I resolve this? If you propose a fix, please make it concise. |
||
| generationType: 'timestamp', | ||
| }, | ||
| }, | ||
| // Search terms for exports (works with all corpus types) | ||
| { | ||
| id: 'terms', | ||
| title: 'Search Terms', | ||
| type: 'long-input', | ||
| placeholder: 'Enter search query (e.g., from:user@example.com subject:confidential)', | ||
| condition: { field: 'operation', value: 'create_matters_export' }, | ||
| wandConfig: { | ||
| enabled: true, | ||
| prompt: `Generate a Google Vault search query based on the user's description. | ||
| The query can use Gmail-style search operators for MAIL corpus: | ||
| - from:user@example.com - emails from specific sender | ||
| - to:user@example.com - emails to specific recipient | ||
| - subject:keyword - emails with keyword in subject | ||
| - has:attachment - emails with attachments | ||
| - filename:pdf - emails with PDF attachments | ||
| - before:YYYY/MM/DD - emails before date | ||
| - after:YYYY/MM/DD - emails after date | ||
|
|
||
| For DRIVE corpus, use Drive search operators: | ||
| - owner:user@example.com - files owned by user | ||
| - type:document - specific file types | ||
|
|
||
| Return ONLY the search query - no explanations, no quotes, no extra text.`, | ||
| placeholder: 'Describe what content to search for...', | ||
| }, | ||
| }, | ||
| // Search terms for holds (only works with MAIL and GROUPS corpus) | ||
| { | ||
| id: 'terms', | ||
| title: 'Search Terms', | ||
| type: 'long-input', | ||
| placeholder: 'Enter search query (e.g., from:user@example.com subject:confidential)', | ||
| condition: { | ||
| field: 'operation', | ||
| value: 'create_matters_holds', | ||
| and: { field: 'corpus', value: ['MAIL', 'GROUPS'] }, | ||
| }, | ||
| wandConfig: { | ||
| enabled: true, | ||
| prompt: `Generate a Google Vault search query based on the user's description. | ||
| The query can use Gmail-style search operators: | ||
| - from:user@example.com - emails from specific sender | ||
| - to:user@example.com - emails to specific recipient | ||
| - subject:keyword - emails with keyword in subject | ||
| - has:attachment - emails with attachments | ||
| - filename:pdf - emails with PDF attachments | ||
|
|
||
| Return ONLY the search query - no explanations, no quotes, no extra text.`, | ||
| placeholder: 'Describe what content to search for...', | ||
| }, | ||
| }, | ||
| // Drive-specific option for holds | ||
| { | ||
| id: 'includeSharedDrives', | ||
| title: 'Include Shared Drives', | ||
| type: 'switch', | ||
| condition: { | ||
| field: 'operation', | ||
| value: 'create_matters_holds', | ||
| and: { field: 'corpus', value: 'DRIVE' }, | ||
| }, | ||
| }, | ||
| { | ||
| id: 'exportId', | ||
| title: 'Export ID', | ||
|
|
@@ -296,9 +457,16 @@ Return ONLY the description text - no explanations, no quotes, no extra text.`, | |
| corpus: { type: 'string', description: 'Data corpus (MAIL, DRIVE, GROUPS, etc.)' }, | ||
| accountEmails: { type: 'string', description: 'Comma-separated account emails' }, | ||
| orgUnitId: { type: 'string', description: 'Organization unit ID' }, | ||
| startTime: { type: 'string', description: 'Start time for date filtering (ISO 8601 format)' }, | ||
| endTime: { type: 'string', description: 'End time for date filtering (ISO 8601 format)' }, | ||
| terms: { type: 'string', description: 'Search query terms' }, | ||
|
|
||
| // Create hold inputs | ||
| holdName: { type: 'string', description: 'Name for the hold' }, | ||
| includeSharedDrives: { | ||
| type: 'boolean', | ||
| description: 'Include files in shared drives (for DRIVE corpus holds)', | ||
| }, | ||
|
|
||
| // Download export file inputs | ||
| bucketName: { type: 'string', description: 'GCS bucket name from export' }, | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,8 +1,7 @@ | ||||||||||||||
| import type { GoogleVaultCreateMattersHoldsParams } from '@/tools/google_vault/types' | ||||||||||||||
| import { enhanceGoogleVaultError } from '@/tools/google_vault/utils' | ||||||||||||||
| import type { ToolConfig } from '@/tools/types' | ||||||||||||||
|
|
||||||||||||||
| // matters.holds.create | ||||||||||||||
| // POST https://vault.googleapis.com/v1/matters/{matterId}/holds | ||||||||||||||
| export const createMattersHoldsTool: ToolConfig<GoogleVaultCreateMattersHoldsParams> = { | ||||||||||||||
| id: 'create_matters_holds', | ||||||||||||||
| name: 'Vault Create Hold (by Matter)', | ||||||||||||||
|
|
@@ -36,6 +35,30 @@ export const createMattersHoldsTool: ToolConfig<GoogleVaultCreateMattersHoldsPar | |||||||||||||
| visibility: 'user-only', | ||||||||||||||
| description: 'Organization unit ID to put on hold (alternative to accounts)', | ||||||||||||||
| }, | ||||||||||||||
| terms: { | ||||||||||||||
| type: 'string', | ||||||||||||||
| required: false, | ||||||||||||||
| visibility: 'user-only', | ||||||||||||||
| description: 'Search terms to filter held content (for MAIL and GROUPS corpus)', | ||||||||||||||
| }, | ||||||||||||||
| startTime: { | ||||||||||||||
| type: 'string', | ||||||||||||||
| required: false, | ||||||||||||||
| visibility: 'user-only', | ||||||||||||||
| description: 'Start time for date filtering (ISO 8601 format, for MAIL and GROUPS corpus)', | ||||||||||||||
| }, | ||||||||||||||
| endTime: { | ||||||||||||||
| type: 'string', | ||||||||||||||
| required: false, | ||||||||||||||
| visibility: 'user-only', | ||||||||||||||
| description: 'End time for date filtering (ISO 8601 format, for MAIL and GROUPS corpus)', | ||||||||||||||
| }, | ||||||||||||||
| includeSharedDrives: { | ||||||||||||||
| type: 'boolean', | ||||||||||||||
| required: false, | ||||||||||||||
| visibility: 'user-only', | ||||||||||||||
| description: 'Include files in shared drives (for DRIVE corpus)', | ||||||||||||||
| }, | ||||||||||||||
| }, | ||||||||||||||
|
|
||||||||||||||
| request: { | ||||||||||||||
|
|
@@ -46,13 +69,11 @@ export const createMattersHoldsTool: ToolConfig<GoogleVaultCreateMattersHoldsPar | |||||||||||||
| 'Content-Type': 'application/json', | ||||||||||||||
| }), | ||||||||||||||
| body: (params) => { | ||||||||||||||
| // Build Hold body. One of accounts or orgUnit must be provided. | ||||||||||||||
| const body: any = { | ||||||||||||||
| name: params.holdName, | ||||||||||||||
| corpus: params.corpus, | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| // Handle accountEmails - can be string (comma-separated) or array | ||||||||||||||
| let emails: string[] = [] | ||||||||||||||
| if (params.accountEmails) { | ||||||||||||||
| if (Array.isArray(params.accountEmails)) { | ||||||||||||||
|
|
@@ -66,20 +87,38 @@ export const createMattersHoldsTool: ToolConfig<GoogleVaultCreateMattersHoldsPar | |||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| if (emails.length > 0) { | ||||||||||||||
| // Google Vault expects HeldAccount objects with 'email' or 'accountId'. Use 'email' here. | ||||||||||||||
| body.accounts = emails.map((email: string) => ({ email })) | ||||||||||||||
| } else if (params.orgUnitId) { | ||||||||||||||
| body.orgUnit = { orgUnitId: params.orgUnitId } | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| if (params.corpus === 'MAIL' || params.corpus === 'GROUPS') { | ||||||||||||||
| const hasQueryParams = params.terms || params.startTime || params.endTime | ||||||||||||||
| if (hasQueryParams) { | ||||||||||||||
| const queryObj: any = {} | ||||||||||||||
| if (params.terms) queryObj.terms = params.terms | ||||||||||||||
| if (params.startTime) queryObj.startTime = params.startTime | ||||||||||||||
| if (params.endTime) queryObj.endTime = params.endTime | ||||||||||||||
|
|
||||||||||||||
| if (params.corpus === 'MAIL') { | ||||||||||||||
| body.query = { mailQuery: queryObj } | ||||||||||||||
| } else { | ||||||||||||||
| body.query = { groupsQuery: queryObj } | ||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
| } else if (params.corpus === 'DRIVE' && params.includeSharedDrives) { | ||||||||||||||
| body.query = { driveQuery: { includeSharedDriveFiles: params.includeSharedDrives } } | ||||||||||||||
| } | ||||||||||||||
|
Comment on lines
+109
to
+111
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The condition
Suggested change
Prompt To Fix With AIThis is a comment left during a code review.
Path: apps/sim/tools/google_vault/create_matters_holds.ts
Line: 116:118
Comment:
The condition `params.includeSharedDrives` only adds the driveQuery when truthy. If explicitly set to `false`, no query is added. Consider whether `false` should explicitly set `includeSharedDriveFiles: false` in the API request.
```suggestion
} else if (params.corpus === 'DRIVE' && params.includeSharedDrives !== undefined) {
body.query = { driveQuery: { includeSharedDriveFiles: params.includeSharedDrives } }
}
```
How can I resolve this? If you propose a fix, please make it concise. |
||||||||||||||
|
|
||||||||||||||
| return body | ||||||||||||||
| }, | ||||||||||||||
| }, | ||||||||||||||
|
|
||||||||||||||
| transformResponse: async (response: Response) => { | ||||||||||||||
| const data = await response.json() | ||||||||||||||
| if (!response.ok) { | ||||||||||||||
| throw new Error(data.error?.message || 'Failed to create hold') | ||||||||||||||
| const errorMessage = data.error?.message || 'Failed to create hold' | ||||||||||||||
| throw new Error(enhanceGoogleVaultError(errorMessage)) | ||||||||||||||
| } | ||||||||||||||
| return { success: true, output: { hold: data } } | ||||||||||||||
| }, | ||||||||||||||
|
|
||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Duplicate field ID
startTimedefined. This field already exists for create_matters_export operation (lines 162-184) and is redefined for create_matters_holds operation (lines 186-208). The UI form system may not handle duplicate field IDs correctly, potentially causing configuration conflicts or only one field being recognized.Consider using unique field IDs like
export_startTimeandhold_startTime, or refactor to use a single field definition with more complex conditions if the behavior should be identical.Prompt To Fix With AI