feat(google-sheets): add filter support to read operation (#3333)

* feat(google-sheets): add filter support to read operation

* ran lint
This commit is contained in:
Waleed
2026-02-25 11:34:12 -08:00
committed by GitHub
parent 8b0c47b06c
commit 95304b2941
3 changed files with 100 additions and 1 deletions
+44
View File
@@ -440,6 +440,36 @@ Return ONLY the range string - no sheet name, no explanations, no quotes.`,
placeholder: 'Describe the range (e.g., "first 50 rows" or "column A")...',
},
},
// Read Filter Fields (advanced mode only)
{
id: 'filterColumn',
title: 'Filter Column',
type: 'short-input',
placeholder: 'Column header name to filter on (e.g., Email, Status)',
condition: { field: 'operation', value: 'read' },
mode: 'advanced',
},
{
id: 'filterValue',
title: 'Filter Value',
type: 'short-input',
placeholder: 'Value to match against',
condition: { field: 'operation', value: 'read' },
mode: 'advanced',
},
{
id: 'filterMatchType',
title: 'Match Type',
type: 'dropdown',
options: [
{ label: 'Contains', id: 'contains' },
{ label: 'Exact Match', id: 'exact' },
{ label: 'Starts With', id: 'starts_with' },
{ label: 'Ends With', id: 'ends_with' },
],
condition: { field: 'operation', value: 'read' },
mode: 'advanced',
},
// Write-specific Fields
{
id: 'values',
@@ -748,6 +778,9 @@ Return ONLY the JSON array - no explanations, no markdown, no extra text.`,
batchData,
sheetId,
destinationSpreadsheetId,
filterColumn,
filterValue,
filterMatchType,
...rest
} = params
@@ -836,6 +869,11 @@ Return ONLY the JSON array - no explanations, no markdown, no extra text.`,
cellRange: cellRange ? (cellRange as string).trim() : undefined,
values: parsedValues,
oauthCredential,
...(filterColumn ? { filterColumn: (filterColumn as string).trim() } : {}),
...(filterValue !== undefined && filterValue !== ''
? { filterValue: filterValue as string }
: {}),
...(filterMatchType ? { filterMatchType: filterMatchType as string } : {}),
}
},
},
@@ -858,6 +896,12 @@ Return ONLY the JSON array - no explanations, no markdown, no extra text.`,
type: 'string',
description: 'Destination spreadsheet ID for copy',
},
filterColumn: { type: 'string', description: 'Column header name to filter on' },
filterValue: { type: 'string', description: 'Value to match against the filter column' },
filterMatchType: {
type: 'string',
description: 'Match type: contains, exact, starts_with, or ends_with',
},
},
outputs: {
// Read outputs
+53 -1
View File
@@ -154,6 +154,26 @@ export const readV2Tool: ToolConfig<GoogleSheetsV2ToolParams, GoogleSheetsV2Read
description:
'The cell range to read (e.g. "A1:D10"). Defaults to "A1:Z1000" if not specified.',
},
filterColumn: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'Column name (from header row) to filter on. If not provided, no filtering is applied.',
},
filterValue: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Value to match against the filter column.',
},
filterMatchType: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'How to match the filter value: "contains", "exact", "starts_with", or "ends_with". Defaults to "contains".',
},
},
request: {
@@ -196,12 +216,44 @@ export const readV2Tool: ToolConfig<GoogleSheetsV2ToolParams, GoogleSheetsV2Read
spreadsheetUrl: `https://docs.google.com/spreadsheets/d/${spreadsheetId}`,
}
let values: unknown[][] = data.values ?? []
// Apply client-side filtering only when both filterColumn and filterValue are provided
if (params?.filterColumn && params?.filterValue !== undefined && values.length > 1) {
const headers = values[0] as string[]
const columnIndex = headers.findIndex(
(h) => String(h).toLowerCase() === params.filterColumn!.toLowerCase()
)
if (columnIndex !== -1) {
const matchType = params.filterMatchType ?? 'contains'
const filterVal = params.filterValue.toLowerCase()
const filteredRows = values.slice(1).filter((row) => {
const cellValue = String(row[columnIndex] ?? '').toLowerCase()
switch (matchType) {
case 'exact':
return cellValue === filterVal
case 'starts_with':
return cellValue.startsWith(filterVal)
case 'ends_with':
return cellValue.endsWith(filterVal)
default:
return cellValue.includes(filterVal)
}
})
// Return header row + matching rows
values = [values[0], ...filteredRows]
}
}
return {
success: true,
output: {
sheetName: params?.sheetName ?? '',
range: data.range ?? '',
values: data.values ?? [],
values,
metadata: {
spreadsheetId: metadata.spreadsheetId,
spreadsheetUrl: metadata.spreadsheetUrl,
+3
View File
@@ -129,6 +129,9 @@ export interface GoogleSheetsV2ToolParams {
includeValuesInResponse?: boolean
responseValueRenderOption?: 'FORMATTED_VALUE' | 'UNFORMATTED_VALUE' | 'FORMULA'
majorDimension?: 'ROWS' | 'COLUMNS'
filterColumn?: string
filterValue?: string
filterMatchType?: 'contains' | 'exact' | 'starts_with' | 'ends_with'
}
export type GoogleSheetsV2Response =