chore: import upstream snapshot with attribution
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled
Publish CLI Package / publish-npm (push) Has been cancelled
Publish Python SDK / publish-pypi (push) Has been cancelled
Publish TypeScript SDK / publish-npm (push) Has been cancelled
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled
Publish CLI Package / publish-npm (push) Has been cancelled
Publish Python SDK / publish-pypi (push) Has been cancelled
Publish TypeScript SDK / publish-npm (push) Has been cancelled
This commit is contained in:
@@ -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,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -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(),
|
||||
},
|
||||
schema: { fields },
|
||||
}
|
||||
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,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -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' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
import type {
|
||||
GoogleBigQueryDeleteTableParams,
|
||||
GoogleBigQueryDeleteTableResponse,
|
||||
} from '@/tools/google_bigquery/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const googleBigQueryDeleteTableTool: ToolConfig<
|
||||
GoogleBigQueryDeleteTableParams,
|
||||
GoogleBigQueryDeleteTableResponse
|
||||
> = {
|
||||
id: 'google_bigquery_delete_table',
|
||||
name: 'BigQuery Delete Table',
|
||||
description: 'Delete a table from 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: 'BigQuery table ID to delete',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) =>
|
||||
`https://bigquery.googleapis.com/bigquery/v2/projects/${encodeURIComponent(params.projectId)}/datasets/${encodeURIComponent(params.datasetId.trim())}/tables/${encodeURIComponent(params.tableId.trim())}`,
|
||||
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 table'
|
||||
throw new Error(errorMessage)
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
deleted: true,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
deleted: { type: 'boolean', description: 'Whether the table was deleted' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
import type {
|
||||
GoogleBigQueryGetQueryResultsParams,
|
||||
GoogleBigQueryGetQueryResultsResponse,
|
||||
} from '@/tools/google_bigquery/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const googleBigQueryGetQueryResultsTool: ToolConfig<
|
||||
GoogleBigQueryGetQueryResultsParams,
|
||||
GoogleBigQueryGetQueryResultsResponse
|
||||
> = {
|
||||
id: 'google_bigquery_get_query_results',
|
||||
name: 'BigQuery Get Query Results',
|
||||
description:
|
||||
'Fetch results for a previously submitted BigQuery job, or the next page of a Run Query result',
|
||||
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',
|
||||
},
|
||||
jobId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'ID of the BigQuery job to fetch results for',
|
||||
},
|
||||
pageToken: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Token for pagination',
|
||||
},
|
||||
maxResults: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Maximum number of rows to return',
|
||||
},
|
||||
timeoutMs: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'How long to wait for the job to complete, in milliseconds',
|
||||
},
|
||||
location: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Processing location of the job (e.g., "US", "EU")',
|
||||
},
|
||||
startIndex: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Zero-based index of the starting row',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const url = new URL(
|
||||
`https://bigquery.googleapis.com/bigquery/v2/projects/${encodeURIComponent(params.projectId)}/queries/${encodeURIComponent(params.jobId.trim())}`
|
||||
)
|
||||
if (params.pageToken) url.searchParams.set('pageToken', params.pageToken)
|
||||
if (params.maxResults !== undefined && params.maxResults !== null) {
|
||||
const maxResults = Number(params.maxResults)
|
||||
if (Number.isFinite(maxResults) && maxResults > 0) {
|
||||
url.searchParams.set('maxResults', String(maxResults))
|
||||
}
|
||||
}
|
||||
if (params.timeoutMs !== undefined && params.timeoutMs !== null) {
|
||||
const timeoutMs = Number(params.timeoutMs)
|
||||
if (Number.isFinite(timeoutMs) && timeoutMs > 0) {
|
||||
url.searchParams.set('timeoutMs', String(timeoutMs))
|
||||
}
|
||||
}
|
||||
if (params.location) url.searchParams.set('location', params.location)
|
||||
if (params.startIndex) url.searchParams.set('startIndex', params.startIndex)
|
||||
return url.toString()
|
||||
},
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
Authorization: `Bearer ${params.accessToken}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
if (!response.ok) {
|
||||
const errorMessage = data.error?.message || 'Failed to fetch BigQuery query results'
|
||||
throw new Error(errorMessage)
|
||||
}
|
||||
|
||||
const columns = (data.schema?.fields ?? []).map((f: { name: string }) => f.name)
|
||||
const rows = (data.rows ?? []).map((row: { f: Array<{ v: unknown }> }) => {
|
||||
const obj: Record<string, unknown> = {}
|
||||
row.f.forEach((field, index) => {
|
||||
obj[columns[index]] = field.v ?? null
|
||||
})
|
||||
return obj
|
||||
})
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
columns,
|
||||
rows,
|
||||
totalRows: data.totalRows ?? null,
|
||||
jobComplete: data.jobComplete ?? false,
|
||||
totalBytesProcessed: data.totalBytesProcessed ?? null,
|
||||
cacheHit: data.cacheHit ?? null,
|
||||
jobReference: data.jobReference ?? null,
|
||||
pageToken: data.pageToken ?? null,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
columns: {
|
||||
type: 'array',
|
||||
description: 'Array of column names from the query result',
|
||||
items: { type: 'string', description: 'Column name' },
|
||||
},
|
||||
rows: {
|
||||
type: 'array',
|
||||
description: 'Array of row objects keyed by column name',
|
||||
items: {
|
||||
type: 'object',
|
||||
description: 'Row with column name/value pairs',
|
||||
},
|
||||
},
|
||||
totalRows: {
|
||||
type: 'string',
|
||||
description: 'Total number of rows in the complete result set',
|
||||
optional: true,
|
||||
},
|
||||
jobComplete: { type: 'boolean', description: 'Whether the job has completed' },
|
||||
totalBytesProcessed: {
|
||||
type: 'string',
|
||||
description: 'Total bytes processed by the query',
|
||||
optional: true,
|
||||
},
|
||||
cacheHit: {
|
||||
type: 'boolean',
|
||||
description: 'Whether the query result was served from cache',
|
||||
optional: true,
|
||||
},
|
||||
jobReference: {
|
||||
type: 'object',
|
||||
description: 'Job reference (useful when jobComplete is false)',
|
||||
optional: true,
|
||||
properties: {
|
||||
projectId: { type: 'string', description: 'Project ID containing the job' },
|
||||
jobId: { type: 'string', description: 'Unique job identifier' },
|
||||
location: { type: 'string', description: 'Geographic location of the job' },
|
||||
},
|
||||
},
|
||||
pageToken: {
|
||||
type: 'string',
|
||||
description: 'Token for fetching additional result pages',
|
||||
optional: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
import type {
|
||||
GoogleBigQueryGetTableParams,
|
||||
GoogleBigQueryGetTableResponse,
|
||||
} from '@/tools/google_bigquery/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const googleBigQueryGetTableTool: ToolConfig<
|
||||
GoogleBigQueryGetTableParams,
|
||||
GoogleBigQueryGetTableResponse
|
||||
> = {
|
||||
id: 'google_bigquery_get_table',
|
||||
name: 'BigQuery Get Table',
|
||||
description: 'Get metadata and schema for a Google BigQuery table',
|
||||
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: 'BigQuery table ID',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) =>
|
||||
`https://bigquery.googleapis.com/bigquery/v2/projects/${encodeURIComponent(params.projectId)}/datasets/${encodeURIComponent(params.datasetId)}/tables/${encodeURIComponent(params.tableId)}`,
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
Authorization: `Bearer ${params.accessToken}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
if (!response.ok) {
|
||||
const errorMessage = data.error?.message || 'Failed to get 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,
|
||||
numRows: data.numRows ?? null,
|
||||
numBytes: data.numBytes ?? null,
|
||||
schema,
|
||||
creationTime: data.creationTime ?? null,
|
||||
lastModifiedTime: data.lastModifiedTime ?? 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 (TABLE, VIEW, SNAPSHOT, MATERIALIZED_VIEW, EXTERNAL)',
|
||||
optional: true,
|
||||
},
|
||||
description: { type: 'string', description: 'Table description', optional: true },
|
||||
numRows: { type: 'string', description: 'Total number of rows', optional: true },
|
||||
numBytes: {
|
||||
type: 'string',
|
||||
description: 'Total size in bytes, excluding data in streaming buffer',
|
||||
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 (STRING, INTEGER, FLOAT, BOOLEAN, TIMESTAMP, RECORD, etc.)',
|
||||
},
|
||||
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,
|
||||
},
|
||||
lastModifiedTime: {
|
||||
type: 'string',
|
||||
description: 'Last modification time (milliseconds since epoch)',
|
||||
optional: true,
|
||||
},
|
||||
location: {
|
||||
type: 'string',
|
||||
description: 'Geographic location where the table resides',
|
||||
optional: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
export { googleBigQueryCreateDatasetTool } from '@/tools/google_bigquery/create_dataset'
|
||||
export { googleBigQueryCreateTableTool } from '@/tools/google_bigquery/create_table'
|
||||
export { googleBigQueryDeleteDatasetTool } from '@/tools/google_bigquery/delete_dataset'
|
||||
export { googleBigQueryDeleteTableTool } from '@/tools/google_bigquery/delete_table'
|
||||
export { googleBigQueryGetQueryResultsTool } from '@/tools/google_bigquery/get_query_results'
|
||||
export { googleBigQueryGetTableTool } from '@/tools/google_bigquery/get_table'
|
||||
export { googleBigQueryInsertRowsTool } from '@/tools/google_bigquery/insert_rows'
|
||||
export { googleBigQueryListDatasetsTool } from '@/tools/google_bigquery/list_datasets'
|
||||
export { googleBigQueryListTableDataTool } from '@/tools/google_bigquery/list_table_data'
|
||||
export { googleBigQueryListTablesTool } from '@/tools/google_bigquery/list_tables'
|
||||
export { googleBigQueryQueryTool } from '@/tools/google_bigquery/query'
|
||||
@@ -0,0 +1,174 @@
|
||||
import type {
|
||||
GoogleBigQueryInsertRowsParams,
|
||||
GoogleBigQueryInsertRowsResponse,
|
||||
} from '@/tools/google_bigquery/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const googleBigQueryInsertRowsTool: ToolConfig<
|
||||
GoogleBigQueryInsertRowsParams,
|
||||
GoogleBigQueryInsertRowsResponse
|
||||
> = {
|
||||
id: 'google_bigquery_insert_rows',
|
||||
name: 'BigQuery Insert Rows',
|
||||
description: 'Insert rows into a Google BigQuery table using streaming insert',
|
||||
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: 'BigQuery table ID',
|
||||
},
|
||||
rows: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'JSON array of row objects to insert',
|
||||
},
|
||||
skipInvalidRows: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Whether to insert valid rows even if some are invalid',
|
||||
},
|
||||
ignoreUnknownValues: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Whether to ignore columns not in the table schema',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) =>
|
||||
`https://bigquery.googleapis.com/bigquery/v2/projects/${encodeURIComponent(params.projectId)}/datasets/${encodeURIComponent(params.datasetId)}/tables/${encodeURIComponent(params.tableId)}/insertAll`,
|
||||
method: 'POST',
|
||||
headers: (params) => ({
|
||||
Authorization: `Bearer ${params.accessToken}`,
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: (params) => {
|
||||
const parsedRows = typeof params.rows === 'string' ? JSON.parse(params.rows) : params.rows
|
||||
const rows = (parsedRows as Record<string, unknown>[]).map(
|
||||
(row: Record<string, unknown>) => ({ json: row })
|
||||
)
|
||||
|
||||
const body: Record<string, unknown> = { rows }
|
||||
if (params.skipInvalidRows !== undefined) body.skipInvalidRows = params.skipInvalidRows
|
||||
if (params.ignoreUnknownValues !== undefined)
|
||||
body.ignoreUnknownValues = params.ignoreUnknownValues
|
||||
|
||||
return body
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response, params?: GoogleBigQueryInsertRowsParams) => {
|
||||
const data = await response.json()
|
||||
if (!response.ok) {
|
||||
const errorMessage = data.error?.message || 'Failed to insert rows into BigQuery table'
|
||||
throw new Error(errorMessage)
|
||||
}
|
||||
|
||||
const insertErrors = data.insertErrors ?? []
|
||||
const errors = insertErrors.map(
|
||||
(err: {
|
||||
index: number
|
||||
errors: Array<{ reason?: string; location?: string; message?: string }>
|
||||
}) => ({
|
||||
index: err.index,
|
||||
errors: err.errors.map((e) => ({
|
||||
reason: e.reason ?? null,
|
||||
location: e.location ?? null,
|
||||
message: e.message ?? null,
|
||||
})),
|
||||
})
|
||||
)
|
||||
|
||||
let totalRows = 0
|
||||
if (params?.rows) {
|
||||
const parsed = typeof params.rows === 'string' ? JSON.parse(params.rows) : params.rows
|
||||
totalRows = Array.isArray(parsed) ? parsed.length : 0
|
||||
}
|
||||
|
||||
// When insertErrors is empty, all rows succeeded.
|
||||
// When insertErrors is present and skipInvalidRows is false (default),
|
||||
// the entire batch is rejected — no rows are inserted.
|
||||
let insertedRows = 0
|
||||
if (insertErrors.length === 0) {
|
||||
insertedRows = totalRows
|
||||
} else if (params?.skipInvalidRows) {
|
||||
const failedIndexes = new Set(insertErrors.map((e: { index: number }) => e.index))
|
||||
insertedRows = totalRows - failedIndexes.size
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
insertedRows,
|
||||
errors,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
insertedRows: { type: 'number', description: 'Number of rows successfully inserted' },
|
||||
errors: {
|
||||
type: 'array',
|
||||
description: 'Array of per-row insertion errors (empty if all succeeded)',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
index: { type: 'number', description: 'Zero-based index of the row that failed' },
|
||||
errors: {
|
||||
type: 'array',
|
||||
description: 'Error details for this row',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
reason: {
|
||||
type: 'string',
|
||||
description: 'Short error code summarizing the error',
|
||||
optional: true,
|
||||
},
|
||||
location: {
|
||||
type: 'string',
|
||||
description: 'Where the error occurred',
|
||||
optional: true,
|
||||
},
|
||||
message: {
|
||||
type: 'string',
|
||||
description: 'Human-readable error description',
|
||||
optional: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
import type {
|
||||
GoogleBigQueryListDatasetsParams,
|
||||
GoogleBigQueryListDatasetsResponse,
|
||||
} from '@/tools/google_bigquery/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const googleBigQueryListDatasetsTool: ToolConfig<
|
||||
GoogleBigQueryListDatasetsParams,
|
||||
GoogleBigQueryListDatasetsResponse
|
||||
> = {
|
||||
id: 'google_bigquery_list_datasets',
|
||||
name: 'BigQuery List Datasets',
|
||||
description: 'List all datasets 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',
|
||||
},
|
||||
maxResults: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Maximum number of datasets to return',
|
||||
},
|
||||
pageToken: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Token for pagination',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const url = new URL(
|
||||
`https://bigquery.googleapis.com/bigquery/v2/projects/${encodeURIComponent(params.projectId)}/datasets`
|
||||
)
|
||||
if (params.maxResults !== undefined && params.maxResults !== null) {
|
||||
const maxResults = Number(params.maxResults)
|
||||
if (Number.isFinite(maxResults) && maxResults > 0) {
|
||||
url.searchParams.set('maxResults', String(maxResults))
|
||||
}
|
||||
}
|
||||
if (params.pageToken) url.searchParams.set('pageToken', params.pageToken)
|
||||
return url.toString()
|
||||
},
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
Authorization: `Bearer ${params.accessToken}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
if (!response.ok) {
|
||||
const errorMessage = data.error?.message || 'Failed to list BigQuery datasets'
|
||||
throw new Error(errorMessage)
|
||||
}
|
||||
|
||||
const datasets = (data.datasets ?? []).map(
|
||||
(ds: {
|
||||
datasetReference: { datasetId: string; projectId: string }
|
||||
friendlyName?: string
|
||||
location?: string
|
||||
}) => ({
|
||||
datasetId: ds.datasetReference.datasetId,
|
||||
projectId: ds.datasetReference.projectId,
|
||||
friendlyName: ds.friendlyName ?? null,
|
||||
location: ds.location ?? null,
|
||||
})
|
||||
)
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
datasets,
|
||||
nextPageToken: data.nextPageToken ?? null,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
datasets: {
|
||||
type: 'array',
|
||||
description: 'Array of dataset objects',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
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,
|
||||
},
|
||||
location: {
|
||||
type: 'string',
|
||||
description: 'Geographic location where the data resides',
|
||||
optional: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
nextPageToken: {
|
||||
type: 'string',
|
||||
description: 'Token for fetching next page of results',
|
||||
optional: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
import type {
|
||||
GoogleBigQueryListTableDataParams,
|
||||
GoogleBigQueryListTableDataResponse,
|
||||
} from '@/tools/google_bigquery/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const googleBigQueryListTableDataTool: ToolConfig<
|
||||
GoogleBigQueryListTableDataParams,
|
||||
GoogleBigQueryListTableDataResponse
|
||||
> = {
|
||||
id: 'google_bigquery_list_table_data',
|
||||
name: 'BigQuery List Table Data',
|
||||
description:
|
||||
'Preview rows from a Google BigQuery table without running a query. Pair with Get Table to know the column order.',
|
||||
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: 'BigQuery table ID',
|
||||
},
|
||||
maxResults: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Maximum number of rows to return',
|
||||
},
|
||||
pageToken: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Token for pagination',
|
||||
},
|
||||
startIndex: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Zero-based index of the starting row',
|
||||
},
|
||||
selectedFields: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Comma-separated list of column names to return',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const url = new URL(
|
||||
`https://bigquery.googleapis.com/bigquery/v2/projects/${encodeURIComponent(params.projectId)}/datasets/${encodeURIComponent(params.datasetId.trim())}/tables/${encodeURIComponent(params.tableId.trim())}/data`
|
||||
)
|
||||
if (params.maxResults !== undefined && params.maxResults !== null) {
|
||||
const maxResults = Number(params.maxResults)
|
||||
if (Number.isFinite(maxResults) && maxResults > 0) {
|
||||
url.searchParams.set('maxResults', String(maxResults))
|
||||
}
|
||||
}
|
||||
if (params.pageToken) url.searchParams.set('pageToken', params.pageToken)
|
||||
if (params.startIndex) url.searchParams.set('startIndex', params.startIndex)
|
||||
if (params.selectedFields) url.searchParams.set('selectedFields', params.selectedFields)
|
||||
return url.toString()
|
||||
},
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
Authorization: `Bearer ${params.accessToken}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
if (!response.ok) {
|
||||
const errorMessage = data.error?.message || 'Failed to list BigQuery table data'
|
||||
throw new Error(errorMessage)
|
||||
}
|
||||
|
||||
const rows = (data.rows ?? []).map((row: { f: Array<{ v: unknown }> }) =>
|
||||
row.f.map((field) => field.v ?? null)
|
||||
)
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
rows,
|
||||
totalRows: data.totalRows ?? null,
|
||||
pageToken: data.pageToken ?? null,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
rows: {
|
||||
type: 'array',
|
||||
description: 'Array of rows, each a raw array of column values in schema order',
|
||||
items: { type: 'array', description: 'Row values in column order' },
|
||||
},
|
||||
totalRows: {
|
||||
type: 'string',
|
||||
description: 'Total number of rows in the table',
|
||||
optional: true,
|
||||
},
|
||||
pageToken: {
|
||||
type: 'string',
|
||||
description: 'Token for fetching the next page of results',
|
||||
optional: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
import type {
|
||||
GoogleBigQueryListTablesParams,
|
||||
GoogleBigQueryListTablesResponse,
|
||||
} from '@/tools/google_bigquery/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const googleBigQueryListTablesTool: ToolConfig<
|
||||
GoogleBigQueryListTablesParams,
|
||||
GoogleBigQueryListTablesResponse
|
||||
> = {
|
||||
id: 'google_bigquery_list_tables',
|
||||
name: 'BigQuery List Tables',
|
||||
description: 'List all tables 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',
|
||||
},
|
||||
maxResults: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Maximum number of tables to return',
|
||||
},
|
||||
pageToken: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Token for pagination',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const url = new URL(
|
||||
`https://bigquery.googleapis.com/bigquery/v2/projects/${encodeURIComponent(params.projectId)}/datasets/${encodeURIComponent(params.datasetId)}/tables`
|
||||
)
|
||||
if (params.maxResults !== undefined && params.maxResults !== null) {
|
||||
const maxResults = Number(params.maxResults)
|
||||
if (Number.isFinite(maxResults) && maxResults > 0) {
|
||||
url.searchParams.set('maxResults', String(maxResults))
|
||||
}
|
||||
}
|
||||
if (params.pageToken) url.searchParams.set('pageToken', params.pageToken)
|
||||
return url.toString()
|
||||
},
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
Authorization: `Bearer ${params.accessToken}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
if (!response.ok) {
|
||||
const errorMessage = data.error?.message || 'Failed to list BigQuery tables'
|
||||
throw new Error(errorMessage)
|
||||
}
|
||||
|
||||
const tables = (data.tables ?? []).map(
|
||||
(t: {
|
||||
tableReference: { tableId: string; datasetId: string; projectId: string }
|
||||
type?: string
|
||||
friendlyName?: string
|
||||
creationTime?: string
|
||||
}) => ({
|
||||
tableId: t.tableReference.tableId,
|
||||
datasetId: t.tableReference.datasetId,
|
||||
projectId: t.tableReference.projectId,
|
||||
type: t.type ?? null,
|
||||
friendlyName: t.friendlyName ?? null,
|
||||
creationTime: t.creationTime ?? null,
|
||||
})
|
||||
)
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
tables,
|
||||
totalItems: data.totalItems ?? null,
|
||||
nextPageToken: data.nextPageToken ?? null,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
tables: {
|
||||
type: 'array',
|
||||
description: 'Array of table objects',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
tableId: { type: 'string', description: 'Table identifier' },
|
||||
datasetId: { type: 'string', description: 'Dataset ID containing this table' },
|
||||
projectId: { type: 'string', description: 'Project ID containing this table' },
|
||||
type: {
|
||||
type: 'string',
|
||||
description: 'Table type (TABLE, VIEW, EXTERNAL, etc.)',
|
||||
optional: true,
|
||||
},
|
||||
friendlyName: {
|
||||
type: 'string',
|
||||
description: 'User-friendly name for the table',
|
||||
optional: true,
|
||||
},
|
||||
creationTime: {
|
||||
type: 'string',
|
||||
description: 'Time when created, in milliseconds since epoch',
|
||||
optional: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
totalItems: {
|
||||
type: 'number',
|
||||
description: 'Total number of tables in the dataset',
|
||||
optional: true,
|
||||
},
|
||||
nextPageToken: {
|
||||
type: 'string',
|
||||
description: 'Token for fetching next page of results',
|
||||
optional: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
import type {
|
||||
GoogleBigQueryQueryParams,
|
||||
GoogleBigQueryQueryResponse,
|
||||
} from '@/tools/google_bigquery/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const googleBigQueryQueryTool: ToolConfig<
|
||||
GoogleBigQueryQueryParams,
|
||||
GoogleBigQueryQueryResponse
|
||||
> = {
|
||||
id: 'google_bigquery_query',
|
||||
name: 'BigQuery Run Query',
|
||||
description: 'Run a SQL query against Google BigQuery and return the results',
|
||||
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',
|
||||
},
|
||||
query: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'SQL query to execute',
|
||||
},
|
||||
useLegacySql: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Whether to use legacy SQL syntax (default: false)',
|
||||
},
|
||||
maxResults: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Maximum number of rows to return',
|
||||
},
|
||||
defaultDatasetId: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Default dataset for unqualified table names',
|
||||
},
|
||||
location: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Processing location (e.g., "US", "EU")',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) =>
|
||||
`https://bigquery.googleapis.com/bigquery/v2/projects/${encodeURIComponent(params.projectId)}/queries`,
|
||||
method: 'POST',
|
||||
headers: (params) => ({
|
||||
Authorization: `Bearer ${params.accessToken}`,
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: (params) => {
|
||||
const body: Record<string, unknown> = {
|
||||
query: params.query,
|
||||
useLegacySql: params.useLegacySql ?? false,
|
||||
}
|
||||
if (params.maxResults !== undefined) body.maxResults = Number(params.maxResults)
|
||||
if (params.defaultDatasetId) {
|
||||
body.defaultDataset = {
|
||||
projectId: params.projectId,
|
||||
datasetId: params.defaultDatasetId,
|
||||
}
|
||||
}
|
||||
if (params.location) body.location = params.location
|
||||
return body
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
if (!response.ok) {
|
||||
const errorMessage = data.error?.message || 'Failed to execute BigQuery query'
|
||||
throw new Error(errorMessage)
|
||||
}
|
||||
|
||||
const columns = (data.schema?.fields ?? []).map((f: { name: string }) => f.name)
|
||||
const rows = (data.rows ?? []).map((row: { f: Array<{ v: unknown }> }) => {
|
||||
const obj: Record<string, unknown> = {}
|
||||
row.f.forEach((field, index) => {
|
||||
obj[columns[index]] = field.v ?? null
|
||||
})
|
||||
return obj
|
||||
})
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
columns,
|
||||
rows,
|
||||
totalRows: data.totalRows ?? null,
|
||||
jobComplete: data.jobComplete ?? false,
|
||||
totalBytesProcessed: data.totalBytesProcessed ?? null,
|
||||
cacheHit: data.cacheHit ?? null,
|
||||
jobReference: data.jobReference ?? null,
|
||||
pageToken: data.pageToken ?? null,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
columns: {
|
||||
type: 'array',
|
||||
description: 'Array of column names from the query result',
|
||||
items: { type: 'string', description: 'Column name' },
|
||||
},
|
||||
rows: {
|
||||
type: 'array',
|
||||
description: 'Array of row objects keyed by column name',
|
||||
items: {
|
||||
type: 'object',
|
||||
description: 'Row with column name/value pairs',
|
||||
},
|
||||
},
|
||||
totalRows: {
|
||||
type: 'string',
|
||||
description: 'Total number of rows in the complete result set',
|
||||
optional: true,
|
||||
},
|
||||
jobComplete: { type: 'boolean', description: 'Whether the query completed within the timeout' },
|
||||
totalBytesProcessed: {
|
||||
type: 'string',
|
||||
description: 'Total bytes processed by the query',
|
||||
optional: true,
|
||||
},
|
||||
cacheHit: {
|
||||
type: 'boolean',
|
||||
description: 'Whether the query result was served from cache',
|
||||
optional: true,
|
||||
},
|
||||
jobReference: {
|
||||
type: 'object',
|
||||
description: 'Job reference (useful when jobComplete is false)',
|
||||
optional: true,
|
||||
properties: {
|
||||
projectId: { type: 'string', description: 'Project ID containing the job' },
|
||||
jobId: { type: 'string', description: 'Unique job identifier' },
|
||||
location: { type: 'string', description: 'Geographic location of the job' },
|
||||
},
|
||||
},
|
||||
pageToken: {
|
||||
type: 'string',
|
||||
description: 'Token for fetching additional result pages',
|
||||
optional: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,224 @@
|
||||
import type { ToolResponse } from '@/tools/types'
|
||||
|
||||
interface GoogleBigQueryBaseParams {
|
||||
accessToken: string
|
||||
projectId: string
|
||||
}
|
||||
|
||||
export interface GoogleBigQueryQueryParams extends GoogleBigQueryBaseParams {
|
||||
query: string
|
||||
useLegacySql?: boolean
|
||||
maxResults?: number
|
||||
defaultDatasetId?: string
|
||||
location?: string
|
||||
}
|
||||
|
||||
export interface GoogleBigQueryListDatasetsParams extends GoogleBigQueryBaseParams {
|
||||
maxResults?: number
|
||||
pageToken?: string
|
||||
}
|
||||
|
||||
export interface GoogleBigQueryListTablesParams extends GoogleBigQueryBaseParams {
|
||||
datasetId: string
|
||||
maxResults?: number
|
||||
pageToken?: string
|
||||
}
|
||||
|
||||
export interface GoogleBigQueryGetTableParams extends GoogleBigQueryBaseParams {
|
||||
datasetId: string
|
||||
tableId: string
|
||||
}
|
||||
|
||||
export interface GoogleBigQueryInsertRowsParams extends GoogleBigQueryBaseParams {
|
||||
datasetId: string
|
||||
tableId: string
|
||||
rows: string
|
||||
skipInvalidRows?: boolean
|
||||
ignoreUnknownValues?: boolean
|
||||
}
|
||||
|
||||
export interface GoogleBigQueryCreateDatasetParams extends GoogleBigQueryBaseParams {
|
||||
datasetId: string
|
||||
location?: string
|
||||
friendlyName?: string
|
||||
description?: string
|
||||
}
|
||||
|
||||
export interface GoogleBigQueryDeleteDatasetParams extends GoogleBigQueryBaseParams {
|
||||
datasetId: string
|
||||
deleteContents?: boolean
|
||||
}
|
||||
|
||||
export interface GoogleBigQueryCreateTableParams extends GoogleBigQueryBaseParams {
|
||||
datasetId: string
|
||||
tableId: string
|
||||
schema: string
|
||||
description?: string
|
||||
friendlyName?: string
|
||||
}
|
||||
|
||||
export interface GoogleBigQueryDeleteTableParams extends GoogleBigQueryBaseParams {
|
||||
datasetId: string
|
||||
tableId: string
|
||||
}
|
||||
|
||||
export interface GoogleBigQueryListTableDataParams extends GoogleBigQueryBaseParams {
|
||||
datasetId: string
|
||||
tableId: string
|
||||
maxResults?: number
|
||||
pageToken?: string
|
||||
startIndex?: string
|
||||
selectedFields?: string
|
||||
}
|
||||
|
||||
export interface GoogleBigQueryGetQueryResultsParams extends GoogleBigQueryBaseParams {
|
||||
jobId: string
|
||||
pageToken?: string
|
||||
maxResults?: number
|
||||
timeoutMs?: number
|
||||
location?: string
|
||||
startIndex?: string
|
||||
}
|
||||
|
||||
interface GoogleBigQueryJobReference {
|
||||
projectId: string
|
||||
jobId: string
|
||||
location: string
|
||||
}
|
||||
|
||||
export interface GoogleBigQueryQueryResponse extends ToolResponse {
|
||||
output: {
|
||||
columns: string[]
|
||||
rows: Record<string, unknown>[]
|
||||
totalRows: string | null
|
||||
jobComplete: boolean
|
||||
totalBytesProcessed: string | null
|
||||
cacheHit: boolean | null
|
||||
jobReference: GoogleBigQueryJobReference | null
|
||||
pageToken: string | null
|
||||
}
|
||||
}
|
||||
|
||||
export interface GoogleBigQueryListDatasetsResponse extends ToolResponse {
|
||||
output: {
|
||||
datasets: Array<{
|
||||
datasetId: string
|
||||
projectId: string
|
||||
friendlyName: string | null
|
||||
location: string | null
|
||||
}>
|
||||
nextPageToken: string | null
|
||||
}
|
||||
}
|
||||
|
||||
export interface GoogleBigQueryListTablesResponse extends ToolResponse {
|
||||
output: {
|
||||
tables: Array<{
|
||||
tableId: string
|
||||
datasetId: string
|
||||
projectId: string
|
||||
type: string | null
|
||||
friendlyName: string | null
|
||||
creationTime: string | null
|
||||
}>
|
||||
totalItems: number | null
|
||||
nextPageToken: string | null
|
||||
}
|
||||
}
|
||||
|
||||
export interface GoogleBigQueryGetTableResponse extends ToolResponse {
|
||||
output: {
|
||||
tableId: string
|
||||
datasetId: string
|
||||
projectId: string
|
||||
type: string | null
|
||||
description: string | null
|
||||
numRows: string | null
|
||||
numBytes: string | null
|
||||
schema: Array<{
|
||||
name: string
|
||||
type: string
|
||||
mode: string | null
|
||||
description: string | null
|
||||
}>
|
||||
creationTime: string | null
|
||||
lastModifiedTime: string | null
|
||||
location: string | null
|
||||
}
|
||||
}
|
||||
|
||||
export interface GoogleBigQueryInsertRowsResponse extends ToolResponse {
|
||||
output: {
|
||||
insertedRows: number
|
||||
errors: Array<{
|
||||
index: number
|
||||
errors: Array<{
|
||||
reason: string | null
|
||||
location: string | null
|
||||
message: string | null
|
||||
}>
|
||||
}>
|
||||
}
|
||||
}
|
||||
|
||||
export interface GoogleBigQueryCreateDatasetResponse extends ToolResponse {
|
||||
output: {
|
||||
datasetId: string
|
||||
projectId: string
|
||||
friendlyName: string | null
|
||||
description: string | null
|
||||
location: string | null
|
||||
creationTime: string | null
|
||||
}
|
||||
}
|
||||
|
||||
export interface GoogleBigQueryDeleteDatasetResponse extends ToolResponse {
|
||||
output: {
|
||||
deleted: boolean
|
||||
}
|
||||
}
|
||||
|
||||
export interface GoogleBigQueryCreateTableResponse extends ToolResponse {
|
||||
output: {
|
||||
tableId: string
|
||||
datasetId: string
|
||||
projectId: string
|
||||
type: string | null
|
||||
description: string | null
|
||||
schema: Array<{
|
||||
name: string
|
||||
type: string
|
||||
mode: string | null
|
||||
description: string | null
|
||||
}>
|
||||
creationTime: string | null
|
||||
location: string | null
|
||||
}
|
||||
}
|
||||
|
||||
export interface GoogleBigQueryDeleteTableResponse extends ToolResponse {
|
||||
output: {
|
||||
deleted: boolean
|
||||
}
|
||||
}
|
||||
|
||||
export interface GoogleBigQueryListTableDataResponse extends ToolResponse {
|
||||
output: {
|
||||
rows: unknown[][]
|
||||
totalRows: string | null
|
||||
pageToken: string | null
|
||||
}
|
||||
}
|
||||
|
||||
export interface GoogleBigQueryGetQueryResultsResponse extends ToolResponse {
|
||||
output: {
|
||||
columns: string[]
|
||||
rows: Record<string, unknown>[]
|
||||
totalRows: string | null
|
||||
jobComplete: boolean
|
||||
totalBytesProcessed: string | null
|
||||
cacheHit: boolean | null
|
||||
jobReference: GoogleBigQueryJobReference | null
|
||||
pageToken: string | null
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user