Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 3.8k
feat(bigquery): validate integration + add dataset/table lifecycle tools#5480
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
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
ce3d33b6c44630e6c07dcd6ba6be6ca7101File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Uh oh!
There was an error while loading. Please reload this page.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,122 @@ | ||
| import type { | ||
| GoogleBigQueryCreateDatasetParams, | ||
| GoogleBigQueryCreateDatasetResponse, | ||
| } from '@/tools/google_bigquery/types' | ||
| import type { ToolConfig } from '@/tools/types' | ||
| export const googleBigQueryCreateDatasetTool: ToolConfig< | ||
| GoogleBigQueryCreateDatasetParams, | ||
| GoogleBigQueryCreateDatasetResponse | ||
| > = { | ||
| id: 'google_bigquery_create_dataset', | ||
| name: 'BigQuery Create Dataset', | ||
| description: 'Create a new dataset in a Google BigQuery project', | ||
| version: '1.0.0', | ||
| oauth: { | ||
| required: true, | ||
| provider: 'google-bigquery', | ||
| }, | ||
| params: { | ||
| accessToken: { | ||
| type: 'string', | ||
| required: true, | ||
| visibility: 'hidden', | ||
| description: 'OAuth access token', | ||
| }, | ||
| projectId: { | ||
| type: 'string', | ||
| required: true, | ||
| visibility: 'user-or-llm', | ||
| description: 'Google Cloud project ID', | ||
| }, | ||
| datasetId: { | ||
| type: 'string', | ||
| required: true, | ||
| visibility: 'user-or-llm', | ||
| description: 'ID for the new BigQuery dataset', | ||
| }, | ||
| location: { | ||
| type: 'string', | ||
| required: false, | ||
| visibility: 'user-or-llm', | ||
| description: 'Geographic location for the dataset (e.g., "US", "EU")', | ||
| }, | ||
| friendlyName: { | ||
| type: 'string', | ||
| required: false, | ||
| visibility: 'user-or-llm', | ||
| description: 'Human-readable name for the dataset', | ||
| }, | ||
| description: { | ||
| type: 'string', | ||
| required: false, | ||
| visibility: 'user-or-llm', | ||
| description: 'Description of the dataset', | ||
| }, | ||
| }, | ||
| request: { | ||
| url: (params) => | ||
| `https://bigquery.googleapis.com/bigquery/v2/projects/${encodeURIComponent(params.projectId)}/datasets`, | ||
| method: 'POST', | ||
| headers: (params) => ({ | ||
| Authorization: `Bearer ${params.accessToken}`, | ||
| 'Content-Type': 'application/json', | ||
| }), | ||
| body: (params) => { | ||
| const body: Record<string, unknown> = { | ||
| datasetReference: { | ||
| projectId: params.projectId, | ||
| datasetId: params.datasetId.trim(), | ||
| }, | ||
| } | ||
| if (params.location) body.location = params.location | ||
| if (params.friendlyName) body.friendlyName = params.friendlyName | ||
| if (params.description) body.description = params.description | ||
| return body | ||
| }, | ||
| }, | ||
| transformResponse: async (response: Response) => { | ||
| const data = await response.json() | ||
| if (!response.ok) { | ||
| const errorMessage = data.error?.message || 'Failed to create BigQuery dataset' | ||
| throw new Error(errorMessage) | ||
| } | ||
| return { | ||
| success: true, | ||
| output: { | ||
| datasetId: data.datasetReference?.datasetId ?? null, | ||
| projectId: data.datasetReference?.projectId ?? null, | ||
| friendlyName: data.friendlyName ?? null, | ||
| description: data.description ?? null, | ||
| location: data.location ?? null, | ||
| creationTime: data.creationTime ?? null, | ||
| }, | ||
| } | ||
| }, | ||
| outputs: { | ||
| datasetId: { type: 'string', description: 'Unique dataset identifier' }, | ||
| projectId: { type: 'string', description: 'Project ID containing this dataset' }, | ||
| friendlyName: { | ||
| type: 'string', | ||
| description: 'Descriptive name for the dataset', | ||
| optional: true, | ||
| }, | ||
| description: { type: 'string', description: 'Dataset description', optional: true }, | ||
| location: { | ||
| type: 'string', | ||
| description: 'Geographic location where the data resides', | ||
| optional: true, | ||
| }, | ||
| creationTime: { | ||
| type: 'string', | ||
| description: 'Dataset creation time (milliseconds since epoch)', | ||
| optional: true, | ||
| }, | ||
| }, | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,173 @@ | ||
| import type { | ||
| GoogleBigQueryCreateTableParams, | ||
| GoogleBigQueryCreateTableResponse, | ||
| } from '@/tools/google_bigquery/types' | ||
| import type { ToolConfig } from '@/tools/types' | ||
| export const googleBigQueryCreateTableTool: ToolConfig< | ||
| GoogleBigQueryCreateTableParams, | ||
| GoogleBigQueryCreateTableResponse | ||
| > = { | ||
| id: 'google_bigquery_create_table', | ||
| name: 'BigQuery Create Table', | ||
| description: 'Create a new table in a Google BigQuery dataset', | ||
| version: '1.0.0', | ||
| oauth: { | ||
| required: true, | ||
| provider: 'google-bigquery', | ||
| }, | ||
| params: { | ||
| accessToken: { | ||
| type: 'string', | ||
| required: true, | ||
| visibility: 'hidden', | ||
| description: 'OAuth access token', | ||
| }, | ||
| projectId: { | ||
| type: 'string', | ||
| required: true, | ||
| visibility: 'user-or-llm', | ||
| description: 'Google Cloud project ID', | ||
| }, | ||
| datasetId: { | ||
| type: 'string', | ||
| required: true, | ||
| visibility: 'user-or-llm', | ||
| description: 'BigQuery dataset ID', | ||
| }, | ||
| tableId: { | ||
| type: 'string', | ||
| required: true, | ||
| visibility: 'user-or-llm', | ||
| description: 'ID for the new BigQuery table', | ||
| }, | ||
| schema: { | ||
| type: 'string', | ||
| required: true, | ||
| visibility: 'user-or-llm', | ||
| description: | ||
| 'JSON array of column field definitions, e.g. [{"name":"id","type":"STRING","mode":"REQUIRED"}]', | ||
| }, | ||
| description: { | ||
| type: 'string', | ||
| required: false, | ||
| visibility: 'user-or-llm', | ||
| description: 'Description of the table', | ||
| }, | ||
| friendlyName: { | ||
| type: 'string', | ||
| required: false, | ||
| visibility: 'user-or-llm', | ||
| description: 'Human-readable name for the table', | ||
| }, | ||
| }, | ||
| request: { | ||
| url: (params) => | ||
| `https://bigquery.googleapis.com/bigquery/v2/projects/${encodeURIComponent(params.projectId)}/datasets/${encodeURIComponent(params.datasetId.trim())}/tables`, | ||
| method: 'POST', | ||
| headers: (params) => ({ | ||
| Authorization: `Bearer ${params.accessToken}`, | ||
| 'Content-Type': 'application/json', | ||
| }), | ||
| body: (params) => { | ||
| let fields: unknown | ||
| try { | ||
| fields = typeof params.schema === 'string' ? JSON.parse(params.schema) : params.schema | ||
| } catch { | ||
| fields = null | ||
| } | ||
| if ( | ||
| !Array.isArray(fields) || | ||
| fields.length === 0 || | ||
| !fields.every( | ||
| (f) => f && typeof f === 'object' && typeof (f as { name?: unknown }).name === 'string' | ||
| ) | ||
| ) { | ||
| throw new Error( | ||
| 'Schema must be a JSON array of column field definitions, e.g. [{"name":"id","type":"STRING"}]' | ||
| ) | ||
| } | ||
| const body: Record<string, unknown> = { | ||
| tableReference: { | ||
| projectId: params.projectId, | ||
| datasetId: params.datasetId.trim(), | ||
| tableId: params.tableId.trim(), | ||
| }, | ||
waleedlatif1 marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| schema: { fields }, | ||
| } | ||
waleedlatif1 marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| if (params.description) body.description = params.description | ||
| if (params.friendlyName) body.friendlyName = params.friendlyName | ||
| return body | ||
| }, | ||
| }, | ||
| transformResponse: async (response: Response) => { | ||
| const data = await response.json() | ||
| if (!response.ok) { | ||
| const errorMessage = data.error?.message || 'Failed to create BigQuery table' | ||
| throw new Error(errorMessage) | ||
| } | ||
| const schema = (data.schema?.fields ?? []).map( | ||
| (f: { name: string; type: string; mode?: string; description?: string }) => ({ | ||
| name: f.name, | ||
| type: f.type, | ||
| mode: f.mode ?? null, | ||
| description: f.description ?? null, | ||
| }) | ||
| ) | ||
| return { | ||
| success: true, | ||
| output: { | ||
| tableId: data.tableReference?.tableId ?? null, | ||
| datasetId: data.tableReference?.datasetId ?? null, | ||
| projectId: data.tableReference?.projectId ?? null, | ||
| type: data.type ?? null, | ||
| description: data.description ?? null, | ||
| schema, | ||
| creationTime: data.creationTime ?? null, | ||
| location: data.location ?? null, | ||
| }, | ||
| } | ||
| }, | ||
| outputs: { | ||
| tableId: { type: 'string', description: 'Table ID' }, | ||
| datasetId: { type: 'string', description: 'Dataset ID' }, | ||
| projectId: { type: 'string', description: 'Project ID' }, | ||
| type: { type: 'string', description: 'Table type (usually TABLE)', optional: true }, | ||
| description: { type: 'string', description: 'Table description', optional: true }, | ||
| schema: { | ||
| type: 'array', | ||
| description: 'Array of column definitions', | ||
| items: { | ||
| type: 'object', | ||
| properties: { | ||
| name: { type: 'string', description: 'Column name' }, | ||
| type: { type: 'string', description: 'Data type' }, | ||
| mode: { | ||
| type: 'string', | ||
| description: 'Column mode (NULLABLE, REQUIRED, or REPEATED)', | ||
| optional: true, | ||
| }, | ||
| description: { type: 'string', description: 'Column description', optional: true }, | ||
| }, | ||
| }, | ||
| }, | ||
| creationTime: { | ||
| type: 'string', | ||
| description: 'Table creation time (milliseconds since epoch)', | ||
| optional: true, | ||
| }, | ||
| location: { | ||
| type: 'string', | ||
| description: 'Geographic location where the table resides', | ||
| optional: true, | ||
| }, | ||
| }, | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,82 @@ | ||
| import type { | ||
| GoogleBigQueryDeleteDatasetParams, | ||
| GoogleBigQueryDeleteDatasetResponse, | ||
| } from '@/tools/google_bigquery/types' | ||
| import type { ToolConfig } from '@/tools/types' | ||
| export const googleBigQueryDeleteDatasetTool: ToolConfig< | ||
| GoogleBigQueryDeleteDatasetParams, | ||
| GoogleBigQueryDeleteDatasetResponse | ||
| > = { | ||
| id: 'google_bigquery_delete_dataset', | ||
| name: 'BigQuery Delete Dataset', | ||
| description: 'Delete a dataset from a Google BigQuery project', | ||
| version: '1.0.0', | ||
| oauth: { | ||
| required: true, | ||
| provider: 'google-bigquery', | ||
| }, | ||
| params: { | ||
| accessToken: { | ||
| type: 'string', | ||
| required: true, | ||
| visibility: 'hidden', | ||
| description: 'OAuth access token', | ||
| }, | ||
| projectId: { | ||
| type: 'string', | ||
| required: true, | ||
| visibility: 'user-or-llm', | ||
| description: 'Google Cloud project ID', | ||
| }, | ||
| datasetId: { | ||
| type: 'string', | ||
| required: true, | ||
| visibility: 'user-or-llm', | ||
| description: 'BigQuery dataset ID to delete', | ||
| }, | ||
| deleteContents: { | ||
| type: 'boolean', | ||
| required: false, | ||
| visibility: 'user-or-llm', | ||
| description: 'Whether to delete tables inside the dataset (default: false)', | ||
| }, | ||
| }, | ||
| request: { | ||
| url: (params) => { | ||
| const url = new URL( | ||
| `https://bigquery.googleapis.com/bigquery/v2/projects/${encodeURIComponent(params.projectId)}/datasets/${encodeURIComponent(params.datasetId.trim())}` | ||
| ) | ||
| if (params.deleteContents !== undefined) { | ||
| url.searchParams.set('deleteContents', String(params.deleteContents)) | ||
| } | ||
| return url.toString() | ||
| }, | ||
| method: 'DELETE', | ||
| headers: (params) => ({ | ||
| Authorization: `Bearer ${params.accessToken}`, | ||
| }), | ||
| }, | ||
| transformResponse: async (response: Response) => { | ||
| if (!response.ok) { | ||
| const data = await response.json() | ||
| const errorMessage = data.error?.message || 'Failed to delete BigQuery dataset' | ||
| throw new Error(errorMessage) | ||
| } | ||
| return { | ||
| success: true, | ||
| output: { | ||
| deleted: true, | ||
| }, | ||
| } | ||
| }, | ||
| outputs: { | ||
| deleted: { type: 'boolean', description: 'Whether the dataset was deleted' }, | ||
| }, | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.