You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 96260f3
Browse filesBrowse the repository at this point in the historyBrowse files
fix(tables): derive select operator guidance from the validator's own sets
Round 2 review. Both bots were right, and the second finding corrected me.
The first fix annotated the column list but left the `filter` PARAMETER
description advertising every operator for every column. That description is
what a model reads when deciding the filter's shape, so the restriction has
to appear there too — it now names the restricted columns inline.
More importantly, the annotation itself was wrong: I omitted isNull and
isNotNull. I had traced the v2 grammar through `predicateToFilter` to the
`$`-prefixed sets in `column-types/select.ts`, which genuinely lack them —
but the v2 query path never goes through that conversion. It compiles
predicates directly in `fieldPredicate`, which gates on a SEPARATE pair of
`FilterOp` sets that do allow both.
Two allowlists for one concept is what made a hand-copied list wrong, so the
v2 sets move next to their v1 siblings in the column-type registry — where
per-type knowledge belongs — and the enrichment now derives its text from
the exact sets the validator gates on. It can no longer drift.
Same correction applied to the block's bestPractices, which carried the
short list too.
- like/ilike use * as the wildcard (e.g. {"field":"name","op":"ilike","value":"*jo*"}).
243
243
- Omit Limit to get the entire matching result in one response — the query fails with a clear error if it exceeds 5MB (narrow with a filter or set a Limit).
244
244
- With a Limit, pages can end at the Limit or the 5MB byte budget, whichever comes first — pass nextCursor back as the cursor and loop until it is null; never infer completion from page size.
245
-
- For substring matching on a text column use ilike with *x*. A select column accepts only a subset of the operators — eq/ne/in/nin when single, contains/ncontains when multi (a multi-select cell holds a list) — and the query is rejected outright on anything else.
245
+
- For substring matching on a text column use ilike with *x*. A select column accepts only a subset of the operators — eq, ne, in, nin when single; contains, ncontains when multi (a multi-select cell holds a list, matched by option name) — plus isEmpty, isNotEmpty, isNull, isNotNull on both. The query is rejected outright on anything else.
246
246
- Use Columns to Return to keep only the fields a downstream step needs (e.g. ["col_email","name"]) — the 5MB budget counts only the returned columns, so narrowing columns is another way to fit a large table; leave it empty for every column.`,
5. like/ilike use * as the wildcard, e.g. {"field":"name","op":"ilike","value":"*jo*"}
121
-
6. Any column listed below with a restricted operator set accepts ONLY those operators - the query is rejected outright otherwise. A multi-select cell holds a list, so match it with contains, never ilike
144
+
6. Any column listed below with a restricted operator set accepts ONLY those operators - the query is rejected outright otherwise. A multi-select cell holds a list, so match it by option name with contains, never ilike
122
145
7. For substring matching on a text column use ilike with *x*
123
146
8. For ranking queries (highest, lowest, Nth, top N) set order and a small limit, e.g. limit 1 for the highest, 2 for the second highest
124
147
9. Omit limit to return every matching row; the query fails if the result exceeds 5MB, so narrow with a filter instead of guessing a limit
@@ -233,7 +256,7 @@ export function enrichTableToolParameters(
233
256
if(enrichedProperties.filter){
234
257
enrichedProperties.filter={
235
258
...enrichedProperties.filter,
236
-
description: `Predicate built from the user's question using columns: ${columnNames}. One condition is {"field":"<column>","op":"<operator>","value":<value>}; combine with {"all":[...]} for AND or {"any":[...]} for OR. Operators: eq, ne, gt, gte, lt, lte, in, nin, like, ilike, nlike, nilike, contains, ncontains, startsWith, endsWith, isNull, isNotNull, isEmpty, isNotEmpty. Omit only to match every row.`,
259
+
description: `Predicate built from the user's question using columns: ${columnNames}. One condition is {"field":"<column>","op":"<operator>","value":<value>}; combine with {"all":[...]} for AND or {"any":[...]} for OR. Operators: eq, ne, gt, gte, lt, lte, in, nin, like, ilike, nlike, nilike, contains, ncontains, startsWith, endsWith, isNull, isNotNull, isEmpty, isNotEmpty.${hasSelectColumn(table) ? selectRestrictionNote(table) : ''} Omit only to match every row.`,
0 commit comments